aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/impl
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2006-02-11 01:11:57 +0000
committerKenneth Russel <[email protected]>2006-02-11 01:11:57 +0000
commit8ebdef6860e34bf16b9b13c657f651bf9ce32ab3 (patch)
treee1b51b0c8cacf3987f219b2e992af089aea5d1b4 /src/classes/com/sun/opengl/impl
parentb75d4a3718b1a5744218e19c4f5c1a9ff0311f34 (diff)
Further work on FBO support in Java2D/JOGL bridge. Upgraded JOGL's
Java2D class to latest proposed set of APIs in OGLUtilities and changed usage of these APIs to be approximately correct. Left in fallback path for working with non-FBO case in current Mustang builds. Not working yet, and don't yet understand why; checking in at this intermediate point to be able to more easily test on more machines. Added error checking to creation of external GLContexts and GLDrawables on Windows and X11 platforms. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@597 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/classes/com/sun/opengl/impl')
-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
7 files changed, 183 insertions, 64 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