Number of images in Java2D

Hi,

I was wondering if there is a problem having a high number of loaded images in Java 2D at the same time? Let say 1000 images?

In my side scrolling game I load a lot of images (32x32x16 bits) for the tiles. I have more than 1000 images and it seems to cause performance issues.

Thanks for answers.

With 1000 32x32x16 tiles loaded in your application, and assuming you are using accelerated images, you would need more than 16MB cached in VRAM. So unless you have more than that amount of free VRAM, some images won’t be accelerated.

Also, drawImage() calls have a hefty overhead (not referring to the actual blitting). It is always significantly better to blit 250 64x64x16 tiles for instance, than to blit 1000 32x32x16 tiles. So if you’re rendering all 1000 images per frame, you can expect a large performance hit there.

The game runs in a resolution of 640x480 so there are 300 tiles that are blitted every frame. The total number of tiles should not fills up the VRAM for 32 megs.

Maybe it’s a GC issue. Since there are a lot of objects, there’s might be a scalability issue with the GC. But since all those objects live for a long time, they should be transferred from the young generation to the second and then they shouldn’t occur too much overhead for the GC. Am I right?

Another point is the fact that I must use 3 video buffers to see a significant difference in performance. When I use 2 buffers, the game is almost locked at 85fps but when I switch to 3 buffers then the game runs from 100 to 110 fps.

I’m not too familiar with the GC mechanism, but I’m pretty sure just having a lot of objects alone is not a problem.

In my opinion, GC is a major issue when you are creating and then subsequently disposing lots of new objects per frame or after a short time. So in your case, unless you are creating 300 new tile objects per frame, I’m pretty sure GC is not largely responsible for your slowdowns.

Sounds like a Vsync issue here. Are you using BufferStrategy with 1.4.2? With 2 buffers, rendering is performed using page-flipping so your frame rate is limited to your monitor refresh rate. I can’t confirm that though.

I suggest you try reducing the amount of drawImage() calls your app makes during rendering. Or you can try running some tests to see the performance difference yourself. I think I posted some FPS benchmarks that shows this in a thread regarding “managed images” or something.

Thanks for you help barfy.

Talking about vertical sync, yes I use a BufferStategy with page flipping (tested) but I ask for a refresh rate of 150hertz. so why when I use 3 buffers the performance is increased?

I’d like to add also that all the images are stored in one array . Maybe accessing an array of this size has consequences on the performance since each entry is accessed sequentially in memory?

[quote]Thanks for you help barfy.
[/quote]
No prob :).

Yes, you can ask for 100000Hz refresh rate but your monitor is only capable of displaying 85 frames per second from the description you gave.

With 3 or more buffers, you are essentially disabling vsync since you’ve got more than 2 offscreen surfaces to alternately render with, so BufferStrategy.show() doesn’t block even if the monitor is not ready at the moment the method is called. So, although your FPS counter is displaying > 85 frames per second, that’s just the amount of times your rendering loop is called per second. The actual drawing that happens on the monitor takes place at 85fps still.

Although there is a small overhead just in iterating through an array, it’s THE OVERHEAD caused by drawImage() that you call each access that’s causing the majority of the slowdown (note that I’m not talking about the actual blitting of pixels, but the preparation that drawImage() does before the blitting operation).
Try writing a little test-case and see for yourself.

So, to compensate you can have either:

a) less but larger tiles to cover the same area - ie 250 64x64 or 445 48x48 tiles instead of 1000 32x32 for example

b) use a dirty rectangle algorithm if your app is suitable for such a scheme (ie, more or less static)

c) Pre-render all the tiles onto an offscreen buffer, and display that on the screen each frame if your app is more or less static.

d) Or something else I (very likely) haven’t thought of.

Just out of curiosity, do you have 1000 different .gif, .jpg and .png images as tiles?

I have more than 1000 different tiles load from png files.

Thanks to barfy for support. I think I will implement some sort of dirty rectangle.