-- Leo's gemini proxy

-- Connecting to republic.circumlunar.space:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Performance of Java 2D drawing operations (part 2: images)


Series: operations, images, opacity


In my previous post I examined the performance of various drawing operations in Java 2D rendering. Here I look at some specifics around rendering images, with an eye to finding optimisations I can apply to my game Rabbit Escape.


operations

opacity

previous post

Rabbit Escape


You can find the code here: gitlab.com/andybalaam/java-2d-performance.


gitlab.com/andybalaam/java-2d-performance


Results


Drawing images with transparent sections is very slow

Drawing one large image is slower than drawing many small images covering the same area(!)

Drawing images outside the screen is slower than not drawing them at all (but faster than drawing them onto a visible area)


Advice


Avoid transparent images where possible

Don't bother pre-rendering your background tiles onto a single image

Don't draw images that are off-screen


Images with transparency


All the images I used were PNG files with a transparency layer, but in most of my experiments there were no transparent pixels. When I used images with transparent pixels the frame rate was much slower, dropping from 78 to 46 FPS. So using images with transparent pixels causes a significant performance hit.


I'd be grateful if someone who knows more about it can recommend how to improve my program to reduce this impact - I suspect there may be tricks I can do around setComposite or setRenderingHint or enabling/encouraging hardware acceleration.


Composite images


I assumed that drawing a single image would be much faster than covering the same area of the screen by drawing lots of small images. In fact, the result was the opposite: drawing lots of small images was much faster than drawing a single image covering the same area.


The code for a single image is:


g2d.drawImage(
   singleLargeImage,
   10,
   10,
   null
)

and for the small images it is:


for (y in 0 until 40)
{
   for (x in 0 until 60)
   {
       g2d.drawImage(
           compositeImages[(y*20 + x) % compositeImages.size],
           10 + (20 * x),
           10 + (20 * y),
           null
       )
   }
}

The single large image was rendered at 74 FPS, whereas covering the same area using repeated copies of 100 images was rendered at 80 FPS. I ran this test several times because I found the result surprising, and it was consistent every time.


I have to assume some caching (possibly via accelerated graphics) of the small images is the explanation.


Drawing images off the side of the screen


Drawing images off the side of the screen was faster than drawing them in a visible area, but slower than not drawing them at all. I tested this by adding 10,000 to the x and y positions of the images being drawn (I also tested subtracting 10,000 with similar results). Not drawing any images ran at 93 FPS, drawing images on-screen at 80 FPS, and drawing them off-screen only 83 FPS, meaning drawing images off the side takes significant time.


Advice: check whether images are on-screen, and avoid drawing them if not.


Numbers


Transparency


[‡ transparency results]


[‡ transparency results]


⊞ table ⊞


Test FPS

large nothing 95

large images20 largeimages 78

large images20 largeimages transparentimages 46


Composite images


(Lots of small images covering an area, or a single larger image.) [‡ composite results]


[‡ composite results]


⊞ table ⊞


Test FPS

large nothing 87

large largesingleimage 74

large compositeimage 80


Offscreen images


[‡ offscreen results]


[‡ offscreen results]


⊞ table ⊞


Test FPS

large nothing 93

large images20 largeimages 80

large images20 largeimages offscreenimages 83


Feedback please

Please do get back to me with tips about how to improve the performance of my experimental code.


Feel free to log issues, make merge requests or add comments to the blog post.


Originally posted at 2019-02-08 02:05:29+00:00. Automatically generated from the original post : apologies for the errors introduced.


issues

merge requests

original post

-- Response ended

-- Page fetched on Sun May 19 04:22:45 2024