aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-07-04 18:02:11 +0200
committerSven Gothel <[email protected]>2012-07-04 18:02:11 +0200
commit9b35c57425b0a5f6b789b9b43a62a8b64be51d86 (patch)
tree04a4e082e00fd4d313346aa8dfc2ce4e5d3ab145
parenteed8508ae1132e5f45f788e9cb3f3d5a1050ac70 (diff)
GLAutoDrawable* refinement of abstraction / generalization - API Change!
- GLAutoDrawable (compat change - recompile): - 'void invoke(boolean wait, GLRunnable glRunnable)' -> 'boolean invoke(boolean wait, GLRunnable glRunnable)' Allows notifying caller whether the task has been executed or at least enqueued. - GLAutoDrawable add 'GLEventListener removeGLEventListener(int index)' - This allow one to remove a specific GLEventListener and reusing it (return value). - GLDrawableImpl remove 'destroy()' to favor 'setRealized(false)' - Using more common code of GLAutoDrawableBase, i.e. GLPbufferImpl can use defaultDestroyOp(). - Removes redundancy of methods - GLAutoDrawableBase/Delegate - better 'default' names to emphasize it's purpose, adding API doc - includes more generic functionality - defaultWindowDestroyNotify() - defaultDestroyOp() - TestGLAutoDrawableDelegateNEWT demonstrates a simple example w/ all window events handled. - Fix TestParenting01cSwingAWT's threading use (gl disturbance thread)
-rw-r--r--src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java46
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawable.java52
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java68
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java43
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java39
-rw-r--r--src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java83
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableHelper.java149
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableImpl.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/GLPbufferImpl.java26
-rw-r--r--src/jogl/classes/jogamp/opengl/GLRunnableTask.java39
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java3
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java15
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java5
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java42
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java84
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java112
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java8
27 files changed, 582 insertions, 311 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 31b679077..62b496891 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -107,7 +107,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
//private static final boolean useSWTThread = ThreadingImpl.getMode() != ThreadingImpl.WORKER;
/* GL Stuff */
- private final GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private final GLDrawableHelper helper = new GLDrawableHelper();
private volatile GLDrawable drawable; // volatile avoids locking all accessors. FIXME still need to sync destroy/display
private GLContext context;
@@ -130,7 +130,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final Runnable initAction = new Runnable() {
@Override
public void run() {
- drawableHelper.init(GLCanvas.this);
+ helper.init(GLCanvas.this);
}
};
@@ -143,10 +143,10 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void run() {
if (sendReshape) {
- 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);
}
};
@@ -154,7 +154,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final Runnable makeCurrentAndDisplayAction = new Runnable() {
@Override
public void run() {
- drawableHelper.invokeGL(drawable, context, displayAction, initAction);
+ helper.invokeGL(drawable, context, displayAction, initAction);
}
};
@@ -170,7 +170,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final Runnable makeCurrentAndSwapBuffersAction = new Runnable() {
@Override
public void run() {
- drawableHelper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ helper.invokeGL(drawable, context, swapBuffersAction, initAction);
}
};
@@ -191,7 +191,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final Runnable disposeOnEDTGLAction = new Runnable() {
@Override
public void run() {
- drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeGLAction);
+ helper.disposeGL(GLCanvas.this, drawable, context, postDisposeGLAction);
}
};
@@ -266,7 +266,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
addPaintListener(new PaintListener() {
@Override
public void paintControl(final PaintEvent arg0) {
- if (!drawableHelper.isExternalAnimatorAnimating()) {
+ if (!helper.isExternalAnimatorAnimating()) {
display();
}
}
@@ -284,12 +284,12 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void addGLEventListener(final GLEventListener arg0) {
- drawableHelper.addGLEventListener(arg0);
+ helper.addGLEventListener(arg0);
}
@Override
public void addGLEventListener(final int arg0, final GLEventListener arg1) throws IndexOutOfBoundsException {
- drawableHelper.addGLEventListener(arg0, arg1);
+ helper.addGLEventListener(arg0, arg1);
}
/**
@@ -312,12 +312,12 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public GLAnimatorControl getAnimator() {
- return drawableHelper.getAnimator();
+ return helper.getAnimator();
}
@Override
public boolean getAutoSwapBufferMode() {
- return drawableHelper.getAutoSwapBufferMode();
+ return helper.getAutoSwapBufferMode();
}
@Override
@@ -336,30 +336,34 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
}
@Override
- public void invoke(final boolean wait, final GLRunnable run) {
- /* Queue task for running during the next display(). */
- drawableHelper.invoke(this, wait, run);
+ public boolean invoke(final boolean wait, final GLRunnable run) {
+ return helper.invoke(this, wait, run);
}
@Override
public void removeGLEventListener(final GLEventListener arg0) {
- drawableHelper.removeGLEventListener(arg0);
+ helper.removeGLEventListener(arg0);
}
@Override
+ public GLEventListener removeGLEventListener(int index) throws IndexOutOfBoundsException {
+ return helper.removeGLEventListener(index);
+ }
+
+ @Override
public void setAnimator(final GLAnimatorControl arg0) throws GLException {
- drawableHelper.setAnimator(arg0);
+ helper.setAnimator(arg0);
}
@Override
public void setAutoSwapBufferMode(final boolean arg0) {
- drawableHelper.setAutoSwapBufferMode(arg0);
+ helper.setAutoSwapBufferMode(arg0);
}
@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();
@@ -477,7 +481,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
if (Threading.isSingleThreaded() && !Threading.isOpenGLThread()) {
runInDesignatedGLThread(disposeOnEDTGLAction);
} else if (context.isCreated()) {
- drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeGLAction);
+ helper.disposeGL(GLCanvas.this, drawable, context, postDisposeGLAction);
}
}
@@ -537,7 +541,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
runInDesignatedGLThread(asyncAction);
} else {
/* Run in current thread... */
- drawableHelper.invokeGL(drawable, context, syncAction, initAction);
+ helper.invokeGL(drawable, context, syncAction, initAction);
}
}
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index e4aaad23d..80d4f796c 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -165,16 +165,32 @@ public interface GLAutoDrawable extends GLDrawable {
* @param listener The GLEventListener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- public void addGLEventListener(int index, GLEventListener listener)
- throws IndexOutOfBoundsException;
+ public void addGLEventListener(int index, GLEventListener listener) throws IndexOutOfBoundsException;
- /** Removes a {@link GLEventListener} from this drawable. Note that
- if this is done from within a particular drawable's {@link
- GLEventListener} handler (reshape, display, etc.) that it is not
- guaranteed that all other listeners will be evaluated properly
- during this update cycle. */
+ /**
+ * Removes a {@link GLEventListener} from this drawable.
+ * Note that if this is done from within a particular drawable's
+ * {@link GLEventListener} handler (reshape, display, etc.) that it is not
+ * guaranteed that all other listeners will be evaluated properly
+ * during this update cycle.
+ * @param listener The GLEventListener object to be removed
+ */
public void removeGLEventListener(GLEventListener listener);
+ /**
+ * Removes a {@link GLEventListener} at the given index from this drawable.
+ * Note that if this is done from within a particular drawable's
+ * {@link GLEventListener} handler (reshape, display, etc.) that it is not
+ * guaranteed that all other listeners will be evaluated properly
+ * during this update cycle.
+ * @param index Position of the listener to be removed.
+ * Should be within (0 <= index && index < size()).
+ * An index value of -1 is interpreted as last listener, size()-1.
+ * @return The removed GLEventListener object
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index < size()), or -1
+ */
+ public GLEventListener removeGLEventListener(int index) throws IndexOutOfBoundsException;
+
/**
* <p>
* Registers the usage of an animator, an {@link javax.media.opengl.GLAnimatorControl} implementation.
@@ -221,14 +237,30 @@ public interface GLAutoDrawable extends GLDrawable {
* <p>
* If an {@link GLAnimatorControl} is animating,<br>
* no {@link #display()} call is issued, since the animator thread performs it.<br>
- * If <code>wait</code> is true, the implementation waits until the <code>GLRunnable</code> is executed.<br>
- * </p><br>
+ * </p>
+ * <p>
+ * If <code>wait</code> is <code>true</code> the call blocks until the <code>glRunnable</code>
+ * has been executed.<p>
+ * <p>
+ * If <code>wait</code> is <code>true</code> <b>and</b>
+ * {@link #isRealized()} returns <code>false</code> <i>or</i> {@link #getContext()} returns <code>null</code>,
+ * the call is ignored and returns <code>false</code>.<br>
+ * This helps avoiding deadlocking the caller.
+ * </p>
+ * <p>
+ * The internal queue of {@link GLRunnable}'s is being flushed with {@link #destroy()}
+ * where all blocked callers are being notified.
+ * </p>
*
+ * @param wait if <code>true</code> block until execution of <code>glRunnable</code> is finished, otherwise return immediatly w/o waiting
+ * @param glRunnable the {@link GLRunnable} to execute within {@link #display()}
+ * @return <code>true</code> if the {@link GLRunnable} has been processed or queued, otherwise <code>false</code>.
+ *
* @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.
* <p>
* 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.
- * </p>
+ * to handle at least:
+ * <ul>
+ * <li>{@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #defaultWindowRepaintOp()}</li>
+ * <li>{@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #defaultWindowResizedOp()}</li>
+ * <li>{@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} using {@link #defaultWindowDestroyNotifyOp()}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}.
+ * </p>
*/
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}
* <p>
- * This implementation simply removes references to drawable and context.
+ * This implementation calls {@link #defaultDestroyOp()}.
+ * </p>
+ * <p>
+ * User still needs to destroy the upstream window, which details are hidden from this aspect.
* </p>
*/
@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:
+ * <ul>
+ * <li>issues the GLEventListener dispose call, if drawable and context are valid</li>
+ * <li>destroys the GLContext, if valid</li>
+ * <li>destroys the GLDrawable, if valid</li>
+ * </ul>
+ */
+ protected void defaultDestroyOp() {
+ if( 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(this, drawable, context, null);
+ } catch (GLException gle) {
+ gle.printStackTrace();
+ }
+ }
+ drawable.setRealized(false);
+ }
+ context = null;
+ drawable = null;
+ }
+
//
// GLAutoDrawable
//
@@ -157,8 +218,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
@Override
- public final void addGLEventListener(int index, GLEventListener listener)
- throws IndexOutOfBoundsException {
+ public final void addGLEventListener(int index, GLEventListener listener) throws IndexOutOfBoundsException {
helper.addGLEventListener(index, listener);
}
@@ -166,7 +226,12 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
public final void removeGLEventListener(GLEventListener listener) {
helper.removeGLEventListener(listener);
}
-
+
+ @Override
+ public GLEventListener removeGLEventListener(int index) throws IndexOutOfBoundsException {
+ return helper.removeGLEventListener(index);
+ }
+
@Override
public final void setAnimator(GLAnimatorControl animatorControl)
throws GLException {
@@ -179,8 +244,8 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
@Override
- public final void invoke(boolean wait, GLRunnable glRunnable) {
- helper.invoke(this, wait, glRunnable);
+ public final boolean invoke(boolean wait, GLRunnable glRunnable) {
+ return helper.invoke(this, wait, glRunnable);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index e7651eaab..0c01aa676 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -61,13 +61,13 @@ public class GLDrawableHelper {
private static final boolean PERF_STATS = Debug.isPropertyDefined("jogl.debug.GLDrawable.PerfStats", true);
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
- private Object listenersLock = new Object();
- private ArrayList<GLEventListener> listeners;
- private HashSet<GLEventListener> listenersToBeInit;
+ private final Object listenersLock = new Object();
+ private final ArrayList<GLEventListener> listeners = new ArrayList<GLEventListener>();
+ private final HashSet<GLEventListener> listenersToBeInit = new HashSet<GLEventListener>();
+ private final Object glRunnablesLock = new Object();
+ private volatile ArrayList<GLRunnableTask> glRunnables = new ArrayList<GLRunnableTask>();
private boolean autoSwapBufferMode;
private Thread skipContextReleaseThread;
- private Object glRunnablesLock = new Object();
- private ArrayList<GLRunnable> glRunnables;
private GLAnimatorControl animatorCtrl;
public GLDrawableHelper() {
@@ -76,13 +76,13 @@ public class GLDrawableHelper {
public final void reset() {
synchronized(listenersLock) {
- listeners = new ArrayList<GLEventListener>();
- listenersToBeInit = new HashSet<GLEventListener>();
+ listeners.clear();
+ listenersToBeInit.clear();
}
autoSwapBufferMode = true;
skipContextReleaseThread = null;
synchronized(glRunnablesLock) {
- glRunnables = new ArrayList<GLRunnable>();
+ glRunnables.clear();
}
animatorCtrl = null;
}
@@ -105,6 +105,46 @@ public class GLDrawableHelper {
return sb.toString();
}
+ /**
+ * Associate a new context to the drawable and also propagates the context/drawable switch by
+ * calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
+ * <p>
+ * 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)}.
+ * </p>
+ * <p>
+ * If the old or new context was current on this thread, it is being released before switching the drawable.
+ * </p>
+ *
+ * @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<GLRunnable> _glRunnables = null;
+ final ArrayList<GLRunnableTask> _glRunnables;
synchronized(glRunnablesLock) {
if(glRunnables.size()>0) {
_glRunnables = glRunnables;
- glRunnables = new ArrayList<GLRunnable>();
+ glRunnables = new ArrayList<GLRunnableTask>();
+ } else {
+ _glRunnables = null;
}
}
if(null!=_glRunnables) {
for (int i=0; i < _glRunnables.size(); i++) {
- res = _glRunnables.get(i).run(drawable) && res;
+ res = _glRunnables.get(i).run(drawable) && res;
}
}
}
return res;
}
+ public final void flushGLRunnables() {
+ if(glRunnables.size()>0) { // volatile OK
+ // swap one-shot list asap
+ final ArrayList<GLRunnableTask> _glRunnables;
+ synchronized(glRunnablesLock) {
+ if(glRunnables.size()>0) {
+ _glRunnables = glRunnables;
+ glRunnables = new ArrayList<GLRunnableTask>();
+ } else {
+ _glRunnables = null;
+ }
+ }
+
+ if(null!=_glRunnables) {
+ for (int i=0; i < _glRunnables.size(); i++) {
+ _glRunnables.get(i).flush();
+ }
+ }
+ }
+ }
+
public final void setAnimator(GLAnimatorControl animator) throws GLException {
synchronized(glRunnablesLock) {
if(animatorCtrl!=animator && null!=animator && null!=animatorCtrl) {
@@ -264,10 +340,28 @@ public class GLDrawableHelper {
return ( null != animatorCtrl ) ? animatorCtrl.isAnimating() : false ;
}
- public final void invoke(GLAutoDrawable drawable, boolean wait, GLRunnable glRunnable) {
- if( null == drawable || null == glRunnable ) {
- return;
+ /**
+ * <p>
+ * If <code>wait</code> is <code>true</code> the call blocks until the <code>glRunnable</code>
+ * has been executed.<p>
+ * <p>
+ * If <code>wait</code> is <code>true</code> <b>and</b>
+ * {@link GLDrawable#isRealized()} returns <code>false</code> <i>or</i> {@link GLAutoDrawable#getContext()} returns <code>null</code>,
+ * the call is ignored and returns <code>false</code>.<br>
+ * This helps avoiding deadlocking the caller.
+ * </p>
+ *
+ * @param drawable the {@link GLAutoDrawable} to be used
+ * @param wait if <code>true</code> block until execution of <code>glRunnable</code> is finished, otherwise return immediatly w/o waiting
+ * @param glRunnable the {@link GLRunnable} to execute within {@link #display()}
+ * @return <code>true</code> if the {@link GLRunnable} has been processed or queued, otherwise <code>false</code>.
+ */
+ 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
@@ -56,11 +56,6 @@ public class EGLPbufferDrawable extends EGLDrawable {
}
@Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
- @Override
protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
final AbstractGraphicsConfiguration config = getNativeSurface().getGraphicsConfiguration();
final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
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
@@ -80,11 +80,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
}
@Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
- @Override
protected void setRealizedImpl() {
if(realized) {
createPbuffer();
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
@@ -62,11 +62,6 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
}
@Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
- @Override
protected void setRealizedImpl() {
if(realized) {
createBitmap();
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
@@ -67,11 +67,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
}
@Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
- @Override
protected void setRealizedImpl() {
if(realized) {
createPbuffer();
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
@@ -59,11 +59,6 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
}
@Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
- @Override
protected void setRealizedImpl() {
if(realized) {
createPbuffer();
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
@@ -59,11 +59,6 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
}
@Override
- protected void destroyImpl() {
- setRealized(false);
- }
-
- @Override
protected void setRealizedImpl() {
if(realized) {
createPixmap();
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();