diff options
author | Sven Gothel <[email protected]> | 2012-01-08 06:31:17 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-01-08 06:31:17 +0100 |
commit | 098398c2a9145447da5314eed9792b3738c2d515 (patch) | |
tree | ec8743137418e6b92644ba02f21c73f559145b16 /src/jogl/classes/javax | |
parent | 7ce29d85bb85c003c9dc3b94efa84b55dfbb7f86 (diff) |
GLContext*/GLDrawableHelper: Fix consistency of recursive makeCurrent()/release()/destroy() calls ; Enable context switch tracing ; GLCanvas: proper AbstractGraphicsDevice destruction
GLContext*/GLDrawableHelper: Fix consistency of recursive makeCurrent()/release()/destroy() calls
Utilizing volatile and lock.tryLock(0) for lockConsiderFailFast(),
reducing redundant synchronization and using RecursiveLock implicit sync.
GLContext 'early-out' is the case where the thread already holds the
context, ie. context is already current and the native makeCurrent is skipped.
makeCurrent()'s 'early-out' w/o incr. the recursive lock of GLContext
and it's NativeSurface could lead to asymetry in lock/unlock count
with release()/destroy() calls. The 1st release actually released the
native ctx already.
Properly utilize recursive lock/unlock in all cases and impl. 'early-out' after locking.
Following the above in GLDrawableHelper.invokeGL()'s 'early-out' case as well,
ie calling makeCurrent()/release() symmetrical.
Introduce GLDrawableHelper.disposeGL(), which issues dispose on all GLEventListeners
within a current context and issued context destruction directly.
This simplifies GLAutodrawable's destroy/dispose calls and ensures
that the above sequence of events happens atomically (lock is being hold until destruction).
Enable context switch tracing
If property 'jogl.debug.GLContext.TraceSwitch' is defined, trace context switch.
GLCanvas: proper AbstractGraphicsDevice destruction
Diffstat (limited to 'src/jogl/classes/javax')
-rw-r--r-- | src/jogl/classes/javax/media/opengl/GLContext.java | 7 | ||||
-rw-r--r-- | src/jogl/classes/javax/media/opengl/awt/GLCanvas.java | 80 | ||||
-rw-r--r-- | src/jogl/classes/javax/media/opengl/awt/GLJPanel.java | 52 |
3 files changed, 59 insertions, 80 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 38c2d79e5..2d304b77c 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -295,8 +295,11 @@ public abstract class GLContext { /** * Destroys this OpenGL context and frees its associated - * resources. The context should have been released before this - * method is called. + * resources. + * <p> + * The context may be current w/o recursion when calling <code>destroy()</code>, + * in which case this method destroys the context and releases the lock. + * </p> */ public abstract void destroy(); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 1b234ef3a..cd341593e 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -59,6 +59,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; +import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.OffscreenLayerOption; import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.AbstractGraphicsDevice; @@ -441,25 +442,25 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing disposeRegenerate=regenerate; - if (Threading.isSingleThreaded() && - !Threading.isOpenGLThread()) { - // Workaround for termination issues with applets -- - // sun.applet.AppletPanel should probably be performing the - // remove() call on the EDT rather than on its own thread - // Hint: User should run remove from EDT. - if (ThreadingImpl.isAWTMode() && - Thread.holdsLock(getTreeLock())) { - // The user really should not be invoking remove() from this - // thread -- but since he/she is, we can not go over to the - // EDT at this point. Try to destroy the context from here. - if(context.isCreated()) { - drawableHelper.invokeGL(drawable, context, disposeAction, null); + if(context.isCreated()) { + if (Threading.isSingleThreaded() && + !Threading.isOpenGLThread()) { + // Workaround for termination issues with applets -- + // sun.applet.AppletPanel should probably be performing the + // remove() call on the EDT rather than on its own thread + // Hint: User should run remove from EDT. + if (ThreadingImpl.isAWTMode() && + Thread.holdsLock(getTreeLock())) { + // The user really should not be invoking remove() from this + // thread -- but since he/she is, we can not go over to the + // EDT at this point. Try to destroy the context from here. + drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction); + } else { + Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction); + } + } else { + drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction); } - } else if(context.isCreated()) { - Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction); - } - } else if(context.isCreated()) { - drawableHelper.invokeGL(drawable, context, disposeAction, null); } if(animatorPaused) { @@ -834,16 +835,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing } } - class DisposeAction implements Runnable { + class PostDisposeAction implements Runnable { public void run() { - drawableHelper.dispose(GLCanvas.this); - - if(null!=context) { - context.makeCurrent(); // implicit wait for lock .. - context.destroy(); - context=null; - } - + context=null; if(null!=drawable) { final JAWTWindow jawtWindow = (JAWTWindow)drawable.getNativeSurface(); drawable.setRealized(false); @@ -867,21 +861,22 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing } } private boolean disposeRegenerate; - private DisposeAction disposeAction = new DisposeAction(); + private PostDisposeAction postDisposeAction = new PostDisposeAction(); private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction = new DisposeOnEventDispatchThreadAction(); class DisposeOnEventDispatchThreadAction implements Runnable { public void run() { - drawableHelper.invokeGL(drawable, context, disposeAction, null); + drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction); } } class DisposeAbstractGraphicsDeviceAction implements Runnable { public void run() { if(null != awtConfig) { - final AbstractGraphicsDevice adevice = awtConfig.getScreen().getDevice(); + final AbstractGraphicsConfiguration aconfig = awtConfig.getNativeGraphicsConfiguration(); + final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); final String adeviceMsg; if(DEBUG) { adeviceMsg = adevice.toString(); @@ -1091,9 +1086,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing } GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) ); - Frame frame = new Frame("JOGL AWT Test"); + final Frame frame = new Frame("JOGL AWT Test"); - GLCanvas glCanvas = new GLCanvas(caps); + final GLCanvas glCanvas = new GLCanvas(caps); frame.add(glCanvas); frame.setSize(128, 128); @@ -1102,24 +1097,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing GL gl = drawable.getGL(); System.err.println(JoglVersion.getGLInfo(gl, null)); } - - public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { - } - - public void display(GLAutoDrawable drawable) { - } - - public void dispose(GLAutoDrawable drawable) { - } + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } + public void display(GLAutoDrawable drawable) { } + public void dispose(GLAutoDrawable drawable) { } }); - final Frame _frame = frame; - final GLCanvas _glCanvas = glCanvas; - try { javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { - _frame.setVisible(true); + frame.setVisible(true); }}); } catch (Throwable t) { t.printStackTrace(); @@ -1128,9 +1114,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing try { javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { - _frame.setVisible(false); - _frame.remove(_glCanvas); - _frame.dispose(); + frame.dispose(); }}); } catch (Throwable t) { t.printStackTrace(); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 0d28ab31b..7a87882ca 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -284,27 +284,24 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing animatorPaused = animator.pause(); } - final GLDrawable drawable = backend.getDrawable(); - final GLContext context = backend.getContext(); - - if (Threading.isSingleThreaded() && - !Threading.isOpenGLThread()) { - // Workaround for termination issues with applets -- - // sun.applet.AppletPanel should probably be performing the - // remove() call on the EDT rather than on its own thread - if (ThreadingImpl.isAWTMode() && - Thread.holdsLock(getTreeLock())) { - // The user really should not be invoking remove() from this - // thread -- but since he/she is, we can not go over to the - // EDT at this point. Try to destroy the context from here. - if(context.isCreated()) { - drawableHelper.invokeGL(drawable, context, disposeAction, null); - } - } else if(context.isCreated()) { - Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction); + if(backend.getContext().isCreated()) { + if (Threading.isSingleThreaded() && + !Threading.isOpenGLThread()) { + // Workaround for termination issues with applets -- + // sun.applet.AppletPanel should probably be performing the + // remove() call on the EDT rather than on its own thread + if (ThreadingImpl.isAWTMode() && + Thread.holdsLock(getTreeLock())) { + // The user really should not be invoking remove() from this + // thread -- but since he/she is, we can not go over to the + // EDT at this point. Try to destroy the context from here. + drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction); + } else { + Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction); + } + } else { + drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction); } - } else if(context.isCreated()) { - drawableHelper.invokeGL(drawable, context, disposeAction, null); } if(null != backend) { // not yet destroyed due to backend.isUsingOwnThreadManagment() == true @@ -689,12 +686,8 @@ public void reshape(int x, int y, int width, int height) { return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+"]"; } - private DisposeAction disposeAction = new DisposeAction(); - - class DisposeAction implements Runnable { + class PostDisposeAction implements Runnable { public void run() { - updater.dispose(GLJPanel.this); - if (backend != null && !backend.isUsingOwnThreadManagment()) { backend.destroy(); backend = null; @@ -702,13 +695,14 @@ public void reshape(int x, int y, int width, int height) { } } } + private PostDisposeAction postDisposeAction = new PostDisposeAction(); private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction = new DisposeOnEventDispatchThreadAction(); class DisposeOnEventDispatchThreadAction implements Runnable { public void run() { - drawableHelper.invokeGL(backend.getDrawable(), backend.getContext(), disposeAction, null); + drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction); } } @@ -1579,15 +1573,13 @@ public void reshape(int x, int y, int width, int height) { backend = null; oglPipelineEnabled = false; handleReshape = true; - j2dContext.release(); j2dContext.destroy(); j2dContext = null; return; } - j2dContext.release(); + } else { + j2dContext.makeCurrent(); } - - j2dContext.makeCurrent(); try { captureJ2DState(j2dContext.getGL(), g); Object curSurface = Java2D.getOGLSurfaceIdentifier(g); |