summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/classes/com/sun/opengl/impl/GLContextImpl.java23
-rw-r--r--src/classes/com/sun/opengl/impl/GLContextShareSet.java19
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/Java2D.java193
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java3
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/windows/WindowsExternalGLDrawable.java3
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java3
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java3
-rw-r--r--src/classes/javax/media/opengl/GLJPanel.java33
8 files changed, 208 insertions, 72 deletions
diff --git a/src/classes/com/sun/opengl/impl/GLContextImpl.java b/src/classes/com/sun/opengl/impl/GLContextImpl.java
index d79de9f5a..0910fe250 100644
--- a/src/classes/com/sun/opengl/impl/GLContextImpl.java
+++ b/src/classes/com/sun/opengl/impl/GLContextImpl.java
@@ -123,15 +123,22 @@ public abstract class GLContextImpl extends GLContext {
// If we are tracking creation and destruction of server-side
// OpenGL objects, we must decrement the reference count of the
// GLObjectTracker upon context destruction.
- int res = makeCurrent();
- if (res != CONTEXT_CURRENT) {
- // FIXME: we really need to behave better than this
- throw new GLException("Unable to make context current to destroy tracked server-side OpenGL objects");
- }
try {
- tracker.unref(getGL());
- } finally {
- release();
+ int res = makeCurrent();
+ if (res != CONTEXT_CURRENT) {
+ // FIXME: we really need to behave better than this
+ throw new GLException("Unable to make context current to destroy tracked server-side OpenGL objects");
+ }
+ try {
+ tracker.unref(getGL());
+ } finally {
+ release();
+ }
+ } catch (GLException e) {
+ // FIXME: should probably do something more intelligent here
+ if (DEBUG) {
+ e.printStackTrace();
+ }
}
}
}
diff --git a/src/classes/com/sun/opengl/impl/GLContextShareSet.java b/src/classes/com/sun/opengl/impl/GLContextShareSet.java
index 283a56f85..20a9364fb 100644
--- a/src/classes/com/sun/opengl/impl/GLContextShareSet.java
+++ b/src/classes/com/sun/opengl/impl/GLContextShareSet.java
@@ -39,6 +39,9 @@
package com.sun.opengl.impl;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
import java.lang.ref.*;
import java.util.*;
import javax.media.opengl.*;
@@ -168,10 +171,20 @@ public class GLContextShareSet {
GLContextImpl impl2 = (GLContextImpl) newContext;
GLObjectTracker tracker = null;
// Don't share object trackers with the primordial share context from Java2D
- GLContext j2dShareContext = Java2D.getShareContext();
- if (impl1 != null && impl1 == j2dShareContext) {
- impl1 = null;
+ if (Java2D.isOGLPipelineActive()) {
+ // FIXME: probably need to do something different here
+ // Need to be able to figure out the GraphicsDevice for the
+ // older context if it's on-screen
+ GraphicsConfiguration gc = GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().
+ getDefaultConfiguration();
+ GLContext j2dShareContext = Java2D.getShareContext(gc);
+ if (impl1 != null && impl1 == j2dShareContext) {
+ impl1 = null;
+ }
}
+
if (impl1 != null) {
tracker = impl1.getObjectTracker();
assert (tracker != null)
diff --git a/src/classes/com/sun/opengl/impl/Java2D.java b/src/classes/com/sun/opengl/impl/Java2D.java
index cf9e8ff1e..bf3219b77 100755
--- a/src/classes/com/sun/opengl/impl/Java2D.java
+++ b/src/classes/com/sun/opengl/impl/Java2D.java
@@ -53,13 +53,27 @@ public class Java2D {
private static boolean DEBUG = Debug.debug("Java2D");
private static boolean VERBOSE = Debug.verbose();
private static boolean isOGLPipelineActive;
- private static boolean isFBOEnabled;
private static Method invokeWithOGLContextCurrentMethod;
private static Method isQueueFlusherThreadMethod;
private static Method getOGLViewportMethod;
private static Method getOGLScissorBoxMethod;
private static Method getOGLSurfaceIdentifierMethod;
+ // The following methods and fields are needed for proper support of
+ // Frame Buffer Objects in the Java2D/OpenGL pipeline
+ // (-Dsun.java2d.opengl.fbobject=true)
+ private static boolean fbObjectSupportInitialized;
+ private static Method invokeWithOGLSharedContextCurrentMethod;
+ private static Method getOGLSurfaceTypeMethod;
+
+ // Publicly-visible constants for OpenGL surface types
+ public static final int UNDEFINED = getOGLUtilitiesIntField("UNDEFINED");
+ public static final int WINDOW = getOGLUtilitiesIntField("WINDOW");
+ public static final int PBUFFER = getOGLUtilitiesIntField("PBUFFER");
+ public static final int TEXTURE = getOGLUtilitiesIntField("TEXTURE");
+ public static final int FLIP_BACKBUFFER = getOGLUtilitiesIntField("FLIP_BACKBUFFER");
+ public static final int FBOBJECT = getOGLUtilitiesIntField("FBOBJECT");
+
// If FBOs are enabled in the Java2D/OpenGL pipeline, all contexts
// created by JOGL must share textures and display lists with the
// Java2D contexts in order to access the frame buffer object for
@@ -69,7 +83,7 @@ public class Java2D {
// (on the same display device?) share textures and display lists;
// this is an approximation to that notion which will be refined
// later.
- private static VolatileImage j2dFBOVolatileImage; // just a dummy image
+ private static boolean initializedJ2DFBOShareContext;
private static GLContext j2dFBOShareContext;
static {
@@ -125,11 +139,32 @@ public class Java2D {
});
getOGLSurfaceIdentifierMethod.setAccessible(true);
- String fbo = System.getProperty("sun.java2d.opengl.fbobject");
- isFBOEnabled = (fbo != null) && "true".equals(fbo);
+ // Try to get additional methods required for proper FBO support
+ fbObjectSupportInitialized = true;
+ try {
+ invokeWithOGLSharedContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLSharedContextCurrent",
+ new Class[] {
+ GraphicsConfiguration.class,
+ Runnable.class
+ });
+ invokeWithOGLSharedContextCurrentMethod.setAccessible(true);
+
+ getOGLSurfaceTypeMethod = utils.getDeclaredMethod("getOGLSurfaceType",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLSurfaceTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ fbObjectSupportInitialized = false;
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("Disabling Java2D/JOGL FBO support");
+ }
+ }
} catch (Exception e) {
if (DEBUG && VERBOSE) {
e.printStackTrace();
+ System.err.println("Disabling Java2D/JOGL integration");
}
isOGLPipelineActive = false;
}
@@ -148,13 +183,11 @@ public class Java2D {
}
public static boolean isFBOEnabled() {
- return isFBOEnabled;
+ return fbObjectSupportInitialized;
}
public static boolean isQueueFlusherThread() {
- if (!isOGLPipelineActive()) {
- throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
- }
+ checkActive();
try {
return ((Boolean) isQueueFlusherThreadMethod.invoke(null, new Object[] {})).booleanValue();
@@ -169,9 +202,7 @@ public class Java2D {
Graphics object and runs the given Runnable on the Queue
Flushing Thread in one atomic action. */
public static void invokeWithOGLContextCurrent(Graphics g, Runnable r) throws GLException {
- if (!isOGLPipelineActive()) {
- throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
- }
+ checkActive();
try {
GLDrawableFactoryImpl.getFactoryImpl().lockAWTForJava2D();
@@ -187,6 +218,31 @@ public class Java2D {
}
}
+ /** Makes current the "shared" OpenGL context associated with the
+ given GraphicsConfiguration object, allowing JOGL to share
+ server-side OpenGL objects like textures and display lists with
+ this context when necessary. This is needed when Java2D's FBO
+ support is enabled, because in order to render into that FBO,
+ JOGL must share textures and display lists with it. Returns
+ false if the passed GraphicsConfiguration was not an OpenGL
+ GraphicsConfiguration. */
+ public static boolean invokeWithOGLSharedContextCurrent(GraphicsConfiguration g, Runnable r) throws GLException {
+ checkActive();
+
+ try {
+ GLDrawableFactoryImpl.getFactoryImpl().lockAWTForJava2D();
+ try {
+ return ((Boolean) invokeWithOGLSharedContextCurrentMethod.invoke(null, new Object[] {g, r})).booleanValue();
+ } finally {
+ GLDrawableFactoryImpl.getFactoryImpl().unlockAWTForJava2D();
+ }
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
/** Returns the OpenGL viewport associated with the given Graphics
object, assuming that the Graphics object is associated with a
component of the specified width and height. The user should
@@ -196,9 +252,7 @@ public class Java2D {
public static Rectangle getOGLViewport(Graphics g,
int componentWidth,
int componentHeight) {
- if (!isOGLPipelineActive()) {
- throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
- }
+ checkActive();
try {
return (Rectangle) getOGLViewportMethod.invoke(null, new Object[] {g,
@@ -218,9 +272,7 @@ public class Java2D {
passed to a call to glScissor(). Should only be called from the
Queue Flusher Thread. */
public static Rectangle getOGLScissorBox(Graphics g) {
- if (!isOGLPipelineActive()) {
- throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
- }
+ checkActive();
try {
return (Rectangle) getOGLScissorBoxMethod.invoke(null, new Object[] {g});
@@ -238,9 +290,7 @@ public class Java2D {
created (and the old ones destroyed). Should only be called from
the Queue Flusher Thread.*/
public static Object getOGLSurfaceIdentifier(Graphics g) {
- if (!isOGLPipelineActive()) {
- throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
- }
+ checkActive();
try {
return getOGLSurfaceIdentifierMethod.invoke(null, new Object[] {g});
@@ -251,6 +301,27 @@ public class Java2D {
}
}
+ /** Returns the underlying surface type for the given Graphics
+ object. This indicates, in particular, whether Java2D is
+ currently rendering into a pbuffer or FBO. */
+ public static int getOGLSurfaceType(Graphics g) {
+ checkActive();
+
+ try {
+ // FIXME: fallback path for pre-b73 (?) Mustang builds -- remove
+ // once fbobject support is in OGLUtilities
+ if (!fbObjectSupportInitialized) {
+ return 0;
+ }
+
+ return ((Integer) getOGLSurfaceTypeMethod.invoke(null, new Object[] { g })).intValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
/** Returns either the given GLContext or a substitute one with
which clients should share textures and display lists. Needed
when the Java2D/OpenGL pipeline is active and FBOs are being
@@ -258,7 +329,11 @@ public class Java2D {
future to indicate which GraphicsDevice the source context is
associated with. */
public static GLContext filterShareContext(GLContext shareContext) {
- initFBOShareContext();
+ // FIXME: this may need adjustment
+ initFBOShareContext(GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().
+ getDefaultConfiguration());
if (j2dFBOShareContext != null) {
return j2dFBOShareContext;
}
@@ -269,8 +344,10 @@ public class Java2D {
context", with which all contexts created by JOGL must share
textures and display lists when the FBO option is enabled for
the Java2D/OpenGL pipeline. */
- public static GLContext getShareContext() {
- initFBOShareContext();
+ public static GLContext getShareContext(GraphicsConfiguration gc) {
+ initFBOShareContext(gc);
+ // FIXME: for full generality probably need to have multiple of
+ // these, one per GraphicsConfiguration seen?
return j2dFBOShareContext;
}
@@ -278,44 +355,54 @@ public class Java2D {
// Internals only below this point
//
- private static void initFBOShareContext() {
+ private static void checkActive() {
+ if (!isOGLPipelineActive()) {
+ throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
+ }
+ }
+
+ private static int getOGLUtilitiesIntField(final String name) {
+ Integer i = (Integer) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class utils = Class.forName("sun.java2d.opengl.OGLUtilities");
+ Field f = utils.getField(name);
+ f.setAccessible(true);
+ return f.get(null);
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }
+ });
+ if (i == null)
+ return 0;
+ if (DEBUG && VERBOSE) {
+ System.err.println("OGLUtilities." + name + " = " + i.intValue());
+ }
+ return i.intValue();
+ }
+
+ private static void initFBOShareContext(final GraphicsConfiguration gc) {
// Note 1: this must not be done in the static initalizer due to
// deadlock problems.
// Note 2: the first execution of this method must not be from the
// Java2D Queue Flusher Thread.
- // Note that at this point it's basically impossible that we're
- // executing on the Queue Flusher Thread since all calls (even
- // from end users) should be going through this interface and
- // we're still in the static initializer
if (isOGLPipelineActive() &&
isFBOEnabled() &&
- j2dFBOVolatileImage == null) {
- // Create a compatible VolatileImage (FIXME: may need one per
- // display device, and may need to create them lazily, which may
- // cause problems) and create a JOGL GLContext to wrap its
- // GLContext.
- //
- // FIXME: this technique is not really adequate. The
- // VolatileImage may be punted at any time, meaning that its
- // OpenGL context will be destroyed and any shares of
- // server-side objects with it will be gone. This context is
- // currently the "pinch point" through which all of the shares
- // with the set of contexts created by JOGL go through. Java2D
- // has the notion of its own share context with which all of the
- // contexts it creates internally share server-side objects;
- // what is really needed is another API in OGLUtilities to
- // invoke a Runnable with that share context current rather than
- // the context associated with a particular Graphics object, so
- // that JOGL can grab a handle to that persistent context.
- j2dFBOVolatileImage =
- GraphicsEnvironment.
- getLocalGraphicsEnvironment().
- getDefaultScreenDevice().
- getDefaultConfiguration().
- createCompatibleVolatileImage(2, 2);
- invokeWithOGLContextCurrent(j2dFBOVolatileImage.getGraphics(), new Runnable() {
+ !initializedJ2DFBOShareContext) {
+
+ // FIXME: this technique is probably not adequate in multi-head
+ // situations. Ideally we would keep track of a given share
+ // context on a per-GraphicsConfiguration basis or something
+ // similar rather than keeping one share context in a global
+ // variable.
+ initializedJ2DFBOShareContext = true;
+ invokeWithOGLSharedContextCurrent(gc, new Runnable() {
public void run() {
j2dFBOShareContext = GLDrawableFactory.getFactory().createExternalGLContext();
}
diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java b/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java
index a12f156f5..c56614599 100755
--- a/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java
+++ b/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLContext.java
@@ -51,6 +51,9 @@ public class WindowsExternalGLContext extends WindowsGLContext {
public WindowsExternalGLContext() {
super(null, null);
hglrc = WGL.wglGetCurrentContext();
+ if (hglrc == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a drawable/context current");
+ }
if (DEBUG) {
System.err.println(getThreadName() + ": !!! Created external OpenGL context " + toHexString(hglrc) + " for " + this);
}
diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLDrawable.java
index 68ab83161..23ec0a1fc 100755
--- a/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/windows/WindowsExternalGLDrawable.java
@@ -46,6 +46,9 @@ public class WindowsExternalGLDrawable extends WindowsGLDrawable {
public WindowsExternalGLDrawable() {
super(new GLCapabilities(), null);
hdc = WGL.wglGetCurrentDC();
+ if (hdc == 0) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
+ }
}
public GLContext createContext(GLContext shareWith) {
diff --git a/src/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java b/src/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java
index ae61c0063..e0446f4d6 100755
--- a/src/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java
+++ b/src/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java
@@ -51,6 +51,9 @@ public class X11ExternalGLContext extends X11GLContext {
lockToolkit();
try {
context = GLX.glXGetCurrentContext();
+ if (context == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a drawable/context current");
+ }
drawable = new Drawable(GLX.glXGetCurrentDisplay());
} finally {
unlockToolkit();
diff --git a/src/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java b/src/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java
index e8fc069ba..10e58d3a0 100755
--- a/src/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java
+++ b/src/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java
@@ -55,6 +55,9 @@ public class X11ExternalGLDrawable extends X11GLDrawable {
display = GLX.glXGetCurrentDisplay();
drawable = GLX.glXGetCurrentDrawable();
readDrawable = GLX.glXGetCurrentReadDrawable();
+ if (drawable == 0) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
+ }
// Need GLXFBConfig ID in order to properly create new contexts
// on this drawable
diff --git a/src/classes/javax/media/opengl/GLJPanel.java b/src/classes/javax/media/opengl/GLJPanel.java
index 6f8340aff..929975f13 100644
--- a/src/classes/javax/media/opengl/GLJPanel.java
+++ b/src/classes/javax/media/opengl/GLJPanel.java
@@ -178,7 +178,10 @@ public class GLJPanel extends JPanel implements GLAutoDrawable {
// otherwise it's likely it will try to be initialized while on
// the Queue Flusher Thread, which is not allowed
if (Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) {
- Java2D.getShareContext();
+ Java2D.getShareContext(GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().
+ getDefaultConfiguration());
}
}
@@ -235,11 +238,19 @@ public class GLJPanel extends JPanel implements GLAutoDrawable {
}
}
- private void captureJ2DState(GL gl) {
+ private void captureJ2DState(GL gl, Graphics g) {
gl.glGetIntegerv(GL.GL_DRAW_BUFFER, drawBuffer, 0);
gl.glGetIntegerv(GL.GL_READ_BUFFER, readBuffer, 0);
- if (Java2D.isFBOEnabled()) {
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("-- Fetching GL_FRAMEBUFFER_BINDING_EXT");
+ }
gl.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING_EXT, frameBuffer, 0);
+
+ // Unbind the framebuffer from this context before attempting to
+ // bind it to ours (may not be necessary)
+ // gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
}
}
@@ -268,14 +279,12 @@ public class GLJPanel extends JPanel implements GLAutoDrawable {
viewportX = oglViewport.x;
viewportY = oglViewport.y;
- gl.glDrawBuffer(drawBuffer[0]);
- gl.glReadBuffer(readBuffer[0]);
-
// If the FBO option is active, bind to the FBO from the Java2D
// context.
// Note that all of the plumbing in the context sharing stuff will
// allow us to bind to this object since it's in our namespace.
- if (Java2D.isFBOEnabled()) {
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) {
if (DEBUG && VERBOSE) {
System.err.println("Binding to framebuffer object " + frameBuffer[0]);
}
@@ -284,6 +293,14 @@ public class GLJPanel extends JPanel implements GLAutoDrawable {
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBuffer[0]);
// FIXME: do we need to do anything else? Bind Texture2D state
// or something else?
+ } else {
+ if (DEBUG && VERBOSE) {
+ System.err.println("Setting up drawBuffer " + drawBuffer[0] +
+ " and readBuffer " + readBuffer[0]);
+ }
+
+ gl.glDrawBuffer(drawBuffer[0]);
+ gl.glReadBuffer(readBuffer[0]);
}
return true;
@@ -363,7 +380,7 @@ public class GLJPanel extends JPanel implements GLAutoDrawable {
j2dContext.makeCurrent();
try {
- captureJ2DState(j2dContext.getGL());
+ captureJ2DState(j2dContext.getGL(), g);
Object curSurface = Java2D.getOGLSurfaceIdentifier(g);
if (curSurface != null) {
if (j2dSurface != curSurface) {