Fast image bitmap rendering (with maximum compatibility)

I am looking into what are the fastest bitmap rendering methods and apparently implementing your own ImageProducer is one of the faster ways to go about it. BufferedImage completely excludes 1.1 and possibly for no good reason so I don’t agree with its implementations and doubt that it could ever be quicker than using an ImageProducer since it is just a mere implementation of it.

What other knowledge is there about this because I’d hate to have the minimum requirements for my application increased by 300% due to using the wrong class. And what about working with indexed palettes? One author claims that using 16 bit RGB (well actually 15 bit) is much faster although I doubt so since most systems have a 32-bit wordsize so it would actually be a great deal slower. And if I have my own ColorModel then would it be slower than creating a MemoryImageSource and using the default RGB constructor since its ColorModel could use native methods that are optimized(just guessing)?

p.s. Sun have given poor advice on what to use, BufferedImage is terribly slow :frowning:

If you want fast rendering, don’t restrict yourself with 1.1. You won’t have hw acceleration available in 1.4 and up.
I think most people have at least 1.4 these days and machines that only have the MS VM installed are probably a small minority, so I think in the end you’re shooting yourself in the foot by holding on to an ancient VM.

That said, if you still want to keep 1.1 compatibility, implementing your own ImageProducer is the fastest option. IIRC, MemoryImageSource has some data copying going on, making it a lot slower than the optimal ImageProducer implementation. It’s been a while since I’ve been using those classes, but I do remember that after a lot of experimentation, the ImageProducer was clearly the fastest solution.
I used 32 bit colors:
model = new DirectColorModel(32,0x00FF0000,0x000FF00,0x000000FF,0);
(under the hood, images in java are always 32 bit I think, so 16 bit colors will be converted to 32 bits, so slower)

Still, unless you want to update these Images all the time, using hw accelleration from 1.4 and up will be LOTS faster.

When you use 1.4 what forces the hardware accelerated blits, is it in BufferedImage? Well in this thread 1.1 is not a must but if there is little or no real benefit to an approach that forces a a later JRE then it wouldn’t be an ideal solution. Having said that it is a real minority that doesn’t have at least 1.4; only problem is that that minority includes a lot of my intended audience - i.e. people using community centres, schools, libraries, public terminals, etc. and most importantly the ones at work!

And yes, the images are being updated all the time around 60fps for my usage from bitmaps using software rendering techniques that cannot be done using the API (in my case)

Why not write a wrapper class for your images around a MemoryImageSource and an BufferedImage implementation. Then you can use a factory pattern to choose BufferedImages where available (they’re a lot faster, even for images that are updated frequently, appearantly there are lots of optimalisations under the hood).

EDIT: Using bufferedimages things might get cached in vram (depends on various things like vram/image size etc), you have no direct control over this. If you update an bufferedimage (get its int[]) the documentation states any chances on hw acceleration are lost because it has to upload the modified content to vram… still in my games I found a worthwhile performance increase using bufferedimages.

I think the 1.1 situation is a temporary one (if it’s even still there), MS has abandonded their VM a long time go.

I agree, from my stats I can tell about 1% uses a 1.1 jvm… it’d be better to tell them to upgrade

I’ve found them to be ridiculously slow when retrieving its int[] image buffer (using the classes methods) and doesn’t come close to what I have now. I will test to see if there is any performance increase over the week though, however I very much doubt it since in the end they all use the same interface to the forms in order to display it which means the BufferedImage should be an added overhead.

A hardware aided blit would be beneficial, but is that truly happening with BufferedImage? If so then that would be great

[quote=“thijs,post:4,topic:30141”]
But they can’t upgrade since they have no administrative privileges! And considering where your traffic comes from you will have a bias in users, any public computer without the need to install JRE is just not going to have it and would probably be using Flash gaming sites. Think of schools, libraries, youth clubs and government funded projects. I can’t tell them to upgrade because they just can’t.

Well it’s about as temporary as a youth club not needing to upgrade for another 5 years since they have the latest flash installed! And I need it to be compatible with at least my work computers which have no administrative privileges. However I have found a solution; I can include the JRE and have it launch from an exe; the web version will use a normal applet with the executable download as an option for people with no administrative rights who also don’t have JRE installed. When I found that one of the most popular public Internet café’s in Greenwich couldn’t run Eclipse since it didn’t have the latest JRE I realized that it’s more common than thought.

Besides how biased are your views? I’m expecting my program to be publicized via connexions very lightly though a targeted mailing list going out to schools and practitioners. Can’t have them unable to play it can I :slight_smile:

This way I can focus on the coding and not worry about whether or not it’s compatible, besides I don’t really have anything that needs to use anything new; in fact what I have is probably 1.0 compatible and that’s just because the only part that uses Java libraries is a single method copying the buffer to the Frame! This method is in a separate class that is not a dependency to the running; I need only change the class and I have an Applet, a JFrame or a JApplet or just a Panel.

From my experience BufferedImage is faster than ImageProducer. My guess is because the ImageProducer requires an ImageConsumer.

Some BufferedImage code:

	DirectColorModel colorModel = 
		new DirectColorModel(24, 0xff0000, 0x00ff00, 0x0000ff);
	
	int w = getWidth();
        int h = getHeight();
	int[] rgbData = new int[w*h]
        
        SampleModel sampleModel = new SinglePixelPackedSampleModel(
            DataBuffer.TYPE_INT, w, h, new int[] { 0xff0000, 0x00ff00, 0x0000ff }); 
        
        DataBuffer dataBuffer = new DataBufferInt(rgbData, w * h);
        
        WritableRaster raster = Raster.createWritableRaster(
            sampleModel, dataBuffer, new Point(0,0));
        
        BufferedImage awtImage = new BufferedImage(colorModel, raster, true, new Hashtable());
	
	// 1. Draw RGB pixels to rgbData
	rgbData[offset] = color;
	
	// 2. Draw BufferedImage to Applet
	g.drawImage(awtImage, 0, 0, null);

But on Mac OS X, if you want 60fps, you need to use BufferStrategy.

Omg that is a great deal faster, it’s almost as processor (un)intensive as no$gba! Looking at the classes I guess that BufferedImage takes out the Java side of the implementation; I completely overlooked the fact that an Image had to return a Graphic. So does using a BufferStrategy negatively affect any of the other OS’s? If so then it can be a switch for OSX users.

p.s. I think it’s a shame that this isn’t the default behaviour of the BufferedImage; when you use anything in the BufferedImage class you end up spending more time copying your buffer than you do rendering it :o

On another front I really want to know how close to that speed I could get from using an ImageProducer … oh, just did it; it’s almost the same. BufferedImage uses around 6% processor power emulating GBA hardware style implementation of Mode 7 using horizontal-blanks and VBL’s on an Athlon XP 3200+; the ImageProducer approach is hovering around 6-8%!

For the game I was doing I just used BufferStrategy if the client was Mac OS X. I didn’t see a speedup on a couple PCs with BufferStrategy (because the engine was using software rendering) and I was concerned about BufferStrategy compatibility on the wide variety of PC hardware and VMs. YMMV.