summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Animator.java29
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java76
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java11
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java72
5 files changed, 151 insertions, 49 deletions
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();
}
}