Hardware accelerated operations in 1.5?

I’m working on an app that (in the worst case scenario) can end up drawing around 100,000 diagonal lines and a few thousand non-rectangular polygon fills with around 10,000 points per poly.

Currently, I’m using a BufferedImage as my backbuffer, and the rendering is terribly slow (around 5 seconds) for the worst case scenario. I’m considering moving to a VolatileImage for my backbuffer, so I can get GPU accelerated ops - like line draws and poly draws/fills, but I’d like to know what operations are actually accelerated. How video card dependent is this? (I.E. what ops can I expect to be accelerated on an integrated Intel chipset vs an ATI/NVidia board).

Another concern I have, is that, if I need to perform some operations that aren’t accelerated (say anti-aliased, rotated text) I’ll lose all the benefit of going to an accelerated image. Is it worthwhile to perform most of the ops on an accelerated image, copy it back to system memory (a BufferedImage), and finish whatever ops I need to there, or would I be better off just letting the software ops run slower against the vram? Or perhaps I render the hardware accelerated ops on a VolatileImage, and the non-accelerated ops on a separate BufferedImage, and blit both to the screen?

In general, I’m looking for render times in the low 100’s of ms. For the worst case scenarios, I’m willing for it to take as long as an entire second. I believe that these times would be entirely reasonable if, for example, I were using something like JOGL, but I can’t go that route. I’m not sure what I can expect out of Java2D. Any suggestions?

God bless,
-Toby Reyelts

One trick you might find useful - use GeneralPath for drawing lines in groups. For application which was drawing around 20000 lines, I have managed to get from 500ms to 50-60ms per full-screen refresh as far as I remember (drawLine versus GeneralPath). There is a lot of micromanagement you may want to do here - I have found out that on my particular configuration, bunches of 32 lines per draw command perform the best. Putting everything in one GeneralPath was around two times slower than 32-line groups (while still few times faster then separate drawLine calls).

In case of my application, I have even not used explicit doublebuffering - I put my view in JScrollPane, set component opaque to true and JScrollPane managed to copy old parts of view itself (and I was drawing only needed parts on repaint of course). This depends on how you application looks like…

As for the ‘few thousand non-rectangular polygon fills with around 10,000 points per poly’ - this sounds terrible. I don’t think you would be able to get reasonable performance even from opengl.

[quote]One trick you might find useful - use GeneralPath for drawing lines in groups…
[/quote]
Hey Artur,

Thanks for the info. GeneralPath is only good for drawing connected lines, though, right?

God bless,
-Toby Reyelts

I have used it for continous paths, but it can be used for separated lines - but I cannot tell you about performance here.

I have just checked my old code and found out that:

  • magic number is either 16 or 64 (I used both in two different draw paths, don’t remember why at that moment)
  • I used batches only for antialiased lines, in case of normal lines I was just putting everything inside big GP and drawing everything in one step
  • for batches, I was reusing same big GP - just call gp.reset() and you are ready

Currently rendering diagonal lines to a volatile image is done via D3D. In 1.5 we’ve added under the hood batching of d3d primitives, which has greatly improved performance for this exact case - rendering lines and accelerated translucent images.

But there’s a catch: horizontal and vertical lines are still handled via ddraw (don’t ask), which will flush the batching queue.

So will any non-d3d operation (rendering text, any non-translucent accelerated image, etc).

So the idea is to structure your code such that you can render as many operations batched as possible:

loop:
   render a bunch of lines
   render the rest of the scene
end of loop

You can also do some tricks with rendering text - cache it in translucent images, for example, and then blit them to the screen. (note: search around for sun.java2d.translaccl property)

You can use our logging to make sure you’re using the right primitives - look for -Dsun.java2d.trace property .

So, the short answer is - try it and see if it works…

Hopefully, when we’ll have fully accelerated D3D and OGL pipelines, all this would be unnecessary…