diff options
Diffstat (limited to 'src')
99 files changed, 1758 insertions, 804 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java index 219d9f4dd..3d4c601fe 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java @@ -122,7 +122,7 @@ public abstract class GLContextImpl extends GLContext { if(DEBUG) { String sgl1 = (null!=this.gl)?this.gl.getClass().toString()+", "+this.gl.toString():"<null>"; String sgl2 = (null!=gl)?gl.getClass().toString()+", "+gl.toString():"<null>"; - Exception e = new Exception("setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread()+", "+sgl1+" -> "+sgl2); + Exception e = new Exception("Info: setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread()+", "+sgl1+" -> "+sgl2); e.printStackTrace(); } this.gl = gl; @@ -1053,7 +1053,7 @@ public abstract class GLContextImpl extends GLContext { e.printStackTrace(); // FIXME: refactor desktop OpenGL dependencies and make this // class work properly for OpenGL ES - System.err.println("ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: "+e); + System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: "+e); major = 1; minor = 0; /* diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java index 1cde00102..c0e554889 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java @@ -69,28 +69,34 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { } AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilities caps = (GLCapabilities) config.getChosenCapabilities(); + AbstractGraphicsDevice adevice = config.getScreen().getDevice(); GLDrawable result = null; - if(caps.isOnscreen()) { - if(DEBUG) { - System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target); - } - result = createOnscreenDrawable(target); - } else { - if( ! ( target instanceof SurfaceChangeable ) ) { - throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target); - } - if(caps.isPBuffer()) { + adevice.lock(); + try { + if(caps.isOnscreen()) { if(DEBUG) { - System.err.println("GLDrawableFactoryImpl.createGLDrawable -> PbufferDrawable: "+target); + System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target); } - result = createGLPbufferDrawable(target); - } - if(null==result) { - if(DEBUG) { - System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable: "+target); + result = createOnscreenDrawableImpl(target); + } else { + if( ! ( target instanceof SurfaceChangeable ) ) { + throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target); + } + if(caps.isPBuffer() && canCreateGLPbuffer(adevice)) { + if(DEBUG) { + System.err.println("GLDrawableFactoryImpl.createGLDrawable -> PbufferDrawable: "+target); + } + result = createGLPbufferDrawable(target); + } + if(null==result) { + if(DEBUG) { + System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable: "+target); + } + result = createOffscreenDrawableImpl(target); } - result = createOffscreenDrawable(target); } + } finally { + adevice.unlock(); } if(DEBUG) { System.err.println("GLDrawableFactoryImpl.createGLDrawable: "+result); @@ -103,23 +109,25 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { // Onscreen GLDrawable construction // - protected abstract GLDrawableImpl createOnscreenDrawable(NativeSurface target); + protected abstract GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target); //--------------------------------------------------------------------------- // // PBuffer GLDrawable construction // + public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device); + /** Target must implement SurfaceChangeable */ protected abstract GLDrawableImpl createGLPbufferDrawableImpl(NativeSurface target); - protected GLDrawableImpl createGLPbufferDrawable(NativeSurface target) { + private GLDrawableImpl createGLPbufferDrawable(NativeSurface target) { if (!canCreateGLPbuffer(target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice())) { throw new GLException("Pbuffer support not available with current graphics card"); } return createGLPbufferDrawableImpl(target); } - + public GLDrawable createGLPbufferDrawable(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, @@ -131,7 +139,12 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { capabilities.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN capabilities.setOnscreen(false); capabilities.setPBuffer(true); - return createGLPbufferDrawable( createOffscreenSurface(capabilities, chooser, height, height) ); + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + return createGLPbufferDrawable( createOffscreenSurfaceImpl(capabilities, chooser, height, height) ); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } } public GLPbuffer createGLPbuffer(GLCapabilities capabilities, @@ -149,7 +162,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { // Offscreen GLDrawable construction // - protected abstract GLDrawableImpl createOffscreenDrawable(NativeSurface target) ; + protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ; public GLDrawable createOffscreenDrawable(GLCapabilities capabilities, GLCapabilitiesChooser chooser, @@ -162,16 +175,53 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { capabilities.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN capabilities.setOnscreen(false); capabilities.setPBuffer(false); - return createOffscreenDrawable( createOffscreenSurface(capabilities, chooser, width, height) ); + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + return createOffscreenDrawableImpl( createOffscreenSurfaceImpl(capabilities, chooser, width, height) ); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } } /** * creates an offscreen NativeSurface, which must implement SurfaceChangeable as well, * so the windowing system related implementation is able to set the surface handle. */ - protected abstract NativeSurface createOffscreenSurface(GLCapabilities capabilities, GLCapabilitiesChooser chooser, + protected abstract NativeSurface createOffscreenSurfaceImpl(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height); + //--------------------------------------------------------------------------- + // + // External GLDrawable construction + // + + protected abstract GLContext createExternalGLContextImpl(); + + public GLContext createExternalGLContext() { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + return createExternalGLContextImpl(); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + protected abstract GLDrawable createExternalGLDrawableImpl(); + + public GLDrawable createExternalGLDrawable() { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + return createExternalGLDrawableImpl(); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + + //--------------------------------------------------------------------------- + // + // GLDrawableFactoryImpl details + // protected abstract GLDrawableImpl getSharedDrawable(); protected abstract GLContextImpl getSharedContext(); protected abstract void shutdown(); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java index 19e637cab..e68ee3644 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java @@ -67,6 +67,14 @@ public abstract class GLDrawableImpl implements GLDrawable { /** For offscreen GLDrawables (pbuffers and "pixmap" drawables), indicates that native resources should be reclaimed. */ public void destroy() { + surface.getGraphicsConfiguration().getScreen().getDevice().lock(); + try { + destroyImpl(); + } finally { + surface.getGraphicsConfiguration().getScreen().getDevice().unlock(); + } + } + protected void destroyImpl() { throw new GLException("Should not call this (should only be called for offscreen GLDrawables)"); } @@ -129,35 +137,41 @@ public abstract class GLDrawableImpl implements GLDrawable { return factory; } - public final void setRealized(boolean realized) { - if ( this.realized != realized ) { + public final synchronized void setRealized(boolean realizedArg) { + if ( realized != realizedArg ) { if(DEBUG) { - System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" -> "+realized); + System.err.println("setRealized: "+getClass().getName()+" "+realized+" -> "+realizedArg); } - this.realized = realized; - if(realized && NativeSurface.LOCK_SURFACE_NOT_READY == lockSurface()) { - throw new GLException("X11GLXDrawable.setRealized(true): lockSurface - surface not ready"); - } - try { - AbstractGraphicsDevice aDevice = getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(); - if(!realized) { - destroyHandle(); + realized = realizedArg; + AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice(); + if(realizedArg) { + if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) { + throw new GLException("X11GLXDrawable.setRealized(true): already realized, but surface not ready (lockSurface)"); } + } else { + aDevice.lock(); + } + try { setRealizedImpl(); - if(realized) { + if(realizedArg) { updateHandle(); + } else { + destroyHandle(); } } finally { - if(realized) { + if(realizedArg) { unlockSurface(); + } else { + aDevice.unlock(); } } } else if(DEBUG) { - System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" == "+realized); + System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" == "+realizedArg); } } protected abstract void setRealizedImpl(); - public boolean isRealized() { + + public synchronized boolean isRealized() { return realized; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java index e2c217ac0..7a30f9a6f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java @@ -49,7 +49,7 @@ import java.beans.PropertyChangeListener; import javax.media.nativewindow.*; import javax.media.opengl.*; -import com.jogamp.common.util.RecursiveToolkitLock; +import com.jogamp.common.util.locks.RecursiveLock; /** Platform-independent class exposing pbuffer functionality to applications. This class is not exposed in the public API as it @@ -216,7 +216,7 @@ public class GLPbufferImpl implements GLPbuffer { return pbufferDrawable.getGLProfile(); } - private RecursiveToolkitLock recurLock = new RecursiveToolkitLock(); + private RecursiveLock recurLock = new RecursiveLock(); public int lockSurface() throws GLException { recurLock.lock(); @@ -231,7 +231,7 @@ public class GLPbufferImpl implements GLPbuffer { return recurLock.isLocked(); } - public Exception getLockedStack() { + public Throwable getLockedStack() { return recurLock.getLockedStack(); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java b/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java index 768eea3f7..c292de778 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java @@ -254,7 +254,7 @@ public class GLWorkerThread { Runnable curAsync = (Runnable) queue.remove(0); curAsync.run(); } catch (Throwable t) { - System.out.println("Exception occurred on JOGL OpenGL worker thread:"); + System.err.println("Exception occurred on JOGL OpenGL worker thread:"); t.printStackTrace(); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java index e5570a8ee..36c0a3250 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java @@ -117,9 +117,4 @@ public class AWTUtil { } } } - - public static boolean isToolkitLocked() { - return JAWTUtil.isToolkitLocked(); - } - } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java index b871c66a7..d8f83a5f7 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java @@ -178,7 +178,7 @@ public class Java2D { fbObjectSupportInitialized = false; if (DEBUG && VERBOSE) { e.printStackTrace(); - System.err.println("Disabling Java2D/JOGL FBO support"); + System.err.println("Info: Disabling Java2D/JOGL FBO support"); } } @@ -192,7 +192,7 @@ public class Java2D { } catch (Exception e) { if (DEBUG && VERBOSE) { e.printStackTrace(); - System.err.println("GL_ARB_texture_rectangle FBO support disabled"); + System.err.println("Info: GL_ARB_texture_rectangle FBO support disabled"); } } @@ -205,7 +205,7 @@ public class Java2D { } catch (Exception e) { if (DEBUG && VERBOSE) { e.printStackTrace(); - System.err.println("Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X"); + System.err.println("Info: Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X"); } } if (cglSurfaceData != null) { @@ -236,7 +236,7 @@ public class Java2D { } catch (Exception e) { if (DEBUG && VERBOSE) { e.printStackTrace(); - System.err.println("Disabling Java2D/JOGL integration"); + System.err.println("Info: Disabling Java2D/JOGL integration"); } isOGLPipelineActive = false; } @@ -265,7 +265,7 @@ public class Java2D { checkActive(); try { - return ((Boolean) isQueueFlusherThreadMethod.invoke(null, new Object[] {})).booleanValue(); + return ((Boolean) isQueueFlusherThreadMethod.invoke(null, null)).booleanValue(); } catch (InvocationTargetException e) { throw new GLException(e.getTargetException()); } catch (Exception e) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java index b1084dd8f..83e85b922 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java @@ -115,14 +115,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { protected final GLDrawableImpl getSharedDrawable() { return null; } protected final GLContextImpl getSharedContext() { return null; } - public GLDrawableImpl createOnscreenDrawable(NativeSurface target) { + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } return new EGLOnscreenDrawable(this, target); } - protected GLDrawableImpl createOffscreenDrawable(NativeSurface target) { + protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { throw new GLException("Not yet implemented"); } @@ -134,13 +134,13 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return new EGLPbufferDrawable(this, target); } - protected NativeSurface createOffscreenSurface(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { + protected NativeSurface createOffscreenSurfaceImpl(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { ProxySurface ns = new ProxySurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(capabilities, chooser)); ns.setSize(width, height); return ns; } - public GLContext createExternalGLContext() { + protected GLContext createExternalGLContextImpl() { AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createScreenDevice(0); return new EGLExternalContext(absScreen); } @@ -149,7 +149,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return false; } - public GLDrawable createExternalGLDrawable() { + protected GLDrawable createExternalGLDrawableImpl() { throw new GLException("Not yet implemented"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java index 33e301ee9..88e8a9ed1 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java @@ -53,9 +53,8 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.egl.EGLGraphicsDevice.class, this); } - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen) { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl ( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { if (absScreen == null) { throw new IllegalArgumentException("This NativeWindowFactory accepts only AbstractGraphicsDevice objects"); } @@ -75,7 +74,7 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor absScreen); } - public static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities capabilities, + private static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities capabilities, GLCapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { if (capabilities == null) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index 396d6aefc..47e0e656f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -80,7 +80,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { try { ReflectionUtil.createInstance("com.jogamp.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory", - new Object[] {}, getClass().getClassLoader()); + null, getClass().getClassLoader()); } catch (JogampRuntimeException jre) { /* n/a .. */ } } @@ -88,14 +88,14 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { protected final GLDrawableImpl getSharedDrawable() { return null; } protected final GLContextImpl getSharedContext() { return null; } - public GLDrawableImpl createOnscreenDrawable(NativeSurface target) { + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } return new MacOSXOnscreenCGLDrawable(this, target); } - protected GLDrawableImpl createOffscreenDrawable(NativeSurface target) { + protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { return new MacOSXOffscreenCGLDrawable(this, target); } @@ -120,14 +120,14 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { return new MacOSXPbufferCGLDrawable(this, target); } - protected NativeSurface createOffscreenSurface(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { + protected NativeSurface createOffscreenSurfaceImpl(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(); ProxySurface ns = new ProxySurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, screen, true)); ns.setSize(width, height); return ns; } - public GLContext createExternalGLContext() { + protected GLContext createExternalGLContextImpl() { return MacOSXExternalCGLContext.create(this, null); } @@ -135,7 +135,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { return false; } - public GLDrawable createExternalGLDrawable() { + protected GLDrawable createExternalGLDrawableImpl() { // FIXME throw new GLException("Not yet implemented"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java index ada5fb1a7..69bb245e1 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java @@ -51,9 +51,8 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GraphicsConfiguration GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.macosx.MacOSXGraphicsDevice.class, this); } - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen) { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen, false); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java index bc470383f..14ed02918 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java @@ -77,7 +77,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { if(realized) { createPbuffer(); } else { - destroy(); + destroyImpl(); } } @@ -85,7 +85,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { return new MacOSXPbufferCGLContext(this, shareWith); } - public void destroy() { + protected void destroyImpl() { if (this.pBuffer != 0) { NativeSurface ns = getNativeSurface(); impl.destroy(pBuffer); @@ -185,7 +185,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { if (haveSetOpenGLMode) { throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once"); } - destroy(); + destroyImpl(); openGLMode = mode; haveSetOpenGLMode = true; if (DEBUG) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java index 0d59da32e..6a9617d27 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java @@ -53,9 +53,8 @@ public class MacOSXAWTCGLGraphicsConfigurationFactory extends GraphicsConfigurat GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this); } - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen) { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { GraphicsDevice device = null; if (absScreen != null && !(absScreen instanceof AWTGraphicsScreen)) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java index 299adec50..9a86f7d08 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java @@ -89,7 +89,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { return new WindowsWGLContext(this, shareWith); } - public void destroy() { + protected void destroyImpl() { if (hdc != 0) { GDI.ReleaseDC(hwnd, hdc); hdc = 0; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java index ea02a4919..f58d2f4bc 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java @@ -48,7 +48,7 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { private long origbitmap; private long hbitmap; - public WindowsOffscreenWGLDrawable(GLDrawableFactory factory, NativeSurface target) { + protected WindowsOffscreenWGLDrawable(GLDrawableFactory factory, NativeSurface target) { super(factory, target, true); create(); } @@ -57,7 +57,7 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { if(realized) { create(); } else { - destroy(); + destroyImpl(); } } @@ -113,11 +113,10 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { hdc = 0; throw new GLException("Error selecting bitmap into new device context"); } - config.updateGraphicsConfiguration(getFactory(), ns); } - public void destroy() { + protected void destroyImpl() { NativeSurface ns = getNativeSurface(); if (ns.getSurfaceHandle() != 0) { // Must destroy bitmap and device context diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index 5708aa6bb..0198f334c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -72,7 +72,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { if(realized) { throw new GLException("Recreation via setRealized not supported."); } else { - destroy(); + destroyImpl(); } } @@ -80,7 +80,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { return new WindowsPbufferWGLContext(this, shareWith); } - public void destroy() { + protected void destroyImpl() { NativeSurface ns = getNativeSurface(); if(0!=buffer) { WGLExt wglExt = cachedWGLExt; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java index c80e46cc2..65a8e8ac3 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -298,7 +298,7 @@ public class WindowsWGLContext extends GLContextImpl { if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { throw new GLException("Error making context current: 0x" + toHexString(contextHandle) + ", werr: 0x" + Integer.toHexString(GDI.GetLastError()) + ", " + this); } else { - if (DEBUG && VERBOSE) { + if (DEBUG && (VERBOSE || newCreated)) { System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getHandle()) + ", contextHandle " + toHexString(contextHandle) + ") succeeded"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index aafea36fd..409e914b0 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -82,9 +82,10 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { new WindowsWGLGraphicsConfigurationFactory(); try { ReflectionUtil.createInstance("com.jogamp.opengl.impl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory", - new Object[] {}, getClass().getClassLoader()); + null, getClass().getClassLoader()); } catch (JogampRuntimeException jre) { /* n/a .. */ } + NativeWindowFactory.getDefaultToolkitLock().lock(); // OK try { sharedDrawable = new WindowsDummyWGLDrawable(this, null); WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null); @@ -94,6 +95,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { sharedContext = ctx; } catch (Throwable t) { throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK } if(null==sharedContext) { throw new GLException("WindowsWGLDrawableFactory - Shared Context is null"); @@ -135,14 +138,14 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } } - public GLDrawableImpl createOnscreenDrawable(NativeSurface target) { + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } return new WindowsOnscreenWGLDrawable(this, target); } - protected GLDrawableImpl createOffscreenDrawable(NativeSurface target) { + protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } @@ -185,7 +188,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return (GLDrawableImpl) returnList.get(0); } - protected NativeSurface createOffscreenSurface(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { + protected NativeSurface createOffscreenSurfaceImpl(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(); ProxySurface ns = new ProxySurface(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( capabilities, chooser, screen) ); @@ -193,7 +196,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return ns; } - public GLContext createExternalGLContext() { + protected GLContext createExternalGLContextImpl() { return WindowsExternalWGLContext.create(this, null); } @@ -201,7 +204,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return true; } - public GLDrawable createExternalGLDrawable() { + protected GLDrawable createExternalGLDrawableImpl() { return WindowsExternalWGLDrawable.create(this, null); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index ae12d254a..c8ecb2b72 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -52,9 +52,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this); } - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen) { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { GLCapabilities caps = (GLCapabilities)capabilities; return chooseGraphicsConfigurationStatic(caps, chooser, absScreen); } @@ -107,10 +106,12 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio GLProfile glProfile = capabilities.getGLProfile(); long hdc = ns.getSurfaceHandle(); - if (DEBUG) { - Exception ex = new Exception("WindowsWGLGraphicsConfigurationFactory got HDC "+toHexString(hdc)); + if(0==hdc) { + throw new GLException("Error: HDC is null "+toHexString(hdc)); + } + if(DEBUG) { + Exception ex = new Exception("Info: WindowsWGLGraphicsConfigurationFactory got HDC "+toHexString(hdc)); ex.printStackTrace(); - System.err.println("WindowsWGLGraphicsConfigurationFactory got NW "+ns); } PIXELFORMATDESCRIPTOR pfd = null; @@ -120,7 +121,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio if (onscreen) { if ((pixelFormat = GDI.GetPixelFormat(hdc)) != 0) { - // Pixelformat already set by either + // Pixelformat already set by either // - a previous updateGraphicsConfiguration() call on the same HDC, // - the graphics driver, copying the HDC's pixelformat to the new one, // - or the Java2D/OpenGL pipeline's configuration diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java index 02cfd14c3..26704acf3 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java @@ -53,9 +53,8 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigura GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this); } - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen) { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { GraphicsDevice device = null; if (absScreen != null && !(absScreen instanceof AWTGraphicsScreen)) { @@ -107,8 +106,7 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigura if(DEBUG) { System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: chosen "+winConfig); } - - // FIXME: we have nothing to match .. so choose the default + return new AWTGraphicsConfiguration(awtScreen, winConfig.getChosenCapabilities(), winConfig.getRequestedCapabilities(), gc, winConfig); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java index 690bc4b52..e77735637 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java @@ -57,7 +57,7 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { int scrn = screen.getIndex(); long visualID = config.getVisualID(); - dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID); + dummyWindow = X11Util.CreateDummyWindow(dpy, scrn, visualID); ns.setSurfaceHandle( dummyWindow ); updateHandle(); @@ -74,11 +74,11 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { return 1; } - public void destroy() { + protected void destroyImpl() { if(0!=dummyWindow) { destroyHandle(); X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - X11Lib.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow); + X11Util.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java index 494860c5b..21de61ff8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -119,7 +119,7 @@ public abstract class X11GLXContext extends GLContextImpl { } } catch (RuntimeException re) { if(DEBUG) { - System.err.println("X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+ + System.err.println("Warning: X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+ "dpy "+toHexString(dpy)+ ", write "+toHexString(writeDrawable)+ ", read "+toHexString(readDrawable)+ @@ -191,7 +191,7 @@ public abstract class X11GLXContext extends GLContextImpl { ctx = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); } catch (RuntimeException re) { if(DEBUG) { - System.err.println("X11GLXContext.createContextARB glXCreateContextAttribsARB failed: "+re+", with "+getGLVersion(major, minor, ctp, "@creation")); + System.err.println("Warning: X11GLXContext.createContextARB glXCreateContextAttribsARB failed: "+re+", with "+getGLVersion(major, minor, ctp, "@creation")); re.printStackTrace(); } } @@ -335,7 +335,7 @@ public abstract class X11GLXContext extends GLContextImpl { if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { throw new GLException("Error making context current: "+this); } - if (DEBUG && (VERBOSE || isCreated())) { + if (DEBUG && (VERBOSE || newCreated)) { System.err.println(getThreadName() + ": glXMakeCurrent(display " + toHexString(dpy)+ ", drawable " + toHexString(drawable.getHandle()) + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 4b84227c3..adf4d8e0d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -53,8 +53,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper x11GLXDynamicLookupHelper; static { - X11Util.initSingleton(); // ensure it's loaded and setup - DesktopGLDynamicLookupHelper tmp = null; try { tmp = new DesktopGLDynamicLookupHelper(new X11GLXDynamicLibraryBundleInfo()); @@ -80,35 +78,45 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { new X11GLXGraphicsConfigurationFactory(); try { ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory", - new Object[] {}, getClass().getClassLoader()); + null, getClass().getClassLoader()); } catch (JogampRuntimeException jre) { /* n/a .. */ } // init shared resources .. - long tlsDisplay = X11Util.createThreadLocalDisplay(null); - X11GraphicsDevice sharedDevice = new X11GraphicsDevice(tlsDisplay); - vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); - isVendorATI = GLXUtil.isVendorATI(vendorName); - isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); - sharedScreen = new X11GraphicsScreen(sharedDevice, 0); - sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault()); - if(isVendorATI() && GLProfile.isAWTAvailable()) { - X11Util.markThreadLocalDisplayUncloseable(tlsDisplay); // failure to close with ATI and AWT usage - } - if(null==sharedScreen || null==sharedDrawable) { - throw new GLException("Couldn't init shared screen("+sharedScreen+")/drawable("+sharedDrawable+")"); - } - // We have to keep this within this thread, - // since we have a 'chicken-and-egg' problem otherwise on the <init> lock of this thread. - try{ - X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); - ctx.makeCurrent(); - ctx.release(); - sharedContext = ctx; - } catch (Throwable t) { - throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t); - } - if(null==sharedContext) { - throw new GLException("X11GLXDrawableFactory - Shared Context is null"); + NativeWindowFactory.getDefaultToolkitLock().lock(); // OK + try { + long tlsDisplay = X11Util.createThreadLocalDisplay(null); + X11Util.XLockDisplay(tlsDisplay); + try { + X11GraphicsDevice sharedDevice = new X11GraphicsDevice(tlsDisplay); + vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); + isVendorATI = GLXUtil.isVendorATI(vendorName); + isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); + sharedScreen = new X11GraphicsScreen(sharedDevice, 0); + sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault()); + if(isVendorATI() && GLProfile.isAWTAvailable()) { + X11Util.markThreadLocalDisplayUncloseable(tlsDisplay); // failure to close with ATI and AWT usage + } + if(null==sharedScreen || null==sharedDrawable) { + throw new GLException("Couldn't init shared screen("+sharedScreen+")/drawable("+sharedDrawable+")"); + } + // We have to keep this within this thread, + // since we have a 'chicken-and-egg' problem otherwise on the <init> lock of this thread. + try{ + X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); + ctx.makeCurrent(); + ctx.release(); + sharedContext = ctx; + } catch (Throwable t) { + throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t); + } + if(null==sharedContext) { + throw new GLException("X11GLXDrawableFactory - Shared Context is null"); + } + } finally { + X11Util.XUnlockDisplay(tlsDisplay); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK } if (DEBUG) { System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA); @@ -122,9 +130,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { private boolean isVendorATI; private boolean isVendorNVIDIA; - public String getVendorName() { return vendorName; } - public boolean isVendorATI() { return isVendorATI; } - public boolean isVendorNVIDIA() { return isVendorNVIDIA; } + protected String getVendorName() { return vendorName; } + protected boolean isVendorATI() { return isVendorATI; } + protected boolean isVendorNVIDIA() { return isVendorNVIDIA; } private X11DummyGLXDrawable sharedDrawable=null; private X11GLXContext sharedContext=null; @@ -165,14 +173,14 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { X11Util.shutdown( false, DEBUG ); } - public GLDrawableImpl createOnscreenDrawable(NativeSurface target) { + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } return new X11OnscreenGLXDrawable(this, target); } - protected GLDrawableImpl createOffscreenDrawable(NativeSurface target) { + protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } @@ -185,7 +193,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { private boolean glxVersionsQueried = false; private int glxVersionMajor=0, glxVersionMinor=0; - public boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) { + protected final boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) { if (!glxVersionsQueried) { if(null == device) { device = (X11GraphicsDevice) sharedScreen.getDevice(); @@ -193,19 +201,24 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { if(null == device) { throw new GLException("FIXME: No AbstractGraphicsDevice (passed or shared-device"); } - long display = device.getHandle(); - int[] major = new int[1]; - int[] minor = new int[1]; - - GLXUtil.getGLXVersion(display, major, minor); - if (DEBUG) { - System.err.println("!!! GLX version: major " + major[0] + - ", minor " + minor[0]); - } + device.lock(); // OK + try { + long display = device.getHandle(); + int[] major = new int[1]; + int[] minor = new int[1]; + + GLXUtil.getGLXVersion(display, major, minor); + if (DEBUG) { + System.err.println("!!! GLX version: major " + major[0] + + ", minor " + minor[0]); + } - glxVersionMajor = major[0]; - glxVersionMinor = minor[0]; - glxVersionsQueried = true; + glxVersionMajor = major[0]; + glxVersionMinor = minor[0]; + glxVersionsQueried = true; + } finally { + device.unlock(); // OK + } } return ( glxVersionMajor > majorReq ) || ( glxVersionMajor == majorReq && glxVersionMinor >= minorReq ) ; } @@ -239,7 +252,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } - protected NativeSurface createOffscreenSurface(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { + protected NativeSurface createOffscreenSurfaceImpl(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { ProxySurface ns = new ProxySurface(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen)); if(ns != null) { ns.setSize(width, height); @@ -247,7 +260,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return ns; } - public GLContext createExternalGLContext() { + protected GLContext createExternalGLContextImpl() { return X11ExternalGLXContext.create(this, null); } @@ -255,7 +268,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return canCreateGLPbuffer(device); } - public GLDrawable createExternalGLDrawable() { + protected GLDrawable createExternalGLDrawableImpl() { return X11ExternalGLXDrawable.create(this, null); } @@ -282,9 +295,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { long display = sharedScreen.getDevice().getHandle(); int[] size = new int[1]; - boolean res = X11Lib.XF86VidModeGetGammaRampSize(display, - X11Lib.DefaultScreen(display), - size, 0); + boolean res = X11Util.XF86VidModeGetGammaRampSize(display, + X11Util.DefaultScreen(display), + size, 0); if (!res) { return 0; } @@ -301,8 +314,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } long display = sharedScreen.getDevice().getHandle(); - boolean res = X11Lib.XF86VidModeSetGammaRamp(display, - X11Lib.DefaultScreen(display), + boolean res = X11Util.XF86VidModeSetGammaRamp(display, + X11Util.DefaultScreen(display), rampData.length, rampData, 0, rampData, 0, @@ -323,8 +336,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); long display = sharedScreen.getDevice().getHandle(); - boolean res = X11Lib.XF86VidModeGetGammaRamp(display, - X11Lib.DefaultScreen(display), + boolean res = X11Util.XF86VidModeGetGammaRamp(display, + X11Util.DefaultScreen(display), size, redRampData, greenRampData, @@ -354,8 +367,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); long display = sharedScreen.getDevice().getHandle(); - X11Lib.XF86VidModeSetGammaRamp(display, - X11Lib.DefaultScreen(display), + X11Util.XF86VidModeSetGammaRamp(display, + X11Util.DefaultScreen(display), size, redRampData, greenRampData, diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java index 589d7b2db..3df9ee541 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java @@ -339,7 +339,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.setVisualid(visualID); - XVisualInfo[] infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask, template, count, 0); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask, template, count, 0); if (infos == null || infos.length == 0) { return null; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 9884db288..8dbd69dce 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -53,9 +53,8 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this); } - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen) { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { if (!(absScreen instanceof X11GraphicsScreen)) { throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here"); } @@ -95,7 +94,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); - long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex()); + long visID = X11Util.DefaultVisualID(display, x11Screen.getIndex()); xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID); caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable); @@ -140,7 +139,8 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac caps2.setDoubleBuffered(false); } - X11GLXGraphicsConfiguration res = chooseGraphicsConfigurationFBConfig(caps2, chooser, x11Screen); + X11GLXGraphicsConfiguration res; + res = chooseGraphicsConfigurationFBConfig(caps2, chooser, x11Screen); if(null==res) { if(usePBuffer) { throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+caps2); @@ -156,7 +156,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac return res; } - protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities, + private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { long recommendedFBConfig = 0; @@ -277,7 +277,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, fbcfgsL.get(chosen), retFBID); } - protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilities capabilities, + private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilities capabilities, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { if (chooser == null) { @@ -315,7 +315,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.setScreen(screen); - infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null || infos.length<1) { throw new GLException("Error while enumerating available XVisualInfos"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java index 3be34eb6a..f46bdbb75 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java @@ -56,7 +56,7 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { if(realized) { create(); } else { - destroy(); + destroyImpl(); } } @@ -74,14 +74,14 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { long dpy = aDevice.getHandle(); int screen = aScreen.getIndex(); - pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen), + pixmap = X11Util.XCreatePixmap(dpy, X11Util.RootWindow(dpy, screen), surface.getWidth(), surface.getHeight(), bitsPerPixel); if (pixmap == 0) { throw new GLException("XCreatePixmap failed"); } long drawable = GLX.glXCreateGLXPixmap(dpy, vis, pixmap); if (drawable == 0) { - X11Lib.XFreePixmap(dpy, pixmap); + X11Util.XFreePixmap(dpy, pixmap); pixmap = 0; throw new GLException("glXCreateGLXPixmap failed"); } @@ -93,7 +93,7 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { } } - public void destroy() { + protected void destroyImpl() { if (pixmap == 0) return; NativeSurface ns = getNativeSurface(); @@ -122,7 +122,7 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { GLX.glXMakeCurrent(display, 0, 0); GLX.glXDestroyGLXPixmap(display, drawable); - X11Lib.XFreePixmap(display, pixmap); + X11Util.XFreePixmap(display, pixmap); drawable = 0; pixmap = 0; ((SurfaceChangeable)ns).setSurfaceHandle(0); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java index ce9e6d75d..b86394cc6 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java @@ -65,7 +65,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { if(realized) { createPbuffer(); } else { - destroy(); + destroyImpl(); } } @@ -73,7 +73,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { return new X11PbufferGLXContext(this, shareWith); } - public void destroy() { + protected void destroyImpl() { NativeSurface ns = getNativeSurface(); if (ns.getSurfaceHandle() != 0) { GLX.glXDestroyPbuffer(ns.getDisplayHandle(), ns.getSurfaceHandle()); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java index de55a3148..99791b43e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -32,6 +32,7 @@ package com.jogamp.opengl.impl.x11.glx.awt; +import com.jogamp.nativewindow.impl.jawt.JAWTUtil; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import javax.media.nativewindow.*; @@ -50,9 +51,8 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this); } - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen) { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { GraphicsDevice device = null; if (absScreen != null && !(absScreen instanceof AWTGraphicsScreen)) { @@ -93,7 +93,7 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle)); } } - ((AWTGraphicsDevice)awtScreen.getDevice()).setHandle(displayHandle); + ((AWTGraphicsDevice)awtScreen.getDevice()).setSubType(NativeWindowFactory.TYPE_X11, displayHandle); X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle); X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex()); diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java index 04b994198..d9fce6e6a 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java +++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java @@ -85,7 +85,7 @@ public class ImmModeSink { public void draw(GL gl, boolean disableBufferAfterDraw) { if(DEBUG_DRAW) { - Exception e = new Exception("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this); + Exception e = new Exception("Info: ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this); e.printStackTrace(); } int n=0; @@ -96,7 +96,7 @@ public class ImmModeSink { public void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw) { if(DEBUG_DRAW) { - Exception e = new Exception("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this); + Exception e = new Exception("Info: ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this); e.printStackTrace(); } int n=0; @@ -107,7 +107,7 @@ public class ImmModeSink { public void glBegin(int mode) { if(DEBUG_BEGIN_END) { - Exception e = new Exception("ImmModeSink.glBegin("+vboSet.mode+"):\n\t"+this); + Exception e = new Exception("Info: ImmModeSink.glBegin("+vboSet.mode+"):\n\t"+this); e.printStackTrace(); } vboSet.modeOrig = mode; @@ -141,7 +141,7 @@ public class ImmModeSink { private void glEnd(GL gl, Buffer indices, boolean immediateDraw) { if(DEBUG_BEGIN_END) { - Exception e = new Exception("ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this); + Exception e = new Exception("Info: ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this); e.printStackTrace(); } if(immediateDraw) { @@ -328,7 +328,7 @@ public class ImmModeSink { protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i) { if(DEBUG_DRAW) { - Exception e = new Exception("ImmModeSink.draw["+i+"](disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this); + Exception e = new Exception("Info: ImmModeSink.draw["+i+"](disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this); e.printStackTrace(); } enableBuffer(gl, true); diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index a85993c8e..f9f5f8324 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -127,7 +127,7 @@ public abstract class GLDrawableFactory { tmp = (GLDrawableFactory) ReflectionUtil.createInstance(factoryClassName, cl); } catch (JogampRuntimeException jre) { if (GLProfile.DEBUG) { - System.err.println("GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName); + System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName); jre.printStackTrace(); } } @@ -139,7 +139,7 @@ public abstract class GLDrawableFactory { tmp = (GLDrawableFactory) ReflectionUtil.createInstance("com.jogamp.opengl.impl.egl.EGLDrawableFactory", cl); } catch (JogampRuntimeException jre) { if (GLProfile.DEBUG) { - System.err.println("GLDrawableFactory.static - EGLDrawableFactory - not available"); + System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available"); jre.printStackTrace(); } } diff --git a/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java b/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java index 352545849..590e88ab7 100644 --- a/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java @@ -152,11 +152,11 @@ public class GLPipelineFactory { instance = cstr.newInstance( cstrArgs ) ; } catch (Throwable t) { t.printStackTrace(); } if(null==instance) { - throw new GLException("Couldn't create instance of pipeline: "+upstreamClazz.getName()+ + throw new GLException("Error: Couldn't create instance of pipeline: "+upstreamClazz.getName()+ " ( "+getArgsClassNameList(downstreamClazz, additionalArgs) +" )"); } if( ! (instance instanceof GL) ) { - throw new GLException(upstreamClazz.getName()+" not an instance of GL"); + throw new GLException("Error: "+upstreamClazz.getName()+" not an instance of GL"); } return (GL) instance; } diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 287e7a5a9..be5968409 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -37,7 +37,9 @@ package javax.media.opengl; +import com.jogamp.common.jvm.JVMUtil; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.opengl.util.VersionInfo; import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.impl.GLDrawableFactoryImpl; import com.jogamp.opengl.impl.GLDynamicLookupHelper; @@ -281,6 +283,7 @@ public class GLProfile { * @see #GL_PROFILE_LIST_ALL */ public static final GLProfile getDefault() { + validateInitialization(); if(null==defaultGLProfile) { throw new GLException("No default profile available"); // should never be reached } @@ -349,6 +352,7 @@ public class GLProfile { public static final GLProfile get(String profile) throws GLException { + validateInitialization(); if(null==profile || profile.equals("GL")) return getDefault(); GLProfile glProfile = (GLProfile) mappedProfiles.get(profile); if(null==glProfile) { @@ -366,6 +370,7 @@ public class GLProfile { public static final GLProfile get(String[] profiles) throws GLException { + validateInitialization(); for(int i=0; i<profiles.length; i++) { String profile = profiles[i]; GLProfile glProfile = (GLProfile) mappedProfiles.get(profile); @@ -851,9 +856,9 @@ public class GLProfile { * Tries the profiles implementation and native libraries. * Throws an GLException if no profile could be found at all. */ - private static void initProfiles() { + private static void initProfiles(boolean firstUIActionOnProcess) { - NativeWindowFactory.initSingleton(); + NativeWindowFactory.initSingleton(firstUIActionOnProcess); ClassLoader classloader = GLProfile.class.getClassLoader(); @@ -898,13 +903,15 @@ public class GLProfile { t=le; } catch (RuntimeException re) { t=re; + } catch (Throwable tt) { + t=tt; } if(DEBUG) { if(null!=t) { t.printStackTrace(); } if(!hasNativeOSFactory) { - System.err.println("GLProfile.static - Native platform GLDrawable factory not available"); + System.err.println("Info: GLProfile.init - Native platform GLDrawable factory not available"); } } @@ -969,41 +976,80 @@ public class GLProfile { mappedProfiles = computeProfileMap(); if (DEBUG) { - System.err.println("GLProfile.static isAWTAvailable "+isAWTAvailable); - System.err.println("GLProfile.static hasNativeOSFactory "+hasNativeOSFactory); - System.err.println("GLProfile.static hasDesktopGL "+hasDesktopGL); - System.err.println("GLProfile.static hasDesktopGLES12 "+hasDesktopGLES12); - System.err.println("GLProfile.static hasGL234Impl "+hasGL234Impl); - System.err.println("GLProfile.static "+glAvailabilityToString()); + System.err.println(VersionInfo.getPackageInfo(null, "GLProfile.init", "javax.media.opengl", "GL")); + System.err.println(VersionInfo.getPlatformInfo(null, "GLProfile.init")); + System.err.println("GLProfile.init firstUIActionOnProcess "+firstUIActionOnProcess); + System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable); + System.err.println("GLProfile.init hasNativeOSFactory "+hasNativeOSFactory); + System.err.println("GLProfile.init hasDesktopGL "+hasDesktopGL); + System.err.println("GLProfile.init hasDesktopGLES12 "+hasDesktopGLES12); + System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl); + System.err.println("GLProfile.init "+glAvailabilityToString()); } + } + static { + JVMUtil.initSingleton(); } + static boolean initialized = false; + /** - * Initializes available profiles eagerly. + * Static one time initialization of JOGL. + * <p> + * Applications shall call this methods <b>ASAP</b>, before any other UI invocation.<br> + * You may issue the call in your main function.<br> + * In case applications are able to initialize JOGL before any other UI action,<br> + * they shall invoke this method with <code>firstUIActionOnProcess=true</code> and benefit from fast native multithreading support on all platforms if possible.</P> + * <P> + * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL may not be able to initialize JOGL + * before the first UI action.<br> + * In such case you shall invoke this method with <code>firstUIActionOnProcess=false</code>.<br> + * On some platforms, notably X11 with AWT usage, JOGL will utilize special locking mechanisms which may slow down your + * application.</P> + * <P> + * Remark: NEWT is currently not affected by this behavior, ie always uses native multithreading.</P> + * <P> + * However, in case this method is not invoked, hence GLProfile is not initialized explicitly by the user,<br> + * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}, etc, will initialize with <code>firstUIActionOnProcess=false</code>,<br> + * hence without the possibility to enable native multithreading.<br> + * This is not the recommended way, since it may has a performance impact, but it allows you to run code without explicit initialization.</P> + * <P> + * In case no explicit initialization was invoked and the implicit initialization didn't happen,<br> + * you may encounter the following exception: + * <pre> + * javax.media.opengl.GLException: No default profile available + * </pre></P> + * + * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program, + * otherwise <code>false</code>. */ - static { - // run the whole static initialization privileged to speed up, - // since this skips checking further access - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - initProfiles(); - return null; - } - }); + public static synchronized void initSingleton(final boolean firstUIActionOnProcess) { + if(!initialized) { + initialized = true; + // run the whole static initialization privileged to speed up, + // since this skips checking further access + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + initProfiles(firstUIActionOnProcess); + return null; + } + }); - if(null==defaultGLProfile) { - throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+glAvailabilityToString()); + if(null==defaultGLProfile) { + throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+glAvailabilityToString()); + } } } - /** - * It is mandatory to call this methods ASAP, before anything else.<br> - * You may issue the call in your main class static initializer block, or in the static main function.<br> - * This will kick off JOGL's static initialization.<br> - * It is essential to do this at the very beginning, so JOGL has a chance to initialize multithreading support.<br> - */ - public static void initSingleton() { + private static void validateInitialization() { + if(!initialized) { + synchronized(GLProfile.class) { + if(!initialized) { + initSingleton(false); + } + } + } } private static final String array2String(String[] list) { @@ -1028,17 +1074,17 @@ public class GLProfile { GLProfile glProfile = new GLProfile(profile, profileImpl); _mappedProfiles.put(profile, glProfile); if (DEBUG) { - System.err.println("GLProfile.static map "+glProfile); + System.err.println("GLProfile.init map "+glProfile); } if(null==defaultGLProfile) { defaultGLProfile=glProfile; if (DEBUG) { - System.err.println("GLProfile.static default "+glProfile); + System.err.println("GLProfile.init default "+glProfile); } } } else { if (DEBUG) { - System.err.println("GLProfile.static map *** no mapping for "+profile); + System.err.println("GLProfile.init map *** no mapping for "+profile); } } } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 60ed731f1..4ac21204f 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -45,7 +45,6 @@ import javax.media.nativewindow.*; import javax.media.nativewindow.awt.*; import com.jogamp.opengl.impl.*; -import com.jogamp.nativewindow.impl.jawt.JAWTUtil; import java.awt.Canvas; import java.awt.Color; @@ -54,7 +53,6 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; -import java.awt.Container; import java.awt.Window; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; @@ -79,9 +77,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { private static final GLProfile defaultGLProfile; static { - NativeWindowFactory.initSingleton(); - defaultGLProfile = GLProfile.getDefault(); DEBUG = Debug.debug("GLCanvas"); + defaultGLProfile = GLProfile.getDefault(); } private GLProfile glProfile; @@ -234,7 +231,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null; boolean equalCaps = config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities()); if(DEBUG) { - Exception e = new Exception("Call Stack: "+Thread.currentThread().getName()); + Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName()); e.printStackTrace(); System.err.println("!!! Created Config (n): HAVE GC "+chosen); System.err.println("!!! Created Config (n): THIS GC "+gc); @@ -313,7 +310,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { protected void dispose(boolean regenerate) { if(DEBUG) { - Exception ex1 = new Exception("dispose("+regenerate+") - start"); + Exception ex1 = new Exception("Info: dispose("+regenerate+") - start"); ex1.printStackTrace(); } @@ -381,7 +378,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { (int) ((getHeight() + bounds.getHeight()) / 2)); return; } - if( this.drawableHelper.isExternalAnimatorAnimating() ) { + if( ! this.drawableHelper.isExternalAnimatorAnimating() ) { display(); } } @@ -408,11 +405,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { /* * Save the chosen capabilities for use in getGraphicsConfiguration(). */ - JAWTUtil.lockToolkit(); + NativeWindowFactory.getDefaultToolkitLock().lock(); try { awtConfig = chooseGraphicsConfiguration(capabilities, chooser, device); if(DEBUG) { - Exception e = new Exception("Created Config: "+awtConfig); + Exception e = new Exception("Info: Created Config: "+awtConfig); e.printStackTrace(); } if(null!=awtConfig) { @@ -427,7 +424,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { context = (GLContextImpl) drawable.createContext(shareWith); context.setSynchronized(true); } finally { - JAWTUtil.unlockToolkit(); + NativeWindowFactory.getDefaultToolkitLock().unlock(); } if(DEBUG) { @@ -446,7 +443,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */ public void removeNotify() { if(DEBUG) { - Exception ex1 = new Exception("removeNotify - start"); + Exception ex1 = new Exception("Info: removeNotify - start"); ex1.printStackTrace(); } @@ -461,7 +458,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } } if(DEBUG) { - System.out.println("removeNotify - end"); + System.err.println("Info: removeNotify - end"); } } @@ -580,7 +577,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } public String toString() { - return "AWT-GLCanvas[ "+awtConfig+", "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+", "+drawableHelper+"]"; + return "AWT-GLCanvas[ "+awtConfig+", "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+"]"; } //---------------------------------------------------------------------- diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index e4a295ba3..192695955 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -138,8 +138,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { private int viewportY; static { - NativeWindowFactory.initSingleton(); - // Force eager initialization of part of the Java2D class since // otherwise it's likely it will try to be initialized while on // the Queue Flusher Thread, which is not allowed @@ -212,7 +210,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { protected void dispose(boolean regenerate) { if(DEBUG) { - Exception ex1 = new Exception("dispose("+regenerate+") - start"); + Exception ex1 = new Exception("Info: dispose("+regenerate+") - start"); ex1.printStackTrace(); } if (backend != null) { @@ -287,10 +285,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { return; } - if ( drawableHelper.isExternalAnimatorAnimating() ) { - return; - } - if (backend == null || !isInitialized) { createAndInitializeBackend(); } @@ -334,7 +328,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */ public void removeNotify() { if(DEBUG) { - Exception ex1 = new Exception("removeNotify - start"); + Exception ex1 = new Exception("Info: removeNotify - start"); ex1.printStackTrace(); } dispose(false); @@ -345,7 +339,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { isInitialized = false; super.removeNotify(); if(DEBUG) { - System.out.println("removeNotify - end"); + System.err.println("Info: removeNotify - end"); } } @@ -617,7 +611,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { } public String toString() { - return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+", "+drawableHelper+"]"; + return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+"]"; } private boolean disposeRegenerate; @@ -1034,7 +1028,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { } catch (GLException e) { if (DEBUG) { e.printStackTrace(); - System.err.println("GLJPanel: Falling back on software rendering because of problems creating pbuffer"); + System.err.println("Info: GLJPanel: Falling back on software rendering because of problems creating pbuffer"); } hardwareAccelerationDisabled = true; backend = null; @@ -1111,7 +1105,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { readBackWidthInPixels = Math.max(1, panelWidth); readBackHeightInPixels = Math.max(1, panelHeight); if (DEBUG) { - System.err.println("WARNING: falling back to software rendering due to bugs in OpenGL drivers"); + System.err.println("Warning: falling back to software rendering due to bugs in OpenGL drivers"); e.printStackTrace(); } createAndInitializeBackend(); diff --git a/src/junit/com/jogamp/test/junit/jogl/acore/DumpVersion.java b/src/junit/com/jogamp/test/junit/jogl/acore/DumpVersion.java index 1c563970f..3fa7f111f 100644 --- a/src/junit/com/jogamp/test/junit/jogl/acore/DumpVersion.java +++ b/src/junit/com/jogamp/test/junit/jogl/acore/DumpVersion.java @@ -35,6 +35,7 @@ import org.junit.AfterClass; import org.junit.Test; import javax.media.opengl.*; +import com.jogamp.opengl.util.VersionInfo; import com.jogamp.common.os.Platform; import java.io.IOException; @@ -44,16 +45,9 @@ public class DumpVersion implements GLEventListener { public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); - System.err.println(Thread.currentThread()+" Platform: " + Platform.getOS() + " (os), " + Platform.getArch() + " (arch)"); - System.err.println(Thread.currentThread()+" Platform: littleEndian " + Platform.isLittleEndian() + ", 32Bit "+Platform.is32Bit() + ", a-ptr bit-size "+Platform.getPointerSizeInBits()); - System.err.println(Thread.currentThread()+" Platform: JavaSE " + Platform.isJavaSE()); - System.err.println(Thread.currentThread()+" GL Profile " + gl.getGLProfile()); - System.err.println(Thread.currentThread()+" CTX VERSION " + gl.getContext().getGLVersion()); - System.err.println(Thread.currentThread()+" GL " + gl); - System.err.println(Thread.currentThread()+" GL_VERSION " + gl.glGetString(gl.GL_VERSION)); - System.err.println(Thread.currentThread()+" GL_EXTENSIONS "); - System.err.println(Thread.currentThread()+" " + gl.glGetString(gl.GL_EXTENSIONS)); - System.err.println(Thread.currentThread()+" swapInterval " + gl.getSwapInterval()); + String prefix = Thread.currentThread().getName(); + + System.err.println(VersionInfo.getInfo(null, prefix, gl).toString()); } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { @@ -64,8 +58,4 @@ public class DumpVersion implements GLEventListener { public void dispose(GLAutoDrawable drawable) { } - - public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { - } - } diff --git a/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java index 711ac7c87..b42fce9bf 100644 --- a/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java @@ -44,13 +44,11 @@ import com.jogamp.newt.*; import java.io.IOException; public class TestGLProfile01NEWT extends UITestCase { - static { - GLProfile.initSingleton(); - } static GLProfile glp; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); glp = GLProfile.getDefault(); Assert.assertNotNull(glp); } diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java index 5ee3d3814..006010eeb 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java @@ -47,15 +47,12 @@ import org.junit.Test; public class TestAWT01GLn extends UITestCase { - static { - GLProfile.initSingleton(); - } - Frame frame=null; GLCanvas glCanvas=null; @BeforeClass public static void startup() { + GLProfile.initSingleton(true); System.out.println("GLProfile <static> "+GLProfile.glAvailabilityToString()); } diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT02WindowClosing.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT02WindowClosing.java index a4726f1c6..9e8cb916a 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT02WindowClosing.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT02WindowClosing.java @@ -42,12 +42,14 @@ import org.junit.After; import org.junit.Test; public class TestAWT02WindowClosing extends UITestCase { - static { - GLProfile.initSingleton(); - } static long durationPerTest = 200; // ms + @BeforeClass + public static void initClass() { + GLProfile.initSingleton(true); + } + @Test public void test01WindowClosing() throws InterruptedException { Frame frame = new Frame(); diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java index c3b9e10ab..4559ee936 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java @@ -53,16 +53,12 @@ import static javax.swing.SwingUtilities.*; * @author Michael Bien */ public class TestSwingAWT01GLn extends UITestCase { - static { - GLProfile.initSingleton(); - } - - private Window[] windows; @BeforeClass public static void startup() { + GLProfile.initSingleton(true); System.out.println("GLProfile <static> "+GLProfile.glAvailabilityToString()); } diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java index 9f12b658a..2f4a95646 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java @@ -117,6 +117,9 @@ public class TestSwingAWTRobotUsageBeforeJOGLInitBug411 extends UITestCase { public static void setup() throws InterruptedException, InvocationTargetException, AWTException { int count; + // GLProfile.initSingleton(false); + // GLProfile.initSingleton(true); + // simulate AWT usage before JOGL's initialization of X11 threading windowClosing=false; border = BorderFactory.createLineBorder (Color.yellow, 2); @@ -166,14 +169,18 @@ public class TestSwingAWTRobotUsageBeforeJOGLInitBug411 extends UITestCase { System.err.println("Clean End of Pre-JOGL-Swing"); - GLProfile.initSingleton(); + GLProfile.initSingleton(false); } @AfterClass - public static void release() { + public static void release() throws InterruptedException, InvocationTargetException { robot = null; Assert.assertNotNull(frame); - frame.dispose(); + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.dispose(); + } + }); frame=null; } diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java index ef5cf134a..3a3823d96 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java @@ -3,10 +3,12 @@ package com.jogamp.test.junit.jogl.demos.gl2.gears; import javax.media.opengl.*; import javax.media.opengl.awt.*; +import com.jogamp.opengl.util.Animator; import com.jogamp.newt.event.*; import com.jogamp.newt.event.awt.*; import java.awt.Component; +import java.awt.Frame; import com.jogamp.newt.Window; /** @@ -24,8 +26,44 @@ public class Gears implements GLEventListener { private int prevMouseX, prevMouseY; private boolean mouseRButtonDown = false; + public static void main(String[] args) { + // set argument 'NotFirstUIActionOnProcess' in the JNLP's application-desc tag for example + // <application-desc main-class="demos.j2d.TextCube"/> + // <argument>NotFirstUIActionOnProcess</argument> + // </application-desc> + boolean firstUIActionOnProcess = 0==args.length || !args[0].equals("NotFirstUIActionOnProcess") ; + GLProfile.initSingleton(firstUIActionOnProcess); + + Frame frame = new Frame("Gear Demo"); + GLCanvas canvas = new GLCanvas(); + // GLCapabilities caps = new GLCapabilities(GLProfile.getDefault()); + // GLCanvas canvas = new GLCanvas(caps); + + final Gears gears = new Gears(); + canvas.addGLEventListener(gears); + + frame.add(canvas); + frame.setSize(300, 300); + final Animator animator = new Animator(canvas); + frame.addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent e) { + // Run this on another thread than the AWT event queue to + // make sure the call to Animator.stop() completes before + // exiting + new Thread(new Runnable() { + public void run() { + animator.stop(); + System.exit(0); + } + }).start(); + } + }); + frame.setVisible(true); + animator.start(); + } + public void init(GLAutoDrawable drawable) { - System.out.println("Gears: Init"); + System.err.println("Gears: Init"); // Use debug pipeline // drawable.setGL(new DebugGL(drawable.getGL())); @@ -78,7 +116,7 @@ public class Gears implements GLEventListener { } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { - System.out.println("Gears: Reshape"); + System.err.println("Gears: Reshape"); GL2 gl = drawable.getGL().getGL2(); float h = (float)height / (float)width; @@ -93,7 +131,7 @@ public class Gears implements GLEventListener { } public void dispose(GLAutoDrawable drawable) { - System.out.println("Gears: Dispose"); + System.err.println("Gears: Dispose"); } public void display(GLAutoDrawable drawable) { @@ -103,14 +141,13 @@ public class Gears implements GLEventListener { // Get the GL corresponding to the drawable we are animating GL2 gl = drawable.getGL().getGL2(); - /** // Special handling for the case where the GLJPanel is translucent // and wants to be composited with other Java 2D content if ((drawable instanceof GLJPanel) && !((GLJPanel) drawable).isOpaque() && ((GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) { gl.glClear(GL2.GL_DEPTH_BUFFER_BIT); - } else */ { + } else { gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); } diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java index 52a4885b4..60435cb4a 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java @@ -48,15 +48,12 @@ import org.junit.After; import org.junit.Test; public class TestGearsAWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glp; static int width, height; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); glp = GLProfile.getDefault(); Assert.assertNotNull(glp); width = 512; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNEWT.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNEWT.java index 88cfa9c95..1589be84c 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNEWT.java @@ -46,15 +46,12 @@ import org.junit.After; import org.junit.Test; public class TestGearsNEWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glp; static int width, height; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); glp = GLProfile.getDefault(); Assert.assertNotNull(glp); width = 512; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNewtAWTWrapper.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNewtAWTWrapper.java index 47cdd4bfa..27c353942 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNewtAWTWrapper.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNewtAWTWrapper.java @@ -46,15 +46,12 @@ import org.junit.After; import org.junit.Test; public class TestGearsNewtAWTWrapper extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glp; static int width, height; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); glp = GLProfile.getDefault(); Assert.assertNotNull(glp); width = 512; diff --git a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java index 243c9e8a7..95db913ab 100644 --- a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java @@ -42,10 +42,6 @@ import com.jogamp.newt.*; import java.io.IOException; public class TestDrawable01NEWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glp; static GLDrawableFactory factory; static int width, height; @@ -56,6 +52,7 @@ public class TestDrawable01NEWT extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); glp = GLProfile.getDefault(); Assert.assertNotNull(glp); factory = GLDrawableFactory.getFactory(glp); diff --git a/src/junit/com/jogamp/test/junit/jogl/glsl/TestTransformFeedbackVeryingsBug407NEWT.java b/src/junit/com/jogamp/test/junit/jogl/glsl/TestTransformFeedbackVeryingsBug407NEWT.java index bedea39ad..0d9a595aa 100644 --- a/src/junit/com/jogamp/test/junit/jogl/glsl/TestTransformFeedbackVeryingsBug407NEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/glsl/TestTransformFeedbackVeryingsBug407NEWT.java @@ -16,6 +16,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import com.jogamp.newt.Display; @@ -32,13 +33,14 @@ import java.io.IOException; */ public class TestTransformFeedbackVeryingsBug407NEWT extends UITestCase { - static { - //NativeUtil.preloadNativeLibs(); // internal method - GLProfile.initSingleton(); - } private GLContext context; private String VERTEX_SHADER_TEXT; + @BeforeClass + public static void initClass() { + GLProfile.initSingleton(true); + } + @Before public void setUp() { if(!GLProfile.isGL3Available()) { diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java index e72d5e506..1d699a1aa 100644 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java @@ -54,10 +54,6 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import java.io.IOException; public class TestOffscreen01NEWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glpDefault; static GLDrawableFactory glDrawableFactory; static int width, height; @@ -65,6 +61,7 @@ public class TestOffscreen01NEWT extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); glpDefault = GLProfile.getDefault(); Assert.assertNotNull(glpDefault); glDrawableFactory = GLDrawableFactory.getFactory(glpDefault); diff --git a/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java b/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java index 7d6b4d7e3..2eb66663c 100644 --- a/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java @@ -54,16 +54,13 @@ import org.junit.BeforeClass; import org.junit.Test; public class TestTexture01AWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glp; static GLCapabilities caps; BufferedImage textureImage; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); glp = GLProfile.get(GLProfile.GL2GL3); Assert.assertNotNull(glp); caps = new GLCapabilities(glp); diff --git a/src/junit/com/jogamp/test/junit/newt/TestDisplayLifecycle01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestDisplayLifecycle01NEWT.java index 7f70d1f8b..072ebafd6 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestDisplayLifecycle01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestDisplayLifecycle01NEWT.java @@ -1,33 +1,29 @@ -/* - * Copyright (c) 2010 Sven Gothel. All Rights Reserved. +/** + * Copyright 2010 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: * - * 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. * - * - Redistribution 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. * - * - Redistribution 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. * - * Neither the name Sven Gothel or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * 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.test.junit.newt; @@ -57,10 +53,6 @@ import com.jogamp.test.junit.util.MiscUtils; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestDisplayLifecycle01NEWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glp; static GLCapabilities caps; static int width, height; @@ -68,6 +60,7 @@ public class TestDisplayLifecycle01NEWT extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; glp = GLProfile.getDefault(); diff --git a/src/junit/com/jogamp/test/junit/newt/TestEventSourceNotNEWTBug.java b/src/junit/com/jogamp/test/junit/newt/TestEventSourceNotAWTBug.java index 7e596eb8c..8776b7be8 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestEventSourceNotNEWTBug.java +++ b/src/junit/com/jogamp/test/junit/newt/TestEventSourceNotAWTBug.java @@ -51,7 +51,7 @@ import com.jogamp.test.junit.util.*; /** * This simple program will throw a {@link RuntimeException} when the application is closed. */ -public class TestEventSourceNotNEWTBug extends UITestCase { +public class TestEventSourceNotAWTBug extends UITestCase { @BeforeClass public static void initClass() { @@ -92,7 +92,7 @@ public class TestEventSourceNotNEWTBug extends UITestCase { } public static void main(String args[]) throws IOException { - String tstname = TestEventSourceNotNEWTBug.class.getName(); + String tstname = TestEventSourceNotAWTBug.class.getName(); /* org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { tstname, diff --git a/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWTRobot.java index 6ae0ee9d3..656783740 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWTRobot.java +++ b/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWTRobot.java @@ -68,11 +68,6 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.util.*; public class TestFocus01SwingAWTRobot extends UITestCase { - - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 800; @@ -81,6 +76,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; glCaps = new GLCapabilities(null); diff --git a/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWTRobot.java b/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWTRobot.java index 1ca5e6cd7..8d262fc3f 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWTRobot.java +++ b/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWTRobot.java @@ -75,7 +75,7 @@ public class TestFocus02SwingAWTRobot extends UITestCase { f.dispose(); f=null; - GLProfile.initSingleton(); + GLProfile.initSingleton(false); glCaps = new GLCapabilities(null); } diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java index df073d0f8..aad61565f 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java @@ -53,16 +53,13 @@ import com.jogamp.test.junit.util.MiscUtils; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestGLWindows01NEWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glp; static int width, height; static long durationPerTest = 100; // ms @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; glp = GLProfile.getDefault(); diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java index f5474c0ec..7a8bc1db0 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java +++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java @@ -54,16 +54,13 @@ import com.jogamp.test.junit.util.MiscUtils; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestGLWindows02NEWTAnimated extends UITestCase { - static { - GLProfile.initSingleton(); - } - static GLProfile glp; static int width, height; static long durationPerTest = 100; // ms @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; glp = GLProfile.getDefault(); diff --git a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java b/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java index a3310f513..39eb47ca9 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java @@ -61,16 +61,13 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestListenerCom01AWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 500; static boolean verbose = false; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; } diff --git a/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java index ae01b14ed..88edd89ba 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java @@ -52,6 +52,7 @@ public class TestWindows01NEWT extends UITestCase { @BeforeClass public static void initClass() { + NativeWindowFactory.initSingleton(true); width = 640; height = 480; } diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01NEWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01NEWT.java index c07601eb6..2d1bb82a6 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01NEWT.java @@ -56,16 +56,13 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01NEWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 500; static GLCapabilities glCaps; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; glCaps = new GLCapabilities(null); diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01aAWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01aAWT.java index 3d3f5234d..931cf2d5f 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01aAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01aAWT.java @@ -63,20 +63,18 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01aAWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 800; static long waitReparent = 0; static GLCapabilities glCaps; @BeforeClass - public static void initClass() { + public static void initClass() throws InterruptedException { + GLProfile.initSingleton(true); width = 640; height = 480; glCaps = new GLCapabilities(null); + // Thread.sleep(10000); } @Test diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01bAWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01bAWT.java index 11d25822a..9eecf31a1 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01bAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01bAWT.java @@ -63,10 +63,6 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01bAWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 800; static long waitReparent = 0; @@ -74,6 +70,7 @@ public class TestParenting01bAWT extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; glCaps = new GLCapabilities(null); diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cAWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cAWT.java index 24ee30bc0..2dcc7af9b 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cAWT.java @@ -62,16 +62,13 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01cAWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 800; static GLCapabilities glCaps; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; glCaps = new GLCapabilities(null); diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java index ece99c0be..3fc39a3f1 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java @@ -66,10 +66,6 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01cSwingAWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 800; static long waitReparent = 0; @@ -77,6 +73,7 @@ public class TestParenting01cSwingAWT extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; glCaps = new GLCapabilities(null); diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02AWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02AWT.java index a4b8c183d..3311bc691 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02AWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02AWT.java @@ -61,10 +61,6 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting02AWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 500; static long waitReparent = 300; @@ -72,6 +68,7 @@ public class TestParenting02AWT extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; } diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java index 8d1c7594c..3d9efcf82 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java @@ -56,15 +56,12 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting02NEWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static int width, height; static long durationPerTest = 500; @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); width = 640; height = 480; } diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting03AWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting03AWT.java index f7374a98b..6130a5fcd 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting03AWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting03AWT.java @@ -64,10 +64,6 @@ import com.jogamp.test.junit.util.*; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting03AWT extends UITestCase { - static { - GLProfile.initSingleton(); - } - static Dimension size; static long durationPerTest = 800; static long waitAdd2nd = 500; @@ -75,6 +71,7 @@ public class TestParenting03AWT extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(true); size = new Dimension(400,200); glCaps = new GLCapabilities(null); } diff --git a/src/junit/com/jogamp/test/junit/util/UITestCase.java b/src/junit/com/jogamp/test/junit/util/UITestCase.java index 5bf76234d..e169405b0 100644 --- a/src/junit/com/jogamp/test/junit/util/UITestCase.java +++ b/src/junit/com/jogamp/test/junit/util/UITestCase.java @@ -55,6 +55,7 @@ public abstract class UITestCase { @AfterClass public static void oneTimeTearDown() { // one-time cleanup code + System.gc(); // force cleanup singletonInstance.unlock(); } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java index 22f2d544f..96f6ab2ba 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java @@ -35,9 +35,8 @@ package com.jogamp.nativewindow.impl; import javax.media.nativewindow.*; public class GraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen screen) { + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) { return new DefaultGraphicsConfiguration(screen, capabilities, capabilities); } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java index 8f82bed2b..34f5d6267 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java @@ -41,6 +41,12 @@ import javax.media.nativewindow.*; public class NativeWindowFactoryImpl extends NativeWindowFactory { protected static final boolean DEBUG = Debug.debug("NativeWindow"); + private static final ToolkitLock nullToolkitLock = new NullToolkitLock(); + + public static ToolkitLock getNullToolkitLock() { + return nullToolkitLock; + } + // This subclass of NativeWindowFactory handles the case of // NativeWindows being passed in protected NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException { @@ -56,7 +62,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory { throw new IllegalArgumentException("AbstractGraphicsConfiguration is null with a non NativeWindow object"); } - if (ReflectionUtil.instanceOf(winObj, AWTComponentClassName)) { + if (NativeWindowFactory.isAWTAvailable() && ReflectionUtil.instanceOf(winObj, AWTComponentClassName)) { return getAWTNativeWindow(winObj, config); } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullToolkitLock.java new file mode 100644 index 000000000..5a03cba7f --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullToolkitLock.java @@ -0,0 +1,50 @@ +/** + * Copyright 2010 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.nativewindow.impl; + +import javax.media.nativewindow.ToolkitLock; + +/** + * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock} + * without any locking. Since there is no locking it all, + * it is intrinsically recursive. + */ +public class NullToolkitLock implements ToolkitLock { + + /** Singleton via {@link NativeWindowFactoryImpl#getNullToolkitLock()} */ + protected NullToolkitLock() { } + + public final void lock() { + if(TRACE_LOCK) { System.err.println("NullToolkitLock.lock()"); } + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("NullToolkitLock.unlock()"); } + } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java index 9d9f360cd..eebcdb0ab 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java @@ -43,10 +43,10 @@ import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.SurfaceChangeable; -import com.jogamp.common.util.RecursiveToolkitLock; +import com.jogamp.common.util.locks.RecursiveLock; public class ProxySurface implements NativeSurface, SurfaceChangeable { - private RecursiveToolkitLock recurLock = new RecursiveToolkitLock(); + private RecursiveLock recurLock = new RecursiveLock(); protected int width, height, scrnIndex; protected long surfaceHandle, displayHandle; protected AbstractGraphicsConfiguration config; @@ -78,31 +78,36 @@ public class ProxySurface implements NativeSurface, SurfaceChangeable { surfaceHandle=0; } - public synchronized int lockSurface() throws NativeWindowException { + public final int lockSurface() throws NativeWindowException { recurLock.lock(); + + if(recurLock.getRecursionCount() == 0) { + config.getScreen().getDevice().lock(); + } return LOCK_SUCCESS; } - public synchronized void unlockSurface() { + public final void unlockSurface() { + recurLock.validateLocked(); + + if(recurLock.getRecursionCount()==0) { + config.getScreen().getDevice().unlock(); + } recurLock.unlock(); } - public synchronized boolean isSurfaceLockedByOtherThread() { + public final boolean isSurfaceLockedByOtherThread() { return recurLock.isLockedByOtherThread(); } - public synchronized boolean isSurfaceLocked() { + public final boolean isSurfaceLocked() { return recurLock.isLocked(); } - public Thread getSurfaceLockOwner() { + public final Thread getSurfaceLockOwner() { return recurLock.getOwner(); } - public Exception getSurfaceLockStack() { - return recurLock.getLockedStack(); - } - public boolean surfaceSwap() { return false; } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTToolkitLock.java new file mode 100644 index 000000000..017d74874 --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTToolkitLock.java @@ -0,0 +1,54 @@ +/** + * Copyright 2010 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.nativewindow.impl.jawt; + +import javax.media.nativewindow.ToolkitLock; + +/** + * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock} + * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()}. + * <br> + * This strategy should only be used if AWT is using the underlying native windowing toolkit + * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call + * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets. + */ +public class JAWTToolkitLock implements ToolkitLock { + + /** Singleton via {@link JAWTUtil#getJAWTToolkitLock()} */ + protected JAWTToolkitLock() {} + + public final void lock() { + if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.lock()"); } + JAWTUtil.lockToolkit(); + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.unlock()"); } + JAWTUtil.unlockToolkit(); + } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java index 7127bacf9..ff62c9521 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java @@ -40,27 +40,28 @@ import com.jogamp.nativewindow.impl.*; import javax.media.nativewindow.*; -import com.jogamp.common.util.RecursiveToolkitLock; +import com.jogamp.common.util.locks.RecursiveLock; import java.awt.GraphicsEnvironment; import java.lang.reflect.*; import java.security.*; public class JAWTUtil { + protected static final boolean DEBUG = Debug.debug("JAWT"); // See whether we're running in headless mode private static final boolean headlessMode; // Java2D magic .. - private static final Class j2dClazz; private static final Method isQueueFlusherThread; private static final boolean j2dExist; private static Class sunToolkitClass; private static Method sunToolkitAWTLockMethod; private static Method sunToolkitAWTUnlockMethod; - private static final boolean hasSunToolkitAWTLock; - private static final boolean useSunToolkitAWTLock; + private static boolean hasSunToolkitAWTLock; + + private static final JAWTToolkitLock jawtToolkitLock; static { JAWTJNILibLoader.loadAWTImpl(); @@ -68,45 +69,53 @@ public class JAWTUtil { headlessMode = GraphicsEnvironment.isHeadless(); - boolean ok=false; - Class jC=null; - Method m=null; - if(!headlessMode) { + boolean ok = false; + Class jC = null; + Method m = null; + if (!headlessMode) { try { jC = Class.forName("com.jogamp.opengl.impl.awt.Java2D"); m = jC.getMethod("isQueueFlusherThread", null); ok = true; - } catch (Exception e) {} + } catch (Exception e) { + } } - j2dClazz = jC; isQueueFlusherThread = m; j2dExist = ok; AccessController.doPrivileged(new PrivilegedAction() { public Object run() { - try { - sunToolkitClass = Class.forName("sun.awt.SunToolkit"); - sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[] {}); - sunToolkitAWTLockMethod.setAccessible(true); - sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[] {}); - sunToolkitAWTUnlockMethod.setAccessible(true); - } catch (Exception e) { - // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 - } - return null; + try { + sunToolkitClass = Class.forName("sun.awt.SunToolkit"); + sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[]{}); + sunToolkitAWTLockMethod.setAccessible(true); + sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[]{}); + sunToolkitAWTUnlockMethod.setAccessible(true); + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return null; + } + }); + boolean _hasSunToolkitAWTLock = false; + if (null != sunToolkitAWTLockMethod && null != sunToolkitAWTUnlockMethod) { + try { + sunToolkitAWTLockMethod.invoke(null, null); + sunToolkitAWTUnlockMethod.invoke(null, null); + _hasSunToolkitAWTLock = true; + } catch (Exception e) { } - }); - boolean _hasSunToolkitAWTLock = false; - if ( null!=sunToolkitAWTLockMethod && null!=sunToolkitAWTUnlockMethod ) { - try { - sunToolkitAWTLockMethod.invoke(null, null); - sunToolkitAWTUnlockMethod.invoke(null, null); - _hasSunToolkitAWTLock = true; - } catch (Exception e) {} - } - hasSunToolkitAWTLock = _hasSunToolkitAWTLock; - // useSunToolkitAWTLock = hasSunToolkitAWTLock; - useSunToolkitAWTLock = false; + } + hasSunToolkitAWTLock = _hasSunToolkitAWTLock; + // hasSunToolkitAWTLock = false; + + jawtToolkitLock = new JAWTToolkitLock(); + + if (DEBUG) { + System.err.println("JAWTUtil: Has sun.awt.SunToolkit.awtLock/awtUnlock " + hasSunToolkitAWTLock); + System.err.println("JAWTUtil: Has Java2D " + j2dExist); + System.err.println("JAWTUtil: Is headless " + headlessMode); + } } public static void initSingleton() { @@ -132,8 +141,14 @@ public class JAWTUtil { return headlessMode; } - private static void awtLock() { - if(useSunToolkitAWTLock) { + /** + * Locks the AWT's global ReentrantLock.<br> + * + * JAWT's native Lock() function calls SunToolkit.awtLock(), + * which just uses AWT's global ReentrantLock.<br> + */ + public static void awtLock() { + if(hasSunToolkitAWTLock) { try { sunToolkitAWTLockMethod.invoke(null, null); } catch (Exception e) { @@ -144,8 +159,14 @@ public class JAWTUtil { } } - private static void awtUnlock() { - if(useSunToolkitAWTLock) { + /** + * Unlocks the AWT's global ReentrantLock.<br> + * + * JAWT's native Unlock() function calls SunToolkit.awtUnlock(), + * which just uses AWT's global ReentrantLock.<br> + */ + public static void awtUnlock() { + if(hasSunToolkitAWTLock) { try { sunToolkitAWTUnlockMethod.invoke(null, null); } catch (Exception e) { @@ -156,36 +177,20 @@ public class JAWTUtil { } } - private static RecursiveToolkitLock recurLock = new RecursiveToolkitLock(); - - public static synchronized void lockToolkit() throws NativeWindowException { - recurLock.lock(); - - if(recurLock.getRecursionCount()==0 && - !isJava2DQueueFlusherThread() && - !headlessMode) { + public static void lockToolkit() throws NativeWindowException { + if(!isJava2DQueueFlusherThread() && !headlessMode) { awtLock(); } } - public static synchronized void unlockToolkit() { - recurLock.validateLocked(); - - if(recurLock.getRecursionCount()==0 && - !isJava2DQueueFlusherThread() && - !headlessMode) { + public static void unlockToolkit() { + if(!isJava2DQueueFlusherThread() && !headlessMode) { awtUnlock(); } - - recurLock.unlock(); - } - - public static boolean isToolkitLocked() { - return recurLock.isLocked(); } - public static Exception getLockedStack() { - return recurLock.getLockedStack(); + public static JAWTToolkitLock getJAWTToolkitLock() { + return jawtToolkitLock; } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java index ad0b6104b..00d64b4e4 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java @@ -38,7 +38,7 @@ package com.jogamp.nativewindow.impl.jawt; import com.jogamp.nativewindow.impl.*; -import com.jogamp.common.util.RecursiveToolkitLock; +import com.jogamp.common.util.locks.RecursiveLock; import java.awt.Component; import java.awt.Window; @@ -48,14 +48,7 @@ import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.Rectangle; public abstract class JAWTWindow implements NativeWindow { - protected static final boolean DEBUG = Debug.debug("JAWT"); - - // See whether we're running in headless mode - private static boolean headlessMode; - - static { - headlessMode = GraphicsEnvironment.isHeadless(); - } + protected static final boolean DEBUG = JAWTUtil.DEBUG; // lifetime: forever protected Component component; @@ -113,47 +106,60 @@ public abstract class JAWTWindow implements NativeWindow { // NativeSurface // - private RecursiveToolkitLock recurLock = new RecursiveToolkitLock(); + private RecursiveLock recurLock = new RecursiveLock(); protected abstract int lockSurfaceImpl() throws NativeWindowException; - public final synchronized int lockSurface() throws NativeWindowException { + public final int lockSurface() throws NativeWindowException { + int res = LOCK_SURFACE_NOT_READY; + recurLock.lock(); if(recurLock.getRecursionCount() == 0) { - return lockSurfaceImpl(); + config.getScreen().getDevice().lock(); + try { + res = lockSurfaceImpl(); + } finally { + // Unlock in case surface couldn't be locked + if(LOCK_SURFACE_NOT_READY >= res ) { + config.getScreen().getDevice().unlock(); + recurLock.unlock(); + } + } + } else { + res = LOCK_SUCCESS; } - return LOCK_SUCCESS; + return res; } protected abstract void unlockSurfaceImpl() throws NativeWindowException; - public synchronized void unlockSurface() { + public final void unlockSurface() { recurLock.validateLocked(); if(recurLock.getRecursionCount()==0) { - unlockSurfaceImpl(); + try { + unlockSurfaceImpl(); + } finally { + config.getScreen().getDevice().unlock(); + } } recurLock.unlock(); } - public synchronized boolean isSurfaceLockedByOtherThread() { + public final boolean isSurfaceLockedByOtherThread() { return recurLock.isLockedByOtherThread(); } - public synchronized boolean isSurfaceLocked() { + public final boolean isSurfaceLocked() { return recurLock.isLocked(); } - public Thread getSurfaceLockOwner() { + public final Thread getSurfaceLockOwner() { return recurLock.getOwner(); } - public Exception getSurfaceLockStack() { - return recurLock.getLockedStack(); - } - public boolean surfaceSwap() { return false; } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTToolkitLock.java new file mode 100644 index 000000000..7eaac2ca6 --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTToolkitLock.java @@ -0,0 +1,60 @@ +/** + * Copyright 2010 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.nativewindow.impl.jawt.x11; + +import com.jogamp.nativewindow.impl.jawt.*; +import com.jogamp.nativewindow.impl.x11.X11Util; +import javax.media.nativewindow.ToolkitLock; + +/** + * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock} + * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}. + * <br> + * This strategy should only be used if AWT is using the underlying native windowing toolkit + * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call + * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets. + */ +public class X11JAWTToolkitLock implements ToolkitLock { + long displayHandle; + + public X11JAWTToolkitLock(long displayHandle) { + this.displayHandle = displayHandle; + } + + public final void lock() { + if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock()"); } + JAWTUtil.lockToolkit(); + X11Util.XLockDisplay(displayHandle); + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock()"); } + X11Util.XUnlockDisplay(displayHandle); + JAWTUtil.unlockToolkit(); + } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java index c74a62b7e..4a2c9ada3 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java @@ -60,79 +60,65 @@ public class X11JAWTWindow extends JAWTWindow { if(0==displayHandle) { displayHandle = X11Util.createThreadLocalDisplay(null); } - awtDevice.setHandle(displayHandle); + awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle); } } protected int lockSurfaceImpl() throws NativeWindowException { - // JAWTUtil.lockToolkit(); - // config.getNativeGraphicsConfiguration().getScreen().getDevice().lock(); - try { - int ret = NativeWindow.LOCK_SUCCESS; - ds = JAWT.getJAWT().GetDrawingSurface(component); - if (ds == null) { - // Widget not yet realized - unlockSurface(); - return LOCK_SURFACE_NOT_READY; - } - int res = ds.Lock(); - dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ; - if (!dsLocked) { - unlockSurface(); - throw new NativeWindowException("Unable to lock surface"); - } - // See whether the surface changed and if so destroy the old - // OpenGL context so it will be recreated (NOTE: removeNotify - // should handle this case, but it may be possible that race - // conditions can cause this code to be triggered -- should test - // more) - if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { - ret = LOCK_SURFACE_CHANGED; - } - dsi = ds.GetDrawingSurfaceInfo(); - if (dsi == null) { - unlockSurface(); - return LOCK_SURFACE_NOT_READY; - } - x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(); - if (x11dsi == null) { - unlockSurface(); - return LOCK_SURFACE_NOT_READY; - } - drawable = x11dsi.getDrawable(); - if (drawable == 0) { - unlockSurface(); - return LOCK_SURFACE_NOT_READY; - } else { - updateBounds(dsi.getBounds()); - } - return ret; - } finally { - // config.getNativeGraphicsConfiguration().getScreen().getDevice().unlock(); - // JAWTUtil.unlockToolkit(); + int ret = NativeWindow.LOCK_SUCCESS; + ds = JAWT.getJAWT().GetDrawingSurface(component); + if (ds == null) { + // Widget not yet realized + unlockSurface(); + return LOCK_SURFACE_NOT_READY; } + int res = ds.Lock(); + dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ; + if (!dsLocked) { + unlockSurface(); + throw new NativeWindowException("Unable to lock surface"); + } + // See whether the surface changed and if so destroy the old + // OpenGL context so it will be recreated (NOTE: removeNotify + // should handle this case, but it may be possible that race + // conditions can cause this code to be triggered -- should test + // more) + if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { + ret = LOCK_SURFACE_CHANGED; + } + dsi = ds.GetDrawingSurfaceInfo(); + if (dsi == null) { + unlockSurface(); + return LOCK_SURFACE_NOT_READY; + } + x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(); + if (x11dsi == null) { + unlockSurface(); + return LOCK_SURFACE_NOT_READY; + } + drawable = x11dsi.getDrawable(); + if (drawable == 0) { + unlockSurface(); + return LOCK_SURFACE_NOT_READY; + } else { + updateBounds(dsi.getBounds()); + } + return ret; } protected void unlockSurfaceImpl() throws NativeWindowException { - // JAWTUtil.lockToolkit(); - // config.getNativeGraphicsConfiguration().getScreen().getDevice().lock(); - try { - if(null!=ds) { - if (null!=dsi) { - ds.FreeDrawingSurfaceInfo(dsi); - } - if (dsLocked) { - ds.Unlock(); - } - JAWT.getJAWT().FreeDrawingSurface(ds); + if(null!=ds) { + if (null!=dsi) { + ds.FreeDrawingSurfaceInfo(dsi); + } + if (dsLocked) { + ds.Unlock(); } - ds = null; - dsi = null; - x11dsi = null; - } finally { - // config.getNativeGraphicsConfiguration().getScreen().getDevice().unlock(); - // JAWTUtil.unlockToolkit(); + JAWT.getJAWT().FreeDrawingSurface(ds); } + ds = null; + dsi = null; + x11dsi = null; } // Variables for lockSurface/unlockSurface diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java index 7cca6f9f3..081975afb 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java @@ -89,7 +89,7 @@ public class X11SunJDKReflection { } try { - return ((Integer) x11GraphicsDeviceGetScreenMethod.invoke(device, new Object[] {})).intValue(); + return ((Integer) x11GraphicsDeviceGetScreenMethod.invoke(device, null)).intValue(); } catch (Exception e) { return 0; } @@ -101,7 +101,7 @@ public class X11SunJDKReflection { } try { - return ((Long) x11GraphicsDeviceGetDisplayMethod.invoke(device, new Object[] {})).longValue(); + return ((Long) x11GraphicsDeviceGetDisplayMethod.invoke(device, null)).longValue(); } catch (Exception e) { return 0; } @@ -124,7 +124,7 @@ public class X11SunJDKReflection { } try { - return ((Integer) x11GraphicsConfigGetVisualMethod.invoke(config, new Object[] {})).intValue(); + return ((Integer) x11GraphicsConfigGetVisualMethod.invoke(config, null)).intValue(); } catch (Exception e) { return 0; } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java index fbf4524a4..87324a57c 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java @@ -38,13 +38,11 @@ import com.jogamp.nativewindow.impl.x11.XVisualInfo; import com.jogamp.nativewindow.impl.x11.X11Lib; public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory { - public AbstractGraphicsConfiguration - chooseGraphicsConfiguration(Capabilities capabilities, - CapabilitiesChooser chooser, - AbstractGraphicsScreen screen) + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) throws IllegalArgumentException, NativeWindowException { - if(null==screen || !(screen instanceof X11GraphicsScreen)) { + if(!(screen instanceof X11GraphicsScreen)) { throw new NativeWindowException("Only valid X11GraphicsScreen are allowed"); } return new X11GraphicsConfiguration((X11GraphicsScreen)screen, capabilities, capabilities, getXVisualInfo(screen, capabilities)); @@ -58,7 +56,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor int num[] = { -1 }; long display = screen.getDevice().getHandle(); - XVisualInfo[] xvis = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0); + XVisualInfo[] xvis = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0); if(xvis==null || num[0]<1) { return null; @@ -84,7 +82,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor vinfo_template.setC_class(c_class); long display = screen.getDevice().getHandle(); - XVisualInfo[] vinfos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0); + XVisualInfo[] vinfos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0); XVisualInfo best=null; int rdepth = capabilities.getRedBits() + capabilities.getGreenBits() + capabilities.getBlueBits() + capabilities.getAlphaBits(); for (int i = 0; vinfos!=null && i < num[0]; i++) { diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11ToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11ToolkitLock.java new file mode 100644 index 000000000..2e0e911b9 --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11ToolkitLock.java @@ -0,0 +1,55 @@ +/** + * Copyright 2010 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.nativewindow.impl.x11; + +import javax.media.nativewindow.ToolkitLock; + +/** + * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock} + * utilizing {@link X11Util#XLockDisplay(long)}. + * <br> + * This strategy should not be used in case XInitThreads() is being used, + * or a higher level toolkit lock is required, ie AWT lock. + */ +public class X11ToolkitLock implements ToolkitLock { + long displayHandle; + + public X11ToolkitLock(long displayHandle) { + this.displayHandle = displayHandle; + } + + public final void lock() { + if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock()"); } + X11Util.XLockDisplay(displayHandle); + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock()"); } + X11Util.XUnlockDisplay(displayHandle); + } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java index 6871cd5f2..3e991e52e 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java @@ -38,11 +38,15 @@ import java.util.Collection; import java.util.ArrayList; import java.util.Iterator; import com.jogamp.common.util.LongObjectHashMap; -import com.jogamp.common.util.RecursiveToolkitLock; +import com.jogamp.common.util.locks.RecursiveLock; import javax.media.nativewindow.*; import com.jogamp.nativewindow.impl.*; +import java.nio.Buffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; +import java.security.AccessController; /** * Contains a thread safe X11 utility to retrieve thread local display connection,<br> @@ -52,25 +56,58 @@ import com.jogamp.nativewindow.impl.*; * where an application heavily utilizing this class on temporary new threads.<br> */ public class X11Util { - private static final boolean DEBUG = Debug.debug("X11Util"); + private static final boolean DEBUG = Debug.debug("X11Util"); - public static final String nullDisplayName; + private static String nullDisplayName = null; + private static boolean isFirstX11ActionOnProcess = false; + private static boolean isInit = false; - static { - NWJNILibLoader.loadNativeWindow("x11"); + public static synchronized void initSingleton(boolean firstX11ActionOnProcess) { + if(!isInit) { + NWJNILibLoader.loadNativeWindow("x11"); - initialize( true ); + /** + * Always issue XInitThreads() since we have independent + * off-thread created Display connections able to utilize multithreading, ie NEWT */ + initialize( true ); + // initialize( firstX11ActionOnProcess ); + isFirstX11ActionOnProcess = firstX11ActionOnProcess; - long dpy = X11Lib.XOpenDisplay(null); - nullDisplayName = X11Lib.XDisplayString(dpy); - X11Lib.XCloseDisplay(dpy); - if(DEBUG) { - System.out.println("X11 Display(NULL) <"+nullDisplayName+">"); + if(DEBUG) { + System.out.println("X11Util.isFirstX11ActionOnProcess: "+isFirstX11ActionOnProcess); + } + isInit = true; } } - public static void initSingleton() { - // just exist to ensure static init has been run + public static boolean isFirstX11ActionOnProcess() { + return isFirstX11ActionOnProcess; + } + + public static String getNullDisplayName() { + if(null==nullDisplayName) { + synchronized(X11Util.class) { + if(null==nullDisplayName) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + long dpy = X11Lib.XOpenDisplay(null); + X11Util.XLockDisplay(dpy); + try { + nullDisplayName = X11Lib.XDisplayString(dpy); + } finally { + X11Util.XUnlockDisplay(dpy); + } + X11Lib.XCloseDisplay(dpy); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + if(DEBUG) { + System.out.println("X11 Display(NULL) <"+nullDisplayName+">"); + } + } + } + } + return nullDisplayName; } private X11Util() {} @@ -82,7 +119,7 @@ public class X11Util { private static ThreadLocal currentDisplayMap = new ThreadLocal(); - public static class NamedDisplay extends RecursiveToolkitLock implements Cloneable { + public static class NamedDisplay extends RecursiveLock implements Cloneable { String name; long handle; int refCount; @@ -147,7 +184,7 @@ public class X11Util { name = validateDisplayName(name); NamedDisplay namedDpy = getCurrentDisplay(name); if(null==namedDpy) { - long dpy = X11Lib.XOpenDisplay(name); + long dpy = XOpenDisplay(name); if(0==dpy) { throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName()); } @@ -199,7 +236,7 @@ public class X11Util { if(null==globalNamedDisplayMap.remove(dpy)) { throw new RuntimeException("Internal: "+namedDpy); } } if(!namedDpy.isUncloseable()) { - X11Lib.XCloseDisplay(dpy); + XCloseDisplay(dpy); } } else if(DEBUG) { Exception e = new Exception("X11Util.Display: Keep TLS "+namedDpy+" in thread "+Thread.currentThread().getName()); @@ -281,7 +318,7 @@ public class X11Util { /** Returns this created named display. */ public static long createDisplay(String name) { name = validateDisplayName(name); - long dpy = X11Lib.XOpenDisplay(name); + long dpy = XOpenDisplay(name); if(0==dpy) { throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection. Thread "+Thread.currentThread().getName()); } @@ -292,7 +329,7 @@ public class X11Util { globalNamedDisplayMap.put(dpy, namedDpy); } if(DEBUG) { - Exception e = new Exception("X11Util.Display: Created new global "+namedDpy+". Thread "+Thread.currentThread().getName()); + Exception e = new Exception("X11Util.Display: Created new "+namedDpy+". Thread "+Thread.currentThread().getName()); e.printStackTrace(); } return namedDpy.getHandle(); @@ -312,7 +349,7 @@ public class X11Util { } if(!namedDpy.isUncloseable()) { - X11Lib.XCloseDisplay(namedDpy.getHandle()); + XCloseDisplay(namedDpy.getHandle()); } } @@ -320,42 +357,331 @@ public class X11Util { * @return If name is null, it returns the previous queried NULL display name, * otherwise the name. */ public static String validateDisplayName(String name) { - return ( null == name ) ? nullDisplayName : name ; + return ( null == name ) ? getNullDisplayName() : name ; } public static String validateDisplayName(String name, long handle) { if(null==name && 0!=handle) { - name = getNameOfDisplay(handle); + name = XDisplayString(handle); } return validateDisplayName(name); } - public static boolean setSynchronizeDisplay(long handle, boolean onoff) { - boolean res = X11Lib.XSynchronize(handle, onoff); - return res; + /******************************* + ** + ** Locked X11Lib wrapped functions + ** + *******************************/ + public static long XOpenDisplay(String arg0) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + return X11Lib.XOpenDisplay(arg0); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + public static int XSync(long display, boolean discard) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XSync(display, discard); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static boolean XSynchronize(long display, boolean onoff) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XSynchronize(display, onoff); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static boolean XineramaEnabled(long display) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XineramaEnabled(display); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static int DefaultScreen(long display) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.DefaultScreen(display); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static long RootWindow(long display, int screen_number) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.RootWindow(display, screen_number); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static long XCreatePixmap(long display, long arg1, int arg2, int arg3, int arg4) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XCreatePixmap(display, arg1, arg2, arg3, arg4); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static String XDisplayString(long display) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XDisplayString(display); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static int XFlush(long display) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XFlush(display); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static int XFree(Buffer arg0) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + return X11Lib.XFree(arg0); + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static int XFreePixmap(long display, long arg1) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XFreePixmap(display, arg1); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static long DefaultVisualID(long display, int screen) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.DefaultVisualID(display, screen); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static long CreateDummyWindow(long display, int screen_index, long visualID) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.CreateDummyWindow(display, screen_index, visualID); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static void DestroyDummyWindow(long display, long window) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + X11Lib.DestroyDummyWindow(display, window); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static int XCloseDisplay(long display) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XCloseDisplay(display); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static XVisualInfo[] XGetVisualInfo(long display, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XGetVisualInfo(display, arg1, arg2, arg3, arg3_offset); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, green_array, blue_array); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, short[] red_array, int red_array_offset, short[] green_array, int green_array_offset, short[] blue_array, int blue_array_offset) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static boolean XF86VidModeGetGammaRampSize(long display, int screen, IntBuffer size) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static boolean XF86VidModeGetGammaRampSize(long display, int screen, int[] size, int size_offset) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size, size_offset); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } + } + + public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, green_array, blue_array); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } } - public static String getNameOfDisplay(long handle) { - String name = X11Lib.XDisplayString(handle); - return name; + public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, short[] red_array, int red_array_offset, short[] green_array, int green_array_offset, short[] blue_array, int blue_array_offset) { + NativeWindowFactory.getDefaultToolkitLock().lock(); + try { + X11Util.XLockDisplay(display); + try { + return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset); + } finally { + X11Util.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultToolkitLock().unlock(); + } } public static void XLockDisplay(long handle) { - if(DEBUG) { - System.out.println("... X11 Display Lock try 0x"+Long.toHexString(handle)); + if(ToolkitLock.TRACE_LOCK) { + System.out.println("+++ X11 Display Lock get 0x"+Long.toHexString(handle)); } X11Lib.XLockDisplay(handle); - if(DEBUG) { - System.out.println("+++ X11 Display Lock got 0x"+Long.toHexString(handle)); - } } public static void XUnlockDisplay(long handle) { - if(DEBUG) { + if(ToolkitLock.TRACE_LOCK) { System.out.println("--- X11 Display Lock rel 0x"+Long.toHexString(handle)); } X11Lib.XUnlockDisplay(handle); } - private static native void initialize(boolean initConcurrentThreadSupport); + private static native void initialize(boolean firstUIActionOnProcess); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java index c133df5b4..b003db8f5 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 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 @@ -56,7 +57,15 @@ public interface AbstractGraphicsDevice extends Cloneable { */ public long getHandle(); + /** + * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}. + * The lock implementation must be recursive. + */ public void lock(); + /** + * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}. + * The lock implementation must be recursive. + */ public void unlock(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java index e18b7b2dc..ca0f106f5 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java @@ -32,18 +32,46 @@ package javax.media.nativewindow; +import com.jogamp.nativewindow.impl.NativeWindowFactoryImpl; + public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice { private String type; protected long handle; + protected ToolkitLock toolkitLock; + /** + * Create an instance with the system default {@link ToolkitLock}, + * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}. + * @param type + */ public DefaultGraphicsDevice(String type) { this.type = type; this.handle = 0; + setToolkitLock( NativeWindowFactory.getDefaultToolkitLock(type) ); } + /** + * Create an instance with the system default {@link ToolkitLock}. + * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}. + * @param type + * @param handle + */ public DefaultGraphicsDevice(String type, long handle) { this.type = type; this.handle = handle; + setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(type, handle) ); + } + + /** + * Create an instance with the given {@link ToolkitLock} instance. + * @param type + * @param handle + * @param locker + */ + public DefaultGraphicsDevice(String type, long handle, ToolkitLock locker) { + this.type = type; + this.handle = handle; + setToolkitLock( locker ); } public Object clone() { @@ -62,10 +90,46 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice return handle; } - public void lock() { + /** + * Set the internal ToolkitLock, which is used within the + * {@link #lock()} and {@link #unlock()} implementation. + * + * @param locker the ToolkitLock, if null, {@link com.jogamp.nativewindow.impl.NullToolkitLock} is being used + */ + protected void setToolkitLock(ToolkitLock locker) { + this.toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ; + } + + /** + * @return the used ToolkitLock + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final ToolkitLock getToolkitLock() { + return toolkitLock; + } + + /** + * No lock is performed on the graphics device per default, + * instead the aggregated recursive {@link ToolkitLock#lock()} is invoked. + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final void lock() { + toolkitLock.lock(); } - public void unlock() { + /** + * No lock is performed on the graphics device per default, + * instead the aggregated recursive {@link ToolkitLock#unlock()} is invoked. + * + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) + * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock) + */ + public final void unlock() { + toolkitLock.unlock(); } public String toString() { diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java index 0a1a91876..75c8aea22 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java @@ -78,7 +78,7 @@ public abstract class GraphicsConfigurationFactory { if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) { try { GraphicsConfigurationFactory factory = (GraphicsConfigurationFactory) - ReflectionUtil.createInstance("com.jogamp.nativewindow.impl.x11.X11GraphicsConfigurationFactory", new Object[] {}, + ReflectionUtil.createInstance("com.jogamp.nativewindow.impl.x11.X11GraphicsConfigurationFactory", null, GraphicsConfigurationFactory.class.getClassLoader()); registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, factory); } catch (Exception e) { @@ -198,9 +198,29 @@ public abstract class GraphicsConfigurationFactory { * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) * @see javax.media.nativewindow.DefaultGraphicsConfiguration#setChosenCapabilities(Capabilities caps) */ - public abstract AbstractGraphicsConfiguration + public final AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) + throws IllegalArgumentException, NativeWindowException { + if(null==screen) { + throw new NativeWindowException("Screen is null"); + } + AbstractGraphicsDevice device = screen.getDevice(); + if(null==device) { + throw new NativeWindowException("Screen's Device is null"); + } + device.lock(); + try { + return chooseGraphicsConfigurationImpl(capabilities, chooser, screen); + } finally { + device.unlock(); + } + } + + protected abstract AbstractGraphicsConfiguration + chooseGraphicsConfigurationImpl(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen screen) throws IllegalArgumentException, NativeWindowException; } diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java index ef45a79d3..a5b71fbf8 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java @@ -1,6 +1,5 @@ /** * Copyright 2010 JogAmp Community. All rights reserved. - * Copyright (c) 2010 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: @@ -63,14 +62,17 @@ public interface NativeSurface extends SurfaceUpdatedListener { * This call allows recursion from the same thread.<P> * * The implementation may want to aquire the - * application level {@link com.jogamp.common.util.RecursiveToolkitLock} + * application level {@link com.jogamp.common.util.locks.RecursiveLock} * first before proceeding with a native surface lock. <P> * + * The implementation shall also invoke {@link AbstractGraphicsDevice#lock()} + * for the initial lock (recursive count zero).<P> + * * @return {@link #LOCK_SUCCESS}, {@link #LOCK_SURFACE_CHANGED} or {@link #LOCK_SURFACE_NOT_READY}. * * @throws RuntimeException after timeout when waiting for the surface lock * - * @see com.jogamp.common.util.RecursiveToolkitLock + * @see com.jogamp.common.util.locks.RecursiveLock */ public int lockSurface(); @@ -79,10 +81,13 @@ public interface NativeSurface extends SurfaceUpdatedListener { * * Shall not modify the surface handle, see {@link #lockSurface()} <P> * + * The implementation shall also invoke {@link AbstractGraphicsDevice#unlock()} + * for the final unlock (recursive count zero).<P> + * * @throws RuntimeException if surface is not locked * * @see #lockSurface - * @see com.jogamp.common.util.RecursiveToolkitLock + * @see com.jogamp.common.util.locks.RecursiveLock */ public void unlockSurface() throws NativeWindowException ; @@ -102,14 +107,6 @@ public interface NativeSurface extends SurfaceUpdatedListener { public Thread getSurfaceLockOwner(); /** - * Return the lock-exception, or null if not locked. - * - * The lock-exception is created at {@link #lockSurface()} - * and hence holds the locker's call stack. - */ - public Exception getSurfaceLockStack(); - - /** * Provide a mechanism to utilize custom (pre-) swap surface * code. This method is called before the render toolkit (e.g. JOGL) * swaps the buffer/surface. The implementation may itself apply the swapping, diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index f716e8ac9..7897460a0 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2008-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 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 @@ -32,13 +33,14 @@ package javax.media.nativewindow; -import java.lang.reflect.*; import java.security.*; import java.util.*; import com.jogamp.common.util.*; import com.jogamp.common.jvm.JVMUtil; import com.jogamp.nativewindow.impl.*; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; /** Provides a pluggable mechanism for arbitrary window toolkits to adapt their components to the {@link NativeWindow} interface, @@ -74,9 +76,20 @@ public abstract class NativeWindowFactory { private static String nativeOSNamePure; private static String nativeWindowingTypeCustom; private static String nativeOSNameCustom; - private static final boolean isAWTAvailable; + private static boolean isAWTAvailable; public static final String AWTComponentClassName = "java.awt.Component" ; + public static final String JAWTUtilClassName = "com.jogamp.nativewindow.impl.jawt.JAWTUtil" ; public static final String X11UtilClassName = "com.jogamp.nativewindow.impl.x11.X11Util"; + public static final String X11JAWTToolkitLockClassName = "com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock" ; + public static final String X11ToolkitLockClassName = "com.jogamp.nativewindow.impl.x11.X11ToolkitLock" ; + private static Class jawtUtilClass; + private static Method jawtUtilGetJAWTToolkitMethod; + private static Method jawtUtilInitMethod; + private static Class x11JAWTToolkitLockClass; + private static Constructor x11JAWTToolkitLockConstructor; + private static Class x11ToolkitLockClass; + private static Constructor x11ToolkitLockConstructor; + private static boolean isFirstUIActionOnProcess; /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ @@ -100,54 +113,117 @@ public abstract class NativeWindowFactory { static { JVMUtil.initSingleton(); + } - // Gather the windowing OS first - AccessControlContext acc = AccessController.getContext(); - nativeOSNamePure = Debug.getProperty("os.name", false, acc); - nativeWindowingTypePure = _getNativeWindowingType(nativeOSNamePure.toLowerCase()); - nativeOSNameCustom = Debug.getProperty("nativewindow.ws.name", true, acc); - if(null==nativeOSNameCustom||nativeOSNameCustom.length()==0) { - nativeOSNameCustom = nativeOSNamePure; - nativeWindowingTypeCustom = nativeWindowingTypePure; - } else { - nativeWindowingTypeCustom = nativeOSNameCustom; - } - - ClassLoader cl = NativeWindowFactory.class.getClassLoader(); + static boolean initialized = false; + + /** + * Static one time initialization of this factory.<br> + * This initialization method <b>must be called</b> once by the program or utilizing modules!<br> + * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program, + * otherwise <code>false</code>. + */ + public static synchronized void initSingleton(final boolean firstUIActionOnProcess) { + if(!initialized) { + initialized = true; + + if(DEBUG) { + Throwable td = new Throwable("Info: NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")"); + td.printStackTrace(); + } - if( TYPE_X11.equals(nativeWindowingTypePure) ) { - ReflectionUtil.callStaticMethod( X11UtilClassName, "initSingleton", new Class[] { }, new Object[] { }, cl ); - } + // Gather the windowing OS first + AccessControlContext acc = AccessController.getContext(); + nativeOSNamePure = Debug.getProperty("os.name", false, acc); + nativeWindowingTypePure = _getNativeWindowingType(nativeOSNamePure.toLowerCase()); + nativeOSNameCustom = Debug.getProperty("nativewindow.ws.name", true, acc); + if(null==nativeOSNameCustom||nativeOSNameCustom.length()==0) { + nativeOSNameCustom = nativeOSNamePure; + nativeWindowingTypeCustom = nativeWindowingTypePure; + } else { + nativeWindowingTypeCustom = nativeOSNameCustom; + } - registeredFactories = Collections.synchronizedMap(new HashMap()); + ClassLoader cl = NativeWindowFactory.class.getClassLoader(); - String factoryClassName = null; + if( TYPE_X11.equals(nativeWindowingTypePure) ) { + // explicit initialization of X11Util + ReflectionUtil.callStaticMethod(X11UtilClassName, "initSingleton", + new Class[] { boolean.class }, + new Object[] { new Boolean(firstUIActionOnProcess) }, cl ); + } + isFirstUIActionOnProcess = firstUIActionOnProcess; + + if( !Debug.getBooleanProperty("java.awt.headless", true, acc) && + ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) && + ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice", cl) ) { + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + jawtUtilClass = Class.forName(JAWTUtilClassName, false, NativeWindowFactory.class.getClassLoader()); + jawtUtilInitMethod = jawtUtilClass.getDeclaredMethod("initSingleton", null); + jawtUtilInitMethod.setAccessible(true); + jawtUtilGetJAWTToolkitMethod = jawtUtilClass.getDeclaredMethod("getJAWTToolkitLock", new Class[]{}); + jawtUtilGetJAWTToolkitMethod.setAccessible(true); + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return null; + } + }); + if(null != jawtUtilClass && null != jawtUtilGetJAWTToolkitMethod && null != jawtUtilInitMethod) { + ReflectionUtil.callMethod(null, jawtUtilInitMethod, null); + + Object resO = ReflectionUtil.callStaticMethod(JAWTUtilClassName, "isHeadlessMode", null, null, cl ); + if(resO instanceof Boolean) { + // AWT is only available in case all above classes are available + // and AWT is not int headless mode + isAWTAvailable = ((Boolean)resO).equals(Boolean.FALSE); + } else { + isAWTAvailable = false; + } + } else { + isAWTAvailable = false; + } + } else { + isAWTAvailable = false; + } - // register our default factory -> NativeWindow - NativeWindowFactory factory = new NativeWindowFactoryImpl(); - nativeWindowClass = javax.media.nativewindow.NativeWindow.class; - registerFactory(nativeWindowClass, factory); - defaultFactory = factory; - - // We break compile-time dependencies on the AWT here to - // make it easier to run this code on mobile devices - isAWTAvailable = !Debug.getBooleanProperty("java.awt.headless", true, acc) && - ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) && - ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice", cl) ; - - if ( isAWTAvailable ) { - // register either our default factory or (if exist) the X11/AWT one -> AWT Component - registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false, cl), factory); - } + registeredFactories = Collections.synchronizedMap(new HashMap()); + + // register our default factory -> NativeWindow + NativeWindowFactory factory = new NativeWindowFactoryImpl(); + nativeWindowClass = javax.media.nativewindow.NativeWindow.class; + registerFactory(nativeWindowClass, factory); + defaultFactory = factory; + + if ( isAWTAvailable ) { + // register either our default factory or (if exist) the X11/AWT one -> AWT Component + registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false, cl), factory); + } - if(DEBUG) { - System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+ - ", defaultFactory "+factory); + if( TYPE_X11 == nativeWindowingTypePure ) { + // passing through RuntimeException if not exists intended + x11ToolkitLockClass = ReflectionUtil.getClass(X11ToolkitLockClassName, false, cl); + x11ToolkitLockConstructor = ReflectionUtil.getConstructor(x11ToolkitLockClass, new Class[] { long.class } ); + if( isAWTAvailable() ) { + x11JAWTToolkitLockClass = ReflectionUtil.getClass(X11JAWTToolkitLockClassName, false, cl); + x11JAWTToolkitLockConstructor = ReflectionUtil.getConstructor(x11JAWTToolkitLockClass, new Class[] { long.class } ); + } + } + + if(DEBUG) { + System.err.println("NativeWindowFactory firstUIActionOnProcess "+firstUIActionOnProcess); + System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory); + } } } - public static void initSingleton() { - // just exist to ensure static init has been run + /** @return true if initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, + otherwise false. */ + public static boolean isFirstUIActionOnProcess() { + return isFirstUIActionOnProcess; } /** @return true if not headless, AWT Component and NativeWindow's AWT part available */ @@ -171,6 +247,91 @@ public abstract class NativeWindowFactory { return defaultFactory; } + /** + * Provides the system default {@link ToolkitLock}, a singleton instance. + * <br> + * This is a {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock} + * in case of a <b>X11 system</b> <em>and</em> <b>AWT availability</b> and if + * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> + * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + */ + public static ToolkitLock getDefaultToolkitLock() { + return getDefaultToolkitLock(getNativeWindowType(false)); + } + + /** + * Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance. + * <br> + * This is a {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock} + * in case of a <b>X11 type</b> or <b>AWT type / X11 system</b> <em>and</em> <b>AWT availability</b> and if + * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> + * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + */ + public static ToolkitLock getDefaultToolkitLock(String type) { + if( isAWTAvailable() && !isFirstUIActionOnProcess() && + ( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) ) { + return getAWTToolkitLock(); + } + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + + protected static ToolkitLock getAWTToolkitLock() { + Object resO = ReflectionUtil.callMethod(null, jawtUtilGetJAWTToolkitMethod, null); + + if(resO instanceof ToolkitLock) { + return (ToolkitLock) resO; + } else { + throw new RuntimeException("JAWTUtil.getJAWTToolkitLock() didn't return a ToolkitLock"); + } + } + + public static ToolkitLock getNullToolkitLock() { + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + /** + * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>. + * <br> + * This is a {@link com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock} + * in case of a <b>X11 type</b> <em>and</em> <b>AWT availability</b> and if + * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> + * or a {@link com.jogamp.nativewindow.impl.x11.X11ToolkitLock} + * in case of a <b>X11 type</b> <em>and</em> <b>no AWT availability</b> and if + * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> + * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + */ + public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) { + if( TYPE_X11 == type ) { + if( 0== deviceHandle ) { + throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11"); + } + if( !isFirstUIActionOnProcess() ) { + if( isAWTAvailable() ) { + return createX11AWTToolkitLock(deviceHandle); + } else { + return createX11ToolkitLock(deviceHandle); + } + } + } + return NativeWindowFactoryImpl.getNullToolkitLock(); + } + + protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) { + try { + return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + protected static ToolkitLock createX11ToolkitLock(long deviceHandle) { + try { + return (ToolkitLock) x11ToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + /** Returns the appropriate NativeWindowFactory to handle window objects of the given type. The windowClass might be {@link NativeWindow NativeWindow}, in which case the client has diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java new file mode 100644 index 000000000..09c89ebe3 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java @@ -0,0 +1,45 @@ +/** + * Copyright 2010 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 javax.media.nativewindow; + +import com.jogamp.nativewindow.impl.Debug; +import java.security.AccessController; + +/** + * Marker for a singleton global recursive blocking lock implementation, + * optionally locking a native windowing toolkit as well. + * <br> + * One use case is the AWT locking on X11, see {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock}. + */ +public interface ToolkitLock { + public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.TraceLock", true, AccessController.getContext()); + + public void lock(); + public void unlock(); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java index d326b9159..e91261211 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java @@ -43,17 +43,18 @@ import javax.media.nativewindow.*; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import javax.media.nativewindow.AbstractGraphicsDevice; -import com.jogamp.nativewindow.impl.*; /** A wrapper for an AWT GraphicsDevice allowing it to be handled in a toolkit-independent manner. */ public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneable { private GraphicsDevice device; + private String subType; protected AWTGraphicsDevice(GraphicsDevice device) { super(NativeWindowFactory.TYPE_AWT); this.device = device; + this.subType = null; } public static AbstractGraphicsDevice createDevice(GraphicsDevice awtDevice) { @@ -73,14 +74,23 @@ public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl /** * In case the native handle was specified, e.g. using X11, - * we shall be able to mark it. + * we shall be able to mark it.<br> + * This will also set the subType, queried with {@link #getSubType()} + * and reset the ToolkitLock type with {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)} + * and {@link #setToolkitLock(javax.media.nativewindow.ToolkitLock)}. */ - public void setHandle(long handle) { + public void setSubType(String subType, long handle) { this.handle = handle; + this.subType = subType; + setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(subType, handle) ); + } + + public String getSubType() { + return subType; } public String toString() { - return getClass().toString()+"[type "+getType()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]"; + return getClass().toString()+"[type "+getType()+"[subType "+getSubType()+"], awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]"; } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java index 192abf775..31744702d 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java @@ -33,14 +33,14 @@ package javax.media.nativewindow.x11; import javax.media.nativewindow.*; -import com.jogamp.nativewindow.impl.*; -import com.jogamp.nativewindow.impl.x11.X11Util; /** Encapsulates a graphics device on X11 platforms. */ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable { - /** Constructs a new X11GraphicsDevice corresponding to the given native display handle. */ + /** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default + * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}. + */ public X11GraphicsDevice(long display) { super(NativeWindowFactory.TYPE_X11, display); if(0==display) { @@ -48,17 +48,19 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl } } - public Object clone() { - return super.clone(); - } - - public void lock() { - X11Util.XLockDisplay(handle); + /** + * @param display the Display connection + * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT + */ + public X11GraphicsDevice(long display, ToolkitLock locker) { + super(NativeWindowFactory.TYPE_X11, display, locker); + if(0==display) { + throw new NativeWindowException("null display"); + } } - public void unlock() { - X11Util.XUnlockDisplay(handle); + public Object clone() { + return super.clone(); } - } diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java index 97bdc37cf..73af5f852 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java @@ -34,7 +34,6 @@ package javax.media.nativewindow.x11; import javax.media.nativewindow.*; import com.jogamp.nativewindow.impl.x11.X11Util; -import com.jogamp.nativewindow.impl.x11.X11Lib; /** Encapsulates a screen index on X11 platforms. Objects of this type are passed to {@link @@ -57,21 +56,21 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl /** Creates a new X11GraphicsScreen using a thread local display connection */ public static AbstractGraphicsScreen createDefault() { long display = X11Util.createThreadLocalDisplay(null); - int scrnIdx = X11Lib.DefaultScreen(display); + int scrnIdx = X11Util.DefaultScreen(display); return createScreenDevice(display, scrnIdx); } public long getDefaultVisualID() { // It still could be an AWT hold handle .. long display = getDevice().getHandle(); - int scrnIdx = X11Lib.DefaultScreen(display); - return X11Lib.DefaultVisualID(display, scrnIdx); + int scrnIdx = X11Util.DefaultScreen(display); + return X11Util.DefaultVisualID(display, scrnIdx); } private static int fetchScreen(X11GraphicsDevice device, int screen) { // It still could be an AWT hold handle .. long display = device.getHandle(); - if(X11Lib.XineramaEnabled(display)) { + if(X11Util.XineramaEnabled(display)) { screen = 0; // Xinerama -> 1 screen } return screen; diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index 2c61a71ef..31d57240f 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -32,6 +32,7 @@ #include <string.h> #include <stdarg.h> #include <unistd.h> +#include <errno.h> #include <X11/Xlib.h> #include <X11/Xutil.h> /* Linux headers don't work properly */ @@ -85,30 +86,12 @@ Bool XF86VidModeSetGammaRamp( #ifdef VERBOSE_ON // Workaround for ancient compiler on Solaris/SPARC - // #define DBG_PRINT(args...) fprintf(stderr, args); - #define DBG_PRINT0(str) fprintf(stderr, str); - #define DBG_PRINT1(str, arg1) fprintf(stderr, str, arg1); - #define DBG_PRINT2(str, arg1, arg2) fprintf(stderr, str, arg1, arg2); - #define DBG_PRINT3(str, arg1, arg2, arg3) fprintf(stderr, str, arg1, arg2, arg3); - #define DBG_PRINT4(str, arg1, arg2, arg3, arg4) fprintf(stderr, str, arg1, arg2, arg3, arg4); - #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5); - #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6); - #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + #define DBG_PRINT(args...) fprintf(stderr, args); #else // Workaround for ancient compiler on Solaris/SPARC - // #define DBG_PRINT(args...) - #define DBG_PRINT0(str) - #define DBG_PRINT1(str, arg1) - #define DBG_PRINT2(str, arg1, arg2) - #define DBG_PRINT3(str, arg1, arg2, arg3) - #define DBG_PRINT4(str, arg1, arg2, arg3, arg4) - #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5) - #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) - #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) - #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + #define DBG_PRINT(args...) #endif @@ -201,18 +184,29 @@ static XErrorHandler origErrorHandler = NULL ; static int x11ErrorHandler(Display *dpy, XErrorEvent *e) { - _throwNewRuntimeException(NULL, x11ErrorHandlerJNIEnv, "Nativewindow X11 Error: Display %p, Code 0x%X", dpy, e->error_code); + fprintf(stderr, "Nativewindow X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno)); + _throwNewRuntimeException(NULL, x11ErrorHandlerJNIEnv, "Nativewindow X11 Error: Display %p, Code 0x%X, errno %s", + dpy, e->error_code, strerror(errno)); + if(NULL!=origErrorHandler) { + origErrorHandler(dpy, e); + } return 0; } -static void x11ErrorHandlerEnable(int onoff, JNIEnv * env) { +static void x11ErrorHandlerEnable(Display *dpy, int onoff, JNIEnv * env) { if(onoff) { if(NULL==origErrorHandler) { x11ErrorHandlerJNIEnv = env; + if(NULL!=dpy) { + XSync(dpy, False); + } origErrorHandler = XSetErrorHandler(x11ErrorHandler); } } else { + if(NULL!=dpy) { + XSync(dpy, False); + } XSetErrorHandler(origErrorHandler); origErrorHandler = NULL; } @@ -223,8 +217,11 @@ static XIOErrorHandler origIOErrorHandler = NULL; static int x11IOErrorHandler(Display *dpy) { - _FatalError(x11ErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p not available", dpy); - origIOErrorHandler(dpy); + fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, XDisplayName(NULL), strerror(errno)); + // _FatalError(x11ErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, XDisplayName(NULL), strerror(errno)); + if(NULL!=origIOErrorHandler) { + origIOErrorHandler(dpy); + } return 0; } @@ -243,9 +240,9 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) { static int _initialized=0; JNIEXPORT void JNICALL -Java_com_jogamp_nativewindow_impl_x11_X11Util_initialize(JNIEnv *env, jclass _unused, jboolean initConcurrentThreadSupport) { +Java_com_jogamp_nativewindow_impl_x11_X11Util_initialize(JNIEnv *env, jclass _unused, jboolean firstUIActionOnProcess) { if(0==_initialized) { - if( JNI_TRUE == initConcurrentThreadSupport ) { + if( JNI_TRUE == firstUIActionOnProcess ) { if( 0 == XInitThreads() ) { fprintf(stderr, "Warning: XInitThreads() failed\n"); } else { @@ -256,7 +253,6 @@ Java_com_jogamp_nativewindow_impl_x11_X11Util_initialize(JNIEnv *env, jclass _un } _initClazzAccess(env); - x11ErrorHandlerEnable(1, env); x11IOErrorHandlerEnable(1, env); _initialized=1; } @@ -284,7 +280,9 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBu if (arg3 != NULL) { _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset); } + x11ErrorHandlerEnable((Display *) (intptr_t) arg0, 1, env); _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3); + x11ErrorHandlerEnable((Display *) (intptr_t) arg0, 0, env); count = _ptr3[0]; if (arg3 != NULL) { (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0); @@ -305,7 +303,9 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass if(0==display) { _FatalError(env, "invalid display connection.."); } + x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env); r = (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) ); + x11ErrorHandlerEnable((Display *) (intptr_t) display, 0, env); return r; } @@ -346,7 +346,9 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclas if(0==display) { _FatalError(env, "invalid display connection.."); } + x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env); _res = XCloseDisplay((Display *) (intptr_t) display); + x11ErrorHandlerEnable(NULL, 0, env); return _res; } @@ -384,7 +386,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy return 0; } - XSync(dpy, False); + x11ErrorHandlerEnable(dpy, 1, env); scrn = ScreenOfDisplay(dpy, scrn_idx); @@ -400,10 +402,11 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy XFree(pVisualQuery); pVisualQuery=NULL; } - DBG_PRINT5( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual); + DBG_PRINT( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual); if (visual==NULL) { + x11ErrorHandlerEnable(dpy, 0, env); _throwNewRuntimeException(dpy, env, "could not query Visual by given VisualID, bail out!"); return 0; } @@ -440,9 +443,9 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy attrMask, &xswa); - XSync(dpy, False); + x11ErrorHandlerEnable(dpy, 0, env); - DBG_PRINT2( "X11: [CreateWindow] created window %p on display %p\n", window, dpy); + DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy); return (jlong) window; } @@ -464,9 +467,10 @@ JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_DestroyDummy return; } - XSync(dpy, False); + x11ErrorHandlerEnable(dpy, 1, env); XUnmapWindow(dpy, w); XSync(dpy, False); XDestroyWindow(dpy, w); - XSync(dpy, False); + x11ErrorHandlerEnable(dpy, 0, env); } + diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java index 5f969777a..e01e04304 100644 --- a/src/newt/classes/com/jogamp/newt/NewtFactory.java +++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java @@ -34,12 +34,8 @@ package com.jogamp.newt; -import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.*; -import java.util.ArrayList; -import java.util.Iterator; import com.jogamp.common.jvm.JVMUtil; -import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.impl.DisplayImpl; import com.jogamp.newt.impl.ScreenImpl; @@ -53,6 +49,7 @@ public class NewtFactory { // between native Newt and (apparently) Fmod static { JVMUtil.initSingleton(); + NativeWindowFactory.initSingleton(false); // last resort .. WindowImpl.init(NativeWindowFactory.getNativeWindowType(true)); } diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java index bbe648c42..61858b083 100644 --- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java @@ -73,6 +73,7 @@ public class NEWTEvent extends java.util.EventObject { static final String WindowClazzName = "com.jogamp.newt.Window" ; static final String AWTNewtEventFactoryClazzName = "com.jogamp.newt.event.awt.AWTNewtEventFactory" ; + /** static final boolean evaluateIsSystemEvent(NEWTEvent event, Throwable t) { StackTraceElement[] stack = t.getStackTrace(); if(stack.length==0 || null==stack[0]) { @@ -104,11 +105,12 @@ public class NEWTEvent extends java.util.EventObject { System.err.println("system: "+res); } return res; - } + } */ protected NEWTEvent(int eventType, Object source, long when) { super(source); - this.isSystemEvent = evaluateIsSystemEvent(this, new Throwable()); + // this.isSystemEvent = evaluateIsSystemEvent(this, new Throwable()); + this.isSystemEvent = false; // FIXME: Need a more efficient way to determine system events this.eventType = eventType; this.when = when; this.attachment=null; diff --git a/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java b/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java index 0d9e295bd..840411984 100644 --- a/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java @@ -349,7 +349,7 @@ public abstract class DisplayImpl extends Display { if(!isEDTRunning()) { // oops .. we are already dead if(DEBUG) { - Throwable t = new Throwable("EDT already stopped: wait:="+wait+", "+e); + Throwable t = new Throwable("Warning: EDT already stopped: wait:="+wait+", "+e); t.printStackTrace(); } return; @@ -371,14 +371,6 @@ public abstract class DisplayImpl extends Display { } } - public void lock() { - aDevice.lock(); - } - - public void unlock() { - aDevice.unlock(); - } - protected EDTUtil edtUtil = null; protected int id; protected String name; diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java index ae2b7c6e1..a0879a634 100644 --- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java @@ -42,10 +42,9 @@ import com.jogamp.newt.event.*; import com.jogamp.common.util.*; import javax.media.nativewindow.*; -import com.jogamp.common.util.RecursiveToolkitLock; +import com.jogamp.common.util.locks.RecursiveLock; import java.util.ArrayList; -import java.util.Iterator; import java.lang.reflect.Method; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; @@ -161,7 +160,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } private LifecycleHook lifecycleHook = null; - private RecursiveToolkitLock windowLock = new RecursiveToolkitLock(); + private RecursiveLock windowLock = new RecursiveLock(); private long windowHandle; private ScreenImpl screen; private boolean screenReferenced = false; @@ -293,17 +292,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // public final int lockSurface() { - // We leave the ToolkitLock lock to the specializtion's discretion, - // ie the implicit JAWTWindow in case of AWTWindow + int res = LOCK_SURFACE_NOT_READY; - // may throw RuntimeException if timed out while waiting for lock windowLock.lock(); - int res = lockSurfaceImpl(); - if(!isNativeValid()) { - windowLock.unlock(); - res = LOCK_SURFACE_NOT_READY; + screen.getDisplay().getGraphicsDevice().lock(); + try { + res = lockSurfaceImpl(); + } finally { + if(!isNativeValid()) { + screen.getDisplay().getGraphicsDevice().unlock(); + windowLock.unlock(); + res = LOCK_SURFACE_NOT_READY; + } } + return res; } @@ -311,11 +314,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // may throw RuntimeException if not locked windowLock.validateLocked(); - unlockSurfaceImpl(); - + try { + unlockSurfaceImpl(); + } finally { + screen.getDisplay().getGraphicsDevice().unlock(); + } windowLock.unlock(); - // We leave the ToolkitLock unlock to the specializtion's discretion, - // ie the implicit JAWTWindow in case of AWTWindow } public final boolean isSurfaceLockedByOtherThread() { @@ -330,10 +334,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return windowLock.getOwner(); } - public final Exception getSurfaceLockStack() { - return windowLock.getLockedStack(); - } - public long getSurfaceHandle() { return windowHandle; // default: return window handle } @@ -437,8 +437,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(!visible && childWindows.size()>0) { synchronized(childWindowsLock) { - for(Iterator i = childWindows.iterator(); i.hasNext(); ) { - NativeWindow nw = (NativeWindow) i.next(); + for(int i = 0; i < childWindows.size(); i++ ) { + NativeWindow nw = (NativeWindow) childWindows.get(i); if(nw instanceof WindowImpl) { ((WindowImpl)nw).setVisible(false); } @@ -464,8 +464,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(0!=windowHandle && visible && childWindows.size()>0) { synchronized(childWindowsLock) { - for(Iterator i = childWindows.iterator(); i.hasNext(); ) { - NativeWindow nw = (NativeWindow) i.next(); + for(int i = 0; i < childWindows.size(); i++ ) { + NativeWindow nw = (NativeWindow) childWindows.get(i); if(nw instanceof WindowImpl) { ((WindowImpl)nw).setVisible(true); } @@ -478,7 +478,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } finally { windowLock.unlock(); } - getScreen().getDisplay().dispatchMessages(); // status up2date } } @@ -885,7 +884,24 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate); runOnEDTIfAvail(true, reparentAction); reparentActionStrategy = reparentAction.getStrategy(); - if( isVisible() ) { + boolean sizeSignaled=false; + if(null!=newParent) { + // refit if size is bigger than parent + int w = getWidth(); + int h = getHeight(); + if(w>newParent.getWidth()) { + w=newParent.getWidth(); + sizeSignaled=true; + } + if(h>newParent.getHeight()) { + h=newParent.getHeight(); + sizeSignaled=true; + } + if(sizeSignaled) { + setSize(w, h); + } + } + if( !sizeSignaled && isVisible() ) { sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener } } finally { @@ -920,7 +936,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } public void setUndecorated(boolean value) { - if(this.undecorated != value) { + if(!fullscreen && this.undecorated != value) { undecorated = value; if( 0 != windowHandle ) { reconfigureWindowImpl(x, y, width, height); @@ -929,10 +945,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - public boolean isUndecorated(boolean fullscreen) { - return 0 != getParentWindowHandle() || undecorated || fullscreen ; - } - public boolean isUndecorated() { return 0 != parentWindowHandle || undecorated || fullscreen ; } @@ -1037,20 +1049,20 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer "\n, ChildWindows "+childWindows.size()); sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedListeners.size()+" ["); - for (Iterator iter = surfaceUpdatedListeners.iterator(); iter.hasNext(); ) { - sb.append(iter.next()+", "); + for (int i = 0; i < surfaceUpdatedListeners.size(); i++ ) { + sb.append(surfaceUpdatedListeners.get(i)+", "); } sb.append("], WindowListeners num "+windowListeners.size()+" ["); - for (Iterator iter = windowListeners.iterator(); iter.hasNext(); ) { - sb.append(iter.next()+", "); + for (int i = 0; i < windowListeners.size(); i++ ) { + sb.append(windowListeners.get(i)+", "); } sb.append("], MouseListeners num "+mouseListeners.size()+" ["); - for (Iterator iter = mouseListeners.iterator(); iter.hasNext(); ) { - sb.append(iter.next()+", "); + for (int i = 0; i < mouseListeners.size(); i++ ) { + sb.append(mouseListeners.get(i)+", "); } sb.append("], KeyListeners num "+keyListeners.size()+" ["); - for (Iterator iter = keyListeners.iterator(); iter.hasNext(); ) { - sb.append(iter.next()+", "); + for (int i = 0; i < keyListeners.size(); i++ ) { + sb.append(keyListeners.get(i)+", "); } sb.append("] ]"); return sb.toString(); @@ -1321,8 +1333,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void surfaceUpdated(Object updater, NativeSurface ns, long when) { synchronized(surfaceUpdatedListenersLock) { - for(Iterator i = surfaceUpdatedListeners.iterator(); i.hasNext(); ) { - SurfaceUpdatedListener l = (SurfaceUpdatedListener) i.next(); + for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) { + SurfaceUpdatedListener l = (SurfaceUpdatedListener) surfaceUpdatedListeners.get(i); l.surfaceUpdated(updater, ns, when); } } @@ -1446,8 +1458,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println("consumeMouseEvent: event: "+e); } - for(Iterator i = mouseListeners.iterator(); i.hasNext(); ) { - MouseListener l = (MouseListener) i.next(); + for(int i = 0; i < mouseListeners.size(); i++ ) { + MouseListener l = (MouseListener) mouseListeners.get(i); switch(e.getEventType()) { case MouseEvent.EVENT_MOUSE_CLICKED: l.mouseClicked(e); @@ -1534,8 +1546,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(DEBUG_KEY_EVENT) { System.err.println("consumeKeyEvent: "+e); } - for(Iterator i = keyListeners.iterator(); i.hasNext(); ) { - KeyListener l = (KeyListener) i.next(); + for(int i = 0; i < keyListeners.size(); i++ ) { + KeyListener l = (KeyListener) keyListeners.get(i); switch(e.getEventType()) { case KeyEvent.EVENT_KEY_PRESSED: l.keyPressed(e); @@ -1606,10 +1618,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer protected void consumeWindowEvent(WindowEvent e) { if(DEBUG_WINDOW_EVENT) { - System.err.println("consumeWindowEvent: "+e); + System.err.println("consumeWindowEvent: "+e+", visible "+isVisible()+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); } - for(Iterator i = windowListeners.iterator(); i.hasNext(); ) { - WindowListener l = (WindowListener) i.next(); + for(int i = 0; i < windowListeners.size(); i++ ) { + WindowListener l = (WindowListener) windowListeners.get(i); switch(e.getEventType()) { case WindowEvent.EVENT_WINDOW_RESIZED: l.windowResized(e); diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java index 8750a8bc1..bbf75798e 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java @@ -90,7 +90,7 @@ public class AWTCanvas extends Canvas { */ awtConfig = chooseGraphicsConfiguration(capabilities, device); if(Window.DEBUG_IMPLEMENTATION) { - Exception e = new Exception("Created Config: "+awtConfig); + Exception e = new Exception("Info: Created Config: "+awtConfig); e.printStackTrace(); } if(null!=awtConfig) { @@ -157,7 +157,7 @@ public class AWTCanvas extends Canvas { AWTGraphicsConfiguration config = chooseGraphicsConfiguration((Capabilities)awtConfig.getRequestedCapabilities(), gc.getDevice()); final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null; if(Window.DEBUG_IMPLEMENTATION) { - Exception e = new Exception("Call Stack: "+Thread.currentThread().getName()); + Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName()); e.printStackTrace(); System.err.println("!!! Created Config (n): HAVE GC "+chosen); System.err.println("!!! Created Config (n): THIS GC "+gc); diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java index 1f481e28b..5abff047f 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java @@ -246,7 +246,7 @@ public class AWTWindow extends WindowImpl { public void run() { if(null!=frame) { if(!container.isDisplayable()) { - frame.setUndecorated(isUndecorated(fullscreen)); + frame.setUndecorated(isUndecorated()); } else { if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { System.err.println("AWTWindow can't undecorate already created frame"); diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java index a2b7cd335..15cadb05f 100644 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java @@ -35,7 +35,7 @@ package com.jogamp.newt.impl.macosx; import javax.media.nativewindow.*; -import com.jogamp.common.util.RecursiveToolkitLock; +import com.jogamp.common.util.locks.RecursiveLock; import com.jogamp.newt.event.*; import com.jogamp.newt.impl.*; @@ -132,7 +132,6 @@ public class MacWindow extends WindowImpl { private volatile long surfaceHandle; // non fullscreen dimensions .. - private int nfs_width, nfs_height, nfs_x, nfs_y; private final Insets insets = new Insets(0,0,0,0); static { @@ -158,7 +157,7 @@ public class MacWindow extends WindowImpl { } } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("closeNative failed - "+Thread.currentThread().getName(), t); + Exception e = new Exception("Warning: closeNative failed - "+Thread.currentThread().getName(), t); e.printStackTrace(); } } finally { @@ -184,7 +183,7 @@ public class MacWindow extends WindowImpl { } } - private RecursiveToolkitLock nsViewLock = new RecursiveToolkitLock(); + private RecursiveLock nsViewLock = new RecursiveLock(); protected int lockSurfaceImpl() { nsViewLock.lock(); @@ -394,7 +393,7 @@ public class MacWindow extends WindowImpl { } setWindowHandle(createWindow0(getParentWindowHandle(), x, y, width, height, fullscreen, - (isUndecorated(fullscreen) ? + (isUndecorated() ? NSBorderlessWindowMask : NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask), NSBackingStoreBuffered, diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index 3c922b9e7..3ade599da 100644 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -76,7 +76,7 @@ public class WindowsWindow extends WindowImpl { long _hmon = MonitorFromWindow0(getWindowHandle()); if (hmon != _hmon) { if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - Exception e = new Exception("!!! Window Device Changed "+Thread.currentThread().getName()+ + Exception e = new Exception("Info: Window Device Changed "+Thread.currentThread().getName()+ ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon)); e.printStackTrace(); } @@ -102,7 +102,7 @@ public class WindowsWindow extends WindowImpl { } windowHandleClose = getWindowHandle(); if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - Exception e = new Exception("!!! Window new window handle "+Thread.currentThread().getName()+ + Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+ " (Parent HWND "+toHexString(getParentWindowHandle())+ ") : HWND "+toHexString(getWindowHandle())+", "+Thread.currentThread()); e.printStackTrace(); @@ -116,7 +116,7 @@ public class WindowsWindow extends WindowImpl { ReleaseDC0(windowHandleClose, hdc); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("closeNativeImpl failed - "+Thread.currentThread().getName(), t); + Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); e.printStackTrace(); } } @@ -128,7 +128,7 @@ public class WindowsWindow extends WindowImpl { DestroyWindow0(windowHandleClose); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("closeNativeImpl failed - "+Thread.currentThread().getName(), t); + Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); e.printStackTrace(); } } finally { @@ -157,7 +157,7 @@ public class WindowsWindow extends WindowImpl { } protected void reconfigureWindowImpl(int x, int y, int width, int height) { - reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getWindowHandle(), x, y, width, height, isUndecorated(fullscreen)); + reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getWindowHandle(), x, y, width, height, isUndecorated()); } protected boolean reparentWindowImpl() { diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java index f96625d8e..7f315d785 100644 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java @@ -76,7 +76,7 @@ public class X11Display extends DisplayImpl { X11Util.closeDisplay(handle); throw e; } - aDevice = new X11GraphicsDevice(handle); + aDevice = new X11GraphicsDevice(handle, NativeWindowFactory.getNullToolkitLock()); } protected void closeNativeImpl() { diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java index f9fce6fc1..80e5068b4 100644 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -76,7 +76,7 @@ public class X11Window extends WindowImpl { display.getJavaObjectAtom(), display.getWindowDeleteAtom()); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("closeNativeImpl failed - "+Thread.currentThread().getName(), t); + Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); e.printStackTrace(); } } finally { @@ -105,7 +105,7 @@ public class X11Window extends WindowImpl { protected void reconfigureWindowImpl(int x, int y, int width, int height) { reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getDisplayHandle(), getScreenIndex(), getWindowHandle(), - x, y, width, height, isUndecorated(fullscreen), isVisible()); + x, y, width, height, isUndecorated(), isVisible()); } protected boolean reparentWindowImpl() { diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 97afab903..50fe3f63a 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -405,23 +405,34 @@ public class GLWindow implements GLAutoDrawable, Window { } public void addGLEventListener(GLEventListener listener) { - helper.addGLEventListener(listener); + if(null!=helper) { + helper.addGLEventListener(listener); + } } public void addGLEventListener(int index, GLEventListener listener) { - helper.addGLEventListener(index, listener); + if(null!=helper) { + helper.addGLEventListener(index, listener); + } } public void removeGLEventListener(GLEventListener listener) { - helper.removeGLEventListener(listener); + if(null!=helper) { + helper.removeGLEventListener(listener); + } } public void setAnimator(GLAnimatorControl animatorControl) { - helper.setAnimator(animatorControl); + if(null!=helper) { + helper.setAnimator(animatorControl); + } } public GLAnimatorControl getAnimator() { - return helper.getAnimator(); + if(null!=helper) { + return helper.getAnimator(); + } + return null; } public boolean getPerfLogEnabled() { return perfLog; } @@ -431,7 +442,9 @@ public class GLWindow implements GLAutoDrawable, Window { } public void invoke(boolean wait, GLRunnable glRunnable) { - helper.invoke(this, wait, glRunnable); + if(null!=helper) { + helper.invoke(this, wait, glRunnable); + } } public void display() { @@ -468,12 +481,17 @@ public class GLWindow implements GLAutoDrawable, Window { /** This implementation uses a static value */ public void setAutoSwapBufferMode(boolean onOrOff) { - helper.setAutoSwapBufferMode(onOrOff); + if(null!=helper) { + helper.setAutoSwapBufferMode(onOrOff); + } } /** This implementation uses a static value */ public boolean getAutoSwapBufferMode() { - return helper.getAutoSwapBufferMode(); + if(null!=helper) { + return helper.getAutoSwapBufferMode(); + } + return false; } public void swapBuffers() { @@ -766,10 +784,6 @@ public class GLWindow implements GLAutoDrawable, Window { } - public final Exception getSurfaceLockStack() { - return window.getSurfaceLockStack(); - } - public final boolean surfaceSwap() { return window.surfaceSwap(); } |