From 9b35c57425b0a5f6b789b9b43a62a8b64be51d86 Mon Sep 17 00:00:00 2001
From: Sven Gothel
* Registers the usage of an animator, an {@link javax.media.opengl.GLAnimatorControl} implementation.
@@ -221,14 +237,30 @@ public interface GLAutoDrawable extends GLDrawable {
*
* If an {@link GLAnimatorControl} is animating,
* no {@link #display()} call is issued, since the animator thread performs it.
- * If wait
is true, the implementation waits until the GLRunnable
is executed.
- *
+ *
+ * If wait
is true
the call blocks until the glRunnable
+ * has been executed.
+ *
+ * If wait
is true
and
+ * {@link #isRealized()} returns false
or {@link #getContext()} returns null
,
+ * the call is ignored and returns false
.
+ * This helps avoiding deadlocking the caller.
+ *
+ * The internal queue of {@link GLRunnable}'s is being flushed with {@link #destroy()} + * where all blocked callers are being notified. + *
* + * @param wait iftrue
block until execution of glRunnable
is finished, otherwise return immediatly w/o waiting
+ * @param glRunnable the {@link GLRunnable} to execute within {@link #display()}
+ * @return true
if the {@link GLRunnable} has been processed or queued, otherwise false
.
+ *
* @see #setAnimator(GLAnimatorControl)
* @see #display()
* @see GLRunnable
*/
- public void invoke(boolean wait, GLRunnable glRunnable);
+ public boolean invoke(boolean wait, GLRunnable glRunnable);
/** Destroys all resources associated with this GLAutoDrawable,
inclusive the GLContext.
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
index 992bf9fee..89d5cc4cb 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
@@ -28,6 +28,9 @@
package javax.media.opengl;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
import jogamp.opengl.Debug;
import jogamp.opengl.GLAutoDrawableBase;
import jogamp.opengl.GLContextImpl;
@@ -39,11 +42,16 @@ import jogamp.opengl.GLDrawableImpl;
* utilizing already created created {@link GLDrawable} and {@link GLContext} instances.
* * Since no native windowing system events are being processed, it is recommended - * to handle at least {@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize}, - * {@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} - * and maybe {@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint}. - * The latter is only required if no {@link GLAnimatorControl} is being used. - *
+ * to handle at least: + *+ * See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}. + *
*/ public class GLAutoDrawableDelegate extends GLAutoDrawableBase { public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate"); @@ -52,36 +60,64 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase { super((GLDrawableImpl)drawable, (GLContextImpl)context); } - public void defaultRepaintOp() { - super.defaultRepaintOp(); + // + // make protected methods accessible + // + + public void defaultWindowRepaintOp() { + super.defaultWindowRepaintOp(); + } + + public void defaultWindowResizedOp() { + super.defaultWindowResizedOp(); } - public void defaultReshapeOp() { - super.defaultReshapeOp(); + public void defaultWindowDestroyNotifyOp() { + super.defaultWindowDestroyNotifyOp(); } // // Complete GLAutoDrawable // + private RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock + /** * {@inheritDoc} *- * This implementation simply removes references to drawable and context. + * This implementation calls {@link #defaultDestroyOp()}. + *
+ *+ * User still needs to destroy the upstream window, which details are hidden from this aspect. *
*/ @Override public void destroy() { - drawable = null; - context = null; + lock.lock(); + try { + defaultDestroyOp(); + } finally { + lock.unlock(); + } } @Override public void display() { - if( null == drawable || !drawable.isRealized() || null == context ) { return; } - - // surface is locked/unlocked implicit by context's makeCurrent/release - helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction); + if( sendDestroy ) { + sendDestroy=false; + destroy(); + return; + } + + lock.lock(); // sync: context/drawable could been recreated/destroyed while animating + try { + if( null != drawable && drawable.isRealized() && null != context ) { + // surface is locked/unlocked implicit by context's makeCurrent/release + helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction); + } + } finally { + lock.unlock(); + } } // diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 8c6e594b5..3161f898d 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -153,7 +153,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing private static final boolean DEBUG = Debug.debug("GLCanvas"); - private final GLDrawableHelper drawableHelper = new GLDrawableHelper(); + private final GLDrawableHelper helper = new GLDrawableHelper(); private AWTGraphicsConfiguration awtConfig; private volatile GLDrawable drawable; // volatile avoids locking all accessors. FIXME still need to sync destroy/display private GLContextImpl context; @@ -510,7 +510,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing (int) ((getHeight() + bounds.getHeight()) / 2)); return; } - if( ! this.drawableHelper.isAnimatorAnimating() ) { + if( ! this.helper.isAnimatorAnimating() ) { display(); } } @@ -670,38 +670,43 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing @Override public void addGLEventListener(GLEventListener listener) { - drawableHelper.addGLEventListener(listener); + helper.addGLEventListener(listener); } @Override - public void addGLEventListener(int index, GLEventListener listener) { - drawableHelper.addGLEventListener(index, listener); + public void addGLEventListener(int index, GLEventListener listener) throws IndexOutOfBoundsException { + helper.addGLEventListener(index, listener); } @Override public void removeGLEventListener(GLEventListener listener) { - drawableHelper.removeGLEventListener(listener); + helper.removeGLEventListener(listener); } + @Override + public GLEventListener removeGLEventListener(int index) throws IndexOutOfBoundsException { + return helper.removeGLEventListener(index); + } + @Override public void setAnimator(GLAnimatorControl animatorControl) { - drawableHelper.setAnimator(animatorControl); + helper.setAnimator(animatorControl); } @Override public GLAnimatorControl getAnimator() { - return drawableHelper.getAnimator(); + return helper.getAnimator(); } @Override - public void invoke(boolean wait, GLRunnable glRunnable) { - drawableHelper.invoke(this, wait, glRunnable); + public boolean invoke(boolean wait, GLRunnable glRunnable) { + return helper.invoke(this, wait, glRunnable); } @Override public GLContext setContext(GLContext newCtx) { final GLContext oldCtx = context; - final boolean newCtxCurrent = drawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags); + final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags); context=(GLContextImpl)newCtx; if(newCtxCurrent) { context.makeCurrent(); @@ -736,12 +741,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing @Override public void setAutoSwapBufferMode(boolean onOrOff) { - drawableHelper.setAutoSwapBufferMode(onOrOff); + helper.setAutoSwapBufferMode(onOrOff); } @Override public boolean getAutoSwapBufferMode() { - return drawableHelper.getAutoSwapBufferMode(); + return helper.getAutoSwapBufferMode(); } @Override @@ -849,7 +854,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing private final Runnable disposeOnEDTAction = new Runnable() { @Override public void run() { - drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction); + helper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction); } }; @@ -897,7 +902,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing private final Runnable initAction = new Runnable() { @Override public void run() { - drawableHelper.init(GLCanvas.this); + helper.init(GLCanvas.this); } }; @@ -910,11 +915,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing } // Note: we ignore the given x and y within the parent component // since we are drawing directly into this heavyweight component. - drawableHelper.reshape(GLCanvas.this, 0, 0, getWidth(), getHeight()); + helper.reshape(GLCanvas.this, 0, 0, getWidth(), getHeight()); sendReshape = false; } - drawableHelper.display(GLCanvas.this); + helper.display(GLCanvas.this); } }; @@ -931,14 +936,14 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing private final Runnable displayOnEDTAction = new Runnable() { @Override public void run() { - drawableHelper.invokeGL(drawable, context, displayAction, initAction); + helper.invokeGL(drawable, context, displayAction, initAction); } }; private final Runnable swapBuffersOnEDTAction = new Runnable() { @Override public void run() { - drawableHelper.invokeGL(drawable, context, swapBuffersAction, initAction); + helper.invokeGL(drawable, context, swapBuffersAction, initAction); } }; diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index c6c7cf9a1..cd18c5098 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -125,7 +125,7 @@ import com.jogamp.opengl.util.GLBuffers; public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol { private static final boolean DEBUG = Debug.debug("GLJPanel"); - private GLDrawableHelper drawableHelper = new GLDrawableHelper(); + private GLDrawableHelper helper = new GLDrawableHelper(); private volatile boolean isInitialized; // Data used for either pbuffers or pixmap-based offscreen surfaces @@ -413,32 +413,37 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing @Override public void addGLEventListener(GLEventListener listener) { - drawableHelper.addGLEventListener(listener); + helper.addGLEventListener(listener); } @Override public void addGLEventListener(int index, GLEventListener listener) { - drawableHelper.addGLEventListener(index, listener); + helper.addGLEventListener(index, listener); } @Override public void removeGLEventListener(GLEventListener listener) { - drawableHelper.removeGLEventListener(listener); + helper.removeGLEventListener(listener); } + @Override + public GLEventListener removeGLEventListener(int index) throws IndexOutOfBoundsException { + return helper.removeGLEventListener(index); + } + @Override public void setAnimator(GLAnimatorControl animatorControl) { - drawableHelper.setAnimator(animatorControl); + helper.setAnimator(animatorControl); } @Override public GLAnimatorControl getAnimator() { - return drawableHelper.getAnimator(); + return helper.getAnimator(); } @Override - public void invoke(boolean wait, GLRunnable glRunnable) { - drawableHelper.invoke(this, wait, glRunnable); + public boolean invoke(boolean wait, GLRunnable glRunnable) { + return helper.invoke(this, wait, glRunnable); } @Override @@ -461,7 +466,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing return null; } final GLContext oldCtx = backend.getContext(); - final boolean newCtxCurrent = drawableHelper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags); + final boolean newCtxCurrent = helper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags); backend.setContext(newCtx); if(newCtxCurrent) { newCtx.makeCurrent(); @@ -662,13 +667,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing if (!backend.preGL(g)) { return; } - drawableHelper.init(GLJPanel.this); + helper.init(GLJPanel.this); backend.postGL(g, false); } @Override public void dispose(GLAutoDrawable drawable) { - drawableHelper.dispose(GLJPanel.this); + helper.dispose(GLJPanel.this); } @Override @@ -680,11 +685,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing if (DEBUG) { System.err.println(getThreadName()+": GLJPanel.display: reshape(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + ")"); } - drawableHelper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight); + helper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight); sendReshape = false; } - drawableHelper.display(GLJPanel.this); + helper.display(GLJPanel.this); backend.postGL(g, true); } @@ -716,7 +721,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing private final Runnable disposeAction = new Runnable() { @Override public void run() { - drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction); + helper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction); } }; @@ -1035,7 +1040,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing } if (offscreenDrawable != null) { final AbstractGraphicsDevice adevice = offscreenDrawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(); - offscreenDrawable.destroy(); + offscreenDrawable.setRealized(false); offscreenDrawable = null; if(null != adevice) { adevice.close(); @@ -1094,7 +1099,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing @Override protected void doPaintComponentImpl() { - drawableHelper.invokeGL(offscreenDrawable, offscreenContext, updaterDisplayAction, updaterInitAction); + helper.invokeGL(offscreenDrawable, offscreenContext, updaterDisplayAction, updaterInitAction); } @Override @@ -1711,7 +1716,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing ((Java2DGLContext) joglContext).setGraphics(g); } - drawableHelper.invokeGL(joglDrawable, joglContext, updaterDisplayAction, updaterInitAction); + helper.invokeGL(joglDrawable, joglContext, updaterDisplayAction, updaterInitAction); } } finally { j2dContext.release(); diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java index 3f50fe420..5c6d7446a 100644 --- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java +++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java @@ -31,6 +31,8 @@ package jogamp.opengl; import java.io.PrintStream; import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.WindowClosingProtocol; +import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode; import javax.media.opengl.FPSCounter; import javax.media.opengl.GL; import javax.media.opengl.GLAnimatorControl; @@ -76,7 +78,8 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { /** Returns the delegated GLDrawable */ public final GLDrawable getDelegatedDrawable() { return drawable; } - protected void defaultRepaintOp() { + /** Default implementation to handle repaint events from the windowing system */ + protected void defaultWindowRepaintOp() { if( null != drawable && drawable.isRealized() ) { if( !drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) { display(); @@ -84,16 +87,74 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { } } - protected void defaultReshapeOp() { + /** Default implementation to handle resize events from the windowing system */ + protected void defaultWindowResizedOp() { if( null!=drawable ) { if(DEBUG) { System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+getWidth()+"x"+getHeight()+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); } sendReshape = true; - defaultRepaintOp(); + defaultWindowRepaintOp(); } } - + + /** Default implementation to handle destroy notifications from the windowing system */ + protected void defaultWindowDestroyNotifyOp() { + final NativeSurface ns = getNativeSurface(); + final boolean shallClose; + if(ns instanceof WindowClosingProtocol) { + shallClose = WindowClosingMode.DISPOSE_ON_CLOSE == ((WindowClosingProtocol)ns).getDefaultCloseOperation(); + } else { + shallClose = true; + } + if( shallClose ) { + // Is an animator thread perform rendering? + if (helper.isExternalAnimatorRunning()) { + // Pause animations before initiating safe destroy. + final GLAnimatorControl ctrl = helper.getAnimator(); + final boolean isPaused = ctrl.pause(); + destroy(); + if(isPaused) { + ctrl.resume(); + } + } else if (null != ns && ns.isSurfaceLockedByOtherThread()) { + // surface is locked by another thread + // Flag that destroy should be performed on the next + // attempt to display. + sendDestroy = true; + } else { + // Without an external thread animating or locking the + // surface, we are safe. + destroy (); + } + } + } + + /** + * Default implementation to destroys the drawable and context of this GLAutoDrawable: + *+ * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable + * is being cleared by calling + * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}. + *
+ *+ * If the old or new context was current on this thread, it is being released before switching the drawable. + *
+ * + * @param drawable the drawable which context is changed + * @param newCtx the new context + * @param oldCtx the old context + * @return true if the newt context was current, otherwise false + * + * @see GLAutoDrawable#setContext(GLContext) + */ + public final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int additionalCtxCreationFlags) { + if(null != oldCtx && oldCtx.isCurrent()) { + oldCtx.release(); + } + final boolean newCtxCurrent; + if(null!=newCtx) { + newCtxCurrent = newCtx.isCurrent(); + if(newCtxCurrent) { + newCtx.release(); + } + newCtx.setContextCreationFlags(additionalCtxCreationFlags); + newCtx.setGLDrawable(drawable, true); // propagate context/drawable switch + } else { + newCtxCurrent = false; + } + if(null!=oldCtx && oldCtx.getGLDrawable() instanceof GLAutoDrawable) { + ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null); + } + return newCtxCurrent; + } + public final void addGLEventListener(GLEventListener listener) { addGLEventListener(-1, listener); } @@ -128,6 +168,16 @@ public class GLDrawableHelper { } } + public final GLEventListener removeGLEventListener(int index) + throws IndexOutOfBoundsException { + synchronized(listenersLock) { + if(0>index) { + index = listeners.size()-1; + } + return listeners.remove(index); + } + } + /** * Issues {@link javax.media.opengl.GLEventListener#dispose(javax.media.opengl.GLAutoDrawable)} * to all listeners. @@ -144,18 +194,19 @@ public class GLDrawableHelper { } } } - - private boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) { + + private final boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) { if(listenersToBeInit.remove(l)) { l.init(drawable); if(sendReshape) { - reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false); + reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */); } return true; } return false; } + /** The default init action to be called once after ctx is being created @ 1st makeCurrent(). */ public final void init(GLAutoDrawable drawable) { synchronized(listenersLock) { for (int i=0; i < listeners.size(); i++) { @@ -166,7 +217,7 @@ public class GLDrawableHelper { // hence the must always be initialized unconditional. listenersToBeInit.add(listener); - if ( ! init( listener, drawable, false ) ) { + if ( ! init( listener, drawable, true /* sendReshape */) ) { throw new GLException("GLEventListener "+listener+" already initialized: "+drawable); } } @@ -179,24 +230,26 @@ public class GLDrawableHelper { displayImpl(drawable); } } - private void displayImpl(GLAutoDrawable drawable) { + private final void displayImpl(GLAutoDrawable drawable) { synchronized(listenersLock) { for (int i=0; i < listeners.size(); i++) { final GLEventListener listener = listeners.get(i) ; // GLEventListener may need to be init, // in case this one is added after the realization of the GLAutoDrawable - init( listener, drawable, true ) ; + init( listener, drawable, true /* sendReshape */) ; listener.display(drawable); } } } - private void reshape(GLEventListener listener, GLAutoDrawable drawable, - int x, int y, int width, int height, boolean setViewport, boolean checkInit) { + private final void reshape(GLEventListener listener, GLAutoDrawable drawable, + int x, int y, int width, int height, boolean setViewport, boolean checkInit) { if(checkInit) { // GLEventListener may need to be init, - // in case this one is added after the realization of the GLAutoDrawable - init( listener, drawable, false ) ; + // in case this one is added after the realization of the GLAutoDrawable + synchronized(listenersLock) { + init( listener, drawable, false /* sendReshape */) ; + } } if(setViewport) { drawable.getGL().glViewport(x, y, width, height); @@ -212,27 +265,50 @@ public class GLDrawableHelper { } } - private boolean execGLRunnables(GLAutoDrawable drawable) { + private final boolean execGLRunnables(GLAutoDrawable drawable) { boolean res = true; - if(glRunnables.size()>0) { + if(glRunnables.size()>0) { // volatile OK // swap one-shot list asap - ArrayList
+ * If wait
is true
the call blocks until the glRunnable
+ * has been executed.
+ *
+ * If wait
is true
and
+ * {@link GLDrawable#isRealized()} returns false
or {@link GLAutoDrawable#getContext()} returns null
,
+ * the call is ignored and returns false
.
+ * This helps avoiding deadlocking the caller.
+ *
true
block until execution of glRunnable
is finished, otherwise return immediatly w/o waiting
+ * @param glRunnable the {@link GLRunnable} to execute within {@link #display()}
+ * @return true
if the {@link GLRunnable} has been processed or queued, otherwise false
.
+ */
+ public final boolean invoke(GLAutoDrawable drawable, boolean wait, GLRunnable glRunnable) {
+ if( null == glRunnable || null == drawable ||
+ wait && ( !drawable.isRealized() || null==drawable.getContext() ) ) {
+ return false;
}
+
Throwable throwable = null;
GLRunnableTask rTask = null;
Object rTaskLock = new Object();
@@ -299,6 +393,7 @@ public class GLDrawableHelper {
}
}
}
+ return true;
}
public final void setAutoSwapBufferMode(boolean enable) {
@@ -439,6 +534,7 @@ public class GLDrawableHelper {
try {
if(isDisposeAction) {
context.destroy();
+ flushGLRunnables();
} else if( GLContext.CONTEXT_NOT_CURRENT != res ) {
context.release();
}
@@ -526,6 +622,7 @@ public class GLDrawableHelper {
try {
if(isDisposeAction) {
context.destroy();
+ flushGLRunnables();
ctxDestroyed = true;
} else if( res != GLContext.CONTEXT_NOT_CURRENT &&
(null == skipContextReleaseThread || currentThread != skipContextReleaseThread) ) {
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index b3884830a..58a4ac6b4 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -70,20 +70,6 @@ public abstract class GLDrawableImpl implements GLDrawable {
return (GLDrawableFactoryImpl) getFactory();
}
- /** For offscreen GLDrawables (pbuffers and "pixmap" drawables),
- indicates that native resources should be reclaimed. */
- public void destroy() {
- surface.getGraphicsConfiguration().getScreen().getDevice().lock();
- try {
- destroyImpl();
- } finally {
- surface.getGraphicsConfiguration().getScreen().getDevice().unlock();
- }
- }
- protected void destroyImpl() {
- throw new GLException("Should not call this (should only be called for offscreen GLDrawables)");
- }
-
@Override
public final void swapBuffers() throws GLException {
if( !realized ) {
@@ -164,7 +150,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice();
if(realizedArg) {
if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) {
- throw new GLException("GLDrawableImpl.setRealized(true): already realized, but surface not ready (lockSurface)");
+ throw new GLException("GLDrawableImpl.setRealized(true): Surface not ready (lockSurface)");
}
} else {
aDevice.lock();
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index d98b41bdc..a8277fd71 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -40,7 +40,6 @@
package jogamp.opengl;
-import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
@@ -114,36 +113,19 @@ public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
@Override
public void destroy() {
- if(drawable.isRealized()) {
- final AbstractGraphicsDevice adevice = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
-
- if (null != context && context.isCreated()) {
- try {
- helper.disposeGL(GLPbufferImpl.this, drawable, context, null);
- } catch (GLException gle) {
- gle.printStackTrace();
- }
- context = null;
- // drawableHelper.reset();
- }
- drawable.destroy();
- drawable = null;
-
- if(null != adevice) {
- adevice.close();
- }
- }
+ defaultDestroyOp();
}
@Override
public GLDrawableFactory getFactory() {
- return drawable.getFactory();
+ return drawable.getFactory();
}
@Override
public void display() {
- if( null == drawable || !drawable.isRealized() || null == context ) { return; }
+ if( null != drawable && drawable.isRealized() && null != context ) {
helper.invokeGL(drawable, context, defaultDisplayAction, initAction);
+ }
}
//----------------------------------------------------------------------
diff --git a/src/jogl/classes/jogamp/opengl/GLRunnableTask.java b/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
index 448f68423..244a3fd79 100644
--- a/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
+++ b/src/jogl/classes/jogamp/opengl/GLRunnableTask.java
@@ -39,7 +39,8 @@ public class GLRunnableTask implements GLRunnable {
GLRunnable runnable;
Object notifyObject;
boolean catchExceptions;
- boolean isExecuted;
+ volatile boolean isExecuted;
+ volatile boolean isFlushed;
Throwable runnableException;
@@ -48,6 +49,7 @@ public class GLRunnableTask implements GLRunnable {
this.notifyObject = notifyObject ;
this.catchExceptions = catchExceptions;
isExecuted = false;
+ isFlushed = false;
}
public boolean run(GLAutoDrawable drawable) {
@@ -84,8 +86,41 @@ public class GLRunnableTask implements GLRunnable {
}
return res;
}
-
+
+ /**
+ * Simply flush this task and notify a waiting executor.
+ * The executor which might have been blocked until notified
+ * will be unblocked and the task removed from the queue.
+ *
+ * @see #isFlushed()
+ * @see #isInQueue()
+ */
+ public void flush() {
+ if(!isExecuted() && null != notifyObject) {
+ synchronized (notifyObject) {
+ isFlushed=true;
+ notifyObject.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * @return !{@link #isExecuted()} && !{@link #isFlushed()}
+ */
+ public boolean isInQueue() { return !isExecuted && !isFlushed; }
+
+ /**
+ * @return whether this task has been executed.
+ * @see #isInQueue()
+ */
public boolean isExecuted() { return isExecuted; }
+
+ /**
+ * @return whether this task has been flushed.
+ * @see #isInQueue()
+ */
+ public boolean isFlushed() { return isFlushed; }
+
public Throwable getThrowable() { return runnableException; }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index f18b8cd02..b2217c095 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -55,11 +55,6 @@ public class EGLPbufferDrawable extends EGLDrawable {
super(factory, target);
}
- @Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
@Override
protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
final AbstractGraphicsConfiguration config = getNativeSurface().getGraphicsConfiguration();
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index cae60702b..257635b8c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -151,8 +151,7 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
if (haveSetOpenGLMode) {
throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once");
}
-
- destroyImpl();
+ setRealized(false);
if (DEBUG) {
System.err.println("MacOSXCGLDrawable: Switching context mode " + openGLMode + " -> " + mode);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 6bdabbf59..4e9d18fed 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -250,7 +250,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
}
}
- drawable.destroy();
+ drawable.setRealized(false);
}
}
sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels);
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index 33021c521..242cea068 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -79,11 +79,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
super(factory, target, false);
}
- @Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
@Override
protected void setRealizedImpl() {
if(realized) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
index dc3b58cfa..296d53ce3 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
@@ -61,11 +61,6 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
super(factory, target, false);
}
- @Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
@Override
protected void setRealizedImpl() {
if(realized) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
index 244c1553f..05d6d9862 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
@@ -70,7 +70,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
System.err.println("WindowsDummyWGLDrawable: "+config);
}
} catch (Throwable t) {
- destroyImpl();
+ setRealized(false);
throw new GLException(t);
} finally {
unlockSurface();
@@ -96,11 +96,14 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
}
@Override
- protected void destroyImpl() {
- if (handleHwndLifecycle && hwnd != 0) {
- GDI.ShowWindow(hwnd, GDI.SW_HIDE);
- GDIUtil.DestroyDummyWindow(hwnd);
- hwnd = 0;
+ protected void setRealizedImpl() {
+ super.setRealizedImpl();
+ if(!realized) {
+ if (handleHwndLifecycle && hwnd != 0) {
+ GDI.ShowWindow(hwnd, GDI.SW_HIDE);
+ GDIUtil.DestroyDummyWindow(hwnd);
+ hwnd = 0;
+ }
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index 762bea3b1..b00c796ec 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -66,11 +66,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
super(factory, target, false);
}
- @Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
@Override
protected void setRealizedImpl() {
if(realized) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
index ddcb898a9..ca7886e7f 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
@@ -62,15 +62,13 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl {
@Override
protected void setRealizedImpl() {
- if(!realized) {
- return; // nothing todo ..
- }
-
- NativeSurface ns = getNativeSurface();
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
- config.updateGraphicsConfiguration(getFactory(), ns, null);
- if (DEBUG) {
- System.err.println("WindowsWGLDrawable.setRealized(true): "+config);
+ if(realized) {
+ NativeSurface ns = getNativeSurface();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
+ config.updateGraphicsConfiguration(getFactory(), ns, null);
+ if (DEBUG) {
+ System.err.println("WindowsWGLDrawable.setRealized(true): "+config);
+ }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 054e1fe90..176d27a71 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -373,7 +373,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
if (null != sr.drawable) {
- sr.drawable.destroy();
+ sr.drawable.setRealized(false);
sr.drawable = null;
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
index 65f65a2ec..8914e2db9 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
@@ -86,13 +86,17 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
public int getHeight() {
return 1;
}
-
+
+
@Override
- protected void destroyImpl() {
- if(0!=dummyWindow) {
- destroyHandle();
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration();
- X11Lib.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow);
+ protected void setRealizedImpl() {
+ super.setRealizedImpl();
+ if(!realized) {
+ if(0!=dummyWindow) {
+ destroyHandle();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration();
+ X11Lib.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow);
+ }
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 77af0d698..9a563bdb8 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -304,7 +304,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
if (null != sr.drawable) {
// may cause JVM SIGSEGV:
- sr.drawable.destroy();
+ sr.drawable.setRealized(false);
sr.drawable = null;
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index 29003ef52..cdf81ebd3 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -58,11 +58,6 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
super(factory, target, false);
}
- @Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
@Override
protected void setRealizedImpl() {
if(realized) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
index 18aa780b6..1e7b89828 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
@@ -58,11 +58,6 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
super(factory, target, false);
}
- @Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
@Override
protected void setRealizedImpl() {
if(realized) {
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 6a328ed07..96baab3ae 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -53,7 +53,6 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import jogamp.newt.WindowImpl;
@@ -109,37 +108,17 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
window.addWindowListener(new WindowAdapter() {
@Override
public void windowRepaint(WindowUpdateEvent e) {
- defaultRepaintOp();
+ defaultWindowRepaintOp();
}
@Override
public void windowResized(WindowEvent e) {
- defaultReshapeOp();
+ defaultWindowResizedOp();
}
@Override
public void windowDestroyNotify(WindowEvent e) {
- if( WindowClosingMode.DISPOSE_ON_CLOSE == GLWindow.this.getDefaultCloseOperation() ) {
- // Is an animator thread perform rendering?
- if (GLWindow.this.helper.isExternalAnimatorRunning()) {
- // Pause animations before initiating safe destroy.
- final GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator();
- boolean isPaused = ctrl.pause();
- destroy();
- if(isPaused) {
- ctrl.resume();
- }
- } else if (GLWindow.this.window.isWindowLockedByOtherThread()) {
- // Window is locked by another thread
- // Flag that destroy should be performed on the next
- // attempt to display.
- sendDestroy = true;
- } else {
- // Without an external thread animating or locking the
- // surface, we are safe.
- destroy ();
- }
- }
+ defaultWindowDestroyNotifyOp();
}
});
this.window.setLifecycleHook(new GLLifecycleHook());
@@ -453,20 +432,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
//e1.printStackTrace();
}
- if( window.isNativeValid() && null != drawable && drawable.isRealized() ) {
- if( null != context && context.isCreated() ) {
- // Catch dispose GLExceptions by GLEventListener, just 'print' them
- // so we can continue with the destruction.
- try {
- helper.disposeGL(GLWindow.this, drawable, context, null);
- } catch (GLException gle) {
- gle.printStackTrace();
- }
- }
- drawable.setRealized(false);
- }
- context = null;
- drawable = null;
+ defaultDestroyOp();
if(Window.DEBUG_IMPLEMENTATION) {
System.err.println("GLWindow.destroy() "+Thread.currentThread()+", fin");
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
index be9ae223b..a2d060a8c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright 2012 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:
@@ -30,60 +30,95 @@ package com.jogamp.opengl.test.junit.jogl.acore;
import java.io.IOException;
-import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLAutoDrawableDelegate;
import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import org.junit.Assert;
import org.junit.Test;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.WindowUpdateEvent;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
-import com.jogamp.opengl.test.junit.util.NEWTGLContext;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.test.junit.util.UITestCase;
+/**
+ * Demonstrates a full featured custom GLAutoDrawable implementation
+ * utilizing {@link GLAutoDrawableDelegate}.
+ */
public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
- @Test
- public void test01() throws GLException, InterruptedException {
- final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(
- new GLCapabilities(GLProfile.getGL2ES2()), 640, 480, false);
- winctx.context.release();
+ /** Note: Creates a full featured GLAutoDrawable w/ all window events connected. */
+ private GLAutoDrawable createGLAutoDrawable(GLCapabilities caps, int x, int y, int width, int height, WindowListener wl) throws InterruptedException {
+ final Window window = NewtFactory.createWindow(caps);
+ Assert.assertNotNull(window);
+ window.setPosition(x, y);
+ window.setSize(width, height);
+ window.setVisible(true);
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
+
+ GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ GLDrawable drawable = factory.createGLDrawable(window);
+ Assert.assertNotNull(drawable);
+
+ drawable.setRealized(true);
+ Assert.assertTrue(drawable.isRealized());
+
+ GLContext context = drawable.createContext(null);
+ Assert.assertNotNull(context);
+
+ int res = context.makeCurrent();
+ Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
+ context.release();
+
+ final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context) {
+ @Override
+ public void destroy() {
+ super.destroy(); // destroys drawable/context
+ window.destroy(); // destroys the actual window
+ }
+ };
- final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(winctx.drawable, winctx.context);
- glad.addGLEventListener(new GearsES2(1));
-
// add basic window interaction
- winctx.window.addWindowListener(new WindowAdapter() {
+ window.addWindowListener(new WindowAdapter() {
@Override
public void windowRepaint(WindowUpdateEvent e) {
- glad.defaultRepaintOp();
+ glad.defaultWindowRepaintOp();
}
@Override
public void windowResized(WindowEvent e) {
- glad.defaultReshapeOp();
+ glad.defaultWindowResizedOp();
}
@Override
public void windowDestroyNotify(WindowEvent e) {
- final GLAnimatorControl ctrl = glad.getAnimator();
- boolean isPaused = ctrl.pause();
- glad.destroy();
- NEWTGLContext.destroyWindow(winctx);
- if(isPaused) {
- ctrl.resume();
- }
+ glad.defaultWindowDestroyNotifyOp();
}
});
+ window.addWindowListener(wl);
+ return glad;
+ }
+
+ @Test
+ public void test01() throws GLException, InterruptedException {
final QuitAdapter quitAdapter = new QuitAdapter();
- winctx.window.addWindowListener(quitAdapter);
-
+ GLAutoDrawable glad = createGLAutoDrawable(new GLCapabilities(GLProfile.getGL2ES2()), 0, 0, 640, 480, quitAdapter);
+ glad.addGLEventListener(new GearsES2(1));
+
final Animator animator = new Animator(glad);
animator.setUpdateFPSFrames(60, null);
animator.start();
@@ -93,7 +128,8 @@ public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
}
animator.stop();
- NEWTGLContext.destroyWindow(winctx);
+
+ glad.destroy();
}
static long duration = 2000; // ms
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
index 22ed7c6fd..41c69336c 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
@@ -66,6 +66,57 @@ public class TestParenting01cSwingAWT extends UITestCase {
glCaps = new GLCapabilities(null);
}
+ static class GLDisturbanceAction implements Runnable {
+ public boolean isRunning = false;
+ private volatile boolean shallStop = false;
+ private final GLAutoDrawable glad;
+ private final GLRunnable glRunnable;
+
+ public GLDisturbanceAction(GLAutoDrawable glad) {
+ this.glad = glad;
+ this.glRunnable = new GLRunnableDummy();
+ }
+
+ public void waitUntilRunning() {
+ synchronized(this) {
+ while(!isRunning) {
+ try {
+ this.wait();
+ } catch (InterruptedException e) { e.printStackTrace(); }
+ }
+ }
+ }
+
+ public void stopAndWaitUntilDone() {
+ shallStop = true;
+ synchronized(this) {
+ while(isRunning) {
+ try {
+ this.wait();
+ } catch (InterruptedException e) { e.printStackTrace(); }
+ }
+ }
+ }
+
+ public void run() {
+ synchronized(this) {
+ isRunning = true;
+ this.notifyAll();
+ System.out.println("$");
+ }
+ while(!shallStop) {
+ try {
+ glad.invoke(true, glRunnable);
+ Thread.sleep(100);
+ } catch (Throwable t) {}
+ }
+ synchronized(this) {
+ isRunning = false;
+ this.notifyAll();
+ }
+ }
+ }
+
@Test
public void testWindowParenting01CreateVisibleDestroy1() throws InterruptedException, InvocationTargetException {
/**
@@ -84,22 +135,9 @@ public class TestParenting01cSwingAWT extends UITestCase {
animator1.setUpdateFPSFrames(1, null);
animator1.start();
- final GLWindow _glWindow1 = glWindow1;
- final GLRunnable _glRunnable = new GLRunnableDummy();
- Thread disturbanceThread = new Thread(new Runnable() {
- public void run() {
- System.out.println("$");
- while(true)
- {
- try {
- _glWindow1.invoke(true, _glRunnable);
- Thread.sleep(100);
- } catch (Throwable t) {}
- }
- }
- });
- disturbanceThread.start();
-
+ final GLDisturbanceAction disturbanceAction = new GLDisturbanceAction(glWindow1);
+ new Thread(disturbanceAction).start();
+ disturbanceAction.waitUntilRunning();
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
Assert.assertNotNull(newtCanvasAWT);
@@ -175,6 +213,7 @@ public class TestParenting01cSwingAWT extends UITestCase {
} });
Assert.assertEquals(true, glWindow1.isNativeValid());
+ disturbanceAction.stopAndWaitUntilDone();
glWindow1.destroy();
Assert.assertEquals(false, glWindow1.isNativeValid());
}
@@ -192,26 +231,33 @@ public class TestParenting01cSwingAWT extends UITestCase {
glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy");
GLEventListener demo1 = new RedSquareES2();
setDemoFields(demo1, glWindow1, false);
+ /*
+ glWindow1.addGLEventListener(new GLEventListener() {
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ System.err.println("XXX init");
+ }
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ System.err.println("XXX dispose");
+ // Thread.dumpStack();
+ }
+ @Override
+ public void display(GLAutoDrawable drawable) {}
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ System.err.println("XXX reshape");
+ // Thread.dumpStack();
+ }
+ }); */
glWindow1.addGLEventListener(demo1);
Animator animator1 = new Animator(glWindow1);
animator1.setUpdateFPSFrames(1, null);
animator1.start();
-
- final GLWindow _glWindow1 = glWindow1;
- final GLRunnable _glRunnable = new GLRunnableDummy();
- Thread disturbanceThread = new Thread(new Runnable() {
- public void run() {
- System.out.println("$");
- while(true)
- {
- try {
- _glWindow1.invoke(true, _glRunnable);
- Thread.sleep(100);
- } catch (Throwable t) {}
- }
- }
- });
- disturbanceThread.start();
+
+ final GLDisturbanceAction disturbanceAction = new GLDisturbanceAction(glWindow1);
+ new Thread(disturbanceAction).start();
+ disturbanceAction.waitUntilRunning();
final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1);
Assert.assertNotNull(newtCanvasAWT);
@@ -298,6 +344,8 @@ public class TestParenting01cSwingAWT extends UITestCase {
animator1.stop();
Assert.assertEquals(false, animator1.isAnimating());
+ disturbanceAction.stopAndWaitUntilDone();
+
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
jFrame1.setVisible(false);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
index bc3988338..8e2c73e9d 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
@@ -111,8 +111,8 @@ public class TestParenting02NEWT extends UITestCase {
Assert.assertEquals(height,glWindow1.getHeight());
glWindow1.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - PARENT");
glWindow1.setPosition(x,y);
- glWindow1.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo)));
- glWindow1.addWindowListener(new TraceWindowAdapter());
+ //glWindow1.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo)));
+ //glWindow1.addWindowListener(new TraceWindowAdapter());
GLEventListener demo1 = new RedSquareES2();
setDemoFields(demo1, window1, glWindow1, false);
@@ -132,8 +132,8 @@ public class TestParenting02NEWT extends UITestCase {
//Assert.assertEquals(height/2,glWindow2.getHeight());
glWindow2.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - CHILD");
glWindow2.setPosition(glWindow1.getWidth()/2, glWindow1.getHeight()/2);
- glWindow2.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo)));
- glWindow2.addWindowListener(new TraceWindowAdapter(new WindowAction(eventFifo)));
+ //glWindow2.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo)));
+ //glWindow2.addWindowListener(new TraceWindowAdapter(new WindowAction(eventFifo)));
// glWindow2.addMouseListener(new TraceMouseAdapter());
GLEventListener demo2 = new GearsES2();
--
cgit v1.2.3