diff options
Diffstat (limited to 'src')
25 files changed, 778 insertions, 386 deletions
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/jogl/classes/com/jogamp/opengl/util/GLDrawableUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLDrawableUtil.java index 68d94d2e2..28349b250 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLDrawableUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLDrawableUtil.java @@ -27,11 +27,13 @@ */ package com.jogamp.opengl.util; +import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.GLAnimatorControl; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; import com.jogamp.opengl.GLEventListenerState; @@ -117,6 +119,7 @@ public class GLDrawableUtil { * </p> * @param a * @param b + * @throws GLException if the {@link AbstractGraphicsDevice} are incompatible w/ each other. */ public static final void swapGLContextAndAllGLEventListener(GLAutoDrawable a, GLAutoDrawable b) { final GLEventListenerState gllsA = GLEventListenerState.moveFrom(a); diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java index 53fe6c3c9..bfa748a54 100644 --- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java +++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java @@ -103,7 +103,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, GLStateKeepe resetFPSCounter(); } - /** Returns the recursive lock object of the upstream implementation, which synchronizes multithreaded access. */ + /** Returns the recursive lock object of the upstream implementation, which synchronizes multithreaded access on top of {@link NativeSurface#lockSurface()}. */ protected abstract RecursiveLock getLock(); @Override diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java index 77e9dc173..8dea10df1 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java @@ -13,6 +13,13 @@ import javax.media.opengl.GLException; import com.jogamp.nativewindow.egl.EGLGraphicsDevice; +/** + * <pre> + * EGLWrappedSurface [ is_a -> WrappedSurface -> ProxySurfaceImpl -> ProxySurface -> MutableSurface -> NativeSurface] has_a + * EGLUpstreamSurfaceHook [ is_a -> UpstreamSurfaceHook.MutableSize -> UpstreamSurfaceHook ] has_a + * NativeSurface (i.e. native X11 surface) + * </pre> + */ public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize { protected static final boolean DEBUG = EGLDrawableFactory.DEBUG; private final NativeSurface upstreamSurface; diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java index 2c2c6cc4b..f816151c7 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java @@ -4,6 +4,13 @@ import javax.media.nativewindow.NativeSurface; import jogamp.nativewindow.WrappedSurface; +/** + * <pre> + * EGLWrappedSurface [ is_a -> WrappedSurface -> ProxySurfaceImpl -> ProxySurface -> MutableSurface -> NativeSurface] has_a + * EGLUpstreamSurfaceHook [ is_a -> UpstreamSurfaceHook.MutableSize -> UpstreamSurfaceHook ] has_a + * NativeSurface (i.e. native X11 surface) + * </pre> + */ public class EGLWrappedSurface extends WrappedSurface { public static EGLWrappedSurface get(NativeSurface surface) { diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java index c3c35ed49..9df042ba8 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -53,6 +53,7 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; +import jogamp.nativewindow.x11.X11Lib; import jogamp.nativewindow.x11.X11Util; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableImpl; @@ -246,6 +247,7 @@ public class X11GLXContext extends GLContextImpl { // critical path, a remote display might not support this command, // hence we need to catch the X11 Error within this block. X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set + X11Lib.XSync(display, false); ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs); } catch (RuntimeException re) { if(DEBUG) { 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/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java index 349da8ee6..1f5d33746 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java @@ -55,6 +55,8 @@ import jogamp.nativewindow.Debug; import com.jogamp.common.os.Platform; import com.jogamp.common.util.VersionNumber; +import com.jogamp.common.util.locks.LockFactory; +import com.jogamp.common.util.locks.RecursiveLock; public class JAWTUtil { public static final boolean DEBUG = Debug.debug("JAWT"); @@ -80,9 +82,7 @@ public class JAWTUtil { private static final Method sunToolkitAWTUnlockMethod; private static final boolean hasSunToolkitAWTLock; - private static volatile Thread exclusiveOwnerThread; - private static int lockCounter; - + private static final RecursiveLock jawtLock; private static final ToolkitLock jawtToolkitLock; private static class PrivilegedDataBlob1 { @@ -232,26 +232,28 @@ public class JAWTUtil { } hasSunToolkitAWTLock = _hasSunToolkitAWTLock; // hasSunToolkitAWTLock = false; - exclusiveOwnerThread = null; - lockCounter = 0; + jawtLock = LockFactory.createRecursiveLock(); - jawtToolkitLock = new ToolkitLock() { + jawtToolkitLock = new ToolkitLock() { public final void lock() { JAWTUtil.lockToolkit(); - if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.lock()"); } } public final void unlock() { - if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.unlock()"); } JAWTUtil.unlockToolkit(); } @Override public final void validateLocked() throws RuntimeException { JAWTUtil.validateLocked(); } + @Override public final void dispose() { // nop - } - }; + } + @Override + public String toString() { + return "JAWTToolkitLock[obj 0x"+Integer.toHexString(hashCode())+", isOwner "+jawtLock.isOwner(Thread.currentThread())+", "+jawtLock+"]"; + } + }; // trigger native AWT toolkit / properties initialization Map<?,?> desktophints = null; @@ -318,80 +320,65 @@ public class JAWTUtil { } /** - * Locks the AWT's global ReentrantLock.<br> - * + * Locks the AWT's global ReentrantLock. + * <p> * JAWT's native Lock() function calls SunToolkit.awtLock(), - * which just uses AWT's global ReentrantLock.<br> + * which just uses AWT's global ReentrantLock. + * </p> + * <p> + * AWT locking is wrapped through a recursive lock object. + * </p> */ - private static final void awtLock() { - if(hasSunToolkitAWTLock) { - try { - sunToolkitAWTLockMethod.invoke(null, (Object[])null); - } catch (Exception e) { - throw new NativeWindowException("SunToolkit.awtLock failed", e); + public static void lockToolkit() throws NativeWindowException { + jawtLock.lock(); + if( 1 == jawtLock.getHoldCount() ) { + if(!headlessMode && !isJava2DQueueFlusherThread()) { + if(hasSunToolkitAWTLock) { + try { + sunToolkitAWTLockMethod.invoke(null, (Object[])null); + } catch (Exception e) { + throw new NativeWindowException("SunToolkit.awtLock failed", e); + } + } else { + jawtLockObject.Lock(); + } } - } else { - jawtLockObject.Lock(); } - if(0 == lockCounter) { - exclusiveOwnerThread = Thread.currentThread(); - } - lockCounter++; + if(ToolkitLock.TRACE_LOCK) { System.err.println("JAWTUtil-ToolkitLock.lock(): "+jawtLock); } } /** - * Unlocks the AWT's global ReentrantLock.<br> - * + * Unlocks the AWT's global ReentrantLock. + * <p> * JAWT's native Unlock() function calls SunToolkit.awtUnlock(), - * which just uses AWT's global ReentrantLock.<br> + * which just uses AWT's global ReentrantLock. + * </p> + * <p> + * AWT unlocking is wrapped through a recursive lock object. + * </p> */ - private static final void awtUnlock() { - awtValidateLocked(); - lockCounter--; - if(0 == lockCounter) { - exclusiveOwnerThread = null; - } - if(hasSunToolkitAWTLock) { - try { - sunToolkitAWTUnlockMethod.invoke(null, (Object[])null); - } catch (Exception e) { - throw new NativeWindowException("SunToolkit.awtUnlock failed", e); - } - } else { - jawtLockObject.Unlock(); - } - } - - private static final void awtValidateLocked() throws RuntimeException { - final Thread ct = Thread.currentThread(); - if( ct != exclusiveOwnerThread ) { - if ( null == exclusiveOwnerThread ) { - throw new RuntimeException(ct.getName()+": JAWT-ToolkitLock not locked"); - } - throw new RuntimeException(ct.getName()+": Not JAWT-ToolkitLock owner. Owner is "+exclusiveOwnerThread.getName()); - } - } - - public static void lockToolkit() throws NativeWindowException { - if(ToolkitLock.TRACE_LOCK) { System.err.println("JAWTUtil-ToolkitLock.lock()"); } - if(!headlessMode && !isJava2DQueueFlusherThread()) { - awtLock(); - } - } - public static void unlockToolkit() { - if(ToolkitLock.TRACE_LOCK) { System.err.println("JAWTUtil-ToolkitLock.unlock()"); } - if(!headlessMode && !isJava2DQueueFlusherThread()) { - awtUnlock(); + jawtLock.validateLocked(); + if(ToolkitLock.TRACE_LOCK) { System.err.println("JAWTUtil-ToolkitLock.unlock(): "+jawtLock); } + if( 1 == jawtLock.getHoldCount() ) { + if(!headlessMode && !isJava2DQueueFlusherThread()) { + if(hasSunToolkitAWTLock) { + try { + sunToolkitAWTUnlockMethod.invoke(null, (Object[])null); + } catch (Exception e) { + throw new NativeWindowException("SunToolkit.awtUnlock failed", e); + } + } else { + jawtLockObject.Unlock(); + } + } } + jawtLock.unlock(); } public static final void validateLocked() throws RuntimeException { - if(!headlessMode && !isJava2DQueueFlusherThread()) { - awtValidateLocked(); - } - } - + jawtLock.validateLocked(); + } public static ToolkitLock getJAWTToolkitLock() { return jawtToolkitLock; diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR.java b/src/newt/classes/jogamp/newt/driver/x11/RandR.java new file mode 100644 index 000000000..485d976ec --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR.java @@ -0,0 +1,39 @@ +/** + * 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 jogamp.newt.driver.x11; + +import com.jogamp.newt.ScreenMode; + +public interface RandR { + + int[] getScreenModeFirstImpl(final long dpy, final int screen_idx); + int[] getScreenModeNextImpl(final long dpy, final int screen_idx); + ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx); + boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx); + +} diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR11.java b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java index e8a616b99..ee67bd304 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR11.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java @@ -1,3 +1,30 @@ +/** + * 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 jogamp.newt.driver.x11; import jogamp.newt.ScreenImpl; @@ -5,7 +32,7 @@ import jogamp.newt.ScreenImpl; import com.jogamp.newt.ScreenMode; import com.jogamp.newt.util.ScreenModeUtil; -public class ScreenRandR11 implements ScreenRandR { +public class RandR11 implements RandR { private static final boolean DEBUG = ScreenDriver.DEBUG; private int[] nrotations; diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java new file mode 100644 index 000000000..24c9806af --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java @@ -0,0 +1,51 @@ +/** + * 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 jogamp.newt.driver.x11; + +import com.jogamp.newt.ScreenMode; + +public class RandR13 implements RandR { + + public int[] getScreenModeFirstImpl(final long dpy, final int screen_idx) { + return null; + } + public int[] getScreenModeNextImpl(final long dpy, final int screen_idx) { + return null; + } + public ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx) { + return null; + } + + public boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx) { + return false; + } + + private static native long getScreenResources0(long display, int screen_index); + private static native void freeScreenResources0(long screenConfiguration); + +} diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java index d94f27371..cd8da9b60 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java @@ -73,11 +73,13 @@ public class ScreenDriver extends ScreenImpl { int v[] = getRandRVersion0(dpy); randrVersion = new VersionNumber(v[0], v[1], 0); } - System.err.println("RandR "+randrVersion); + if( DEBUG ) { + System.err.println("RandR "+randrVersion); + } if( !randrVersion.isZero() ) { - screenRandR = new ScreenRandR11(); + rAndR = new RandR11(); } else { - screenRandR = null; + rAndR = null; } } @@ -85,42 +87,42 @@ public class ScreenDriver extends ScreenImpl { } private VersionNumber randrVersion; - private ScreenRandR screenRandR; + private RandR rAndR; @Override protected int[] getScreenModeFirstImpl() { - if( null == screenRandR ) { return null; } + if( null == rAndR ) { return null; } return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() { public int[] run(long dpy) { - return screenRandR.getScreenModeFirstImpl(dpy, screen_idx); + return rAndR.getScreenModeFirstImpl(dpy, screen_idx); } } ); } @Override protected int[] getScreenModeNextImpl() { - if( null == screenRandR ) { return null; } + if( null == rAndR ) { return null; } // assemble: w x h x bpp x f x r return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() { public int[] run(long dpy) { - return screenRandR.getScreenModeNextImpl(dpy, screen_idx); + return rAndR.getScreenModeNextImpl(dpy, screen_idx); } } ); } @Override protected ScreenMode getCurrentScreenModeImpl() { - if( null == screenRandR ) { return null; } + if( null == rAndR ) { return null; } return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<ScreenMode>() { public ScreenMode run(long dpy) { - return screenRandR.getCurrentScreenModeImpl(dpy, screen_idx); + return rAndR.getCurrentScreenModeImpl(dpy, screen_idx); } } ); } @Override protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) { - if( null == screenRandR ) { return false; } + if( null == rAndR ) { return false; } final List<ScreenMode> screenModes = this.getScreenModesOrig(); final int screenModeIdx = screenModes.indexOf(screenMode); @@ -131,7 +133,7 @@ public class ScreenDriver extends ScreenImpl { boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() { public Boolean run(long dpy) { final int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); - return Boolean.valueOf( screenRandR.setCurrentScreenModeImpl(dpy, screen_idx, screenMode, screenModeIdx, resIdx) ); + return Boolean.valueOf( rAndR.setCurrentScreenModeImpl(dpy, screen_idx, screenMode, screenModeIdx, resIdx) ); } }).booleanValue(); diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR.java deleted file mode 100644 index abf20ba59..000000000 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR.java +++ /dev/null @@ -1,12 +0,0 @@ -package jogamp.newt.driver.x11; - -import com.jogamp.newt.ScreenMode; - -public interface ScreenRandR { - - int[] getScreenModeFirstImpl(final long dpy, final int screen_idx); - int[] getScreenModeNextImpl(final long dpy, final int screen_idx); - ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx); - boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx); - -} diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h index 7f35216e3..e58cdb755 100644 --- a/src/newt/native/X11Common.h +++ b/src/newt/native/X11Common.h @@ -47,7 +47,8 @@ #include "jogamp_newt_driver_x11_DisplayDriver.h" #include "jogamp_newt_driver_x11_ScreenDriver.h" -#include "jogamp_newt_driver_x11_ScreenRandR11.h" +#include "jogamp_newt_driver_x11_RandR11.h" +#include "jogamp_newt_driver_x11_RandR13.h" #include "jogamp_newt_driver_x11_WindowDriver.h" #include "Window.h" diff --git a/src/newt/native/X11ScreenRandR11.c b/src/newt/native/X11RandR11.c index a457fd47b..cbf911a38 100644 --- a/src/newt/native/X11ScreenRandR11.c +++ b/src/newt/native/X11RandR11.c @@ -29,11 +29,11 @@ #include "X11Screen.h" /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: getAvailableScreenModeRotations0 * Signature: (JI)I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getAvailableScreenModeRotations0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getAvailableScreenModeRotations0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -43,11 +43,6 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getAvailab int rotations[4]; int major, minor; - if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) { - fprintf(stderr, "RANDR not available\n"); - return (*env)->NewIntArray(env, 0); - } - rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation); if(0 != (rotations_supported & RR_Rotate_0)) { @@ -79,11 +74,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getAvailab } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: getNumScreenModeResolution0 * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getNumScreenModeResolutions0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenModeResolutions0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -93,11 +88,6 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getNumScreenMod timespec_now(&t0); #endif - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_getNumScreenModeResolutions0: RANDR not available\n"); - return 0; - } - #ifdef DBG_PERF timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL); @@ -117,20 +107,15 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getNumScreenMod } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: getScreenModeResolutions0 * Signature: (JII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenModeResolution0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenModeResolution0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) { Display *dpy = (Display *) (intptr_t) display; - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenModeResolution0: RANDR not available\n"); - return (*env)->NewIntArray(env, 0); - } - int num_sizes; XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions @@ -159,20 +144,15 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenM } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: getScreenModeRates0 * Signature: (JII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenModeRates0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenModeRates0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) { Display *dpy = (Display *) (intptr_t) display; - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenModeRates0: RANDR not available\n"); - return (*env)->NewIntArray(env, 0); - } - int num_sizes; XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions @@ -202,11 +182,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenM } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: getScreenConfiguration0 * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenConfiguration0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenConfiguration0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -217,10 +197,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenConfi timespec_now(&t0); #endif - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenConfiguration0: RANDR not available\n"); - return 0; - } #ifdef DBG_PERF timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); fprintf(stderr, "X11Screen_getScreenConfiguration0.1: %ld ms\n", td_ms); fflush(NULL); @@ -237,22 +213,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenConfi } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: freeScreenConfiguration0 * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_freeScreenConfiguration0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR11_freeScreenConfiguration0 (JNIEnv *env, jclass clazz, jlong screenConfiguration) { XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration ); } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: getCurrentScreenRate0 * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScreenRate0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getCurrentScreenRate0 (JNIEnv *env, jclass clazz, jlong screenConfiguration) { XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; @@ -264,11 +240,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScree } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: getCurrentScreenRotation0 * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScreenRotation0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getCurrentScreenRotation0 (JNIEnv *env, jclass clazz, jlong screenConfiguration) { XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; @@ -281,11 +257,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScree /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: getCurrentScreenResolutionIndex0 * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScreenResolutionIndex0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getCurrentScreenResolutionIndex0 (JNIEnv *env, jclass clazz, jlong screenConfiguration) { XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; @@ -300,11 +276,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScree } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: setCurrentScreenModeStart0 * Signature: (JIJIII)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_setCurrentScreenModeStart0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR11_setCurrentScreenModeStart0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation) { Display *dpy = (Display *) (intptr_t) display; @@ -349,11 +325,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_setCurrentS } /* - * Class: jogamp_newt_driver_x11_ScreenRandR11 + * Class: jogamp_newt_driver_x11_RandR11 * Method: setCurrentScreenModePollEnd0 * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_setCurrentScreenModePollEnd0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR11_setCurrentScreenModePollEnd0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation) { Display *dpy = (Display *) (intptr_t) display; @@ -361,11 +337,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_setCurrentS XEvent evt; XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt; - if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_setCurrentScreenModePollEnd0: RANDR not available\n"); - return JNI_FALSE; - } - int num_sizes; XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions XRRScreenConfiguration *conf; diff --git a/src/newt/native/X11ScreenRandR13.c b/src/newt/native/X11RandR13.c index da90d15c9..ea72cd35d 100644 --- a/src/newt/native/X11ScreenRandR13.c +++ b/src/newt/native/X11RandR13.c @@ -28,7 +28,48 @@ #include "X11Common.h" -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getOrigin0_RandR13 +/* + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getScreenResources0 + * Signature: (JI)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenResources0 + (JNIEnv *env, jclass clazz, jlong display, jint screen_idx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)screen_idx); +#ifdef DBG_PERF + struct timespec t0, t1, td; + long td_ms; + timespec_now(&t0); +#endif + +#ifdef DBG_PERF + timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); + fprintf(stderr, "X11Screen_getScreenResources0.1: %ld ms\n", td_ms); fflush(NULL); +#endif + + XRRScreenResources *res = XRRGetScreenResourcesCurrent( dpy, root); +#ifdef DBG_PERF + timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); + fprintf(stderr, "X11Screen_getScreenResources0.2 (XRRScreenResources): %ld ms\n", td_ms); fflush(NULL); +#endif + + return (jlong) (intptr_t) res; +} + +/* + * Class: jogamp_newt_driver_x11_RandR13 + * Method: freeScreenResources0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_freeScreenResources0 + (JNIEnv *env, jclass clazz, jlong screenResources) +{ + XRRFreeScreenResources( (XRRScreenResources *) (intptr_t) screenResources ); +} + +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getOrigin0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display * dpy = (Display *) (intptr_t) display; @@ -55,7 +96,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getOrigin0_ return jpos; } -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0_RandR13 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableScreenModeRotations0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -65,11 +106,6 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailabl int rotations[4]; int major, minor; - if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) { - fprintf(stderr, "RANDR not available\n"); - return (*env)->NewIntArray(env, 0); - } - rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation); if(0 != (rotations_supported & RR_Rotate_0)) { @@ -100,7 +136,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailabl return properties; } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0_RandR13 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getNumScreenModeResolutions0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -131,11 +167,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenMode } /* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getScreenModeResolutions0_RandR13 + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getScreenModeResolutions0 * Signature: (JII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0_RandR13 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenModeResolution0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -168,11 +204,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenMo } /* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getScreenModeRates0_RandR13 + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getScreenModeRates0 * Signature: (JII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0_RandR13 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenModeRates0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -206,11 +242,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenMo } /* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getCurrentScreenRate0_RandR13 + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getCurrentScreenRate0 * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0_RandR13 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenRate0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -229,11 +265,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreen } /* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getCurrentScreenRotation0_RandR13 + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getCurrentScreenRotation0 * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0_RandR13 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenRotation0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -253,11 +289,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreen /* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: getCurrentScreenResolutionIndex0_RandR13 + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getCurrentScreenResolutionIndex0 * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0_RandR13 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenResolutionIndex0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -278,11 +314,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreen } /* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: setCurrentScreenModeStart0_RandR13 + * Class: jogamp_newt_driver_x11_RandR13 + * Method: setCurrentScreenModeStart0 * Signature: (JIIII)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0_RandR13 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setCurrentScreenModeStart0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation) { Display *dpy = (Display *) (intptr_t) display; @@ -318,11 +354,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentSc } /* - * Class: jogamp_newt_driver_x11_ScreenDriver - * Method: setCurrentScreenModePollEnd0_RandR13 + * Class: jogamp_newt_driver_x11_RandR13 + * Method: setCurrentScreenModePollEnd0 * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0_RandR13 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setCurrentScreenModePollEnd0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation) { Display *dpy = (Display *) (intptr_t) display; diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c index 69a06aad0..3d4b2a26c 100644 --- a/src/newt/native/X11Screen.c +++ b/src/newt/native/X11Screen.c @@ -74,24 +74,6 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getHeight0 return (jint) DisplayHeight( dpy, scrn_idx); } -static int showedRandRVersion = 0; - -Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) { - if( 0 == XRRQueryVersion(dpy, major, minor) ) { - return False; - } - if(0 == showedRandRVersion) { - DBG_PRINT("X11 RandR Version %d.%d\n", *major, *minor); - showedRandRVersion = 1; - } - return True; -} - -Bool NewtScreen_hasRANDR(Display *dpy) { - int major, minor; - return NewtScreen_getRANDRVersion(dpy, &major, &minor); -} - int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) { int rot; if(xrotation == RR_Rotate_0) { @@ -121,8 +103,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getRandRVer { Display * dpy = (Display *)(intptr_t)display; jint version[2]; - Bool res = NewtScreen_getRANDRVersion(dpy, &version[0], &version[1]); - if( False == res ) { + if( 0 == XRRQueryVersion(dpy, &version[0], &version[1] ) ) { version[0] = 0; version[1] = 0; } diff --git a/src/newt/native/X11Screen.h b/src/newt/native/X11Screen.h index a5b8e3e70..1a1440054 100644 --- a/src/newt/native/X11Screen.h +++ b/src/newt/native/X11Screen.h @@ -32,8 +32,6 @@ #include "X11Common.h" -Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor); -Bool NewtScreen_hasRANDR(Display *dpy); int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation); #endif /* _X11SCREEN_H */ 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(); } |