PS:CPU Usage was around 17-20% on an Intel Core i5-2540M 2.6GHz 2-Core, 4-Logical Processorswhen i used the BufferedImage...But when i used the VolatileImage, this sank to about 6-7%..That is because now the GPU is used to take the load of the CPU.Now i can have lots more stuff in the GameLoop

...I thought Java2D could never take advantage of the GPU. Are you sure that is what's actually happening?Simply changing to a volatile image shouldn't make that kind of difference...unless I've totally missed something

Yes since java 1.5 all images loaded will try and become manged images if they can.

The major thing that volatile can do better than bufferedImages is acting like a backbuffer.

volatileImage.getGraphics() /BufferedImage.getGraphics()

draw...draw...draw....

BufferedImages are slow for this but for just using BufferedStrategy and g2d.drawImage there is no difference and you really get no speed boost for using a volatile image as a back buffer instead of a BufferedStrategy

That's right. Though I think since JDK1.5 BufferedImage converts to VolatileImage under-the-hood when it can.

Not quite accurate. A managed BufferedImage can automatically cache the data in the graphics hardware for rendering from, but all rendering to it happens in software. A VolatileImage can be rendered to by the hardware pipeline. BufferedImage is more akin to texture, VolatileImage to FBO - in fact, from recollection that's how they're done in the OpenGL pipeline.

Just ran some tests and without any transparency, volatileimages are much faster then most bufferedimages. With transparency, they are 10-15% slower.

Basically Alphacomp will give you a huge slow down (8300 sprites) 80fps to 8fps when using volatileimages. So anything that does not need to fade or have any transparency should be a volatileimage (backgrounds and stuff);

Hehe win 7 d3d and I just ran it under opengl pipeline and buffered images were as good as volatile and they can load transparent images where volatile cannot....well I have never gotten them to. And opengl flag also boosts alphacomp performances as well...

Managed BIs are accelerated when used as source, when used as destination ("drawing on bufferedimages"), they are strictly CPU only.I did the new xrender java2d pipeline thats in jdk7, I know its the same for the opengl pipeline and thinking about the java2d-internals I really doubt the d3d pipeline accelerates rendering TO BIs.

So the code posted compares software-only rendering with hw-accelerated rendering, but by using a BufferedImage as buffer (=destination) it doesn't give "image management" even a chance.

Basically Kerai summed it up quite nicely:

Quote

Java2D tries to cache BufferedImage as texture whenever possible, so drawing it anywhere is as fast as drawing texture.problem is.. drawing ON BufferedImage is performed in software, while drawing ON VolatileImage is (if possible) on GPU.so its only faster to use VolatileImage if you want to draw ON IT, otherwise its better to use compatible BufferedImage.

Thanks Linuxhippy for backing up Kerai and my points about this earlier. I think this is now the third or fourth thread recently I've picked up ra4king on this.

As Riven correctly pointed out (pity about the second sentence! ) Kerai's information is somewhat old. There is no need to use a compatible image for it to be managed since Java 5. In fact, I've generally found createCompatibleImage(..) to be more trouble than it's worth, particularly on Linux in the past - YMMV.

I'm working on my rendering classes now, and from what I've gathered from the java API, one thing that forces an image to Software mode is exposing the underlying data structure as a Java type (For example, a int array of RGBA values).

This is a problem for me, as I intended to expose said data structure to be able to operate directly on a per-pixel basis. This is how I get said structure:

Right now yes, it is a 1:1 process, each frame is drawn before showing, but that's just because it's still under development.

My first idea is to decouple the rendering process from the drawing process, so frames are only sent to the drawing surface once they are complete (not sure if this would help).

Then, to further save on processing, split the frame into layers to be assembled, reusing those that need not be updated as often (for example, backgrounds).

Thing is, in the test I have now, I'm applying a full-screen static filter (Made by randomizing the lightness value on a per-pixel basis), so I don't see how can I break such a thing down so as not to need to update the pixel buffer each time.

Keep in mind I'm a graphics pipeline noob here, bashing my head in an effort to learn!

Thing is, in the test I have now, I'm applying a full-screen static filter (Made by randomizing the lightness value on a per-pixel basis), so I don't see how can I break such a thing down so as not to need to update the pixel buffer each time.

If you're manipulating the whole image array each time before you draw it, it will never be accelerated. You're processing it in software!

Then, to further save on processing, split the frame into layers to be assembled, reusing those that need not be updated as often (for example, backgrounds).

This is the only scenario where it may be worth worrying that an image is forced to unmanaged (software only) mode. If you manipulate the pixel array of a background image, then draw it to the screen 10, 100, 1000 ... times, consider drawing it to another BufferedImage (that you haven't grabbed the array of!) first. This will mean the image can be cached on the graphics card and so faster to draw to the screen.

A BufferedImage is always stored and manipulated in software - the pixels are stored in Java memory. What "managed image" means is that when you draw the image more than once to the screen, Java2D will try to cache a copy of the image on the graphics card rather than uploading the pixels each time. Each time you draw on a BufferedImage, the cached copy is invalidated and drawing the image will not be accelerated again at least the second time you draw it to the screen. Grabbing the pixel array means the image is never cached on the graphics card.

Therefore, to put it simply, unless you draw an image more than once to the screen before you modify it again, it is pointless to worry about grabbing the pixel array.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org