current state of 2D acceleration

Sorry if this is overly vague (and probably gets asked a lot), but I’ve been reading around this for the last couple of hours, and am thoroughly confused.

Basically, my question is: what’s the relative performance of the D3D and OpenGL pipelines? I’ve been reading Chris and Chet’s blogs, and it seem that vast improvements have been made to the OpenGL pipeline in the last couple of years, but is that just catching up to what D3D has already been doing? It’s hard to get a head-to-head comparison.

What I’m doing is extremely simple in its graphical requirements: it’s a data visualization application that just needs to draw a bunch of tiny (a couple of pixels) colored segments; the problem is that it needs to draw hundreds of thousands of them in real time.

I also understand that there are serious stability issues with OpenGL drivers - has it at least gotten to the point where it’s worth giving it a shot?

Any advice is appreciated.

I’m not a definitive expert on this either but let me try to share what I’ve learned. Others like LinuxHippy (and ofcourse the Java2D team) know lots about this stuff.

By default Java2D uses Directx and direct3D in combination with ‘software’ rendering on windows XP and older windows versions. There are additional VM flags you can use to get more out of D3D and DirectX like:

These are turned off by default since some drivers play up with them. By turning these on I suppose we’re using the ‘D3D pipeline’.

The ogl pipeline is more advanced than the D3D one mainly because it does more fancy things like transparency, scaling, rotations etc which the D3D pipeline just won’t do (it does it in software which is usually slower). Also, the OGL pipeline uses a fast threading architecture called STR which is in Chris Campbell’s blog.

A big problem coming up is that the D3D-software mixing which has worked OK to date just won’t work in Windows Vista. Everything has to be done in software or D3D. Chet talked about it in his blog and currently java 6 just uses software. Hopefully the Java2D team will make a full-on 100% awesome D3D pipeline for a future version of Java whioch doesn’t use software rendering at all.

About the OGL stability issue. To me it seems as though no drivers which come with the computer/graphics card/operating system work with OGL at all :(. You have to download a new one from the net.

That’s why I’d recommend staying with Java2D to do your graphics since then you can give the user the option of using OGL, D3D, or software by just supplying different VM arguments. Software rendering by the way is actually very quick on fast-CPU computers, nearly as fast as OGL.

Let us know how things work out!
Keith

Well there is also a “native” D3D pipeline which uses D3D exclusivly (as far as I know) but lacks some features of the OpenGL pipeline.
So OpenGL is currently the most advanced Java2D backend if it works :wink:

lg Clemens

I also have a question about this issue. You say, software rendering is almost as fast as opengl on fast computers, but I have a simple test application, that renders randomly antialiased lines on the screen. My problem now is, that normal (D3D) or with opengl pipeline enabled I can draw about 10.000 lines per second. But directly with jogl I can draw 500.000 lines! So why can this be?

I guess this is because the way Java2D handles Antialiasing. To ensure correctness Java2D does not rely on OpenGLs antialiasing and does some kind of combined hardware/software rendering. However I also could be wrong.
However OpenGL should clearly outperform the default pipeline because no VRAM readbacks are needed.

lg Clemens

Perhaps I was doing something wrong, but when I enabled the OGL pipeline for my game, for people with ATI cards or older cards, there was a lot of artifacting going on (black rectangles over sprites or random lines). It all ran just as well as the LWJGL variant, but the graphical artifacts ruined it.

Wow, sounds great. I’ve never heard of this, what is the VM option to turn it on?

It could be the graphics card driver but it could also be the version of java that was running the OGL pipeline. Java 6 is much more robust. For example on 1.4 or 1.5 JVMs I often got colour inversion using the OGL pipeline but with 1.6 (java 6) this hasn’t happened.

The users were all using Java 6, and one had a top of the line ATI card (X1900), but then again, bad drivers can foul anything up. Still, LWJGL remains the safest option.

Did you file a bug report at bugs.sun.com? (Screenshots, exact driver version, etc would help.) We can’t fix problems that we don’t know about. You’re correct that in most cases it’s the drivers fault, but we can work with ATI/Nvidia/etc to correct the problem.

Chris

Ok, I’ve run some benchmarks, lets see if they make sense.

Very simple test - fill a 1024 x 768 panel with line segments 3 pixels tall (so, 262,144 segments total).

All tests were on win2k with the latest java 1.6; I ran everything a few times and picked representative numbers.

I first ran this on my (fairly uncommon) Matrox Parhelia 650:

Default (trace: DXDrawLine)
time: 2344, segs/s: 111836

-Dsun.java2d.d3d=true (trace: D3DDrawLine)
time: 4625, segs/s: 56679

-Dsun.java2d.noddraw=true (trace: sun.java2d.loops.DrawLine::DrawLine(OpaqueColor, SrcNoEa, AnyInt))
time: 375, segs/s: 699050

-Dsun.java2d.opengl=true just ran in software.

So turning on D3D halves the speed from the original DX, and software is 12 times faster than D3D? Of course this card isn’t supposed to do much 3D acceleration.

I am also not very familiar with the windows 3D APIs: what exactly is the difference between D3D and DX? I thought they were part of the same thing?
While playing around with the start-up options from my IDE, I also managed to run it in a mode that traced as “sun.awt.windows.Win32BlitLoops::Blit(“Integer RGB DirectDraw”, SrcNoEa, “Integer RGB DirectDraw”)” - so DD, DX, and D3D are all different? (this ran a tiny bit slower than the DX).

I then figured I should run this on something that’s a) more common, b) has decent 3D performance, and c) is far from the top of the line : GeForce2MX 200.

Default (trace: DXDrawLine)
time: 4438, segs/s: 59068

-Dsun.java2d.d3d=true (trace: D3DDrawLine)
time: 734, segs/s: 357144

-Dsun.java2d.noddraw=true (trace: sun.java2d.loops.DrawLine::DrawLine(OpaqueColor, SrcNoEa, AnyInt))
time: 250, segs/s: 1048576

-Dsun.java2d.opengl=true (trace: OGLDrawLine )
time: 141, segs/s: 1859177

So here at least D3D is 6 times faster than DX, but software is still 3 times faster, and OpenGL blows everything else away.

Is this a fair test for what I’m trying to do?

Thanks for doing all that! Very useful to know. Even though your 3-pixel lines were probably straight up and not angled, maybe turning off anti-aliasing will produce different results.

I assume you meant -Dsun.java2d.opengl instead of d3d.

By the way, I thought that -Dsun.java2d.d3d was turned on by default since in the docs (http://java.sun.com/javase/6/docs/technotes/guides/2d/flags.html) it says that you should turn it off if there’s problems with the driver. Since you got unique stats with that option I suppose that is THE d3d flag. If this is the case then maybe the docs on this should be changed.

Cool stuff, it’s about time we found out how all of the options actually work on windows 8).

Keith

By the way drawing directly to screen destroys the opengl-backend’s capability of Single-threaded-rendering.
So for comparison better draw to a VolatileImage and draw this one after the test has been finished.

Giving it the ANTIALIAS_OFF rendering hint didn’t seem to make a difference.

You are right, it does seem that d3d should be on for win2k (I even glanced at the source for 1.6, seems to be on) - don’t know why it’s getting turned off.

Thanks for the tip - that made the opengl results another 15% faster.

This is a bit OT, but what’s the correct way to use VolatileImage buffers? Does it make sense to always allocate one just for the render and throw it away after copying to the screen? Or is it expensive to allocate them?

Or should I render to the VI, copy to a regular image buffer before releasing it, and use that for double buffering? (so that a repaint never causes and unexpected, and expensive, render because the VI has been invalidated).

Thanks for the help.

?

This is not true. Are you just making things up as you go along? :slight_smile:

This one I can agree with. It’s pretty rare that anyone renders directly to the screen these days, so better to do your benchmarking to an accelerated offscreen, like BufferStrategy or VolatileImage. But then you always have to remember to call Toolkit.sync() at the end of your rendering loop, to ensure pixels are completely flushed to the destination. These things are taken care of already for you if you use our standard microbenchmarking utility, J2DBench:
http://weblogs.java.net/blog/campbell/archive/2005/03/strcrazy_improv_1.html

Chris

Oha I normally write a disclaimer that it maybe simply wrong what I wrote - but it seems here I simply missed it.
I thought I’ve read about that in some blog some time ago … strange.

Sorry :’(

lg Clemens

I hope this is still on topic but I have a relevant question: is the OpenGL accelerated backend supported on OS X ?

If not, any estimates ? :slight_smile:

Thank you.