1.1 performance renderer

Hey guys,
I’m trying to write a high-performance Java 1.1 renderer for a 2d game and am having some frustrations. Things run okay, but I’m convinced there are more efficient ways to push image data around within Java.
Here’s what the renderer does:

DirectColorModel cm = new DirectColorModel(24,0x00ff0000,0x0000ff00,0x000000ff);
mis = new MemoryImageSource(m_width, m_height, cm, m_pixels, 0, m_width);
mis.setAnimated(true);
m_image = GetAppInstance().createImage(mis);

Then, for every frame, the renderer writes to the m_pixels int array, calls mis.newPixels() and repaint()s. When Applet.paint() is called, it does a g.drawImage(mis, 0, 0, null).

The problem is that, in 550x400 at 25 fps, the newPixels() call takes 1/3 of a frame, and the drawImage() takes about 1/2. This only leaves a 1/6 of a frame for the game to do its real work. Does anyone know if this is normal? Is it possible to combine these two calls? This is a painful overhead.
Thanks for your help.

Argh…
Maybe it would help if I was more specific, eh?
-no important code is taking place in synchronized() or try/catch blocks
-most of this code is running in a separate thread from the browser
-full window updates (all 550x400 pixels) are, unfortunately, necessary

Here’s a speed breakdown. In a 40 ms frame:
14 ms - newPixels()
17 ms - drawImage()
8 ms - renderer fooling around with the int[] m_pixels

This leaves a sad 1 ms/frame for other game code. Is it possible I’m hitting a bus bandwidth limitation? I’m at a loss for further ideas. Any expert advice is most welcome.

On my machine (PIII 600 MHz, 256 RAM) simple filling the pixels array then displaying the 550x400 image (MemoryImageSource, etc.) in applet (within MS IE 6) take:
~28 FPS for MS Java
~11 FPS for Sun Java 1.4.1

I think that this is the AWT 1.1 limitation… not the bandwidth one… :frowning:

This is perfectly normal I’m afraid.

You should try using a 32 bit colour model though with:


dcmModel = new DirectColorModel(32, 0xff0000, 0xff00, 0xff);

Using a desktop colour depth of 16bits will also speed this up considerably.

Although at the end of the day the PIII just falls over - best solution for this is to get an Athlon!

You should also try using a BufferedImage, this will speed it up to the point of a redraw being a non-issue, especially in Java 1.4.1 as MemoryImageSource has been sidelined (since 1.2.1 I believe) and has steadily been getting slower and more buggie (I wont use 1.4.1 until it’s fixed).

So slow in fact that MS 1.1.4 JVM can usually beat it (but there in lies a riddle, with an interesting answer).

Interestingly it is still quicker to use a 32bit colour BufferedImage when using a 16bit colour desktop, especially for IBM’s 1.3 JVM.


Woz.

You can also get better results by not using MemoryImageSource, but by writing your own ImageProducer class (MIS is an ImageProducer implementing class).
The mis.newPixels() slows things down.
For an example, go to jef.sourceforge.net, dl the source and look at jef.video.GfxProducer. It’s fairly easy.

But… rendering in pre-1.4 will never be really fast.

I’ve just looked in my code (the old one) and found that actually my timing above was made with my class implementing ImageProducer interface… not MemoryImageSource… :stuck_out_tongue:

Thank you, thank you, thank you… :smiley:

I’ve been using MemoryImageSource since forever - never bothered implementing my own ImageProducer since I figured the default implementation was so simple that there could hardly be any perfomance gains in messing with it.

How wrong I was.

And what’s MUCH more important: it made me realize that I could blit my circular buffers in a single blit by wrapping data in the imageproducer rather than when blitting -> much faster and no shearing artifacts.

Thank you… In 30 minutes work I doubled my potential framerate. Why the f*ck is stuff like this not in the official documentation from Sun? Or in a tutorial? No wonder people think Java is slow…

Same thing with the color model issue - hardly documented, yet choosing the wrong model can chop your framerate in half with no warnings or indications of problems what-so-ever.

The Java gaming community needs a list of do’s and dont’s with respect to the performance of std. core java libraries (eg. JavaSound)…

Thats because Sun is crap! :-X :stuck_out_tongue: :-X

That even the idea of providing decent documentation is beyond them.

A MemoryImageSource is a ImageProducer anyway, so there is (usually) little if no difference between performance.

The big kill is the 32 bit colour model over the crappy 24 bit colour model - this makes a massive difference.

But I do hope you are implementing a BufferedImage for Java 2 folk as this much faster than an ImageProducer.

The best thing most Java developers can do is ignore those near useless JavaDocs and go straight for the source code, you will learn more about how java works. Although there are plenty of unreference static attributes - what they are for can sometimes be a mistery!

Don’t even get me started on Java Sound, it does work - just! - if you stay with certain parameters. Always use 44.1Khz Stereo 16bit sound as it may not work right if you don’t. (Problems with different sound card et al.)

I was under the impression that they had got someone in to fix it, but that was ages ago and still it has the worst latency I have ever seen.


Woz.

P.S.
Does this class as trolling? Pitty on the old board they would have thrown me in the troll bin!

A little harsh maybe - Sun did create a wonderful (free) language and software platform in Java and its VM ;). I do agree though, that their core APIs are mysteriously inefficient compared to the platform itself.

I think it’s odd how MemoryImageSource can be so much less efficient than my own implementation - try calling newPixels twice on a MemoryImageSource. BAD idea, yet, in my own class I update several smaller chunks and it doesn’t seem to have any impact at all.

I guess the conclusion is that there’s no point in EVER using MemoryImageSource.

As for buffered Images - I doubt if I will have much to gain as I rely heavily on pixel-operations and have multiple gfx layers added/blended and multiplied together (extensive framebuffer access both read and write) - I assume the speed improvement with buffered images comes from storing data in vmem, no?

Hey guys,
Thanks for the help. The ImageProducer wasn’t that hard to implement (thanks NielsJ and erikd), and is buying me about a 20% speed increase. That could be because it’s allowing me to draw 20% fewer unnecessary pixels. Regardless, it’s good to see these gains.
Lavahead

the other url is somewhat empty right now :>

[quote]the other url is somewhat empty right now :>
[/quote]
Oops :stuck_out_tongue: