The problem with java2d is that it can very easily fall back to software rendering. And the software java2d rendering pipeline is really slow. So you get particularly slow software rendering without doing anything "wrong".

Basically don't rotate, don't scale, only use bit alpha channel, don't use AA, use compatible image pixel/colour formats. With all that you have good odds of getting some HW acceleration.

But i have noticed that java2d is really pretty poor for this sort of thing. Its fine for gui's that don't need to draw whole thing every frame, but once you are doing animations or games its a very poor match. I would recommend looking into using lwjgl or slick or something to get anything like real consistent performance.

I have no special talents. I am only passionately curious.--Albert Einstein

Threads are overrated. It also has nothing to do with gui performance really. I have written snappy swing apps. There are slow C++ gui apps. But consistent performance with animation/games is not what java2d is really designed for. Regardless of what the engineers planed or claim. At the very least there would be somewhat reliable full screen modes and vsync if it was.

I have no special talents. I am only passionately curious.--Albert Einstein

The problem with java2d is that it can very easily fall back to software rendering.

You say that as if it is a bad thing. A virtue of Java2D is that IF something cannot be hardware accelerated by the video hardware/drivers, it is no problem as Java2D will indeed use the software rendering techniques. It will be slower but at least you'll see -something-. This is not a problem of Java2D, it is a defining feature. Luckily nowadays you don't have to worry too much about that, video hardware and drivers are very mature so most of what you can do using Java2D (with the exception of some specific effects) can be hardware accelerated, even by Intel hardware.

Quote

And the software java2d rendering pipeline is really slow.

Again not true, unless you do things which are slow in any software rendering environment. Translucent transparency is a good example. When you do it properly it is actually quite fast. Of course there is some overhead because the tech is aimed at drawing flat user interfaces, not dynamic games. Most algorithms built into the Graphics object are optimized for accuracy, not performance. The Sun way of working around that was not to optimize what was already there, but to add new ways of doing it. For example there are multiple ways of performing scaling, ranging from dead slow to wicked fast.

Most of this is not a problem though, as in game development (using Java2D) your main weapon of choice is drawImage() anyway. The main thing to focus on is that images are accelerated, meaning they can stay in videomemory. Which is the case if it is a compatible image and you keep your fingers off of the underlying raster.

Quote

Basically don't rotate, don't scale, only use bit alpha channel, don't use AA, use compatible image pixel/colour formats. With all that you have good odds of getting some HW acceleration.

All true if you would recommend using the software rendering pipeline, but it has absolutely nothing to do with "getting hardware acceleration". These things mentioned here will not cause slowdowns IF you use the hardware rendering pipeline, as they are exactly the things that can be hardware accelerated (except for bit translucency; you should use translucent images in a hardware accelerated environment).

Try it on more than your home machine. I am not making this up. Just check the threads here for example. Non bit alpha falls back to software rendering on everything i have tested as does AA and any image scaling that is not Nearest neighbor. The -Dsun.java2d.opengl=true|True results in very buggy output on my test platforms now as it did 6 years ago. Right now on linux you don't get any rendering at all! Rotation very quickly trips the very conservative HW acceleration in java2d easily as well, again i have seen this happen. Just asserting it didn't is not fixing the problem. Finally the java2d SW pipe line is slow. look at the source, is a large number of classes and calls that really make it hard work for the JIT and the GC, so you don't get any MMX/SSE acceleration.

I have no special talents. I am only passionately curious.--Albert Einstein

Neither am I, it performs very well on all machines I have used so far (gaming oriented machines) :/

What we can probably both agree on is that a major downside of Java2D is that because of all the plumbing built into it since its inception, you cannot depend on it performing the same on all machines. I believe the JDK6U10 changes made it a whole lot worse. I wonder if Prism of JavaFX2 can be a better alternative...

I also have a question about image acceleration and overall java2d performance.

I draw graphics by active rendering. It's nearly same everywhere - create JFrame with JPanel, set display mode, create buffer strategy and draw graphics. It's the way how the fullscreen application is made. When creating in window there is no need to change display mode and work with buffer strategy. When everything is done with screen display I normally create BufferedImages via GraphicsConfiguration.createCompatibleImage() to display.

Now is the thing that's really strange for me. I run application in window mode with frame rate counter. I do the same with fullscreen display mode and there is no change in frame rate. I always think that fullscreen mode has a really big advantage in processing images. I also add, that same thing is true for two other pc's around me. In each case frame rate still nearly the same.

So my question is, is it something wrong with code and me or is that the way that java handles graphics? If needed I can also paste some application's code with the way how the things are done. I highly appreciate any suggestions about this case.

I create a BufferStrategy from JFrame which object is my main window. Before that, I create JPanel where events and drawings are made and put it into frame. I tried to change JPanel into Canvas and create BufferStrategy from there, but drawing time didn't change and all events on JPanel stop working. I measure drawing time by using System.nanoTime() before and after main drawing function.

Key listener is added to JFrame because there were problems with focus on JPanel, but for now it doesn't matter.

Now I even removed BufferStrategy at all and nothing changed. I read somewhere that all Swing components are default double buffered so it makes sense. In fullscreen mode there is access to many exclusive graphics card functions, so I thought that something is going to help to render faster.

That's because JPanel isn't set to be focusable in the first place. You have to call JPanel.setFocusable(true) for it to receive focus.

Java2D is slow in either situation. "exclusive graphics card functions", I don't know about that one. Those "functions" you seek are low level DirectX/OpenGL functions which are not accessible to you through Java2D nor are they supposed to make anything go "faster".

I really suggest you stop worrying about tiny performance details like this. As I told you earlier, if your game/app runs at a reasonable framerate, STOP worrying and finish writing your game already!

And why should there be an change? Your CPU/GPU doesn't get "faster" render things when in full screen.

It's about exclusive fullscreen mode. There is a clear difference in performance between fullscreen and windowed, but I'm not sure if Java2D can actually enter exclusive mode. If it can then YES, fullscreen is faster.

For now rendering all 2D tile map in resolution 640x480 takes about 3 ms, so I think it's quite good result and maybe it's true that I seek for too much performance boost in places where it cannot be granted Cpu usage for entire game takes 5-10% with 30fps on c2d processor, so there is much more to improvement

For example "Killer Game Programming in Java" calls it Full-Screen Exclusive Mode (FSEM) and it's done by invoking setDisplayMode(), but for what i can see there is no performance boost between it and window mode what's really strange for me.

It's a really low-level thing, so it's probably the best that Java doesn't use it. I've had so much trouble with it (specifically ridiculous VM crashes on Intel graphics cards), so it's not really worth it anyway unless you're making a 3D game. That was with LWJGL though, which does use exclusive mode.

OT: To solve the crash I ended up creating an undecorated LWJGL window that was (width+2, height) to prevent automatic fullscreen just for Intel cards. Guess why I hate Intel?

OT: To solve the crash I ended up creating an undecorated LWJGL window that was (width+2, height) to prevent automatic fullscreen just for Intel cards. Guess why I hate Intel?

Java2D used to implement FSEM on Linux via a window whose viewport was the size of the desktop, though I believe as of Java 6 they have "true" full screen functionality implemented. I'm not sure if they did so because of time constraints, buggy native support, nobody cared about games on Linux, or what.

Today I tried to change the options of virtual machine to force acceleration on graphics card. After a while that give me an answer - support for DirectX/OpenGL is default enabled. When I turned off Direct3D acceleration, render time gone higher, so that solves my case Java2d is trying to use platform depended acceleration and if that fail, there is switch to software rendering. That's it - clean and simple

Today I tried to change the options of virtual machine to force acceleration on graphics card. After a while that give me an answer - support for DirectX/OpenGL is default enabled. When I turned off Direct3D acceleration, render time gone higher, so that solves my case Java2d is trying to use platform depended acceleration and if that fail, there is switch to software rendering. That's it - clean and simple

For a really demanding game (one that runs at <10 FPS without hardware acceleration for example) this is way too unreliable though. It might work everywhere, but not be playable everywhere.

Today I tried to change the options of virtual machine to force acceleration on graphics card. After a while that give me an answer - support for DirectX/OpenGL is default enabled. When I turned off Direct3D acceleration, render time gone higher, so that solves my case Java2d is trying to use platform depended acceleration and if that fail, there is switch to software rendering. That's it - clean and simple

Hmm, are you drawing images with bit translucency I wonder? As far as I know those type of images cannot be accelerated under hardware rendering environments but will perform a whole lot better in a software rendering one (where they can be accelerated). You could try switching to full translucent images to see if that makes a difference with D3D/OGL enabled.

Note that I disabled hardware support by default myself; the type of games I make (simple retro remakes) generally don't need it. Gives the least amount of cross-computer misery.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org