How do I do it better?

I am using an extended Applet class as an Image Producer (for my software sprite rendering):

public class myApplet extends Applet implements ImageProducer

Setup code:

_model = new DirectColorModel(32,0x00FF0000,0x000FF00,0x000000FF,0);
                  
_image = createImage(_width,_height);
_graphics = getGraphics();

Now by getting the graphics object (from the Component I presume) this means that my render is using AWT, right?

My render function contains:


// get current buffer
int pixels[] = myStrategy.current.dest;
// check consumer
if (_consumer!=null)
{
// copy integer pixel data to image consumer
    _consumer.setPixels(0,0,_width,_height,_model,pixels,0,_width);
                              
// notify image consumer that the frame is done
     _consumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
}
// draw image to graphics context
_graphics.drawImage(_image, 0, 0, _width, _height, null);

paint() & update() are both empty functions.

I get the feeling that this ‘drawImage’ call can stall for quite a while - I am averaging 25 fps at the moment (Athlon 2 GHz, ATI Radeon 9500, - I should be able to render a bit faster than 25 fps!

If I cover up most of the rendering window, I get a tasty 60 fps - the refresh rate. All my software sprite rendering is still filling the whole screen as it does not account for visible window area, so it must be just the render to the window. Taking close to 24ms just to draw my 640x480 window when I can fill it (with about 2x overdraw) and do the game logic in under 16ms is crazy.

A profile shows most of time in the event loop, & Im not sure exactly what this means. All the articles on profiling I have looked at normally say ‘we’ll ignore the entry for the event loop’. Bah! :-/

My question is really this:
How do I draw to the window, in the fastest, most efficient way possible? Oh - and Java 1.1 compatible too.

  • Dom

Doing it in software is ment to be slow :slight_smile:

Take a look at the Java Emulation Framework if you didn’t do that already. IIRC it’s 1.1ish… but I can’t check it right now (We’re Sorry. The SourceForge.net Website is currently down for maintenance. We will be back shortly).

In JEF we did basically the same although we didn’t implement ImageProducer in an applet, but created a seperate class. Shouldn’t matter I suppose.

You could try setting some hints:

_consumer.setHints(ImageConsumer.TOPDOWNLEFTRIGHT|ImageConsumer.COMPLETESCANLINES|ImageConsumer.SINGLEPASS|ImageConsumer.SINGLEFRAME);

We created the image differently

_image = Toolkit.getDefaultToolkit().createImage(this);

but I don’t know if that will make any difference. It won’t ever be really fast, that’s for sure.

(BTW, JEF is fully 1.1 compatible (not 1.1ish ;)). It does support JavaSound though if it’s available. If not, it’s falls back to com.sun.audio (or whatever the package is).)

Erik

Thanks for the replies…
What we have is basically the same as the JEF code - including the hints when a consumer is set.
I was just hoping there was some other (possibly undocumented way!) to perform the final image to window draw, as this seems to be the slowest part.
Its strange that the final copy to the screen takes longer than my full software rendering (including z-buffering!) Now if I could just get the display surface as an array of pixels…

  • Dom

Use a pixelgrabber to get a pixel array. Good luck, every time I’ve tried this I’ve gotten fairly decent framerates until after about 20 seconds it goes to about 1 fps.

http://www.geocities.com/nonnus29/mode7/mode7.htm

This version may be using a buffered image, I’ll mem image source version up later and post the source.

I’d love to figure this out.

Really, working with pixelsdirectly isn’t the fastest way. If possible, avoid using PixelGrabber/ImageConsumer/ImageProducer. They’re really old 1.1 apis, and we don’t pay much attention to optimizing them in newer releases. For example, PixelGrabber has gotten hundreds of times slower in 1.4 due to our under the hood acceleration for the generic case (you can look up the bug on JDC).

Try using our primitves for rendering. Take a look at our performance paper for more hints:
http://java.sun.com/products/java-media/2D/perf_graphics.html

I would love to use the 1.4 drawing code, except for two issues:

  1. 75% of the website visitors we had did NOT have Java 1.4, and would not say ‘yes’ when the dialogue box popped up asking them to install it. As a commercial venture, losing 75% of potential customers at this stage is unacceptable. By making our games 1.1 compatible, we now have just 25% of people failing to load the game (they quit the page before the applet loads - either no Java, or they get bored, etc.). I have posted on this subject at great length before.

  2. We are now doing things with the pixels that you cannot do even in 1.4. This includes alpha blending that does not slow the framerate to a crawl, z-buffering (yum yum!), rotating & flipping sprites, etc. etc. We are planning on writing a full software 3D renderer for the same reasons as (1).

We will probably always be using 1.1 code (as do the large players like Popcap.com), unless we switch entirely to something like C# or straight ActiveX controls (which Popcap have now done for the first time). Neither option is particularly appealing, but we will do whatever it takes to get our games as easily accesible as possible to the majority general public. By ignoring these older features (& making them worse in fact) you are damaging the use of Java for web browser games in general. If a game runs badly in Java, the average user won’t upgrade - he will switch it off and go find a Flash game that runs Ok.

  • Dom

I agree on most of what you’re saying. Some comments, suggestions:

  • I wonder if you consider going trough the lengths of writing a 3D software renderer, how much influence it would make in the number of users saying ‘yes’ to the 1.4 download dialog if you would be using fancy willy waving fully accellerated blisteringly fast 3D graphics instead of slow software 3D. I could imagine demand for fast 3D could be much higher than software 3D, perhaps even making up for the lower number of people having 1.4 installed (or people willing to upgrade). Software 3D is a bit outdated don’t you think?

  • Have you considered using JPCT as the software 3D renderer? It’s really good, supports 1.1, but also supports LWJGL for hardware accelerated 3D (the latter requires 1.4). So by using JPCT you could have it both ways.

Software rendering was just for the 1.1 compatability & running in a web browser that we are after.

JPCT looks very interesting - if it does everything it says it does fast enough then it would save me a fair amount of effort (although I was writing software renderers for PC games before so its not as much work as it would be if I hadn’t done it before, if you get my drift). THe automatic switch to OpenGL rendering sounds very tasty - it just depends on library size 7 formats - so I will give it a good look.

Thanks for that one :slight_smile:

  • Dom

Stuck in the Applet 1.1 world is nasty :-[

You have my sympathies. My suggestion is to do another version under Java2 thats run through either webstart or Java Plugin, and just have a “For a faster game, download JRE1.4” link :confused:

Yes, you can even integrate 1.1 and java2 code in the same applet so that it will revert to slow 1.1 if java2 is not available. There was a spectrum emulator that did just that.
And still have the ‘upgrade to java2 for better performance’ -link of course :slight_smile: