JDK-6309763 : RFE: APIs for integration of JOGL with Java2D / OpenGL pipeline
  • Type: Enhancement
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 5.0,6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2005-08-11
  • Updated: 2008-02-06
  • Resolved: 2005-09-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
6 b51Fixed
Related Reports
Duplicate :  
Relates :  
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

     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.

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).