United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6309763 : RFE: APIs for integration of JOGL with Java2D / OpenGL pipeline

Details
Type:
Enhancement
Submit Date:
2005-08-11
Status:
Resolved
Updated Date:
2008-02-06
Project Name:
JDK
Resolved Date:
2005-09-06
Component:
client-libs
OS:
generic,windows_xp
Sub-Component:
2d
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
5.0,6
Fixed Versions:

Related Reports
Duplicate:
Relates:

Sub Tasks

Description
The JOGL Java binding to OpenGL (http://jogl.dev.java.net/) contains
both a heavyweight OpenGL widget (GLCanvas) and a lightweight one
(GLJPanel). The GLJPanel is used principally in applications
containing JInternalFrames in a JDesktopPane. Currently the GLJPanel
must be implemented by reading back the pixel data of a rendering
surface such as a pbuffer into a BufferedImage, and then drawing that
BufferedImage using Graphics.drawImage(). This incurs many copies of
the data and is very slow. With the Java2D OpenGL pipeline enabled, it
is technically feasible to allow JOGL to draw directly to the Swing
back buffer. Prototypes of this have shown dramatic speedups while
maintaining correct z-ordering of lightweight widgets with the OpenGL
rendering, with no modification to JOGL applications. In order to make
this a supported option in JOGL when running on Java 6 some private
APIs in sun.java2d.opengl.OGLRenderQueue are needed.

1. A static method which invokes a runnable on the Java2D Queue
   Flusher Thread while the OpenGL context corresponding to a
   particular Graphics object is current.  The current signature is

    public static void invokeDisplayAction(Graphics g, Runnable r);

   It is necessary to allow a null Graphics object to be passed in
   order to support running of other arbitrary OpenGL operations on
   the QFT such as the creation of OpenGL contexts for heavyweight
   widgets. This is needed to prevent OpenGL operations from being
   performed on multiple threads because of instability of multiple
   vendors' OpenGL drivers when used in a multithreaded fashion.

   It would be helpful if this method could be invoked from other
   threads than the AWT Event Queue thread. There are certainly race
   conditions to be considered in this case, but we have found that
   having an animation thread invoke an action on the Event Queue
   Thread, which itself invokes the "display action" on the QFT,
   induces a significant amount of lag in mouse operations. This may
   be due to holding locks for too long.

2. A static method for determining the OpenGL viewport of a
   lightweight widget on the back buffer. This can probably be derived
   if the coordinates of the lower-left corner of the widget, with
   respect to the lower-left corner of the back buffer, could be
   returned. Ideally a Rectangle would be returned, but a 2D point of
   the lower-left corner is also acceptable. Currently heuristics
   involving querying the OpenGL scissor box and viewport, as well as
   the position of the widget in its parent container. are being used,
   but these are not robust and do not handle all cases such as being
   placed in a JScrollPane.

3. A static method indicating whether the current thread is the OpenGL
   queue flusher thread. This is needed to understand whether
   recursive OpenGL operations in JOGL, expressed as Runnables, can be
   implemented by simply executing the Runnable rather than calling
   invokeDisplayAction (which is incorrect, in the same way that
   calling EventQueue.invokeAndWait() from the Event Queue thread is
   incorrect):

     public static boolean isQFTThread();

These three APIs should be sufficient to allow JOGL to interoperate
with the Java2D OpenGL pipeline in its current incarnation. When FBO
support is added to the OGL pipeline it is possible we may need an
additional API.
With more prototyping, a need for two additional methods has been discovered. The first is a static method for determining the OpenGL scissor box for a lightweight widget on the back buffer. Previously this had been fetched by querying the OpenGL state. This is necessary to avoid destroying other rendering results.

The second is a method to return an opaque Object identifier for the Java2D back buffer. When the back buffer is resized this identifier changes. The client library (JOGL, in this case) can detect the change and destroy and recreate its OpenGL context on the new back buffer.

                                    

Comments
EVALUATION

A new package protected class (accessible only by reflection) has been added
to provide the static utility methods requested here.  With these changes in
place, it will be possible for JOGL to look for these methods and if present,
to provide an optimized codepath for GLJPanel so that JOGL rendering goes
directly into the OGL-enabled Swing backbuffer.  The existing GLJPanel codepath
(with all the intermediate steps) described above will still be available when
the OGL-based Java 2D pipeline is not available or not enabled, or when JOGL is
sitting on top a non-Sun or pre-Mustang JDK that does not contain these private
utility methods.

Note that there is an existing RFE (5037133) filed regarding JOGL/Java 2D
interoperability.  I will leave that RFE open as placeholder for future work
in this area, such as providing an official bridge between JOGL and Java 2D
(as opposed to the unofficial solution provided here).
                                     
2005-08-23



Hardware and Software, Engineered to Work Together