Here is the tutorial/article I am working on. Any other tips/corrections would be great. Basically, tips/tricks/corrections about java2D
After reading all the posts that constantly ask the fastest way to render/draw stuff in jave2D or best way of drawing in java2D and all sorts of speed/trick/hint questions, I decided to write a quick tut about java2D. I am going to give you a bunch of info about java2D that should give you a good understanding what to expect when using java2D and how to do a bunch of stuff. First made sure you know how to setup an app that uses double buffering before you read this. There are plenty of links on this site so just do a search first.
Java2D is not meant for game development and thus is much slower than anything that uses opengl.
(hint: slick, libgdx, lwjgl <--not a game lib)
If you want to make simple games, than it is more than enough but do not expect to make an AAA title with it.
First: Best way to draw/render image in java2D
That is probably the easiest and fastest way to get pixels onto the screen. There are all sorts of other ways but this is ridiculously easy and is fast. Second: Scaling/fillrate
Fillrate, put simply, is how many pixels your graphics card can pump out every frame. In most opengl 2d engines this is your biggest bottle neck. In java2D however, it is not. You can do a whole lot of pixel filling before you see performance drops often you will hit the real bottle neck of java2D first, which is listed below.
So what is the easiest/most efficient way of scaling an image in java2D?
g.drawImage(... width, height)
Yup you can just add in the width and height you want the image to be and grab a can of soda/beer (or bottle if that is your thing) because I have never seen any performance drop in scaling images smaller or larger and if there is one, it is tiny.Third: Transparency/Alpha blending performance hit
Easiest way of doing alpha blending is this
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) (yourAlpha)));
The performance hit for blending is very small. It exists but you will not see a huge difference and alpha transparency is kinda a must for games.
Note: java does not do additive blending. Also, please read below about BufferedImages and VolatileImages with alpha blending.
Fourth: Volatile or Buffered?
All images you create in java2D are hardware accelerated by default since java 1.5. So any ImageIcons or what ever will be fast. There are no special tricks to get a "managed" image as they are managed already. BufferedImages are not to be used as a back buffer or drawing surface. Basically, do not grab a BufferedImage's graphics object and draw with it as it will be very slow. Some say that you need to create compatible images when using BufferedImages but I have never had an issue and I will post some code at the end that abstracts this away from you.
VolatileImages are much faster then BufferedImages when the image has no transparency. When you turn on blending their performance is cut in half. Buffer Strategies use a VolatileImage as a back buffer so these are ideal for drawing surfaces. You can use getSnapShot() to get a BufferedImage from a VolatileImage if you want to do tricks on the pixels.
VolatileImages are hard to manage and are not as versatile as BufferedImages so stick to buffs.Fifth: Performance Tips/Bottle Neck: ........
The biggest bottle neck you will encounter is draw calls. That is how often you call g2d.drawImage()/g2d.fillRect()...... You can get about 4-5k calls till most cpus will start slowing down. Anytime you can trade off fewer drawcalls for bigger images to be rendered, do it. Example would be particle systems. Keep effects using as few particles as you can. Do not worry about large images.
RenderingHints does very little to performance. The only thing you may want to turn off/on is interpolation/rendering they both do almost the same thing, whether or not to use nearest neighbor filtering or bilinear filtering. Rendering quality uses bilinear and speed uses nearest neighbor. You can turn on bicubic but that will greatly slow things down. Anti aliasing is primarily for text so no need to turn that off. Fractional metrics is also for text and keep this on as well. Dithering, color rendering, and alpha interp have not visual or performance impacts that I have seen.
The magic opengl flag. This is all experience and may not be the same for everyone so take it with a grain of salt. This flag should not be turned on unless the game is very very slow and should never be turned on when using volatile images as in every test case I have done, strange things happen. When opengl flag is on volatile images performance drops to a snail speed and BufferedImages get a nice speed boost especially with alpha blending on. This flag can also solve problems with integrated chips be seemingly fillrate limited but I have had a great deal of weird issues with the flag on so only use it as a last resort.
Now I want to leave you with some nice utilities I use to load/manage bufferedimages. If there are other questions/additions just comment and I will add/address them. http://pastebin.java-gaming.org/f1303887e2e
Here is also a particle toy I made in java2D that you can have fun with to test out performance. http://www.mediafire.com/?rhhbadiv1f17cii