diff options
author | Sven Gothel <[email protected]> | 2012-09-07 08:13:06 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-09-07 08:13:06 +0200 |
commit | f2cfb6119a3663715ed2d572643949b3bef58662 (patch) | |
tree | 7a31217a343c16e81549fab8beed1a1012e13156 | |
parent | ffcfd35929407c75308ab41883463bc8c8a89b91 (diff) |
Cleanup shutdown mechanism ; Fix X11/ATI SIGV at shutdown ; EGLDisplayUtil: Check for leaked display handles
GLProfile / all shutdown methods: Remove ShutdownType to remove complexity (not required)
Proper shutdown sequence:
GLProfile - GLDrawableFactory+ - GLContext - NativeWindowFactory - [X11Util, OSXUtil, ..]
GLDrawableFactory: Always keep shutdown-hook alive, required for X11Util shutdown (@ JVMShutdown only)
X11Util: Shutdown
- @ JVMShutdown only
- If GL vendor ATI: close pending X11 display connections in proper order of creation.
This finally removes the SIGV when shutting down the JVM on X11 w/ ATI driver.
EGLDisplayUtil: Add shutdown, allowing to validate whether leaked EGL display handles remain.
21 files changed, 243 insertions, 429 deletions
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat index 669e0212e..22cce49aa 100755 --- a/make/scripts/tests-x64.bat +++ b/make/scripts/tests-x64.bat @@ -1,7 +1,9 @@ REM scripts\java-win64-dbg.bat jogamp.newt.awt.opengl.VersionApplet REM scripts\java-win64-dbg.bat com.jogamp.newt.opengl.GLWindow REM scripts\java-win64-dbg.bat javax.media.opengl.awt.GLCanvas -scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $* +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $* +scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $* +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $* REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %* REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 1314094cf..5668893f7 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -53,6 +53,7 @@ function jrun() { swton=$1 shift + #D_ARGS="-Djogl.disable.opengles" #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.GLSLCode -Dnewt.debug.Window.MouseEvent" #D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode" #D_ARGS="-Djogl.debug.FBObject" @@ -217,12 +218,12 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFloatUtil01MatrixMatrixMultNOUI $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextSurfaceLockNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $* @@ -260,7 +261,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00bNEWT -#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT +testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01bNEWT #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT #testnoawt com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT @@ -281,7 +282,6 @@ function testawtswt() { #testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestPBufferDeadlockAWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $* -#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedAWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.x11.TestGLXCallsOnAWT $* #testawt com.jogamp.opengl.test.junit.jogl.awt.TestSwingAWT01GLn #testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01 $* @@ -379,7 +379,6 @@ function testawtswt() { # # FBO / .. # -testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable00NEWT $* @@ -429,11 +428,6 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $* #testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $* #linux: -# EARMARK removal of shutdown mode! -#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $* -#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedAWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT $* # osx: #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable02NEWT $* diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index acda45bff..9fd895c1f 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -55,7 +55,6 @@ import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.ProxySurface; import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook; -import javax.media.opengl.GLProfile.ShutdownType; import jogamp.opengl.Debug; @@ -106,6 +105,7 @@ public abstract class GLDrawableFactory { // Shutdown hook mechanism for the factory private static boolean factoryShutdownHookRegistered = false; private static Thread factoryShutdownHook = null; + private static volatile boolean isJVMShuttingDown = false; /** * Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones. @@ -176,21 +176,24 @@ public abstract class GLDrawableFactory { } } - protected static void shutdown(ShutdownType shutdownType) { + protected static void shutdown() { if (isInit) { // volatile: ok synchronized (GLDrawableFactory.class) { if (isInit) { isInit=false; - unregisterFactoryShutdownHook(); - shutdownImpl(shutdownType); + shutdownImpl(); } } } } - private static void shutdownImpl(ShutdownType shutdownType) { + + private static void shutdownImpl() { + // Following code will _always_ remain in shutdown hook + // due to special semantics of native utils, i.e. X11Utils. + // The latter requires shutdown at JVM-Shutdown only. synchronized(glDrawableFactories) { for(int i=0; i<glDrawableFactories.size(); i++) { - glDrawableFactories.get(i).destroy(shutdownType); + glDrawableFactories.get(i).destroy(); } glDrawableFactories.clear(); @@ -198,6 +201,8 @@ public abstract class GLDrawableFactory { nativeOSFactory = null; eglFactory = null; } + GLContext.shutdown(); + NativeWindowFactory.shutdown(isJVMShuttingDown); } private static synchronized void registerFactoryShutdownHook() { @@ -206,7 +211,8 @@ public abstract class GLDrawableFactory { } factoryShutdownHook = new Thread(new Runnable() { public void run() { - GLDrawableFactory.shutdownImpl(GLProfile.ShutdownType.COMPLETE); + isJVMShuttingDown = true; + GLDrawableFactory.shutdownImpl(); } }); AccessController.doPrivileged(new PrivilegedAction<Object>() { @@ -218,20 +224,6 @@ public abstract class GLDrawableFactory { factoryShutdownHookRegistered = true; } - private static synchronized void unregisterFactoryShutdownHook() { - if (!factoryShutdownHookRegistered) { - return; - } - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - Runtime.getRuntime().removeShutdownHook(factoryShutdownHook); - return null; - } - }); - factoryShutdownHookRegistered = false; - } - - protected GLDrawableFactory() { synchronized(glDrawableFactories) { glDrawableFactories.add(this); @@ -244,7 +236,7 @@ public abstract class GLDrawableFactory { protected void enterThreadCriticalZone() {}; protected void leaveThreadCriticalZone() {}; - protected abstract void destroy(ShutdownType shutdownType); + protected abstract void destroy(); /** * Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection}, diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 513ccd101..23d789afd 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -198,44 +198,25 @@ public class GLProfile { getProfileMap(device, true); } - /** - * Shutdown type for {@link GLProfile#shutdown(ShutdownType)}. - * <p> - * {@link #SHARED_ONLY} For thread based resources only, suitable for eg. {@link java.applet.Applet Applet} restart.<br> - * {@link #COMPLETE} Everything.<br> - * </p> - */ - public enum ShutdownType { - /* Shared thread based resources only, eg. for Applets */ - SHARED_ONLY, - /* Everything */ - COMPLETE; - } - /** * Manual shutdown method, may be called after your last JOGL use * within the running JVM.<br> * It releases all temporary created resources, ie issues {@link javax.media.opengl.GLDrawableFactory#shutdown()}.<br> * The shutdown implementation is called via the JVM shutdown hook, if not manually invoked.<br> * <p> - * This method shall not need to be called for other reasons than issuing a proper shutdown of resources. + * This method shall not need to be called for other reasons than issuing a proper shutdown of resources at a defined time. * </p> - * @param type the shutdown type, see {@link ShutdownType}. */ - public static void shutdown(ShutdownType type) { + public static void shutdown() { initLock.lock(); try { if(initialized) { // volatile: ok initialized = false; if(DEBUG) { - System.err.println("GLProfile.shutdown(type: "+type+") - thread "+Thread.currentThread().getName()); + System.err.println("GLProfile.shutdown() - thread "+Thread.currentThread().getName()); Thread.dumpStack(); } - GLDrawableFactory.shutdown(type); - if(ShutdownType.COMPLETE == type) { - GLContext.shutdown(); - } - NativeWindowFactory.shutdown(); + GLDrawableFactory.shutdown(); } } finally { initLock.unlock(); @@ -1480,7 +1461,7 @@ public class GLProfile { if(DEBUG) { System.err.println("Info: GLProfile.init - EGL/ES2 ANGLE disabled"); } - eglFactory.destroy(ShutdownType.COMPLETE); + eglFactory.destroy(); eglFactory = null; hasEGLFactory = false; } else { diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java index 18d2f830d..ce2e824f5 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java @@ -29,6 +29,7 @@ package jogamp.opengl.egl; import java.nio.IntBuffer; +import java.util.Iterator; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; @@ -51,7 +52,7 @@ import com.jogamp.nativewindow.egl.EGLGraphicsDevice; * </p> */ public class EGLDisplayUtil { - protected static final boolean DEBUG = Debug.debug("EGL"); + protected static final boolean DEBUG = Debug.debug("EGLDisplayUtil"); static LongIntHashMap eglDisplayCounter; @@ -60,6 +61,32 @@ public class EGLDisplayUtil { eglDisplayCounter.setKeyNotFoundValue(0); } + /** + * @return number of unclosed EGL Displays.<br> + */ + public static int shutdown(boolean verbose) { + if(DEBUG || verbose || eglDisplayCounter.size() > 0 ) { + System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+eglDisplayCounter.size()+")"); + if(DEBUG) { + Thread.dumpStack(); + } + if( eglDisplayCounter.size() > 0) { + EGLDisplayUtil.dumpOpenDisplayConnections(); + } + } + + return eglDisplayCounter.size(); + } + + public static void dumpOpenDisplayConnections() { + System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+eglDisplayCounter.size()); + int i=0; + for(Iterator<LongIntHashMap.Entry> iter = eglDisplayCounter.iterator(); iter.hasNext(); i++) { + final LongIntHashMap.Entry e = iter.next(); + System.err.println("EGLDisplayUtil: Open["+i+"]: 0x"+Long.toHexString(e.key)+": refCnt "+e.value); + } + } + public static long eglGetDisplay(long nativeDisplay_id) { final long eglDisplay = EGL.eglGetDisplay(nativeDisplay_id); if(DEBUG) { @@ -89,6 +116,7 @@ public class EGLDisplayUtil { eglDisplayCounter.put(eglDisplay, refCnt); if(DEBUG) { System.err.println("EGLDisplayUtil.eglInitialize1("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res); + // Thread.dumpStack(); } return res; } @@ -117,6 +145,7 @@ public class EGLDisplayUtil { } if(DEBUG) { System.err.println("EGLDisplayUtil.eglInitialize2("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res); + // Thread.dumpStack(); } return res; } @@ -185,12 +214,13 @@ public class EGLDisplayUtil { final int refCnt = eglDisplayCounter.get(eglDisplay) - 1; // 1 - 1 = 0 -> final terminate if(0==refCnt) { // no terminate if still in use or already terminated res = EGL.eglTerminate(eglDisplay); + eglDisplayCounter.remove(eglDisplay); } else { + if(0 < refCnt) { // no negative refCount + eglDisplayCounter.put(eglDisplay, refCnt); + } res = true; } - if(0<=refCnt) { // no negative refCount - eglDisplayCounter.put(eglDisplay, refCnt); - } if(DEBUG) { System.err.println("EGLDisplayUtil.eglTerminate("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res); // Thread.dumpStack(); diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java index 986b110be..292eb17c8 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -64,7 +64,6 @@ import javax.media.opengl.GLDrawable; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import javax.media.opengl.GLProfile.ShutdownType; import jogamp.opengl.Debug; import jogamp.opengl.GLDrawableFactoryImpl; @@ -201,13 +200,13 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { @Override - protected final void destroy(ShutdownType shutdownType) { + protected final void destroy() { if(null != sharedMap) { Collection<SharedResource> srl = sharedMap.values(); for(Iterator<SharedResource> sri = srl.iterator(); sri.hasNext(); ) { SharedResource sr = sri.next(); if(DEBUG) { - System.err.println("EGLDrawableFactory.destroy("+shutdownType+"): "+sr.device.toString()); + System.err.println("EGLDrawableFactory.destroy(): "+sr.device.toString()); } sr.device.close(); } @@ -220,17 +219,16 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { /** * Pulling away the native library may cause havoc .. */ - if(ShutdownType.COMPLETE == shutdownType) { - if(null != eglES1DynamicLookupHelper) { - // eglES1DynamicLookupHelper.destroy(); - eglES1DynamicLookupHelper = null; - } - if(null != eglES2DynamicLookupHelper) { - // eglES2DynamicLookupHelper.destroy(); - eglES2DynamicLookupHelper = null; - } + if(null != eglES1DynamicLookupHelper) { + // eglES1DynamicLookupHelper.destroy(); + eglES1DynamicLookupHelper = null; + } + if(null != eglES2DynamicLookupHelper) { + // eglES2DynamicLookupHelper.destroy(); + eglES2DynamicLookupHelper = null; } EGLGraphicsConfigurationFactory.unregisterFactory(); + EGLDisplayUtil.shutdown(DEBUG); } private HashMap<String /*connection*/, SharedResource> sharedMap = null; diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java index c1b15cac5..591fafc68 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -60,7 +60,6 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import javax.media.opengl.GLProfile.ShutdownType; import jogamp.nativewindow.macosx.OSXUtil; import jogamp.opengl.DesktopGLDynamicLookupHelper; @@ -124,7 +123,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected final void destroy(ShutdownType shutdownType) { + protected final void destroy() { if(null != sharedMap) { sharedMap.clear(); sharedMap = null; @@ -133,10 +132,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { /** * Pulling away the native library may cause havoc .. * - if(ShutdownType.COMPLETE == shutdownType && null != macOSXCGLDynamicLookupHelper) { - macOSXCGLDynamicLookupHelper.destroy(); - macOSXCGLDynamicLookupHelper = null; - } */ + macOSXCGLDynamicLookupHelper.destroy(); + */ + macOSXCGLDynamicLookupHelper = null; } @Override diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java index c414083c4..7ea487523 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java @@ -61,7 +61,6 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import javax.media.opengl.GLProfile.ShutdownType; import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.GDISurface; @@ -136,7 +135,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { @Override - protected final void destroy(ShutdownType shutdownType) { + protected final void destroy() { if(null != sharedResourceRunner) { sharedResourceRunner.stop(); sharedResourceRunner = null; @@ -149,10 +148,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { /** * Pulling away the native library may cause havoc .. * - if(ShutdownType.COMPLETE == shutdownType && null != windowsWGLDynamicLookupHelper) { - windowsWGLDynamicLookupHelper.destroy(); - windowsWGLDynamicLookupHelper = null; - } */ + windowsWGLDynamicLookupHelper.destroy(); + */ + windowsWGLDynamicLookupHelper = null; RegisteredClassFactory.shutdownSharedClasses(); } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java index 293ac96f7..bc3e5b793 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java @@ -58,7 +58,6 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import javax.media.opengl.GLProfile.ShutdownType; import jogamp.nativewindow.x11.X11Lib; import jogamp.nativewindow.x11.X11Util; @@ -129,7 +128,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected final void destroy(ShutdownType shutdownType) { + protected final void destroy() { if(null != sharedResourceRunner) { sharedResourceRunner.stop(); sharedResourceRunner = null; @@ -142,14 +141,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { /** * Pulling away the native library may cause havoc .. * - if(ShutdownType.COMPLETE == shutdownType && null != x11GLXDynamicLookupHelper) { - x11GLXDynamicLookupHelper.destroy(); - x11GLXDynamicLookupHelper = null; - } */ - - // Don't really close pending Display connections, - // since this may trigger a JVM exception - X11Util.shutdown( false, DEBUG ); + x11GLXDynamicLookupHelper.destroy(); + */ + x11GLXDynamicLookupHelper = null; } @Override diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index afcd0a008..89d476a3b 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -102,6 +102,8 @@ public abstract class NativeWindowFactory { private static Constructor<?> x11ToolkitLockConstructor; private static boolean requiresToolkitLock; + private static volatile boolean isJVMShuttingDown = false; + /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ protected NativeWindowFactory() { @@ -168,6 +170,22 @@ public abstract class NativeWindowFactory { } } + private static void shutdownNativeImpl(final ClassLoader cl) { + final String clazzName; + if( TYPE_X11 == nativeWindowingTypePure ) { + clazzName = X11UtilClassName; + } else if( TYPE_WINDOWS == nativeWindowingTypePure ) { + clazzName = GDIClassName; + } else if( TYPE_MACOSX == nativeWindowingTypePure ) { + clazzName = OSXUtilClassName; + } else { + clazzName = null; + } + if( null != clazzName ) { + ReflectionUtil.callStaticMethod(clazzName, "shutdown", null, null, cl ); + } + } + /** * Static one time initialization of this factory.<br> * This initialization method <b>must be called</b> once by the program or utilizing modules! @@ -268,22 +286,28 @@ public abstract class NativeWindowFactory { } } - public static synchronized void shutdown() { + public static synchronized void shutdown(boolean _isJVMShuttingDown) { + isJVMShuttingDown = _isJVMShuttingDown; + if(DEBUG) { + System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown); + } if(initialized) { initialized = false; - if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START"); + if(null != registeredFactories) { + registeredFactories.clear(); + registeredFactories = null; } - registeredFactories.clear(); - registeredFactories = null; GraphicsConfigurationFactory.shutdown(); - // X11Util.shutdown(..) already called via GLDrawableFactory.shutdown() .. - if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END"); - } + } + shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown + if(DEBUG) { + System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown); } } + /** Returns true if the JVM is shutting down, otherwise false. */ + public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; } + /** @return true if the underlying toolkit requires locking, otherwise false. */ public static boolean requiresToolkitLock() { return requiresToolkitLock; diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java index 36d7c3727..f1e8a786a 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java @@ -48,6 +48,7 @@ import java.util.ArrayList; import java.util.Map; import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.ToolkitLock; import jogamp.nativewindow.Debug; @@ -271,10 +272,18 @@ public class JAWTUtil { } } + /** + * Called by {@link NativeWindowFactory#initSingleton()} + */ public static void initSingleton() { // just exist to ensure static init has been run } - + + /** + * Called by {@link NativeWindowFactory#shutdown()} + */ + public static void shutdown() { + } public static boolean hasJava2D() { return j2dExist; diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index f5f735051..149ebdf4a 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -28,6 +28,7 @@ package jogamp.nativewindow.macosx; import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; @@ -38,6 +39,9 @@ public class OSXUtil { private static boolean isInit = false; private static final boolean DEBUG = Debug.debug("OSXUtil"); + /** + * Called by {@link NativeWindowFactory#initSingleton()} + */ public static synchronized void initSingleton() { if(!isInit) { if(DEBUG) { @@ -54,6 +58,12 @@ public class OSXUtil { } } + /** + * Called by {@link NativeWindowFactory#shutdown()} + */ + public static void shutdown() { + } + public static boolean requiresToolkitLock() { return false; } diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java index fda1649b6..613c76032 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java @@ -29,6 +29,7 @@ package jogamp.nativewindow.windows; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowFactory; import jogamp.nativewindow.NWJNILibLoader; import jogamp.nativewindow.Debug; @@ -41,6 +42,9 @@ public class GDIUtil { private static RegisteredClassFactory dummyWindowClassFactory; private static boolean isInit = false; + /** + * Called by {@link NativeWindowFactory#initSingleton()} + */ public static synchronized void initSingleton() { if(!isInit) { synchronized(X11Util.class) { @@ -61,6 +65,12 @@ public class GDIUtil { } } + /** + * Called by {@link NativeWindowFactory#shutdown()} + */ + public static void shutdown() { + } + public static boolean requiresToolkitLock() { return false; } private static RegisteredClass dummyWindowClass = null; diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index 860238649..93b7f3487 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -67,13 +67,13 @@ public class X11Util { * </p> * <p> * You may test this, ie just reverse the destroy order below. - * See also native test: jogl/test/native/displayMultiple02.c + * See also native test: jogl/test-native/displayMultiple02.c * </p> * <p> * Workaround is to not close them at all if driver vendor is ATI. * </p> */ - public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = true; + public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG", true); /** Value is <code>true</code>, best 'stable' results if always using XInitThreads(). */ public static final boolean XINITTHREADS_ALWAYS_ENABLED = true; @@ -95,6 +95,9 @@ public class X11Util { private static Object setX11ErrorHandlerLock = new Object(); + /** + * Called by {@link NativeWindowFactory#initSingleton()} + */ public static void initSingleton() { if(!isInit) { synchronized(X11Util.class) { @@ -138,6 +141,52 @@ public class X11Util { } } + /** + * Cleanup resources. + * <p> + * Called by {@link NativeWindowFactory#shutdown()} + * </p> + */ + public static void shutdown() { + if(isInit) { + synchronized(X11Util.class) { + if(isInit) { + final boolean isJVMShuttingDown = NativeWindowFactory.isJVMShuttingDown() ; + if(DEBUG || openDisplayMap.size() > 0 || reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0) { + System.err.println("X11Util.Display: Shutdown (JVM shutdown: "+isJVMShuttingDown+ + ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+ + ", reusable (open, marked uncloseable): "+reusableDisplayList.size()+ + ", pending (post closing): "+pendingDisplayList.size()+ + ")"); + if(DEBUG) { + Thread.dumpStack(); + } + if( openDisplayList.size() > 0) { + X11Util.dumpOpenDisplayConnections(); + } + if( reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0 ) { + X11Util.dumpPendingDisplayConnections(); + } + } + + synchronized(globalLock) { + // Only at JVM shutdown time, since AWT impl. seems to + // dislike closing of X11 Display's (w/ ATI driver). + if( isJVMShuttingDown ) { + isInit = false; + closePendingDisplayConnections(); + openDisplayList.clear(); + reusableDisplayList.clear(); + pendingDisplayList.clear(); + openDisplayMap.clear(); + shutdown0(); + } + } + } + } + } + } + public static synchronized boolean isNativeLockAvailable() { return isX11LockAvailable; } @@ -183,6 +232,7 @@ public class X11Util { private static Object globalLock = new Object(); private static LongObjectHashMap openDisplayMap = new LongObjectHashMap(); // handle -> name private static List<NamedDisplay> openDisplayList = new ArrayList<NamedDisplay>(); + private static List<NamedDisplay> reusableDisplayList = new ArrayList<NamedDisplay>(); private static List<NamedDisplay> pendingDisplayList = new ArrayList<NamedDisplay>(); public static class NamedDisplay { @@ -218,8 +268,7 @@ public class X11Util { public final boolean equals(Object obj) { if(this == obj) { return true; } if(obj instanceof NamedDisplay) { - NamedDisplay n = (NamedDisplay) obj; - return handle == n.handle; + return handle == ((NamedDisplay) obj).handle; } return false; } @@ -246,43 +295,6 @@ public class X11Util { } } - /** - * Cleanup resources. - * If <code>realXCloseOpenAndPendingDisplays</code> is <code>false</code>, - * keep alive all references (open display connection) for restart on same ClassLoader. - * - * @return number of unclosed X11 Displays.<br> - * @param realXCloseOpenAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called. - */ - public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) { - int num=0; - if(DEBUG || verbose || openDisplayMap.size() > 0 || pendingDisplayList.size() > 0) { - System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+ - ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+ - ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")"); - if(DEBUG) { - Thread.dumpStack(); - } - if( openDisplayList.size() > 0) { - X11Util.dumpOpenDisplayConnections(); - } - if( pendingDisplayList.size() > 0 ) { - X11Util.dumpPendingDisplayConnections(); - } - } - - synchronized(globalLock) { - if(realXCloseOpenAndPendingDisplays) { - closePendingDisplayConnections(); - openDisplayList.clear(); - pendingDisplayList.clear(); - openDisplayMap.clear(); - shutdown0(); - } - } - return num; - } - /** * Closing pending Display connections in reverse order. * @@ -292,9 +304,9 @@ public class X11Util { int num=0; synchronized(globalLock) { if(DEBUG) { - System.err.println("X11Util: Closing Pending X11 Display Connections: "+pendingDisplayList.size()); + System.err.println("X11Util: Closing Pending X11 Display Connections in order of their creation: "+pendingDisplayList.size()); } - for(int i=pendingDisplayList.size()-1; i>=0; i--) { + for(int i=0; i<pendingDisplayList.size(); i++) { NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i); if(DEBUG) { System.err.println("X11Util.closePendingDisplayConnections(): Closing ["+i+"]: "+ndpy); @@ -328,6 +340,12 @@ public class X11Util { } } + public static int getReusableDisplayConnectionNumber() { + synchronized(globalLock) { + return reusableDisplayList.size(); + } + } + public static int getPendingDisplayConnectionNumber() { synchronized(globalLock) { return pendingDisplayList.size(); @@ -336,7 +354,18 @@ public class X11Util { public static void dumpPendingDisplayConnections() { synchronized(globalLock) { - System.err.println("X11Util: Pending X11 Display Connections: "+pendingDisplayList.size()); + System.err.println("X11Util: Reusable X11 Display Connections: "+reusableDisplayList.size()); + for(int i=0; i<reusableDisplayList.size(); i++) { + NamedDisplay ndpy = (NamedDisplay) reusableDisplayList.get(i); + System.err.println("X11Util: Reusable["+i+"]: "+ndpy); + if(null!=ndpy) { + Throwable t = ndpy.getCreationStack(); + if(null!=t) { + t.printStackTrace(); + } + } + } + System.err.println("X11Util: Pending X11 Display Connections (creation order): "+pendingDisplayList.size()); for(int i=0; i<pendingDisplayList.size(); i++) { NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i); System.err.println("X11Util: Pending["+i+"]: "+ndpy); @@ -370,9 +399,9 @@ public class X11Util { boolean reused = false; synchronized(globalLock) { - for(int i=0; i<pendingDisplayList.size(); i++) { - if(pendingDisplayList.get(i).getName().equals(name)) { - namedDpy = pendingDisplayList.remove(i); + for(int i=0; i<reusableDisplayList.size(); i++) { + if(reusableDisplayList.get(i).getName().equals(name)) { + namedDpy = reusableDisplayList.remove(i); dpy = namedDpy.getHandle(); reused = true; break; @@ -386,6 +415,7 @@ public class X11Util { // if you like to debug and synchronize X11 commands .. // setSynchronizeDisplay(dpy, true); namedDpy = new NamedDisplay(name, dpy); + pendingDisplayList.add(namedDpy); } namedDpy.addRef(); openDisplayMap.put(dpy, namedDpy); @@ -420,9 +450,10 @@ public class X11Util { if(!namedDpy.isUncloseable()) { XCloseDisplay(namedDpy.getHandle()); + pendingDisplayList.remove(namedDpy); } else { // for reuse - pendingDisplayList.add(namedDpy); + reusableDisplayList.add(namedDpy); } if(DEBUG) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java index 9f2820a37..976885de4 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java @@ -93,12 +93,12 @@ public class TestShutdownCompleteAWT extends UITestCase { long t1 = System.nanoTime(); runTestGL(); long t2 = System.nanoTime(); - GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE); + GLProfile.shutdown(); long t3 = System.nanoTime(); System.err.println("Total: "+ (t3-t0)/1e6 +"ms"); System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms"); System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms"); - System.err.println(" GLProfile.shutdown(COMPLETE): "+ (t3-t2)/1e6 +"ms"); + System.err.println(" GLProfile.shutdown(): "+ (t3-t2)/1e6 +"ms"); } @Test diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java index b21ad5b5b..f376cd6d4 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java @@ -48,8 +48,12 @@ public class TestShutdownCompleteNEWT extends UITestCase { static long duration = 300; // ms - protected void runTestGL() throws InterruptedException { - GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getGL2ES2())); + protected void runTestGL(boolean onscreen) throws InterruptedException { + GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2()); + caps.setOnscreen(onscreen); + caps.setPBuffer(!onscreen); + + GLWindow glWindow = GLWindow.create(caps); Assert.assertNotNull(glWindow); glWindow.setTitle("Gears NEWT Test"); @@ -82,19 +86,19 @@ public class TestShutdownCompleteNEWT extends UITestCase { GLProfile.initSingleton(); long t1 = System.nanoTime(); if(!initOnly) { - runTestGL(); + runTestGL(true); } long t2 = System.nanoTime(); if(glInfo) { System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, false).toString()); } long t3 = System.nanoTime(); - GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE); + GLProfile.shutdown(); long t4 = System.nanoTime(); System.err.println("Total: "+ (t3-t0)/1e6 +"ms"); System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms"); System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms"); - System.err.println(" GLProfile.shutdown(COMPLETE): "+ (t4-t3)/1e6 +"ms"); + System.err.println(" GLProfile.shutdown(): "+ (t4-t3)/1e6 +"ms"); } @Test diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java deleted file mode 100644 index 3274ea820..000000000 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java +++ /dev/null @@ -1,124 +0,0 @@ -/** - * 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.opengl.test.junit.jogl.acore; - -import java.awt.Frame; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLProfile; -import javax.media.opengl.awt.GLCanvas; - -import org.junit.Assert; -import org.junit.Test; - -import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; -import com.jogamp.opengl.test.junit.util.UITestCase; -import com.jogamp.opengl.util.Animator; - -public class TestShutdownSharedAWT extends UITestCase { - - static long duration = 300; // ms - - protected void runTestGL() throws InterruptedException, InvocationTargetException { - final Frame frame = new Frame("Gears AWT Test"); - Assert.assertNotNull(frame); - - final GLCanvas glCanvas = new GLCanvas(new GLCapabilities(GLProfile.getGL2ES2())); - Assert.assertNotNull(glCanvas); - frame.add(glCanvas); - frame.setSize(256, 256); - - glCanvas.addGLEventListener(new GearsES2(1)); - - Animator animator = new Animator(glCanvas); - - javax.swing.SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - frame.setVisible(true); - }}); - animator.setUpdateFPSFrames(60, System.err); - animator.start(); - Assert.assertEquals(true, animator.isAnimating()); - Assert.assertEquals(true, glCanvas.isVisible()); - Assert.assertEquals(true, glCanvas.isDisplayable()); - - while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) { - Thread.sleep(100); - } - Assert.assertEquals(true, glCanvas.isRealized()); - - animator.stop(); - Assert.assertEquals(false, animator.isAnimating()); - frame.setVisible(false); - Assert.assertEquals(false, frame.isVisible()); - javax.swing.SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - frame.remove(glCanvas); - frame.dispose(); - }}); - } - - protected void oneLife() throws InterruptedException, InvocationTargetException { - long t0 = System.nanoTime(); - GLProfile.initSingleton(); - long t1 = System.nanoTime(); - runTestGL(); - long t2 = System.nanoTime(); - GLProfile.shutdown(GLProfile.ShutdownType.SHARED_ONLY); - long t3 = System.nanoTime(); - System.err.println("Total: "+ (t3-t0)/1e6 +"ms"); - System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms"); - System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms"); - System.err.println(" GLProfile.shutdown(SHARED): "+ (t3-t2)/1e6 +"ms"); - } - - @Test - public void test01OneLife() throws InterruptedException, InvocationTargetException { - oneLife(); - } - - @Test - public void test01AnotherLife() throws InterruptedException, InvocationTargetException { - oneLife(); - } - - @Test - public void test01TwoLifes() throws InterruptedException, InvocationTargetException { - oneLife(); - oneLife(); - } - - public static void main(String args[]) throws IOException { - String tstname = TestShutdownSharedAWT.class.getName(); - org.junit.runner.JUnitCore.main(tstname); - } - -} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java deleted file mode 100644 index 8db7dff9b..000000000 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * 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.opengl.test.junit.jogl.acore; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLProfile; - -import org.junit.Assert; -import org.junit.Test; - -import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; -import com.jogamp.opengl.test.junit.util.UITestCase; -import com.jogamp.opengl.util.Animator; - -public class TestShutdownSharedNEWT extends UITestCase { - - static long duration = 300; // ms - - protected void runTestGL() throws InterruptedException { - GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getGL2ES2())); - Assert.assertNotNull(glWindow); - glWindow.setTitle("Gears NEWT Test"); - - glWindow.addGLEventListener(new GearsES2()); - - Animator animator = new Animator(glWindow); - - glWindow.setSize(256, 256); - glWindow.setVisible(true); - animator.setUpdateFPSFrames(60, System.err); - animator.start(); - Assert.assertEquals(true, animator.isAnimating()); - Assert.assertEquals(true, glWindow.isVisible()); - Assert.assertEquals(true, glWindow.isNativeValid()); - Assert.assertEquals(true, glWindow.isRealized()); - - while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) { - Thread.sleep(100); - } - - animator.stop(); - glWindow.destroy(); - } - - protected void oneLife() throws InterruptedException { - long t0 = System.nanoTime(); - GLProfile.initSingleton(); - long t1 = System.nanoTime(); - runTestGL(); - long t2 = System.nanoTime(); - GLProfile.shutdown(GLProfile.ShutdownType.SHARED_ONLY); - long t3 = System.nanoTime(); - System.err.println("Total: "+ (t3-t0)/1e6 +"ms"); - System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms"); - System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms"); - System.err.println(" GLProfile.shutdown(SHARED): "+ (t3-t2)/1e6 +"ms"); - } - - @Test - public void test01OneLife() throws InterruptedException { - oneLife(); - } - - @Test - public void test01AnotherLife() throws InterruptedException { - oneLife(); - } - - @Test - public void test01TwoLifes() throws InterruptedException { - oneLife(); - oneLife(); - } - - public static void main(String args[]) throws IOException { - boolean waitForKey = false; - - for(int i=0; i<args.length; i++) { - if(args[i].equals("-wait")) { - waitForKey = true; - } - } - - if(waitForKey) { - BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); - System.err.println("Press enter to continue"); - try { - System.err.println(stdin.readLine()); - } catch (IOException e) { } - } - - String tstname = TestShutdownSharedNEWT.class.getName(); - org.junit.runner.JUnitCore.main(tstname); - } - -} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java index fab5bf99b..a79c924d6 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java @@ -85,7 +85,7 @@ public class TestGearsES2NEWT extends UITestCase { static boolean mouseConfined = false; static boolean showFPS = false; static int loops = 1; - static GLProfile.ShutdownType loop_shutdown = null; + static boolean loop_shutdown = false; static boolean forceES2 = false; @BeforeClass @@ -258,8 +258,8 @@ public class TestGearsES2NEWT extends UITestCase { GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2()); caps.setBackgroundOpaque(opaque); runTestGL(caps, undecorated); - if(null != loop_shutdown) { - GLProfile.shutdown(loop_shutdown); + if(loop_shutdown) { + GLProfile.shutdown(); } } } @@ -316,12 +316,7 @@ public class TestGearsES2NEWT extends UITestCase { i++; loops = MiscUtils.atoi(args[i], 1); } else if(args[i].equals("-loop-shutdown")) { - i++; - switch(MiscUtils.atoi(args[i], 0)) { - case 1: loop_shutdown = GLProfile.ShutdownType.SHARED_ONLY; break; - case 2: loop_shutdown = GLProfile.ShutdownType.COMPLETE; break; - default: throw new IllegalArgumentException("should be [0..2], 0-off, 1-shared, 2-complete"); - } + loop_shutdown = true; } } wsize = new Dimension(w, h); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java index ff231ef91..f0c3bb684 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java @@ -51,7 +51,7 @@ import org.junit.Test; public class TestRedSquareES2NEWT extends UITestCase { static int width, height; static int loops = 1; - static GLProfile.ShutdownType loop_shutdown = null; + static boolean loop_shutdown = false; static boolean vsync = false; static boolean forceES2 = false; static boolean doRotate = true; @@ -129,8 +129,8 @@ public class TestRedSquareES2NEWT extends UITestCase { System.err.println("Loop "+i+"/"+loops); GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2()); runTestGL(caps); - if(null != loop_shutdown) { - GLProfile.shutdown(loop_shutdown); + if(loop_shutdown) { + GLProfile.shutdown(); } } } @@ -152,12 +152,7 @@ public class TestRedSquareES2NEWT extends UITestCase { i++; loops = MiscUtils.atoi(args[i], 1); } else if(args[i].equals("-loop-shutdown")) { - i++; - switch(MiscUtils.atoi(args[i], 0)) { - case 1: loop_shutdown = GLProfile.ShutdownType.SHARED_ONLY; break; - case 2: loop_shutdown = GLProfile.ShutdownType.COMPLETE; break; - default: throw new IllegalArgumentException("should be [0..2], 0-off, 1-shared, 2-complete"); - } + loop_shutdown = true; } } System.err.println("loops "+loops); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java index c3c68e46c..b9f3e67dc 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java @@ -111,7 +111,7 @@ public class TestScreenMode01NEWT extends UITestCase { */ @After public void cleanupGL() throws InterruptedException { - GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE); + GLProfile.shutdown(); GLProfile.initSingleton(); } |