[java] Direct rendering speed results ( awt vs java2d )

Started by
16 comments, last by snowmoon 23 years, 4 months ago
I have finished doning some rough testing of various drawing routings in respect to java direct screen rendering. These were on a pIII700, but I believe most of the routines are memory/bus limited more than anything else, and %80 of execution time was in native methods of either awt or java2d. Ok here are the results all results were from drawing 1200 32x32 tiles ( 4 layers ) on the 640x480 screen. This represents a total of 1,228,800 pixels per frame. Not too shabby. Old style offscreen image + opaque images 20fps@16bit 15fps@32bit MemoryImage 1 + copyarray 11fps@16bit 10fps@32bit MemoryImage 2 + copyarray 2.29fps@16bit 13fps@32bit BufferedImage + drawImage 55fps@16bit 30fps@32bit BufferedImage + copyarray 58fps@16bit 33fps@32bit Buffered + copyarray 16bit 300 tiles( 1 layer ) 142fps So as you can clearly see if you do any direct rendering of images your choice is clear, use BufferedImage. It looks to be 2.5-25x faster than the equivialint awt functions. There are drawbacks. It only runs under the java2d ( java1.1 with j2d or 1.2+ ). To get the best speed you have to write a handler for each DataBuffer type byte, short, unsigned short, and int. Well I''m going to get back to work, just though all you out there might be interested.
Advertisement
Interesting numbers. It would be greatly appreciated if you could post the code for your tests somewhere and drop a link to it here. What exactely do you mean by BufferedImage + copyarray, do you just copy your tiles using arracopy into the databuffer and then draw the image with drawimage?

Henry
Not quite. When I say arraycopy I use ayyapcopy to blit raw short ot int data into the surface array. With the memory image source you then have to update the imageproducer to key the data update. Under buffered image you get an array into the buffer and you just update it.

If others would like to see the code just shout, if I get enough people I''ll write an article for gamedev. I''m also finishing the helper chlasses so I can do...

main() {
ForcedTimingLoop test = new ForcedTimingLoop( new Component );
test.drawResultsOverImage();
test.run();
}
Ok, thanks, that was what I meant too. You copy the data of the tiles using arracopy into the array that you get from the DataBuffer of the BufferedImage, but you still use drawImage in your paint method to draw the BufferedImage to screen.

Btw, read in the Java2D FAQ that jdk1.4 will feature a new hardware accelerated rendering technique:

http://www.javasoft.com/products/java-media/2D/forDevelopers/java2dfaq.html#accel

Henry
Wow, interesting stuff. Naysayers will be caught off guard when jvm starts exceeding compiled languages in time to market and overall performace. I''m a little upset that they are only planning these enhancements for the win32 platform kinda negates the platform independance thing. I checked the early access area and 1.4 is still not availible yet.

The performace of BufferedImage is more than enough for what I''m trying to do, and with a nice wrapper interface I should be able to run transparently on java1.1 and java1.2+ platforms assuming they are fast enough. I did the math my drawing routines are pushing almost 200 MB/s not that bad for a language most people consider slow.

Now if they could only incude functional mulit-track audio mixing I would be set. Java Media 1.0 looks good I just need to sit down and play with it.

Well, since the VolatileImage interface will be available in all implementations of the JDK, I am assuming that they will use it to enhance the rendering speed on Linux and other platforms too. IBM might do it for Linux if Sun ignores that platform.

I am not entirely satisfied with the speeds that you present though. First off, you ran the tests on a very fast computer (wonder what kind of rates I''ll get on my ol'' PII 450). Second, since you can not change the screen resolution from Java you will either require some native code that changes the resolution to 640*480 or your image will be tiny (most people use 800*600 or 1024*768). If you do not want to have native code to change the resolution of the screen and choose to draw a larger image instead, your framerates will probably be divided by approx 2-4 (you will just be able to draw 1 or 2 layers instead of 4).

The combination of a slower processor and being forced to draw a 1024*768 image can lower your numbers a lot. Then the fact that one wants to do AI calculations, play music, handle input etc., all while drawing makes me realize how much I really want that accelerated image interface

Henry
I''m not agains using native code to do things that java is incapable of doing like changin resolution. The program will run fine at 640x480 without native code to switch, but I would love to get scaling for free. I''m going to test these results on my wife''s Cele 450 to see if I''m correct in assuming it''s more memory bound than CPU bound.

Something that some other programs have used that may give almost free scaling is using the buffered image as the texture on a polygon that fills the screen. A little overkill, but it it gets me scaling for free on 3d accelerated platforms I''ll take it.

I''ve only been working on this for a few days now and have anready been able to signifigantly increase my speed, so just give me some more time.
Ok since I''ve got .. well no experience with Java2d at all, I''m guessing that when you say oldstyle offscreen vs bufferedImage I''ll take it you mean awt and java2d?

And as anon said, if you could post a link to get the source (when you''re done of course ) that would be cool.

Smoo
Yes oldstyle = awt ( Image + MemoryImageSource )
BufferedImage = java2d ( getRaster().getData() )

I''ll clean up the 6 or so test cases I''ve developed as well as the component fps tester. If I get a chance I''ll also throw in at no additional my handy Debugging class that redirects stdout and stderr to a window at the bottom of the screen.
Regarding ''oldstyle''/AWT methods, I''ve found that implementing ImageProducer is faster than using MemoryImageSource. I think by about 20%, but it''s been ages since I''ve actually done a direct comparison.

Don''t think it comes close to the fps rates you''re quoting for Java2d though. I''m impressed.

I came across some code (with source) to change the screen resolution (JNI link to a DLL). I can''t remember where I found it, but I''ll email it to anyone who wants it.

J.

PS. I''d be interested in seeing your code as well.

This topic is closed to new replies.

Advertisement