aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/scripts/tests.sh3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java47
-rw-r--r--src/jogl/classes/javax/media/opengl/GLException.java14
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java26
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java21
-rw-r--r--src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java33
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableHelper.java96
-rw-r--r--src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLException01NEWT.java235
9 files changed, 427 insertions, 52 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index c0ca6c99e..bce9a6907 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -475,6 +475,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLException01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMapBufferRead01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT $*
@@ -538,7 +539,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.ect.TestExclusiveContext12FPSAnimNEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch02NEWT $*
-testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch02AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch02AWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch10NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch11NewtAWT $*
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);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLException01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLException01NEWT.java
new file mode 100644
index 000000000..a2dca2dda
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLException01NEWT.java
@@ -0,0 +1,235 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestGLException01NEWT extends UITestCase {
+ static GLProfile glp;
+ static int width, height;
+
+ @BeforeClass
+ public static void initClass() {
+ glp = GLProfile.getGL2ES2();
+ Assert.assertNotNull(glp);
+ width = 512;
+ height = 512;
+ }
+
+ public static void dumpThrowable(final Throwable t) {
+ System.err.println("User caught exception "+t.getClass().getSimpleName()+": "+t.getMessage()+" on thread "+Thread.currentThread().getName());
+ t.printStackTrace();
+ }
+
+ protected void runTestGL(final GLCapabilities caps, final boolean onThread,
+ final boolean throwInInit, final boolean throwInDisplay,
+ final boolean throwInReshape, final boolean throwInDispose) throws InterruptedException {
+ final GLWindow glWindow = GLWindow.create(caps);
+ Assert.assertNotNull(glWindow);
+ glWindow.setTitle("NEWT Exception Test");
+ final GearsES2 demo1 = new GearsES2();
+ demo1.setVerbose(false);
+ glWindow.addGLEventListener(demo1);
+ final AtomicInteger initCount = new AtomicInteger();
+ final AtomicInteger disposeCount = new AtomicInteger();
+ final AtomicInteger displayCount = new AtomicInteger();
+ final AtomicInteger reshapeCount = new AtomicInteger();
+ final AtomicInteger exceptionSent = new AtomicInteger();
+
+ glWindow.addGLEventListener(new GLEventListener() {
+ @Override
+ public void init(final GLAutoDrawable drawable) {
+ if( throwInInit && 0 == exceptionSent.get() ) {
+ exceptionSent.incrementAndGet();
+ throw new RuntimeException("Injected GLEventListener exception in init");
+ }
+ }
+ @Override
+ public void dispose(final GLAutoDrawable drawable) {
+ if( throwInDispose && 0 == exceptionSent.get() ) {
+ exceptionSent.incrementAndGet();
+ throw new RuntimeException("Injected GLEventListener exception in dispose");
+ }
+ }
+ @Override
+ public void display(final GLAutoDrawable drawable) {
+ if( throwInDisplay && 0 == exceptionSent.get() ) {
+ exceptionSent.incrementAndGet();
+ throw new RuntimeException("Injected GLEventListener exception in display");
+ }
+ }
+ @Override
+ public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ if( throwInReshape && 0 == exceptionSent.get() ) {
+ exceptionSent.incrementAndGet();
+ throw new RuntimeException("Injected GLEventListener exception in reshape");
+ }
+ }
+ });
+ glWindow.addGLEventListener(new GLEventListener() {
+ @Override
+ public void init(final GLAutoDrawable drawable) {
+ initCount.incrementAndGet();
+ }
+ @Override
+ public void dispose(final GLAutoDrawable drawable) {
+ disposeCount.incrementAndGet();
+ }
+ @Override
+ public void display(final GLAutoDrawable drawable) {
+ displayCount.incrementAndGet();
+ }
+ @Override
+ public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ reshapeCount.incrementAndGet();
+ }
+ });
+
+ RuntimeException execptionAtInitReshapeDisplay = null;
+ RuntimeException execptionAtDispose = null;
+
+ final Animator animator = !onThread ? new Animator(glWindow) : null;
+
+ glWindow.setSize(width, height);
+
+ if( !onThread ) {
+ animator.setUpdateFPSFrames(1, null);
+ animator.start();
+ }
+ try {
+ glWindow.setVisible(true);
+ } catch (final RuntimeException re) {
+ execptionAtInitReshapeDisplay = re;
+ dumpThrowable(re);
+ }
+
+ final long t0 = System.currentTimeMillis();
+ long t1 = t0;
+ while(0 == exceptionSent.get() && ( onThread || animator.isAnimating() ) && t1-t0<duration ) {
+ if( onThread ) {
+ try {
+ glWindow.display();
+ } catch (final RuntimeException re) {
+ execptionAtInitReshapeDisplay = re;
+ dumpThrowable(re);
+ }
+ }
+ Thread.sleep(100);
+ t1 = System.currentTimeMillis();
+ }
+
+ if( !onThread ) {
+ animator.stop();
+ }
+ try {
+ glWindow.destroy();
+ } catch (final RuntimeException re) {
+ execptionAtDispose = re;
+ dumpThrowable(re);
+ }
+
+ if( throwInInit || throwInReshape || throwInDisplay || throwInDispose ) {
+ Assert.assertEquals("Not one exception sent", 1, exceptionSent.get());
+ if( throwInInit ) {
+ Assert.assertNotNull("No exception forwarded from init", execptionAtInitReshapeDisplay);
+ }
+ if( throwInReshape ) {
+ Assert.assertNotNull("No exception forwarded from reshape", execptionAtInitReshapeDisplay);
+ }
+ if( throwInDisplay ) {
+ Assert.assertNotNull("No exception forwarded from display", execptionAtInitReshapeDisplay);
+ }
+ if( throwInDispose ) {
+ Assert.assertNotNull("No exception forwarded from dispose", execptionAtDispose);
+ }
+ }
+ }
+
+ @Test
+ public void test01OnThreadAtInit() throws InterruptedException {
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setBackgroundOpaque(true); // default
+ runTestGL(caps, true /* onThread */, true /* init */, false /* display */, false /* reshape */, false /* dispose */);
+ }
+ @Test
+ public void test02OnThreadAtReshape() throws InterruptedException {
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setBackgroundOpaque(true); // default
+ runTestGL(caps, true /* onThread */, false /* init */, false /* display */, true /* reshape */, false /* dispose */);
+ }
+ @Test
+ public void test03OnThreadAtDisplay() throws InterruptedException {
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setBackgroundOpaque(true); // default
+ runTestGL(caps, true /* onThread */, false /* init */, true /* display */, false /* reshape */, false /* dispose */);
+ }
+ @Test
+ public void test04OnThreadAtDispose() throws InterruptedException {
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setBackgroundOpaque(true); // default
+ runTestGL(caps, true /* onThread */, false /* init */, false /* display */, false /* reshape */, true /* dispose */);
+ }
+
+ static long duration = 500; // ms
+
+ public static void main(final String args[]) {
+ boolean waitForKey = false;
+
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration = MiscUtils.atol(args[i], duration);
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
+ }
+ }
+ if( waitForKey ) {
+ UITestCase.waitForKey("main");
+ }
+ org.junit.runner.JUnitCore.main(TestGLException01NEWT.class.getName());
+ }
+}