diff options
Diffstat (limited to 'src/jogl')
7 files changed, 190 insertions, 51 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java index 03c6d6929..c409bb253 100644 --- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java +++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java @@ -205,10 +205,9 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS animatorPaused = false; } - if ( null != context ) { + GLException exceptionOnDisposeGL = null; + if( null != context ) { if( context.isCreated() ) { - // Catch dispose GLExceptions by GLEventListener, just 'print' them - // so we can continue with the destruction. try { if( !GLCanvas.this.isDisposed() ) { helper.disposeGL(GLCanvas.this, context, true); @@ -216,28 +215,50 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS context.destroy(); } } catch (final GLException gle) { - gle.printStackTrace(); + exceptionOnDisposeGL = gle; } } context = null; } - if ( null != drawable ) { - drawable.setRealized(false); + + Throwable exceptionOnUnrealize = null; + if( null != drawable ) { + try { + drawable.setRealized(false); + } catch( final Throwable re ) { + exceptionOnUnrealize = re; + } drawable = null; } - if( 0 != x11Window) { - SWTAccessor.destroyX11Window(screen.getDevice(), x11Window); - x11Window = 0; - } else if( 0 != gdkWindow) { - SWTAccessor.destroyGDKWindow(gdkWindow); - gdkWindow = 0; + + Throwable exceptionOnDeviceClose = null; + try { + if( 0 != x11Window) { + SWTAccessor.destroyX11Window(screen.getDevice(), x11Window); + x11Window = 0; + } else if( 0 != gdkWindow) { + SWTAccessor.destroyGDKWindow(gdkWindow); + gdkWindow = 0; + } + screen.getDevice().close(); + } catch (final Throwable re) { + exceptionOnDeviceClose = re; } - screen.getDevice().close(); if (animatorPaused) { animator.resume(); } + // throw exception in order of occurrence .. + if( null != exceptionOnDisposeGL ) { + throw exceptionOnDisposeGL; + } + if( null != exceptionOnUnrealize ) { + throw GLException.newGLException(exceptionOnUnrealize); + } + if( null != exceptionOnDeviceClose ) { + throw GLException.newGLException(exceptionOnDeviceClose); + } } finally { _lock.unlock(); } diff --git a/src/jogl/classes/javax/media/opengl/GLException.java b/src/jogl/classes/javax/media/opengl/GLException.java index 6a287c969..15e9cddac 100644 --- a/src/jogl/classes/javax/media/opengl/GLException.java +++ b/src/jogl/classes/javax/media/opengl/GLException.java @@ -41,7 +41,7 @@ package javax.media.opengl; /** A generic exception for OpenGL errors used throughout the binding as a substitute for {@link RuntimeException}. */ - +@SuppressWarnings("serial") public class GLException extends RuntimeException { /** Constructs a GLException object. */ public GLException() { @@ -65,4 +65,16 @@ public class GLException extends RuntimeException { public GLException(final Throwable cause) { super(cause); } + + /** Constructs a GLException object with the specified root + cause with a decorating message including the current thread name. */ + public static GLException newGLException(final Throwable t) { + return new GLException("Caught "+t.getClass().getSimpleName()+": "+t.getMessage()+" on thread "+Thread.currentThread().getName(), t); + } + + /** Dumps a Throwable in a decorating message including the current thread name, and stack trace. */ + public static void dumpThrowable(final Throwable t) { + System.err.println("Caught "+t.getClass().getSimpleName()+": "+t.getMessage()+" on thread "+Thread.currentThread().getName()); + t.printStackTrace(); + } } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 0599c1086..ca5cf0e45 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -1232,26 +1232,32 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing animatorPaused = false; } + GLException exceptionOnDisposeGL = null; + // OLS will be detached by disposeGL's context destruction below if( null != context ) { if( context.isCreated() ) { - // Catch dispose GLExceptions by GLEventListener, just 'print' them - // so we can continue with the destruction. try { helper.disposeGL(GLCanvas.this, context, true); if(DEBUG) { System.err.println(getThreadName()+": destroyOnEDTAction() - post ctx: "+context); } } catch (final GLException gle) { - gle.printStackTrace(); + exceptionOnDisposeGL = gle; } } context = null; } + + Throwable exceptionOnUnrealize = null; if( null != drawable ) { - drawable.setRealized(false); - if(DEBUG) { - System.err.println(getThreadName()+": destroyOnEDTAction() - post drawable: "+drawable); + try { + drawable.setRealized(false); + if(DEBUG) { + System.err.println(getThreadName()+": destroyOnEDTAction() - post drawable: "+drawable); + } + } catch( final Throwable re ) { + exceptionOnUnrealize = re; } drawable = null; } @@ -1260,6 +1266,14 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing animator.resume(); } + // throw exception in order of occurrence .. + if( null != exceptionOnDisposeGL ) { + throw exceptionOnDisposeGL; + } + if( null != exceptionOnUnrealize ) { + throw GLException.newGLException(exceptionOnUnrealize); + } + if(DEBUG) { System.err.println(getThreadName()+": dispose() - END, animator "+animator); } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 6e6bb1cad..d08839b7f 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -1338,20 +1338,33 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing if ( null != backend ) { final GLContext _context = backend.getContext(); final boolean backendDestroy = !backend.isUsingOwnLifecycle(); + + GLException exceptionOnDisposeGL = null; if( null != _context && _context.isCreated() ) { - // Catch dispose GLExceptions by GLEventListener, just 'print' them - // so we can continue with the destruction. try { helper.disposeGL(GLJPanel.this, _context, !backendDestroy); } catch (final GLException gle) { - gle.printStackTrace(); + exceptionOnDisposeGL = gle; } } + Throwable exceptionBackendDestroy = null; if ( backendDestroy ) { - backend.destroy(); + try { + backend.destroy(); + } catch( final Throwable re ) { + exceptionBackendDestroy = re; + } backend = null; isInitialized = false; } + + // throw exception in order of occurrence .. + if( null != exceptionOnDisposeGL ) { + throw exceptionOnDisposeGL; + } + if( null != exceptionBackendDestroy ) { + throw GLException.newGLException(exceptionBackendDestroy); + } } } }; diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java index 45240df29..016d07ed6 100644 --- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java +++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java @@ -356,25 +356,48 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe preserveGLStateAtDestroy(false); preserveGLEventListenerState(); } + + GLException exceptionOnDisposeGL = null; if( null != context ) { if( context.isCreated() ) { - // Catch dispose GLExceptions by GLEventListener, just 'print' them - // so we can continue with the destruction. try { helper.disposeGL(this, context, true); } catch (final GLException gle) { - gle.printStackTrace(); + exceptionOnDisposeGL = gle; } } context = null; } + + final AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(); + Throwable exceptionOnUnrealize = null; if( null != drawable ) { - final AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(); - drawable.setRealized(false); + try { + drawable.setRealized(false); + } catch( final Throwable re ) { + exceptionOnUnrealize = re; + } drawable = null; + } + + Throwable exceptionOnDeviceClose = null; + try { if( ownsDevice ) { device.close(); } + } catch (final Throwable re) { + exceptionOnDeviceClose = re; + } + + // throw exception in order of occurrence .. + if( null != exceptionOnDisposeGL ) { + throw exceptionOnDisposeGL; + } + if( null != exceptionOnUnrealize ) { + throw GLException.newGLException(exceptionOnUnrealize); + } + if( null != exceptionOnDeviceClose ) { + throw GLException.newGLException(exceptionOnDeviceClose); } } diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java index 7d05174ce..6462b801b 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java @@ -511,15 +511,24 @@ public class GLDrawableHelper { * </p> * @param autoDrawable * @return the disposal count + * @throws GLException caused by {@link GLEventListener#dispose(GLAutoDrawable)} */ - public final int disposeAllGLEventListener(final GLAutoDrawable autoDrawable, final boolean remove) { + public final int disposeAllGLEventListener(final GLAutoDrawable autoDrawable, final boolean remove) throws GLException { + Throwable firstCaught = null; int disposeCount = 0; synchronized(listenersLock) { if( remove ) { for (int count = listeners.size(); 0 < count && 0 < listeners.size(); count--) { final GLEventListener listener = listeners.remove(0); if( !listenersToBeInit.remove(listener) ) { - listener.dispose(autoDrawable); + try { + listener.dispose(autoDrawable); + } catch (final Throwable t) { + if( null == firstCaught ) { + firstCaught = t; + } + GLException.dumpThrowable(t); + } disposeCount++; } } @@ -527,13 +536,23 @@ public class GLDrawableHelper { for (int i = 0; i < listeners.size(); i++) { final GLEventListener listener = listeners.get(i); if( !listenersToBeInit.contains(listener) ) { - listener.dispose(autoDrawable); + try { + listener.dispose(autoDrawable); + } catch (final Throwable t) { + if( null == firstCaught ) { + firstCaught = t; + } + GLException.dumpThrowable(t); + } listenersToBeInit.add(listener); disposeCount++; } } } } + if( null != firstCaught ) { + throw GLException.newGLException(firstCaught); + } return disposeCount; } @@ -1048,8 +1067,7 @@ public class GLDrawableHelper { try { forceNativeRelease(context); } catch (final Throwable ex) { - ex.printStackTrace(); - throw new GLException(ex); + throw GLException.newGLException(ex); } } exclusiveContextThread = t; @@ -1105,8 +1123,8 @@ public class GLDrawableHelper { final Runnable initAction) { if(null==context) { if (DEBUG) { - final Exception e = new GLException(getThreadName()+" Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext"); - e.printStackTrace(); + final Exception e = new GLException("Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext"); + GLException.dumpThrowable(e); } return; } @@ -1131,9 +1149,11 @@ public class GLDrawableHelper { * @param autoDrawable * @param context * @param destroyContext destroy context in the end while holding the lock + * @throws GLException caused by {@link GLEventListener#dispose(GLAutoDrawable)} or context closing + * */ public final void disposeGL(final GLAutoDrawable autoDrawable, - final GLContext context, final boolean destroyContext) { + final GLContext context, final boolean destroyContext) throws GLException { // Support for recursive makeCurrent() calls as well as calling // other drawables' display() methods from within another one's GLContext lastContext = GLContext.getCurrent(); @@ -1148,15 +1168,22 @@ public class GLDrawableHelper { } } + GLException disposeCaught = null; + Throwable contextCloseCaught = null; + int res; try { res = context.makeCurrent(); if (GLContext.CONTEXT_NOT_CURRENT != res) { if(GLContext.CONTEXT_CURRENT_NEW == res) { - throw new GLException(getThreadName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context was not created (new ctx): "+context); + throw new GLException(GLDrawableHelper.getThreadName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context was not created (new ctx): "+context); } if( listeners.size() > 0 && null != autoDrawable ) { - disposeAllGLEventListener(autoDrawable, false); + try { + disposeAllGLEventListener(autoDrawable, false); + } catch(final GLException t) { + disposeCaught = t; + } } } } finally { @@ -1167,9 +1194,9 @@ public class GLDrawableHelper { forceNativeRelease(context); } flushGLRunnables(); - } catch (final Exception e) { - System.err.println("Caught exception on thread "+getThreadName()); - e.printStackTrace(); + } catch (final Throwable t) { + GLException.dumpThrowable(t); + contextCloseCaught = t; } if (lastContext != null) { final int res2 = lastContext.makeCurrent(); @@ -1177,6 +1204,12 @@ public class GLDrawableHelper { lastInitAction.run(); } } + if( null != disposeCaught ) { + throw disposeCaught; + } + if( null != contextCloseCaught ) { + throw GLException.newGLException(contextCloseCaught); + } } } @@ -1186,6 +1219,9 @@ public class GLDrawableHelper { final Runnable initAction) { final Thread currentThread = Thread.currentThread(); + Throwable glEventListenerCaught = null; + Throwable contextReleaseCaught = null; + // Exclusive Cases: // 1: lock - unlock : default // 2: lock - - : exclusive, not locked yet @@ -1243,6 +1279,9 @@ public class GLDrawableHelper { if ( autoSwapBufferMode ) { drawable.swapBuffers(); } + } catch (final Throwable t) { + GLException.dumpThrowable(t); + glEventListenerCaught = t; } finally { if( _releaseExclusiveThread ) { exclusiveContextThread = null; @@ -1253,9 +1292,9 @@ public class GLDrawableHelper { if( releaseContext ) { try { context.release(); - } catch (final Exception e) { - System.err.println("Caught exception on thread "+getThreadName()); - e.printStackTrace(); + } catch (final Throwable t) { + GLException.dumpThrowable(t); + contextReleaseCaught = t; } } } @@ -1267,6 +1306,12 @@ public class GLDrawableHelper { lastInitAction.run(); } } + if( null != glEventListenerCaught ) { + throw GLException.newGLException(glEventListenerCaught); + } + if( null != contextReleaseCaught ) { + throw GLException.newGLException(contextReleaseCaught); + } } } @@ -1276,6 +1321,9 @@ public class GLDrawableHelper { final Runnable initAction) { final Thread currentThread = Thread.currentThread(); + Throwable glEventListenerCaught = null; + Throwable contextReleaseCaught = null; + // Exclusive Cases: // 1: lock - unlock : default // 2: lock - - : exclusive, not locked yet @@ -1347,6 +1395,9 @@ public class GLDrawableHelper { tdX = System.currentTimeMillis(); tdS = tdX - tdS; // swapBuffers } + } catch (final Throwable t) { + GLException.dumpThrowable(t); + glEventListenerCaught = t; } finally { if( _releaseExclusiveThread ) { exclusiveContextSwitch = 0; @@ -1359,9 +1410,9 @@ public class GLDrawableHelper { try { context.release(); ctxReleased = true; - } catch (final Exception e) { - System.err.println("Caught exception on thread "+getThreadName()); - e.printStackTrace(); + } catch (final Throwable t) { + GLException.dumpThrowable(t); + contextReleaseCaught = t; } } } @@ -1374,11 +1425,16 @@ public class GLDrawableHelper { lastInitAction.run(); } } + if( null != glEventListenerCaught ) { + throw GLException.newGLException(glEventListenerCaught); + } + if( null != contextReleaseCaught ) { + throw GLException.newGLException(contextReleaseCaught); + } } final long td = System.currentTimeMillis() - t0; System.err.println("td0 "+td+"ms, fps "+(1.0/(td/1000.0))+", td-makeCurrent: "+tdA+"ms, td-render "+tdR+"ms, td-swap "+tdS+"ms, td-release "+tdX+"ms, ctx claimed: "+ctxClaimed+", ctx release: "+ctxReleased+", ctx destroyed "+ctxDestroyed); } protected static String getThreadName() { return Thread.currentThread().getName(); } - } diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java index 2d0f8f70b..a779fed3b 100644 --- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java @@ -322,10 +322,10 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { } } if(null != tFBO) { - throw new GLException("GLFBODrawableImpl.reset(..) FBObject.reset(..) exception", tFBO); + throw GLException.newGLException(tFBO); } if(null != tGL) { - throw new GLException("GLFBODrawableImpl.reset(..) GLContext.release() exception", tGL); + throw GLException.newGLException(tGL); } if(DEBUG) { System.err.println("GLFBODrawableImpl.reset(newSamples "+newSamples+"): END "+this); |