MemoryImageSource vs. BufferedImage

Started by Fencer, May 01, 2008, 05:14:52 PM

Previous topic - Next topic

Fencer

I have noticed that jPCT takes advantage of BufferedImage (if available), otherwise is uses a MemoryImageSource for software rendering (in Java 1.1, right?).

This point caught my attention because I would like to know which method is the best (fastest) one to make a software rendering with an ability to manipulate pixels directly. I read many articles about this topic, some of them say that a MemoryImageSource with an ImageProducer is still the fastest one, some of them claim that BufferedImage is preferred on Java 1.4+, etc. The conclusion is that I am just confused and I am not sure about anything.

Would someone know the answer to this issue?

EgonOlsen

I've never noticed a large difference between them. Usually, BufferedImage (where available) was a little faster for me. We'll see what the next Java6 update will bring, because the alpha version killed BI-performance on some machines...but i doubt that it'll handle MIS better.

Fencer

Thanks, that's what I thought.
I guess that one of BufferedImage benefits is that it can be hardware accelerated but it is probably not applicable when the image is fully rendered 100 times a second.

EgonOlsen

Quote from: Fencer on May 01, 2008, 08:00:14 PM
Thanks, that's what I thought.
I guess that one of BufferedImage benefits is that it can be hardware accelerated but it is probably not applicable when the image is fully rendered 100 times a second.
Yes, and that's the problem with Java6 update10. It defaults to a new D3D-pipeline, which is (due to the way D3D9 works) rather slow in that case. There's a bug for it, why don't you vote for it?  ;D http://bugs.sun.com/view_bug.do?bug_id=6652116

Fencer

I've just voted.  8)
By the way, I hope it's not too off-topic to discuss these issues here.

EgonOlsen

No, it's fine to discuss this here. Thanks for voting... ;)

Fencer

No problem. I have read the java.net thread about this topic (http://forums.java.net/jive/thread.jspa?threadID=35484&tstart=0) and the problem seems to be more complex than I ever thought.

For instance, I am developing an applet game which is displayed in 618x406 area and when I measure FPS value, it gives me 50-60 on my laptop with Intel Core 2, Nvidia GeForce Go 7400 and Windows Vista (I should add that I am not using any pixel manipulation yet, I just create a BufferedImage as a back buffer, draw all sprites there using Graphics.drawImage and then blit it to applet canvas).

What I don't get is that when I try to add this param to the applet code

    <param name="java_arguments" value="-Dsun.java2d.d3d=false -Dsun.java2d.opengl=true">

it does nothing in most cases but sometimes it increases FPS to 190-200. I am using Java Plugin 1.6 update 5, not the mentioned update 10.

As far as I know, it should make no effect to pass the java_arguments to applet prior to update 10 plugin, which makes me even more confused. Can it be a Vista-specific behavior? I have tried it with Firefox 2, Internet Explorer 7 and Opera 9, all of them show the same results.

Fencer

Quote from: EgonOlsen on May 02, 2008, 09:35:54 AM
No, it's fine to discuss this here. Thanks for voting... ;)

Very well, since it is fine, I have another dilemma to solve:

My applet game is using hundreds of small-sized sprites to draw on every frame and I am currently doing it with the standard Graphics.drawImage method. However, I am not sure how the drawImage method works under the hood, and since I've been observing some kind of slowdown when the number of sprites is high, I am thinking about a better performing way to do it.

So the question is, which of the following approaches is better?

1) Convert all sprites (which are loaded as png images at the applet start) to pixel arrays and simply copy them to the proper positions of the offscreen pixel array (obtained from BufferedImage or ImageProducer etc.). Since I want to do some particle using effects after all sprites are drawn (smokes, fires etc.), I would need to modify the target image pixels anyway.

2) Keep the current code, i.e. draw all sprites using drawImage methods, then get the resulting pixel array and do all required pixel modification stuff.

I don't want to rewrite what doesn't have to be rewritten. On the other hand, I need the best possible performance, and I am afraid that any kind of hardware acceleration cannot be used here (or am I wrong?).

Thanks for any tips.
Filip

EgonOlsen

Write some test cases. It's difficult to say without trying. I tend to say that using drawImage() should be faster, but if you are grabbing the target image's pixels anyway, you may destroy the advantage of automatic hardware acceleration that you would be getting by using drawImage.