aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-04-23 07:53:31 +0200
committerSven Gothel <[email protected]>2013-04-23 07:53:31 +0200
commit0f7412855c118cb501d8a001df7a7487354b5029 (patch)
tree13da9cd0d86bb37aedbad199811700f1de87ef04
parent03a3f209aff955410e0f3133e73078529c23d3e1 (diff)
Fix Bug 722: Make GLEventListenerState 'transaction' safe Animator.pause[ surface.lock[ modify ] ]
GLEventListenerState: New model for GLEventListenerState's transaction safety: - Z Decorate-1: Animator.pause [ X ] Animator.resume - X Decorate-2: Surface.lock [ Y ] Surface.unlock - Instead of setting AbstractGraphicsDevice, just swap the handle and ownership. - Issuing setRealized(..) only if required, i.e. having an upstream-surface (EGL..) depending on used device - Utilizing setRealized(..) on the GLAD's delegated 'real' drawable, avoiding optional GLAD locking. - Cleanup and above changes shall render impl. easier to read. GLEventListenerState Unit Tests: - If swapping/moving from AWT -> NEWT, use a NEWT dedicated Display avoiding ATI driver XCB crash - read comment.
-rw-r--r--make/build-test.xml1
-rwxr-xr-xmake/scripts/tests.sh8
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLEventListenerState.java332
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java11
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java10
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java40
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/GLContextDrawableSwitchBase.java37
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestBug722GLContextDrawableSwitchNewt2AWT.java143
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch11NewtAWT.java16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch12AWT.java16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch21Newt2AWT.java61
11 files changed, 485 insertions, 190 deletions
diff --git a/make/build-test.xml b/make/build-test.xml
index 3d9c31d83..e00348c38 100644
--- a/make/build-test.xml
+++ b/make/build-test.xml
@@ -437,6 +437,7 @@
<fileset dir="${classes}">
<include name="${java.dir.junit}/**/newt/**/Test*AWT*"/>
<!--include name="${java.dir.junit}/**/newt/**/TestNewtEventModifiers*AWT*"/-->
+ <!--include name="${java.dir.junit}/**/acore/glels/Test**"/-->
<exclude name="**/*$$*"/>
</fileset>
<formatter usefile="false" type="brief"/>
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 75e5f7fd6..65e070a99 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -115,6 +115,7 @@ function jrun() {
#D_ARGS="-Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.GLCanvas"
#D_ARGS="-Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.GLEventListenerState"
#D_ARGS="-Djogl.fbo.force.none"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
#D_ARGS="-Djogl.debug=all"
@@ -362,8 +363,9 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch10NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch11NewtAWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch12AWT $*
-##testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch21Newt2AWT $*
+testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch12AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch21Newt2AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestBug722GLContextDrawableSwitchNewt2AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
@@ -379,7 +381,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.newt.TestGLWindowInvisiblePointer01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT
-testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00bNEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01bNEWT
diff --git a/src/jogl/classes/com/jogamp/opengl/GLEventListenerState.java b/src/jogl/classes/com/jogamp/opengl/GLEventListenerState.java
index 2914a1bf9..21dafecb1 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLEventListenerState.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLEventListenerState.java
@@ -32,11 +32,9 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -57,8 +55,8 @@ import com.jogamp.nativewindow.MutableGraphicsConfiguration;
* <li>{@link GLContext}</li>
* <li>All {@link GLEventListener}, incl. their init state</li>
* <li>{@link GLAnimatorControl}</li>
- * <li>{@link GLCapabilitiesImmutable} for compatibility check</li>
- * <li>{@link AbstractGraphicsScreen} for compatibility check and preserving the {@link AbstractGraphicsDevice}</li>
+ * <!--li>{@link GLCapabilitiesImmutable} for compatibility check</li-->
+ * <li>{@link AbstractGraphicsDevice} for compatibility check and preserving the native device handle incl. ownership</li>
* </ul>
* <p>
* A GLEventListenerState instance can be created while components are {@link #moveFrom(GLAutoDrawable) moved from} a {@link GLAutoDrawable}
@@ -68,16 +66,16 @@ import com.jogamp.nativewindow.MutableGraphicsConfiguration;
* A GLEventListenerState instance's components can be {@link #moveTo(GLAutoDrawable) moved to} a {@link GLAutoDrawable},
* while loosing {@link #isOwner() ownership} of the moved components.
* </p>
- * <p>
*/
public class GLEventListenerState {
- private static final boolean DEBUG = Debug.debug("GLDrawable");
+ private static final boolean DEBUG = Debug.debug("GLDrawable") || Debug.debug("GLEventListenerState");
- private GLEventListenerState(AbstractGraphicsScreen upstreamScreen, boolean proxyOwnsUpstreamDevice, AbstractGraphicsScreen screen, GLCapabilitiesImmutable caps,
+ private GLEventListenerState(AbstractGraphicsDevice upstreamDevice, boolean proxyOwnsUpstreamDevice, AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable caps,
GLContext context, int count, GLAnimatorControl anim, boolean animStarted) {
- this.upstreamScreen = upstreamScreen;
+ this.upstreamDevice = upstreamDevice;
this.proxyOwnsUpstreamDevice = proxyOwnsUpstreamDevice;
- this.screen = screen;
+ this.device = device;
this.caps = caps;
this.context = context;
this.listeners = new GLEventListener[count];
@@ -99,9 +97,9 @@ public class GLEventListenerState {
public final int listenerCount() { return listeners.length; }
- public final AbstractGraphicsScreen upstreamScreen;
+ public final AbstractGraphicsDevice upstreamDevice;
public final boolean proxyOwnsUpstreamDevice;
- public final AbstractGraphicsScreen screen;
+ public final AbstractGraphicsDevice device;
public final GLCapabilitiesImmutable caps;
public final GLContext context;
public final GLEventListener[] listeners;
@@ -121,14 +119,13 @@ public class GLEventListenerState {
listeners[i] = null;
}
// context.destroy(); - NPE (null drawable)
- screen.getDevice().close();
+ device.close();
owner = false;
}
}
- private static AbstractGraphicsScreen cloneScreen(AbstractGraphicsScreen aScreen) {
- final AbstractGraphicsDevice aDevice2 = (AbstractGraphicsDevice) aScreen.getDevice().clone();
- return NativeWindowFactory.createScreen( aDevice2, aScreen.getIndex() );
+ private static AbstractGraphicsDevice cloneDevice(AbstractGraphicsDevice aDevice) {
+ return (AbstractGraphicsDevice) aDevice.clone();
}
/**
@@ -152,51 +149,6 @@ public class GLEventListenerState {
* @see #moveTo(GLAutoDrawable)
*/
public static GLEventListenerState moveFrom(GLAutoDrawable a) {
- final int aSz = a.getGLEventListenerCount();
-
- // Create new AbstractGraphicsScreen w/ cloned AbstractGraphicsDevice for future GLAutoDrawable
- // allowing this AbstractGraphicsDevice to loose ownership -> not closing display/device!
- final NativeSurface aSurface = a.getNativeSurface();
- final AbstractGraphicsConfiguration aCfg = aSurface.getGraphicsConfiguration();
- final AbstractGraphicsScreen aScreen1 = aCfg.getScreen();
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) aCfg.getChosenCapabilities();
- final AbstractGraphicsScreen aScreen2 = cloneScreen(aScreen1);
- aScreen1.getDevice().clearHandleOwner(); // don't close device handle
- if( DEBUG ) {
- System.err.println("GLEventListenerState.moveFrom.0a: orig 0x"+Integer.toHexString(aScreen1.getDevice().hashCode())+", "+aScreen1.getDevice());
- System.err.println("GLEventListenerState.moveFrom.0b: pres 0x"+Integer.toHexString(aScreen2.getDevice().hashCode())+", "+aScreen2.getDevice());
- System.err.println("GLEventListenerState.moveFrom.1: "+aSurface.getClass().getName()+", "+aSurface);
- }
- final AbstractGraphicsScreen aUpScreen2;
- final boolean proxyOwnsUpstreamDevice;
- {
- AbstractGraphicsScreen _aUpScreen2=null;
- if(aSurface instanceof ProxySurface) {
- final ProxySurface aProxy = (ProxySurface)aSurface;
- proxyOwnsUpstreamDevice = aProxy.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
- final NativeSurface aUpSurface = aProxy.getUpstreamSurface();
- if(DEBUG && null != aUpSurface) {
- System.err.println("GLEventListenerState.moveFrom.2: "+aUpSurface.getClass().getName()+", "+aUpSurface);
- }
- if(null != aUpSurface) {
- final AbstractGraphicsScreen aUpScreen1 = aUpSurface.getGraphicsConfiguration().getScreen();
- _aUpScreen2 = cloneScreen(aUpScreen1);
- if(null != aUpScreen1) {
- aUpScreen1.getDevice().clearHandleOwner(); // don't close device handle
- }
- if(DEBUG) {
- System.err.println("GLEventListenerState.moveFrom.3a: up-orig 0x"+Integer.toHexString(aUpScreen1.getDevice().hashCode())+", "+aUpScreen1.getDevice());
- System.err.println("GLEventListenerState.moveFrom.3b: up-pres 0x"+Integer.toHexString(_aUpScreen2.getDevice().hashCode())+", "+_aUpScreen2.getDevice());
- System.err.println("GLEventListenerState.moveFrom.3c: "+aSurface.getClass().getName()+", "+aSurface);
- System.err.println("GLEventListenerState.moveFrom.3d: "+aUpSurface.getClass().getName()+", "+aUpSurface);
- }
- }
- } else {
- proxyOwnsUpstreamDevice = false;
- }
- aUpScreen2=_aUpScreen2;
- }
-
final GLAnimatorControl aAnim = a.getAnimator();
final boolean aAnimStarted;
if( null != aAnim ) {
@@ -206,23 +158,75 @@ public class GLEventListenerState {
aAnimStarted = false;
}
- final GLEventListenerState glls = new GLEventListenerState(aUpScreen2, proxyOwnsUpstreamDevice, aScreen2, caps, a.getContext(), aSz, aAnim, aAnimStarted);
-
- //
- // remove and cache all GLEventListener and their init-state
- //
- for(int i=0; i<aSz; i++) {
- final GLEventListener l = a.getGLEventListener(0);
- glls.listenersInit[i] = a.getGLEventListenerInitState(l);
- glls.listeners[i] = a.removeGLEventListener( l );
- }
-
- //
- // trigger glFinish to sync GL ctx
- //
- a.invoke(true, glFinish);
-
- a.setContext( null, false );
+ final GLEventListenerState glls;
+ final NativeSurface aSurface = a.getNativeSurface();
+ final boolean surfaceLocked = false; // NativeSurface.LOCK_SURFACE_NOT_READY < aSurface.lockSurface();
+ try {
+ final int aSz = a.getGLEventListenerCount();
+
+ // Create new AbstractGraphicsScreen w/ cloned AbstractGraphicsDevice for future GLAutoDrawable
+ // allowing this AbstractGraphicsDevice to loose ownership -> not closing display/device!
+ final AbstractGraphicsConfiguration aCfg = aSurface.getGraphicsConfiguration();
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) aCfg.getChosenCapabilities();
+ final AbstractGraphicsDevice aDevice1 = aCfg.getScreen().getDevice();
+ final AbstractGraphicsDevice aDevice2 = cloneDevice(aDevice1);
+ aDevice1.clearHandleOwner(); // don't close device handle
+ if( DEBUG ) {
+ System.err.println("GLEventListenerState.moveFrom.0a: orig 0x"+Integer.toHexString(aDevice1.hashCode())+", "+aDevice1);
+ System.err.println("GLEventListenerState.moveFrom.0b: pres 0x"+Integer.toHexString(aDevice2.hashCode())+", "+aDevice2);
+ System.err.println("GLEventListenerState.moveFrom.1: "+aSurface.getClass().getName()/*+", "+aSurface*/);
+ }
+ final AbstractGraphicsDevice aUpDevice2;
+ final boolean proxyOwnsUpstreamDevice;
+ {
+ AbstractGraphicsDevice _aUpDevice2 = null;
+ if(aSurface instanceof ProxySurface) {
+ final ProxySurface aProxy = (ProxySurface)aSurface;
+ proxyOwnsUpstreamDevice = aProxy.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ final NativeSurface aUpSurface = aProxy.getUpstreamSurface();
+ if(DEBUG && null != aUpSurface) {
+ System.err.println("GLEventListenerState.moveFrom.2: "+aUpSurface.getClass().getName()+", "+aUpSurface);
+ }
+ if(null != aUpSurface) {
+ final AbstractGraphicsDevice aUpDevice1 = aUpSurface.getGraphicsConfiguration().getScreen().getDevice();
+ _aUpDevice2 = cloneDevice(aUpDevice1);
+ aUpDevice1.clearHandleOwner(); // don't close device handle
+ if(DEBUG) {
+ System.err.println("GLEventListenerState.moveFrom.3a: up-orig 0x"+Integer.toHexString(aUpDevice1.hashCode())+", "+aUpDevice1);
+ System.err.println("GLEventListenerState.moveFrom.3b: up-pres 0x"+Integer.toHexString(_aUpDevice2.hashCode())+", "+_aUpDevice2);
+ System.err.println("GLEventListenerState.moveFrom.3c: "+aSurface.getClass().getName()+", "+aSurface);
+ System.err.println("GLEventListenerState.moveFrom.3d: "+aUpSurface.getClass().getName()/*+", "+aUpSurface+", "*/+aProxy.getUpstreamOptionBits(null).toString());
+ }
+ }
+ } else {
+ proxyOwnsUpstreamDevice = false;
+ }
+ aUpDevice2 = _aUpDevice2;
+ }
+
+ glls = new GLEventListenerState(aUpDevice2, proxyOwnsUpstreamDevice, aDevice2, caps, a.getContext(), aSz, aAnim, aAnimStarted);
+
+ //
+ // remove and cache all GLEventListener and their init-state
+ //
+ for(int i=0; i<aSz; i++) {
+ final GLEventListener l = a.getGLEventListener(0);
+ glls.listenersInit[i] = a.getGLEventListenerInitState(l);
+ glls.listeners[i] = a.removeGLEventListener( l );
+ }
+
+ //
+ // trigger glFinish to sync GL ctx
+ //
+ a.invoke(true, glFinish);
+
+ a.setContext( null, false );
+
+ } finally {
+ if( surfaceLocked ) {
+ aSurface.unlockSurface();
+ }
+ }
return glls;
}
@@ -241,84 +245,123 @@ public class GLEventListenerState {
*
* @param a {@link GLAutoDrawable} destination to move GLEventListenerState components to
*
- * @throws GLException if the {@link GLAutoDrawable}'s configuration is incompatible, i.e. different {@link GLCapabilitiesImmutable}.
+ * <!-- @throws GLException if the {@link GLAutoDrawable}'s configuration is incompatible, i.e. different {@link GLCapabilitiesImmutable}. -->
+ * @throws GLException if this preserved {@link AbstractGraphicsDevice} is incompatible w/ the given destination one.
*
* @see #moveFrom(GLAutoDrawable)
* @see #isOwner()
*/
public final void moveTo(GLAutoDrawable a) {
+ final GLAnimatorControl aAnim = a.getAnimator();
+ final boolean hasAnimator = null != aAnim;
+ final boolean aPaused;
+ if( hasAnimator ) {
+ aPaused = aAnim.pause();
+ aAnim.remove(a); // also handles ECT
+ if( aPaused ) {
+ aAnim.resume();
+ }
+ } else {
+ aPaused = false;
+ }
+
final List<GLRunnable> aGLCmds = new ArrayList<GLRunnable>();
final int aSz = listenerCount();
final NativeSurface aSurface = a.getNativeSurface();
- final MutableGraphicsConfiguration aCfg = (MutableGraphicsConfiguration) aSurface.getGraphicsConfiguration();
- final GLCapabilitiesImmutable aCaps = (GLCapabilitiesImmutable) aCfg.getChosenCapabilities();
- if( caps.getVisualID(VisualIDHolder.VIDType.INTRINSIC) != aCaps.getVisualID(VisualIDHolder.VIDType.INTRINSIC) ||
- caps.getVisualID(VisualIDHolder.VIDType.NATIVE) != aCaps.getVisualID(VisualIDHolder.VIDType.NATIVE) ) {
- throw new GLException("Incompatible Capabilities - Prev-Holder: "+caps+", New-Holder "+caps);
- }
- // Destroy and remove currently associated GLContext, if any (will be replaced)
- a.setContext( null, true );
- final boolean aRealized = a.isRealized();
- if( aRealized ) {
- a.setRealized(false);
- }
- // Set new Screen and close previous one
- {
- final AbstractGraphicsScreen aScreen1 = aCfg.getScreen();
- if( DEBUG ) {
- System.err.println("GLEventListenerState.moveTo.0a: orig 0x"+Integer.toHexString(aScreen1.getDevice().hashCode())+", "+aScreen1.getDevice());
- System.err.println("GLEventListenerState.moveTo.0b: pres 0x"+Integer.toHexString(screen.getDevice().hashCode())+", "+screen.getDevice());
+ final boolean surfaceLocked = false; // NativeSurface.LOCK_SURFACE_NOT_READY < aSurface.lockSurface();
+ final boolean aRealized;
+ try {
+
+ final MutableGraphicsConfiguration aCfg = (MutableGraphicsConfiguration) aSurface.getGraphicsConfiguration();
+ /**
+ final GLCapabilitiesImmutable aCaps = (GLCapabilitiesImmutable) aCfg.getChosenCapabilities();
+ if( caps.getVisualID(VisualIDHolder.VIDType.INTRINSIC) != aCaps.getVisualID(VisualIDHolder.VIDType.INTRINSIC) ||
+ caps.getVisualID(VisualIDHolder.VIDType.NATIVE) != aCaps.getVisualID(VisualIDHolder.VIDType.NATIVE) ) {
+ throw new GLException("Incompatible Capabilities - Prev-Holder: "+caps+", New-Holder "+caps);
+ } */
+ final DefaultGraphicsDevice aDevice1 = (DefaultGraphicsDevice) aCfg.getScreen().getDevice();
+ final DefaultGraphicsDevice aDevice2 = (DefaultGraphicsDevice) device;
+ if( !aDevice1.getUniqueID().equals( aDevice2.getUniqueID() ) ) {
+ throw new GLException("Incompatible devices: Preserved <"+aDevice2.getUniqueID()+">, target <"+aDevice1.getUniqueID()+">");
+ }
+
+ // collect optional upstream surface info
+ final ProxySurface aProxy;
+ final NativeSurface aUpSurface;
+ if(aSurface instanceof ProxySurface) {
+ aProxy = (ProxySurface)aSurface;
+ aUpSurface = aProxy.getUpstreamSurface();
+ } else {
+ aProxy = null;
+ aUpSurface = null;
}
- aCfg.setScreen( screen );
- aScreen1.getDevice().close();
if( DEBUG ) {
- System.err.println("GLEventListenerState.moveTo.1a: orig 0x"+Integer.toHexString(aScreen1.getDevice().hashCode())+", "+aScreen1.getDevice());
- System.err.println("GLEventListenerState.moveTo.1b: pres 0x"+Integer.toHexString(screen.getDevice().hashCode())+", "+screen.getDevice());
+ System.err.println("GLEventListenerState.moveTo.0 : has aProxy "+(null!=aProxy));
+ System.err.println("GLEventListenerState.moveTo.0 : has aUpSurface "+(null!=aUpSurface));
}
- }
-
- // If using a ProxySurface w/ an upstream surface, set new Screen and close previous one on it
- {
- boolean upstreamSet = false;
- if(aSurface instanceof ProxySurface) {
- final ProxySurface aProxy = (ProxySurface)aSurface;
- final NativeSurface aUpSurface = aProxy.getUpstreamSurface();
- if(null != aUpSurface) {
- final MutableGraphicsConfiguration aUpCfg = (MutableGraphicsConfiguration) aUpSurface.getGraphicsConfiguration();
- if( null != upstreamScreen ) {
- final AbstractGraphicsScreen aUpScreen1 = aUpCfg.getScreen();
- if( DEBUG ) {
- System.err.println("GLEventListenerState.moveTo.2a: up-orig 0x"+Integer.toHexString(aUpScreen1.getDevice().hashCode())+", "+aUpScreen1.getDevice());
- System.err.println("GLEventListenerState.moveTo.2b: up-pres 0x"+Integer.toHexString(upstreamScreen.getDevice().hashCode())+", "+upstreamScreen.getDevice());
- System.err.println("GLEventListenerState.moveTo.2c: "+aUpSurface.getClass().getName()+", "+aUpSurface+", "+aProxy.getUpstreamOptionBits(null).toString());
- }
- aUpScreen1.getDevice().close();
- aUpCfg.setScreen( upstreamScreen );
- if( proxyOwnsUpstreamDevice ) {
- aProxy.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
- }
- upstreamSet = true;
- if( DEBUG ) {
- System.err.println("GLEventListenerState.moveTo.3a: up-orig 0x"+Integer.toHexString(aUpScreen1.getDevice().hashCode())+", "+aUpScreen1.getDevice());
- System.err.println("GLEventListenerState.moveTo.3b: up-pres 0x"+Integer.toHexString(upstreamScreen.getDevice().hashCode())+", "+upstreamScreen.getDevice());
- System.err.println("GLEventListenerState.moveTo.3c: "+aUpSurface.getClass().getName()+", "+aUpSurface+", "+aProxy.getUpstreamOptionBits(null).toString());
- }
- } else {
- throw new GLException("Incompatible Surface config - Has Upstream-Surface: Prev-Holder = false, New-Holder = true");
+ if( null==aUpSurface && null != upstreamDevice ) {
+ throw new GLException("Incompatible Surface config - Has Upstream-Surface: Prev-Holder = true, New-Holder = false");
+ }
+
+ // Destroy and remove currently associated GLContext, if any (will be replaced)
+ a.setContext( null, true );
+ aRealized = a.isRealized();
+ if( aRealized && null != aUpSurface ) {
+ // Unrealize due to device dependencies of an upstream surface, e.g. EGLUpstreamSurfaceHook
+ a.getDelegatedDrawable().setRealized(false);
+ }
+
+ // Set new Screen and close previous one
+ {
+ if( DEBUG ) {
+ System.err.println("GLEventListenerState.moveTo.0a: orig 0x"+Integer.toHexString(aDevice1.hashCode())+", "+aDevice1);
+ System.err.println("GLEventListenerState.moveTo.0b: pres 0x"+Integer.toHexString(aDevice2.hashCode())+", "+aDevice2);
+ }
+ DefaultGraphicsDevice.swapDeviceHandleAndOwnership(aDevice1, aDevice2);
+ aDevice2.close();
+ if( DEBUG ) {
+ System.err.println("GLEventListenerState.moveTo.1a: orig 0x"+Integer.toHexString(aDevice1.hashCode())+", "+aDevice1);
+ System.err.println("GLEventListenerState.moveTo.1b: pres 0x"+Integer.toHexString(aDevice2.hashCode())+", "+aDevice2);
+ }
+ }
+
+ // If using a ProxySurface w/ an upstream surface, set new Screen and close previous one on it
+ if( null != aUpSurface ) {
+ final MutableGraphicsConfiguration aUpCfg = (MutableGraphicsConfiguration) aUpSurface.getGraphicsConfiguration();
+ if( null != upstreamDevice ) {
+ final DefaultGraphicsDevice aUpDevice1 = (DefaultGraphicsDevice) aUpCfg.getScreen().getDevice();
+ final DefaultGraphicsDevice aUpDevice2 = (DefaultGraphicsDevice)upstreamDevice;
+ if( !aUpDevice1.getUniqueID().equals( aUpDevice2.getUniqueID() ) ) {
+ throw new GLException("Incompatible updtream devices: Preserved <"+aUpDevice2.getUniqueID()+">, target <"+aUpDevice1.getUniqueID()+">");
+ }
+ if( DEBUG ) {
+ System.err.println("GLEventListenerState.moveTo.2a: up-orig 0x"+Integer.toHexString(aUpDevice1.hashCode())+", "+aUpDevice1);
+ System.err.println("GLEventListenerState.moveTo.2b: up-pres 0x"+Integer.toHexString(aUpDevice2.hashCode())+", "+aUpDevice2);
+ System.err.println("GLEventListenerState.moveTo.2c: "+aUpSurface.getClass().getName()/*+", "+aUpSurface+", "*/+aProxy.getUpstreamOptionBits(null).toString());
+ }
+ DefaultGraphicsDevice.swapDeviceHandleAndOwnership(aUpDevice1, aUpDevice2);
+ aUpDevice2.close();
+ if( proxyOwnsUpstreamDevice ) {
+ aProxy.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ if( DEBUG ) {
+ System.err.println("GLEventListenerState.moveTo.3a: up-orig 0x"+Integer.toHexString(aUpDevice1.hashCode())+", "+aUpDevice1);
+ System.err.println("GLEventListenerState.moveTo.3b: up-pres 0x"+Integer.toHexString(aUpDevice2.hashCode())+", "+aUpDevice2);
+ System.err.println("GLEventListenerState.moveTo.3c: "+aUpSurface.getClass().getName()/*+", "+aUpSurface+", "*/+aProxy.getUpstreamOptionBits(null).toString());
}
+ } else {
+ throw new GLException("Incompatible Surface config - Has Upstream-Surface: Prev-Holder = false, New-Holder = true");
}
}
- if( !upstreamSet && null != upstreamScreen ) {
- throw new GLException("Incompatible Surface config - Has Upstream-Surface: Prev-Holder = true, New-Holder = false");
+
+ if( aRealized && null != aUpSurface ) {
+ a.getDelegatedDrawable().setRealized(true);
+ }
+ if( DEBUG ) {
+ System.err.println("GLEventListenerState.moveTo.X : has aProxy "+(null!=aProxy));
+ System.err.println("GLEventListenerState.moveTo.X : has aUpSurface "+(null!=aUpSurface));
}
- }
-
- if( aRealized ) {
- a.setRealized(true);
- }
- final boolean surfaceLocked = false; // NativeSurface.LOCK_SURFACE_NOT_READY < aSurface.lockSurface();
- try {
a.setContext( context, false );
} finally {
if( surfaceLocked ) {
@@ -347,7 +390,14 @@ public class GLEventListenerState {
listeners[i] = null;
}
- if( null != anim && null == a.getAnimator() ) {
+ if( hasAnimator ) {
+ // prefer already bound animator
+ aAnim.add(a);
+ if( aPaused ) {
+ aAnim.resume();
+ }
+ } else if ( null != anim ) {
+ // use previously bound animator
anim.add(a); // also handles ECT
if(animStarted) {
anim.start();
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index 63200b393..fb6d39b2f 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -120,6 +120,15 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
public void clearHandleOwner() {
eglLifecycleCallback = null;
}
-
+ @Override
+ protected Object getHandleOwnership() {
+ return eglLifecycleCallback;
+ }
+ @Override
+ protected Object setHandleOwnership(Object newOwnership) {
+ final EGLDisplayLifecycleCallback oldOwnership = eglLifecycleCallback;
+ eglLifecycleCallback = (EGLDisplayLifecycleCallback) newOwnership;
+ return oldOwnership;
+ }
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index da3b31de4..e630e012e 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -162,4 +162,14 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
public void clearHandleOwner() {
handleOwner = false;
}
+ @Override
+ protected Object getHandleOwnership() {
+ return Boolean.valueOf(handleOwner);
+ }
+ @Override
+ protected Object setHandleOwnership(Object newOwnership) {
+ final Boolean oldOwnership = Boolean.valueOf(handleOwner);
+ handleOwner = ((Boolean) newOwnership).booleanValue();
+ return oldOwnership;
+ }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index b3ae4628c..66b81d7fa 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -185,6 +185,42 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
}
/**
+ * Set the native handle of the underlying native device
+ * and return the previous one.
+ */
+ protected final long setHandle(long newHandle) {
+ final long oldHandle = handle;
+ handle = newHandle;
+ return oldHandle;
+ }
+
+ protected Object getHandleOwnership() {
+ return null;
+ }
+ protected Object setHandleOwnership(Object newOwnership) {
+ return null;
+ }
+
+ public static final void swapDeviceHandleAndOwnership(final DefaultGraphicsDevice aDevice1, final DefaultGraphicsDevice aDevice2) {
+ aDevice1.lock();
+ try {
+ aDevice2.lock();
+ try {
+ final long aDevice1Handle = aDevice1.getHandle();
+ final long aDevice2Handle = aDevice2.setHandle(aDevice1Handle);
+ aDevice1.setHandle(aDevice2Handle);
+ final Object aOwnership1 = aDevice1.getHandleOwnership();
+ final Object aOwnership2 = aDevice2.setHandleOwnership(aOwnership1);
+ aDevice1.setHandleOwnership(aOwnership2);
+ } finally {
+ aDevice2.unlock();
+ }
+ } finally {
+ aDevice1.unlock();
+ }
+ }
+
+ /**
* Set the internal ToolkitLock, which is used within the
* {@link #lock()} and {@link #unlock()} implementation.
*
@@ -194,8 +230,9 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
* </p>
*
* @param locker the ToolkitLock, if null, {@link jogamp.nativewindow.NullToolkitLock} is being used
+ * @return the previous ToolkitLock instance
*/
- protected void setToolkitLock(ToolkitLock locker) {
+ protected ToolkitLock setToolkitLock(ToolkitLock locker) {
final ToolkitLock _toolkitLock = toolkitLock;
_toolkitLock.lock();
try {
@@ -203,6 +240,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
} finally {
_toolkitLock.unlock();
}
+ return _toolkitLock;
}
/**
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/GLContextDrawableSwitchBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/GLContextDrawableSwitchBase.java
index 300b4ec85..905cbcf25 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/GLContextDrawableSwitchBase.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/GLContextDrawableSwitchBase.java
@@ -42,6 +42,7 @@ import javax.media.opengl.awt.GLCanvas;
import jogamp.nativewindow.jawt.JAWTUtil;
+import com.jogamp.newt.Screen;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GLEventListenerState;
@@ -150,11 +151,12 @@ public abstract class GLContextDrawableSwitchBase extends UITestCase {
return true;
}
- protected void testGLADOneLifecycle(GLCapabilities caps, GLADType gladType, int width, int height,
- GLEventListenerCounter glelTracker, SnapshotGLEventListener snapshotGLEventListener,
- GLEventListenerState glelsIn, GLEventListenerState glelsOut[], GLAnimatorControl animator)
+ protected void testGLADOneLifecycle(Screen screen, GLCapabilities caps, GLADType gladType, int width,
+ int height, GLEventListenerCounter glelTracker,
+ SnapshotGLEventListener snapshotGLEventListener, final GLEventListenerState glelsIn, final GLEventListenerState glelsOut[], GLAnimatorControl animator)
throws InterruptedException {
+ System.err.println("GLAD Lifecycle.0 "+gladType+", restoring "+((null!=glelsIn)?true:false)+", preserving "+((null!=glelsOut)?true:false));
final Frame frame;
final GLAutoDrawable glad;
if( GLADType.GLCanvasOnscreen == gladType ) {
@@ -179,7 +181,11 @@ public abstract class GLContextDrawableSwitchBase extends UITestCase {
} else if( GLADType.GLWindow == gladType ) {
frame = null;
- glad = GLWindow.create(caps);
+ if( null != screen ) {
+ glad = GLWindow.create(screen, caps);
+ } else {
+ glad = GLWindow.create(caps);
+ }
((GLWindow)glad).setTitle("Newt GLWindow");
((GLWindow)glad).setSize(width, height);
} else if( GLADType.GLOffscreen == gladType ) {
@@ -212,7 +218,9 @@ public abstract class GLContextDrawableSwitchBase extends UITestCase {
if( null != glelsIn ) {
Assert.assertEquals(0, glad.getGLEventListenerCount());
- glelsIn.moveTo(glad);
+ System.err.println(".. restoring.0");
+ glelsIn.moveTo(glad);
+ System.err.println(".. restoring.X");
Assert.assertEquals(1, glelTracker.initCount);
Assert.assertTrue(1 <= glelTracker.reshapeCount);
@@ -227,6 +235,12 @@ public abstract class GLContextDrawableSwitchBase extends UITestCase {
Assert.assertEquals(false, glelsIn.isOwner());
}
+ for (int wait=0; wait<AWTRobotUtil.POLL_DIVIDER &&
+ ( 1 > glelTracker.initCount || 1 > glelTracker.reshapeCount || 1 > glelTracker.displayCount );
+ wait++) {
+ Thread.sleep(AWTRobotUtil.TIME_SLICE);
+ }
+
final long t0 = System.currentTimeMillis();
long t1 = t0;
@@ -242,17 +256,17 @@ public abstract class GLContextDrawableSwitchBase extends UITestCase {
if( null != glelsOut ) {
final GLContext context1 = glad.getContext();
- final GLEventListenerState _gllsOut = GLEventListenerState.moveFrom(glad);
+ System.err.println(".. preserving.0");
+ glelsOut[0] = GLEventListenerState.moveFrom(glad);
+ System.err.println(".. preserving.X");
- Assert.assertEquals(context1, _gllsOut.context);
+ Assert.assertEquals(context1, glelsOut[0].context);
Assert.assertNull(context1.getGLReadDrawable());
Assert.assertNull(context1.getGLDrawable());
- Assert.assertEquals(3, _gllsOut.listenerCount());
- Assert.assertEquals(true, _gllsOut.isOwner());
+ Assert.assertEquals(3, glelsOut[0].listenerCount());
+ Assert.assertEquals(true, glelsOut[0].isOwner());
Assert.assertEquals(null, glad.getContext());
Assert.assertEquals(0, glad.getGLEventListenerCount());
-
- glelsOut[0] = _gllsOut;
}
if( GLADType.GLCanvasOnscreen == gladType || GLADType.GLCanvasOffscreen == gladType ) {
destroyFrame(frame);
@@ -272,5 +286,6 @@ public abstract class GLContextDrawableSwitchBase extends UITestCase {
} else {
Assert.assertEquals(1, glelTracker.disposeCount);
}
+ System.err.println("GLAD Lifecycle.X "+gladType);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestBug722GLContextDrawableSwitchNewt2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestBug722GLContextDrawableSwitchNewt2AWT.java
new file mode 100644
index 000000000..a11978784
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestBug722GLContextDrawableSwitchNewt2AWT.java
@@ -0,0 +1,143 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore.glels;
+
+import java.io.IOException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+
+
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
+import com.jogamp.opengl.GLEventListenerState;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.GLRendererQuirks;
+import com.jogamp.opengl.test.junit.util.GLEventListenerCounter;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+
+import org.junit.Test;
+
+/**
+ * Tests Bug 722
+ * <p>
+ * See Bug 722 - https://jogamp.org/bugzilla/show_bug.cgi?id=722.
+ * </p>
+ */
+public class TestBug722GLContextDrawableSwitchNewt2AWT extends GLContextDrawableSwitchBase {
+
+ static int loops = 10;
+ static long duration2 = 100; // ms
+
+ /**
+ * Interesting artifact w/ ATI proprietary driver is that the
+ * bug causing the quirk {@link GLRendererQuirks#DontCloseX11Display}
+ * also causes an XCB crash when reusing the X11 display connection
+ * from AWT -> NEWT. Pre-allocating the X11 Display and keeping it referenced
+ * to avoid such re-usage worksaround this problem.
+ */
+ public static boolean fixedNewtDisplay = true;
+
+ @Test(timeout=3000000)
+ public void test11GLWindow2GLCanvasOnScrnGL2ES2() throws InterruptedException {
+ final GLCapabilities caps = getCaps(GLProfile.GL2ES2);
+ if(null == caps) return;
+
+ GLADType gladType1 = GLADType.GLWindow;
+ GLADType gladType2 = GLADType.GLCanvasOnscreen;
+
+ final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener();
+ final Animator animator = new Animator();
+ animator.start();
+
+ final Display dpy;
+ final Screen screen;
+ if( fixedNewtDisplay ) {
+ dpy = NewtFactory.createDisplay(null);
+ screen = NewtFactory.createScreen(dpy, 0);
+ screen.addReference();
+ } else {
+ dpy = null;
+ screen = null;
+ }
+
+ duration = duration2;
+
+ for(int i=0; i<loops; i++) {
+ final GLEventListenerState glels[] = new GLEventListenerState[1];
+ final GLEventListenerCounter glelTracker = new GLEventListenerCounter();
+
+ // - create glad1 w/o context
+ // - create context using glad1 and assign it to glad1
+ {
+ System.err.println("Test "+i+"/"+loops+".1: GLAD-1 "+gladType1+", preserving.");
+ testGLADOneLifecycle(screen, caps, gladType1, width, height,
+ glelTracker, snapshotGLEventListener,
+ null,
+ glels, animator);
+ System.err.println("Test "+i+"/"+loops+".1: done");
+ }
+
+ // - create glad2 w/ survived context
+ {
+ System.err.println("Test "+i+"/"+loops+".2: GLAD-1 "+gladType2+", restoring.");
+ testGLADOneLifecycle(screen, caps, gladType2, width+100, height+100,
+ glelTracker, snapshotGLEventListener,
+ glels[0],
+ null, null);
+ System.err.println("Test "+i+"/"+loops+".2: done.");
+ }
+ }
+ animator.stop();
+
+ if( fixedNewtDisplay ) {
+ screen.removeReference();
+ }
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration2 = MiscUtils.atol(args[i], duration2);
+ } else if(args[i].equals("-loops")) {
+ i++;
+ loops = MiscUtils.atoi(args[i], loops);
+ } else if(args[i].equals("-noFixedNewtDisplay")) {
+ fixedNewtDisplay = false;
+ }
+ }
+ /**
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ System.err.println(stdin.readLine()); */
+ org.junit.runner.JUnitCore.main(TestBug722GLContextDrawableSwitchNewt2AWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch11NewtAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch11NewtAWT.java
index 68f74a27a..a3f3ffbee 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch11NewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch11NewtAWT.java
@@ -84,18 +84,18 @@ public class TestGLContextDrawableSwitch11NewtAWT extends GLContextDrawableSwitc
// - create glad1 w/o context
// - create context using glad1 and assign it to glad1
{
- testGLADOneLifecycle(caps, GLADType.GLWindow, width, height,
- glelTracker, snapshotGLEventListener,
- null,
- glels, animator);
+ testGLADOneLifecycle(null, caps, GLADType.GLWindow, width,
+ height, glelTracker,
+ snapshotGLEventListener,
+ null, glels, animator);
}
// - create glad2 w/ survived context
{
- testGLADOneLifecycle(caps, GLADType.GLWindow, width+100, height+100,
- glelTracker, snapshotGLEventListener,
- glels[0],
- null, null);
+ testGLADOneLifecycle(null, caps, GLADType.GLWindow, width+100,
+ height+100, glelTracker,
+ snapshotGLEventListener,
+ glels[0], null, null);
}
animator.stop();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch12AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch12AWT.java
index 684208909..95e895d44 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch12AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch12AWT.java
@@ -110,18 +110,18 @@ public class TestGLContextDrawableSwitch12AWT extends GLContextDrawableSwitchBas
// - create glad1 w/o context
// - create context using glad1 and assign it to glad1
{
- testGLADOneLifecycle(caps, offscreenLayer ? GLADType.GLCanvasOffscreen : GLADType.GLCanvasOnscreen, width, height,
- glelTracker, snapshotGLEventListener,
- null,
- glels, animator);
+ testGLADOneLifecycle(null, caps, offscreenLayer ? GLADType.GLCanvasOffscreen : GLADType.GLCanvasOnscreen, width,
+ height, glelTracker,
+ snapshotGLEventListener,
+ null, glels, animator);
}
// - create glad2 w/ survived context
{
- testGLADOneLifecycle(caps, offscreenLayer ? GLADType.GLCanvasOffscreen : GLADType.GLCanvasOnscreen, width+100, height+100,
- glelTracker, snapshotGLEventListener,
- glels[0],
- null, null);
+ testGLADOneLifecycle(null, caps, offscreenLayer ? GLADType.GLCanvasOffscreen : GLADType.GLCanvasOnscreen, width+100,
+ height+100, glelTracker,
+ snapshotGLEventListener,
+ glels[0], null, null);
}
animator.stop();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch21Newt2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch21Newt2AWT.java
index 87057f5a9..d337570ec 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch21Newt2AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch21Newt2AWT.java
@@ -34,7 +34,11 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
import com.jogamp.opengl.GLEventListenerState;
+import com.jogamp.opengl.GLRendererQuirks;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.util.GLEventListenerCounter;
@@ -58,6 +62,13 @@ import org.junit.Test;
* <p>
* See Bug 665 - https://jogamp.org/bugzilla/show_bug.cgi?id=665.
* </p>
+ * <p>
+ * Interesting artifact w/ ATI proprietary driver is that the
+ * bug causing the quirk {@link GLRendererQuirks#DontCloseX11Display}
+ * also causes an XCB crash when reusing the X11 display connection
+ * from AWT -> NEWT. Pre-allocating the X11 Display and keeping it referenced
+ * to avoid such re-usage worksaround this problem.
+ * </p>
*/
public class TestGLContextDrawableSwitch21Newt2AWT extends GLContextDrawableSwitchBase {
@@ -65,59 +76,75 @@ public class TestGLContextDrawableSwitch21Newt2AWT extends GLContextDrawableSwit
public void test01GLCanvasOnScrn2GLWindowGL2ES2() throws InterruptedException {
final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2);
if(null == reqGLCaps) return;
- testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLCanvasOnscreen, GLADType.GLWindow);
+ testGLCanvas2GLWindowImpl(null, reqGLCaps, GLADType.GLCanvasOnscreen, GLADType.GLWindow);
}
@Test(timeout=30000)
public void test02GLCanvasOnScrn2GLWindowGLES2() throws InterruptedException {
final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
if(null == reqGLCaps) return;
- testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLCanvasOnscreen, GLADType.GLWindow);
+ testGLCanvas2GLWindowImpl(null, reqGLCaps, GLADType.GLCanvasOnscreen, GLADType.GLWindow);
}
@Test(timeout=30000)
public void test11GLWindow2GLCanvasOnScrnGL2ES2() throws InterruptedException {
final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2);
if(null == reqGLCaps) return;
- testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOnscreen);
+ final Display dpy = NewtFactory.createDisplay(null);
+ final Screen screen = NewtFactory.createScreen(dpy, 0);
+ screen.addReference();
+ testGLCanvas2GLWindowImpl(screen, reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOnscreen);
+ screen.removeReference();
}
@Test(timeout=30000)
public void test12GLWindow2GLCanvasOnScrnGLES2() throws InterruptedException {
final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
if(null == reqGLCaps) return;
- testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOnscreen);
+ final Display dpy = NewtFactory.createDisplay(null);
+ final Screen screen = NewtFactory.createScreen(dpy, 0);
+ screen.addReference();
+ testGLCanvas2GLWindowImpl(screen, reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOnscreen);
+ screen.removeReference();
}
@Test(timeout=30000)
public void test21GLCanvasOffScrn2GLWindowGL2ES2() throws InterruptedException {
final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2);
if(null == reqGLCaps) return;
- testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLCanvasOffscreen, GLADType.GLWindow);
+ testGLCanvas2GLWindowImpl(null, reqGLCaps, GLADType.GLCanvasOffscreen, GLADType.GLWindow);
}
@Test(timeout=30000)
public void test22GLCanvasOffScrn2GLWindowGLES2() throws InterruptedException {
final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
if(null == reqGLCaps) return;
- testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLCanvasOffscreen, GLADType.GLWindow);
+ testGLCanvas2GLWindowImpl(null, reqGLCaps, GLADType.GLCanvasOffscreen, GLADType.GLWindow);
}
@Test(timeout=30000)
public void test31GLWindow2GLCanvasOffScrnGL2ES2() throws InterruptedException {
final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2);
if(null == reqGLCaps) return;
- testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOffscreen);
+ final Display dpy = NewtFactory.createDisplay(null);
+ final Screen screen = NewtFactory.createScreen(dpy, 0);
+ screen.addReference();
+ testGLCanvas2GLWindowImpl(screen, reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOffscreen);
+ screen.removeReference();
}
@Test(timeout=30000)
public void test32GLWindow2GLCanvasOffScrnGLES2() throws InterruptedException {
final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2);
if(null == reqGLCaps) return;
- testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOffscreen);
+ final Display dpy = NewtFactory.createDisplay(null);
+ final Screen screen = NewtFactory.createScreen(dpy, 0);
+ screen.addReference();
+ testGLCanvas2GLWindowImpl(screen, reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOffscreen);
+ screen.removeReference();
}
- private void testGLCanvas2GLWindowImpl(GLCapabilities caps, GLADType gladType1, GLADType gladType2) throws InterruptedException {
+ private void testGLCanvas2GLWindowImpl(Screen screen, GLCapabilities caps, GLADType gladType1, GLADType gladType2) throws InterruptedException {
if( !validateOnOffscreenLayer(gladType1, gladType2) ) {
return;
}
@@ -131,18 +158,18 @@ public class TestGLContextDrawableSwitch21Newt2AWT extends GLContextDrawableSwit
// - create glad1 w/o context
// - create context using glad1 and assign it to glad1
{
- testGLADOneLifecycle(caps, gladType1, width, height,
- glelTracker, snapshotGLEventListener,
- null,
- glels, animator);
+ testGLADOneLifecycle(screen, caps, gladType1, width,
+ height, glelTracker,
+ snapshotGLEventListener,
+ null, glels, animator);
}
// - create glad2 w/ survived context
{
- testGLADOneLifecycle(caps, gladType2, width+100, height+100,
- glelTracker, snapshotGLEventListener,
- glels[0],
- null, null);
+ testGLADOneLifecycle(screen, caps, gladType2, width+100,
+ height+100, glelTracker,
+ snapshotGLEventListener,
+ glels[0], null, null);
}
animator.stop();
}