On May 22, 2007, at 2:50 AM, [EMAIL PROTECTED] wrote:
Thanks for all of the advice. You provided enough hints for me to
get a workaround that performs just as well on both the opengl and
d3d pipelines. This is what works for me:

In a static method do something like this so I have a dummy
graphics lying about for future use:

GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice
().getDefaultConfiguration();
dummyImage = gc.createCompatibleVolatileImage
(1,1,Transparency.OPAQUE);
dummyImage.validate(gc);
dummyGraphics = dummyImage.getGraphics();

Then when loading the image (in a Thread that paintComponent kicks
off if the image is not 'loaded')

mapImage = this.read(new File(baseURL + fileName));
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice
().getDefaultConfiguration();
for(int i = 0 ; i < 4 && !mapImage.getCapabilities(gc).isAccelerated
(); i ++){
         dummyGraphics.drawImage(mapImage,0,0,null);
}

This makes the image managed and gives acceptable performance for
what I want to do. There are still some delays with this approach
that are noticeable to a picky programmer like I. They might be
caused by kicking off the thread from paintComponent, or maybe the
native code is doing some sort of caching of the images the first
time they are drawn (less likely), or maybe my code is messed up
(most likely).

Actually, I suspect the former; your code is doing the best it can do
with our current implementation.  But what's really happening under
the covers is:
  i=0 --> copy mapImage (in sysmem) to dummyImage (in VRAM)
  i=1 --> a) copy mapImage (in sysmem) to cached texture version of
mapImage (in VRAM)
          b) copy mapImage (texture in VRAM) to dummyImage (in VRAM)
later --> copy mapImage (texture in VRAM) to your Swing backbuffer
(in VRAM)

Steps (0) and (1a) can be fairly costly since shipping pixels from
sysmem to VRAM can be one of the slowest operations in OpenGL/D3D.
It really depends on how large your image is (how large is it,
btw?).  I think that spawning a thread from paintComponent() to do
ImageIO work is probably not a great idea, especially if you treat it
as a synchronous operation, because that will most likely block the
EDT anyway.  Loading an image in a separate thread *is* a good idea,
but it would be better to do so before the paintComponent() method if
possible.  In any case, I wouldn't suggest doing your "dummyImage"
work on that separate thread either, as that's likely overkill,
especially given the single-threaded architecture of the OGL pipeline
and the new forthcoming D3D pipeline, which have their own thread for
doing rendering operations anyway.

BTW, you can probably minimize the cost of step (0) by rendering only
a single pixel, instead of telling Java 2D to render the whole
thing.  I don't think OpenGL itself is smart enough to know not to
clip to the 1x1 destination.  You can do this quite easily like this:

for(int i = 0 ; i < 4 && !mapImage.getCapabilities(gc).isAccelerated
(); i ++){
         dummyGraphics.drawImage(mapImage,0,0,1,1,0,0,1,1,null);
}

So anyway, this demonstrates the advantage of using
setAccelerationPriority(1f) for this sort of thing (which I'm glad to
see us do finally), because instead of 4 steps as in your workaround
code above, we'll only have two simple steps:
  - copy mapImage (in sysmem) to cached texture version of mapImage
(in VRAM)
  - copy mapImage (texture in VRAM) to your Swing backbuffer (in VRAM)


I heeded the warning on using Sun private code. I really want to
avoid it if possible. There is not other place in my app that uses
it and this is they way I will endevour to keep it.


That's good, because we've already changed our surface management
code in JDK 7, so your code would be broken already on that release.
We'll look into the setAccelerationPriority(1f) idea, and the benefit
there is that we could probably get it into a 6 update release.

Thanks,
Chris

A few really important points that I failed to take notice of before:
- You must validate the VolatileImage or it will not cause images
drawn to it to be accelerated.
- The VolatileImage must be Transparency.OPAQUE. I originally had
it as Transparency .TRANSLUCENT. On the d3d pipeline this does not
get acclerated, hence the image drawn to it will not be made
accelerated.
[Message sent by forum member 'alnrelly' (alnrelly)]

http://forums.java.net/jive/thread.jspa?messageID=218289

======================================================================
=====
To unsubscribe, send email to [EMAIL PROTECTED] and include in
the body
of the message "signoff JAVA2D-INTEREST".  For general help, send
email to
[EMAIL PROTECTED] and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to