diff options
Diffstat (limited to 'src/jogl')
15 files changed, 271 insertions, 62 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java index c409bb253..e33ceeefb 100644 --- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java +++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java @@ -789,6 +789,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextS } @Override + public void flushGLRunnables() { + helper.flushGLRunnables(); + } + + @Override public void setAnimator(final GLAnimatorControl arg0) throws GLException { helper.setAnimator(arg0); } diff --git a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java index 496fb88c0..62df3faca 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java @@ -41,12 +41,14 @@ import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; + import javax.swing.JComponent; import javax.swing.RepaintManager; import javax.swing.SwingUtilities; - import javax.media.opengl.GLAutoDrawable; +import com.jogamp.opengl.util.AnimatorBase.UncaughtAnimatorException; + /** Abstraction to factor out AWT dependencies from the Animator's implementation in a way that still allows the FPSAnimator to pick up this behavior if desired. */ @@ -61,7 +63,7 @@ class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl { @Override public void display(final ArrayList<GLAutoDrawable> drawables, final boolean ignoreExceptions, - final boolean printExceptions) { + final boolean printExceptions) throws UncaughtAnimatorException { for (int i=0; i<drawables.size(); i++) { final GLAutoDrawable drawable = drawables.get(i); if (drawable instanceof JComponent) { @@ -73,13 +75,13 @@ class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl { } else { try { drawable.display(); - } catch (final RuntimeException e) { + } catch (final Throwable t) { if (ignoreExceptions) { if (printExceptions) { - e.printStackTrace(); + t.printStackTrace(); } } else { - throw(e); + throw new UncaughtAnimatorException(drawable, t); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java index 634e83353..d9a957199 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java +++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java @@ -132,7 +132,7 @@ public class Animator extends AnimatorBase { @Override public void run() { - GLException displayCaught = null; + UncaughtAnimatorException displayCaught = null; try { synchronized (Animator.this) { @@ -161,9 +161,9 @@ public class Animator extends AnimatorBase { ectCleared = true; setDrawablesExclCtxState(false); try { - display(); // propagate exclusive change! - } catch (final Throwable t) { - displayCaught = GLException.newGLException(t); + display(); // propagate exclusive context -> off! + } catch (final UncaughtAnimatorException dre) { + displayCaught = dre; stopIssued = true; isAnimating = false; break; // end pause loop @@ -189,15 +189,15 @@ public class Animator extends AnimatorBase { // Resume from pause or drawablesEmpty, // implies !pauseIssued and !drawablesEmpty isAnimating = true; - setDrawablesExclCtxState(exclusiveContext); + setDrawablesExclCtxState(exclusiveContext); // may re-enable exclusive context Animator.this.notifyAll(); } } // sync Animator.this if (!stopIssued) { try { display(); - } catch (final Throwable t) { - displayCaught = GLException.newGLException(t); + } catch (final UncaughtAnimatorException dre) { + displayCaught = dre; stopIssued = true; isAnimating = false; break; // end animation loop @@ -216,14 +216,13 @@ public class Animator extends AnimatorBase { } finally { if( exclusiveContext && !drawablesEmpty ) { setDrawablesExclCtxState(false); - display(); // propagate exclusive change! try { - display(); // propagate exclusive change! - } catch (final Throwable t) { + display(); // propagate exclusive context -> off! + } catch (final UncaughtAnimatorException dre) { if( null == displayCaught ) { - displayCaught = GLException.newGLException(t); + displayCaught = dre; } else { - GLException.newGLException(t).printStackTrace(); + dre.printStackTrace(); } } } @@ -237,12 +236,12 @@ public class Animator extends AnimatorBase { } stopIssued = false; pauseIssued = false; - animThread = null; isAnimating = false; - Animator.this.notifyAll(); if( null != displayCaught ) { - throw displayCaught; + handleUncaughtException(displayCaught); } + animThread = null; + Animator.this.notifyAll(); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java index a5bdb9350..ed23a78ba 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java +++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java @@ -67,8 +67,25 @@ public abstract class AnimatorBase implements GLAnimatorControl { */ public static final int MODE_EXPECT_AWT_RENDERING_THREAD = 1 << 0; - public interface AnimatorImpl { - void display(ArrayList<GLAutoDrawable> drawables, boolean ignoreExceptions, boolean printExceptions); + + @SuppressWarnings("serial") + public static class UncaughtAnimatorException extends RuntimeException { + final GLAutoDrawable drawable; + public UncaughtAnimatorException(final GLAutoDrawable drawable, final Throwable cause) { + super(cause); + this.drawable = drawable; + } + public final GLAutoDrawable getGLAutoDrawable() { return drawable; } + } + + public static interface AnimatorImpl { + /** + * @param drawables + * @param ignoreExceptions + * @param printExceptions + * @throws UncaughtAnimatorException as caused by {@link GLAutoDrawable#display()} + */ + void display(ArrayList<GLAutoDrawable> drawables, boolean ignoreExceptions, boolean printExceptions) throws UncaughtAnimatorException; boolean blockUntilDone(Thread thread); } @@ -83,6 +100,7 @@ public abstract class AnimatorBase implements GLAnimatorControl { protected boolean printExceptions; protected boolean exclusiveContext; protected Thread userExclusiveContextThread; + protected UncaughtGLAnimatorExceptionHandler uncaughtExceptionHandler; protected FPSCounterImpl fpsCounter = new FPSCounterImpl(); private final static Class<?> awtAnimatorImplClazz; @@ -313,11 +331,16 @@ public abstract class AnimatorBase implements GLAnimatorControl { } } final Thread dECT = enable ? ( null != _exclusiveContextThread ? _exclusiveContextThread : animThread ) : null ; + UncaughtAnimatorException displayCaught = null; if( propagateState ) { setDrawablesExclCtxState(enable); if( !enable ) { if( Thread.currentThread() == getThread() || Thread.currentThread() == _exclusiveContextThread ) { - display(); + try { + display(); // propagate exclusive context -> off! + } catch (final UncaughtAnimatorException dre) { + displayCaught = dre; + } } else { final boolean resumed = isAnimating() ? false : resume(); int counter = 10; @@ -338,6 +361,13 @@ public abstract class AnimatorBase implements GLAnimatorControl { } if(DEBUG) { System.err.println("AnimatorBase.setExclusiveContextThread: all-GLAD Ok: "+validateDrawablesExclCtxState(dECT)+", "+this); + if( null != displayCaught ) { + System.err.println("AnimatorBase.setExclusiveContextThread: caught: "+displayCaught.getMessage()); + displayCaught.printStackTrace(); + } + } + if( null != displayCaught ) { + throw displayCaught; } return oldExclusiveContext; } @@ -412,7 +442,7 @@ public abstract class AnimatorBase implements GLAnimatorControl { this to get the most optimized painting behavior for the set of components this Animator manages, in particular when multiple lightweight widgets are continually being redrawn. */ - protected final void display() { + protected final void display() throws UncaughtAnimatorException { impl.display(drawables, ignoreExceptions, printExceptions); fpsCounter.tickFPS(); } @@ -482,7 +512,43 @@ public abstract class AnimatorBase implements GLAnimatorControl { this.printExceptions = printExceptions; } - protected interface Condition { + @Override + public final UncaughtGLAnimatorExceptionHandler getUncaughtExceptionHandler() { + return uncaughtExceptionHandler; + } + + @Override + public final void setUncaughtExceptionHandler(final UncaughtGLAnimatorExceptionHandler handler) { + uncaughtExceptionHandler = handler; + } + + /** + * Should be called in case of an uncaught exception + * from within the animator thread to flush all animator + */ + protected final synchronized void handleUncaughtException(final UncaughtAnimatorException ue) { + if( null != uncaughtExceptionHandler ) { + try { + uncaughtExceptionHandler.uncaughtException(this, ue.getGLAutoDrawable(), ue.getCause()); + } catch (final Throwable t) { /* ignore intentionally */ } + flushGLRunnables(); + } else { + flushGLRunnables(); + throw ue; + } + } + + /** + * Should be called in case of an uncaught exception + * from within the animator thread to flush all animator + */ + protected final synchronized void flushGLRunnables() { + for (int i=0; i<drawables.size(); i++) { + drawables.get(i).flushGLRunnables(); + } + } + + protected static interface Condition { /** * @return true if branching (continue waiting, action), otherwise false */ diff --git a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java index 7fa4011f8..6b1485a6a 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java @@ -34,8 +34,11 @@ package com.jogamp.opengl.util; import java.util.ArrayList; + import javax.media.opengl.GLAutoDrawable; +import com.jogamp.opengl.util.AnimatorBase.UncaughtAnimatorException; + /** Abstraction to factor out AWT dependencies from the Animator's implementation in a way that still allows the FPSAnimator to pick up this behavior if desired. */ @@ -44,18 +47,18 @@ class DefaultAnimatorImpl implements AnimatorBase.AnimatorImpl { @Override public void display(final ArrayList<GLAutoDrawable> drawables, final boolean ignoreExceptions, - final boolean printExceptions) { + final boolean printExceptions) throws UncaughtAnimatorException { for (int i=0; i<drawables.size(); i++) { final GLAutoDrawable drawable = drawables.get(i); try { drawable.display(); - } catch (final RuntimeException e) { + } catch (final Throwable t) { if (ignoreExceptions) { if (printExceptions) { - e.printStackTrace(); + t.printStackTrace(); } } else { - throw(e); + throw new UncaughtAnimatorException(drawable, t); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java index 746b642c2..9ae880414 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java +++ b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java @@ -148,6 +148,8 @@ public class FPSAnimator extends AnimatorBase { @Override public void run() { + UncaughtAnimatorException displayCaught = null; + if( justStarted ) { justStarted = false; synchronized (FPSAnimator.this) { @@ -160,7 +162,7 @@ public class FPSAnimator extends AnimatorBase { shouldRun = false; // isAnimating:=false @ pause below } else { shouldRun = true; - setDrawablesExclCtxState(exclusiveContext); + setDrawablesExclCtxState(exclusiveContext); // may re-enable exclusive context FPSAnimator.this.notifyAll(); } if(DEBUG) { @@ -168,46 +170,76 @@ public class FPSAnimator extends AnimatorBase { } } } - if( shouldRun ) { - display(); - } else if( shouldStop ) { // STOP + if( shouldRun && !shouldStop ) { // RUN + try { + display(); + } catch (final UncaughtAnimatorException dre) { + displayCaught = dre; + shouldRun = false; + shouldStop = true; + } + } else if( !shouldRun && !shouldStop ) { // PAUSE if(DEBUG) { - System.err.println("FPSAnimator P4: "+alreadyStopped+", "+ Thread.currentThread() + ": " + toString()); + System.err.println("FPSAnimator pausing: "+alreadyPaused+", "+ Thread.currentThread() + ": " + toString()); } this.cancel(); - if( !alreadyStopped ) { - alreadyStopped = true; + if( !alreadyPaused ) { // PAUSE + alreadyPaused = true; if( exclusiveContext && !drawablesEmpty ) { setDrawablesExclCtxState(false); - display(); // propagate exclusive change! + try { + display(); // propagate exclusive context -> off! + } catch (final UncaughtAnimatorException dre) { + displayCaught = dre; + shouldRun = false; + shouldStop = true; + } } - synchronized (FPSAnimator.this) { - if(DEBUG) { - System.err.println("FPSAnimator stop " + Thread.currentThread() + ": " + toString()); + if( null == displayCaught ) { + synchronized (FPSAnimator.this) { + if(DEBUG) { + System.err.println("FPSAnimator pause " + Thread.currentThread() + ": " + toString()); + } + isAnimating = false; + FPSAnimator.this.notifyAll(); } - animThread = null; - isAnimating = false; - FPSAnimator.this.notifyAll(); } } - } else { + } + if( shouldStop ) { // STOP if(DEBUG) { - System.err.println("FPSAnimator P5: "+alreadyPaused+", "+ Thread.currentThread() + ": " + toString()); + System.err.println("FPSAnimator stopping: "+alreadyStopped+", "+ Thread.currentThread() + ": " + toString()); } this.cancel(); - if( !alreadyPaused ) { // PAUSE - alreadyPaused = true; + if( !alreadyStopped ) { + alreadyStopped = true; if( exclusiveContext && !drawablesEmpty ) { setDrawablesExclCtxState(false); - display(); // propagate exclusive change! + try { + display(); // propagate exclusive context -> off! + } catch (final UncaughtAnimatorException dre) { + if( null == displayCaught ) { + displayCaught = dre; + } else { + dre.printStackTrace(); + } + } } synchronized (FPSAnimator.this) { if(DEBUG) { - System.err.println("FPSAnimator pause " + Thread.currentThread() + ": " + toString()); + System.err.println("FPSAnimator stop " + Thread.currentThread() + ": " + toString()); + if( null != displayCaught ) { + System.err.println("AnimatorBase.setExclusiveContextThread: caught: "+displayCaught.getMessage()); + displayCaught.printStackTrace(); + } } isAnimating = false; + if( null != displayCaught ) { + handleUncaughtException(displayCaught); + } + animThread = null; FPSAnimator.this.notifyAll(); } } diff --git a/src/jogl/classes/javax/media/opengl/GLAnimatorControl.java b/src/jogl/classes/javax/media/opengl/GLAnimatorControl.java index 827145654..50f7e9bbb 100644 --- a/src/jogl/classes/javax/media/opengl/GLAnimatorControl.java +++ b/src/jogl/classes/javax/media/opengl/GLAnimatorControl.java @@ -33,6 +33,38 @@ package javax.media.opengl; * which implementation may drive a {@link javax.media.opengl.GLAutoDrawable} animation. */ public interface GLAnimatorControl extends FPSCounter { + /** + * A {@link GLAnimatorControl#setUncaughtExceptionHandler(UncaughtGLAnimatorExceptionHandler) registered} + * {@link UncaughtGLAnimatorExceptionHandler} instance is invoked when an {@link GLAnimatorControl animator} abruptly {@link #stop() stops} + * due to an uncaught exception from one of its {@link GLAutoDrawable}s. + * @see #uncaughtException(GLAnimatorControl, GLAutoDrawable, Throwable) + * @see GLAnimatorControl#setUncaughtExceptionHandler(UncaughtGLAnimatorExceptionHandler) + * @since 2.2 + */ + public static interface UncaughtGLAnimatorExceptionHandler { + /** + * Method invoked when the given {@link GLAnimatorControl} is {@link GLAnimatorControl#stop() stopped} due to the + * given uncaught exception happened on the given {@link GLAutoDrawable}. + * <p> + * The animator thread can still be retrieved via {@link GLAnimatorControl#getThread()}. + * </p> + * <p> + * All {@link GLAnimatorControl} states already reflect its stopped state. + * </p> + * <p> + * After this handler method is called, the {@link GLAnimatorControl} is stopped. + * </p> + * <p> + * Any exception thrown by this method will be ignored. + * </p> + * @param animator the {@link GLAnimatorControl} + * @param drawable the causing {@link GLAutoDrawable} + * @param cause the uncaught exception + * @see GLAnimatorControl#setUncaughtExceptionHandler(UncaughtGLAnimatorExceptionHandler) + * @since 2.2 + */ + void uncaughtException(final GLAnimatorControl animator, final GLAutoDrawable drawable, final Throwable cause); + } /** * Indicates whether this animator has been {@link #start() started}. @@ -181,4 +213,24 @@ public interface GLAnimatorControl extends FPSCounter { * @throws IllegalArgumentException if drawable was not added to this animator */ void remove(GLAutoDrawable drawable); + + /** + * Returns the {@link UncaughtGLAnimatorExceptionHandler} invoked when this {@link GLAnimatorControl animator} abruptly {@link #stop() stops} + * due to an uncaught exception from one of its {@link GLAutoDrawable}s. + * <p> + * Default is <code>null</code>. + * </p> + * @since 2.2 + */ + UncaughtGLAnimatorExceptionHandler getUncaughtExceptionHandler(); + + /** + * Set the handler invoked when this {@link GLAnimatorControl animator} abruptly {@link #stop() stops} + * due to an uncaught exception from one of its {@link GLAutoDrawable}s. + * @param handler the {@link UncaughtGLAnimatorExceptionHandler} to use as this {@link GLAnimatorControl animator}'s uncaught exception + * handler. Pass <code>null</code> to unset the handler. + * @see UncaughtGLAnimatorExceptionHandler#uncaughtException(GLAnimatorControl, GLAutoDrawable, Throwable) + * @since 2.2 + */ + void setUncaughtExceptionHandler(final UncaughtGLAnimatorExceptionHandler handler); } diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java index 5745e197f..bded88d20 100644 --- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java +++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java @@ -229,6 +229,7 @@ public interface GLAutoDrawable extends GLDrawable { /** * Returns true if all added {@link GLEventListener} are initialized, otherwise false. + * @since 2.2 */ boolean areAllGLEventListenerInitialized(); @@ -458,6 +459,7 @@ public interface GLAutoDrawable extends GLDrawable { * @see #display() * @see GLRunnable * @see #invoke(boolean, List) + * @see #flushGLRunnables() */ public boolean invoke(boolean wait, GLRunnable glRunnable) throws IllegalStateException ; @@ -469,9 +471,22 @@ public interface GLAutoDrawable extends GLDrawable { * @return <code>true</code> if the {@link GLRunnable}s has been processed or queued, otherwise <code>false</code>. * @throws IllegalStateException in case of a detected deadlock situation ahead, see {@link #invoke(boolean, GLRunnable)}. * @see #invoke(boolean, GLRunnable) + * @see #flushGLRunnables() */ public boolean invoke(boolean wait, List<GLRunnable> glRunnables) throws IllegalStateException; + /** + * Flushes all {@link #invoke(boolean, GLRunnable) enqueued} {@link GLRunnable} of this {@link GLAutoDrawable} + * including notifying waiting executor. + * <p> + * The executor which might have been blocked until notified + * will be unblocked and all tasks removed from the queue. + * </p> + * @see #invoke(boolean, GLRunnable) + * @since 2.2 + */ + public void flushGLRunnables(); + /** Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext. If a window is attached to it's implementation, it shall be closed. @@ -602,6 +617,7 @@ public interface GLAutoDrawable extends GLDrawable { * <p> * See <a href="#locking">GLAutoDrawable Locking</a>. * </p> + * @since 2.2 */ public RecursiveLock getUpstreamLock(); @@ -613,6 +629,7 @@ public interface GLAutoDrawable extends GLDrawable { * whether {@link #display()} performs the OpenGL commands on the current thread directly * or spawns them on the dedicated OpenGL thread. * </p> + * @since 2.2 */ public boolean isThreadGLCapable(); diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java index ac8644640..7ed057ea4 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawable.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java @@ -201,6 +201,7 @@ public interface GLDrawable extends NativeSurfaceHolder { </p> @return The immutable queried instance. @see #getChosenGLCapabilities() + @since 2.2 */ public GLCapabilitiesImmutable getRequestedGLCapabilities(); diff --git a/src/jogl/classes/javax/media/opengl/GLException.java b/src/jogl/classes/javax/media/opengl/GLException.java index dff9b9dad..3f76a6299 100644 --- a/src/jogl/classes/javax/media/opengl/GLException.java +++ b/src/jogl/classes/javax/media/opengl/GLException.java @@ -69,14 +69,18 @@ public class GLException extends RuntimeException { /** * Constructs a GLException object with the specified root * cause with a decorating message including the current thread name. + * @since 2.2 */ 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()); + /** + * Dumps a Throwable in a decorating message including the current thread name, and stack trace. + * @since 2.2 + */ + public static void dumpThrowable(final String additionalDescr, final Throwable t) { + System.err.println("Caught "+additionalDescr+" "+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 ca5cf0e45..dba1dbc04 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -1059,6 +1059,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing } @Override + public void flushGLRunnables() { + helper.flushGLRunnables(); + } + + @Override public GLContext setContext(final GLContext newCtx, final boolean destroyPrevCtx) { final RecursiveLock _lock = lock; _lock.lock(); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index d08839b7f..1682c6d2a 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -958,6 +958,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing } @Override + public void flushGLRunnables() { + helper.flushGLRunnables(); + } + + @Override public GLContext createContext(final GLContext shareWith) { final Backend b = backend; if ( null == b ) { diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java index e1cd59a04..6e6aaf58d 100644 --- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java +++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java @@ -279,7 +279,13 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe shallClose = true; } if( shallClose ) { - destroyAvoidAwareOfLocking(); + try { + destroyAvoidAwareOfLocking(); + } catch( final Throwable t ) { + // Intentionally catch and ignore exception, + // so the destroy mechanism of the native windowing system is not corrupted! + GLException.dumpThrowable("ignored", t); + } } } @@ -602,6 +608,11 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe } @Override + public void flushGLRunnables() { + helper.flushGLRunnables(); + } + + @Override public final void setAutoSwapBufferMode(final boolean enable) { helper.setAutoSwapBufferMode(enable); } diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java index 945ca5479..f91e1bdba 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java @@ -526,8 +526,9 @@ public class GLDrawableHelper { } catch (final Throwable t) { if( null == firstCaught ) { firstCaught = t; + } else { + GLException.dumpThrowable("subsequent", t); } - GLException.dumpThrowable(t); } disposeCount++; } @@ -541,8 +542,9 @@ public class GLDrawableHelper { } catch (final Throwable t) { if( null == firstCaught ) { firstCaught = t; + } else { + GLException.dumpThrowable("subsequent", t); } - GLException.dumpThrowable(t); } listenersToBeInit.add(listener); disposeCount++; @@ -1125,8 +1127,7 @@ public class GLDrawableHelper { final Runnable initAction) { if(null==context) { if (DEBUG) { - final Exception e = new GLException("Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext"); - GLException.dumpThrowable(e); + GLException.dumpThrowable("informal", new GLException("Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext")); } return; } @@ -1196,7 +1197,6 @@ public class GLDrawableHelper { forceNativeRelease(context); } } catch (final Throwable t) { - GLException.dumpThrowable(t); contextCloseCaught = t; } flushGLRunnables(); // always flush GLRunnables at dispose @@ -1208,6 +1208,9 @@ public class GLDrawableHelper { } } if( null != disposeCaught ) { + if( null != contextCloseCaught ) { + GLException.dumpThrowable("subsequent", contextCloseCaught); + } throw disposeCaught; } if( null != contextCloseCaught ) { @@ -1283,7 +1286,6 @@ public class GLDrawableHelper { drawable.swapBuffers(); } } catch (final Throwable t) { - GLException.dumpThrowable(t); glEventListenerCaught = t; } finally { if( _releaseExclusiveThread ) { @@ -1296,7 +1298,6 @@ public class GLDrawableHelper { try { context.release(); } catch (final Throwable t) { - GLException.dumpThrowable(t); contextReleaseCaught = t; } } @@ -1311,6 +1312,9 @@ public class GLDrawableHelper { } if( null != glEventListenerCaught ) { flushGLRunnables(); + if( null != contextReleaseCaught ) { + GLException.dumpThrowable("subsequent", contextReleaseCaught); + } throw GLException.newGLException(glEventListenerCaught); } if( null != contextReleaseCaught ) { @@ -1401,7 +1405,6 @@ public class GLDrawableHelper { tdS = tdX - tdS; // swapBuffers } } catch (final Throwable t) { - GLException.dumpThrowable(t); glEventListenerCaught = t; } finally { if( _releaseExclusiveThread ) { @@ -1416,7 +1419,6 @@ public class GLDrawableHelper { context.release(); ctxReleased = true; } catch (final Throwable t) { - GLException.dumpThrowable(t); contextReleaseCaught = t; } } @@ -1432,6 +1434,9 @@ public class GLDrawableHelper { } if( null != glEventListenerCaught ) { flushGLRunnables(); + if( null != contextReleaseCaught ) { + GLException.dumpThrowable("subsequent", contextReleaseCaught); + } throw GLException.newGLException(glEventListenerCaught); } if( null != contextReleaseCaught ) { diff --git a/src/jogl/classes/jogamp/opengl/GLRunnableTask.java b/src/jogl/classes/jogamp/opengl/GLRunnableTask.java index 0ceef6bf7..ca1c1869e 100644 --- a/src/jogl/classes/jogamp/opengl/GLRunnableTask.java +++ b/src/jogl/classes/jogamp/opengl/GLRunnableTask.java @@ -90,8 +90,10 @@ public class GLRunnableTask implements GLRunnable { /** * Simply flush this task and notify a waiting executor. + * <p> * The executor which might have been blocked until notified * will be unblocked and the task removed from the queue. + * </p> * * @see #isFlushed() * @see #isInQueue() |