minimizing image bit depth and resolution for better performance?

But according to the code you’ve posted you do render to a BufferedImage.

The BackBuffer is defined as BufferedImage. Am I missing something? Or this piece of code
is some old version?

What image did you get the ImageCapabilities from?

Dmitri
Java2D Team

Just to answer the original question: if everything is setup correctly and we can accelerate
your image, the cached copy will be kept in vram in the best format possible, it doesn’t matter
what bit depth the original image was in.

Suppose you have a 24-bit opaque image, but the current display mode is 16-bit. The vram-cached image
will be in 16-bit format. There are some details specific to the pipelines, but in general you
can’t affect what format the image will be accelerated in.

But you can save some heap space if you use a smaller bit depth for your artwork.

If we can’t for some reason use the hw acceleration (like it appears to be in your case),
we’ll use our software loops. For those the pixel size that matters but whether
or not we have a specific loop for the particular image format. Or, should I say,
it matters more than the pixel size.

Dmitri
Java2D Team

indeed, it’s an old version. i’ve moved to double buffering using buffer strategy somewhere in the middle of this post :slight_smile:

Hey folks,

In this thread, a few people (Abuse and Dmitri) seem to imply that it’s possible to get hardware acceleration using a BufferStrategy in Windowed Mode (good for debug)…

I’m trying to do this, and I get a runtime Exception:

java.lang.IllegalStateException: Component must have a valid peer
at java.awt.Component$FlipBufferStrategy.createBuffers(Component.java:3023)
at java.awt.Component$FlipBufferStrategy.(Component.java:2998)
at java.awt.Component.createBufferStrategy(Component.java:2925)
at java.awt.Window.createBufferStrategy(Window.java:2041)
at java.awt.Component.createBufferStrategy(Component.java:2857)
at java.awt.Window.createBufferStrategy(Window.java:2016)

The fullscreen code I have that works is:

        mainFrame = new JFrame(gc);
        mainFrame.setUndecorated(true);
        mainFrame.setIgnoreRepaint(true);
        device.setFullScreenWindow(mainFrame);
        if (device.isDisplayChangeSupported()) 
        {
            chooseBestDisplayMode(device);
        }
        
        mainFrame.createBufferStrategy(2);
        bufferStrategy = mainFrame.getBufferStrategy();

… and the windowed code that doesn’t is:

        mainFrame = new JFrame("title");
        mainFrame.createBufferStrategy(2);
        bufferStrategy = mainFrame.getBufferStrategy();  

… and it throws the Exception on the second line (mainFrame.createBufferStrategy(2):wink:

I remember reading somewhere that the frame the BufferStrategy is created from needs to be ‘undecorated’, but if I call mainFrame.setUndecorated(true) after I construct it, it doesn’t seem to make any difference.

Any ideas?

Cheers,

Ricky

isDisplayable() must return true, i.e. the Frame must be attached to a native screen resource.
You achieve this by simply making the Frame visible i.e. setVisible(true).

The reason your fullscreen code worked, is because setFullscreenWindow(…) itself makes the Frame displayable.

Ah cool - that works!

I now have:

        mainFrame = new JFrame("title");
        mainFrame.setVisible(true);
        mainFrame.setIgnoreRepaint(true);            
        mainFrame.createBufferStrategy(2);
        bufferStrategy = mainFrame.getBufferStrategy();

I get only about half the FPS running in windowed mode, versus fullscreen mode (~20 a second versus ~ 40). Does this sound normal?

I wouldn’t expect that much of a performance hit, no.

The only reason Windowed should be slower than fullscreen, is because blitting will be used instead of page flipping to transfer data to the front buffer.

Unless you have a very poor graphics card, the difference between these 2 methods is small.

Ofcourse, there maybe other things happening in the background - something on your desktop or taskbar continually updating for instance can completely kill windowed performance, (I believe because of the context switching between GDI<->DirectDraw?)

Only 40 fps in fullscreen? your game must be doing quite alot of rendering & game logic to kick the framerate so low :S

Hmm, no, I didn’t think so.

My card is a Radeon9800, so perhaps background tasks are hurting me, yes

Also, I’m running it through Eclipse. I’ll have to kill as much as I can and see how it does then.

As for my fullscreen framerate, that was actually my next point of investigation last night. I have a bunch of objects (well, okay, they’re caterpillars), crawing along an undulating 2D landscape made of straight line segments. In their paint method, I call g.rotate(angle) … paint … g.rotate(-angle), to paint the caterpillars rotated to the angle of the line they’re currently on.

The totally weird thing is that if I have only one caterpillar, I get 60fps a lot of the time, until he hits particular line segments, and thus his angle is set to certain values (seemingly greater than 6 radians, and less than 0.5 radians). Then, with these angles, the framerate falls to more like 30-40fps (so when I have a bunch of caterpillars, the chances are the framerate stays low most of the time).

Even weirder - this still happens even if I don’t paint anything of the caterpillar, i.e.

g.translate(catx, caty);
g.rotate(angle);

// nothing here…

g.rotate(-angle);
g.translate(-catx, -caty);

Oh, and I’m calling g.rotate all over the place elsewhere in my game, and it seems to cope fine with all those cases - it’s just this one that causes the drop.

I realise that this is perhaps too weird to get a simple answer for. I’ll have to try to isolate it as a test case, but my concern is that maybe it’s happening only in combination with all the other stuff I’m painting - kind of a final-straw scenario.

Any wild speculation folks have would be appreciated anyway!

Cheers,

Ricky

[broken record]
blits that have a Transform other than translate will not be accelerated unless you enable the opengl pipeline.
[/broken record]

Well, I’m doing this in Eclipse’s ‘VM arguments’ :

-Dsun.java2d.opengl=true

(And I’ve also tried -Dsun.java2d.d3d=true)

Does that not enable the gl pipe?

Like I say, I’m doing g.rotate all over the shop, without any framerate dropout - it’s just this one instance that causes problems, and even then only with certain angles.

And it still slows down even if I don’t blit (just rotate).

I’ll try to isolate it as some test code if possible.

I think the problem could be a rounding error somewhere. Up to a point your rotate(angle)…rotate(-angle)
turn the transform on and off, but at some angle the restored transform that’s left after rotate(-angle) may
have some tiny amount of rotation left because of rounding error, which means that all the rest of the
rendering will be rendered transformed, even though you don’t see it.

So one suggestion would be to instead of rotate/unrotate try savetransform/rotate/restoretransform .

Also, I can’t find it, but I believe there was a bug fixed in mustang (jdk6.0) which at least partly addressed
this. Could you please try mustang (http://mustang.dev/java.net)?

Thanks,
Dmitri
Java2D Team

This sounds pretty plausible, and it reminded me of the last thing I did in desperation last night before going to bed - I tried casting my double to a float, i.e.

g.rotate((float)angle);

g.rotate(-(float)angle);

This seemed to have the effect of changing the angles for which the slow-down occured (so angles which previously were fine now caused problems, and angles which were slow were now fine).

I’ll try your suggestion this evening, and check out mustang too…

Cheers,

Ricky

Marvellous! That fix works - thanks Dmitri.

I now have:

AffineTransform transform = g.getTransform();
g.translate(x, y);
g.rotate(angle);

g.setTransform(transform);

… and I’m back in the wonderful world of 60fps. I’m guessing this way is also slightly more optimal.

For reference, the values causing the trouble were:

0.41887902047863906 (Math.toRadians(24))
6.073745796940266 (Math.toRadians(348))
1.4311699866353502 (Math.toRadians(82)).

Thanks for the help. I’ve downloaded Mustang - will check it out soon

Ricky