summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-10-29 03:30:25 +0200
committerSven Gothel <[email protected]>2010-10-29 03:30:25 +0200
commitef8da46af8ef42d04b9f0701f0d18e1277765d01 (patch)
treec5fd779e20de84de544669ef381c4756007a494d /src/jogl/classes/javax
parentbe82dc62e22bbbb76acd7af889908a272bda6d09 (diff)
Promoted the shutdown hook from GLDrawableFactoryImpl to GLProfile.
Each GLDrawableFactory implementation provides a shutdownInstance() method, issued by GLProfile.
Diffstat (limited to 'src/jogl/classes/javax')
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java48
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java285
2 files changed, 196 insertions, 137 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index f9f5f8324..d1bdcdda1 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -40,12 +40,17 @@
package javax.media.opengl;
-import javax.media.nativewindow.*;
-
-import java.security.*;
import com.jogamp.common.JogampRuntimeException;
-import com.jogamp.common.util.*;
-import com.jogamp.opengl.impl.*;
+import com.jogamp.common.impl.Debug;
+import com.jogamp.common.util.ReflectionUtil;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
/** <P> Provides a virtual machine- and operating system-independent
mechanism for creating {@link GLDrawable}s. </P>
@@ -69,10 +74,11 @@ import com.jogamp.opengl.impl.*;
raising a {@link GLException}. The semantics of the rejection
process are (unfortunately) left unspecified for now. The current
implementation will cause a {@link GLException} to be raised
- during the first repaint of the {@link GLCanvas} or {@link
- GLJPanel} if the capabilities can not be met. Pbuffers are always
- created immediately and their creation will fail with a {@link
- GLException} if errors occur. </P>
+ during the first repaint of the {@link javax.media.opengl.awt.GLCanvas} or {@link
+ javax.media.opengl.awt.GLJPanel} if the capabilities can not be met.<br>
+ {@link javax.media.opengl.GLPbuffer} are always
+ created immediately and their creation will fail with a
+ {@link javax.media.opengl.GLException} if errors occur. </P>
<P> The concrete GLDrawableFactory subclass instantiated by {@link
#getFactory getFactory} can be changed by setting the system
@@ -81,10 +87,6 @@ import com.jogamp.opengl.impl.*;
*/
public abstract class GLDrawableFactory {
- /** Creates a new GLDrawableFactory instance. End users do not need
- to call this method. */
- protected GLDrawableFactory() {
- }
private static final GLDrawableFactory eglFactory;
private static final GLDrawableFactory nativeOSFactory;
@@ -92,6 +94,8 @@ public abstract class GLDrawableFactory {
static final String macosxFactoryClassNameCGL = "com.jogamp.opengl.impl.macosx.cgl.MacOSXCGLDrawableFactory";
static final String macosxFactoryClassNameAWTCGL = "com.jogamp.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory";
+ protected static ArrayList/*<GLDrawableFactoryImpl>*/ glDrawableFactories = new ArrayList();
+
/**
* Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
*/
@@ -146,6 +150,24 @@ public abstract class GLDrawableFactory {
eglFactory = tmp;
}
+ protected GLDrawableFactory() {
+ synchronized(glDrawableFactories) {
+ glDrawableFactories.add(this);
+ }
+ }
+
+ protected static void shutdown() {
+ synchronized(glDrawableFactories) {
+ for(int i=0; i<glDrawableFactories.size(); i++) {
+ GLDrawableFactory factory = (GLDrawableFactory) glDrawableFactories.get(i);
+ factory.shutdownInstance();
+ }
+ glDrawableFactories.clear();
+ }
+ }
+
+ protected abstract void shutdownInstance();
+
/**
* Returns the sole GLDrawableFactory instance.
*
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index be5968409..233bebcb4 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -47,6 +47,7 @@ import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper;
import java.util.HashMap;
import java.util.Iterator;
import java.security.*;
+import java.util.ArrayList;
import javax.media.opengl.fixedfunc.GLPointerFunc;
import javax.media.nativewindow.NativeWindowFactory;
@@ -63,6 +64,68 @@ public class GLProfile {
public static final boolean DEBUG = Debug.debug("GLProfile");
+ /**
+ * 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>.
+ */
+ 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() {
+ registerFactoryShutdownHook();
+ initProfiles(firstUIActionOnProcess);
+ return null;
+ }
+ });
+
+ if(null==defaultGLProfile) {
+ throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+glAvailabilityToString());
+ }
+ }
+ }
+
+ /**
+ * Manual shutdown method, may be called after your last JOGL use
+ * within the running JVM.<br>
+ * This method is called via the JVM shutdown hook.<br>
+ * It releases all temporary created resources, ie issues {@link javax.media.opengl.GLDrawableFactory#shutdown()}.<br>
+ */
+ public static synchronized void shutdown() {
+ if(initialized) {
+ initialized = false;
+ GLDrawableFactory.shutdown();
+ }
+ }
+
//
// Query platform available OpenGL implementation
//
@@ -77,16 +140,6 @@ public class GLProfile {
public static final boolean isGL2ES1Available() { return null != mappedProfiles.get(GL2ES1); }
public static final boolean isGL2ES2Available() { return null != mappedProfiles.get(GL2ES2); }
- private static final void glAvailabilityToString(StringBuffer sb, int major, int profile) {
- String str = GLContext.getGLVersionAvailable(major, profile);
- if(null==str) {
- throw new GLException("Internal Error");
- }
- sb.append("[");
- sb.append(str);
- sb.append("]");
- }
-
public static final String glAvailabilityToString() {
boolean avail;
StringBuffer sb = new StringBuffer();
@@ -400,22 +453,52 @@ public class GLProfile {
return usesNativeGLES2(profileImpl) || usesNativeGLES1(profileImpl);
}
- private static final String getGLImplBaseClassName(String profileImpl) {
- if ( GL4bc.equals(profileImpl) ||
- GL4.equals(profileImpl) ||
- GL3bc.equals(profileImpl) ||
- GL3.equals(profileImpl) ||
- GL2.equals(profileImpl) ) {
- return "com.jogamp.opengl.impl.gl4.GL4bc";
- } else if(GL2ES12.equals(profileImpl)) {
- return "com.jogamp.opengl.impl.gl2es12.GL2ES12";
- } else if(GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl)) {
- return "com.jogamp.opengl.impl.es1.GLES1";
- } else if(GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl)) {
- return "com.jogamp.opengl.impl.es2.GLES2";
- } else {
- throw new GLException("unsupported profile \"" + profileImpl + "\"");
+ /** @return {@link javax.media.nativewindow.NativeWindowFactory#isAWTAvailable()} and
+ JOGL's AWT part */
+ public static boolean isAWTAvailable() { return isAWTAvailable; }
+
+ public static String getGLTypeName(int type) {
+ switch (type) {
+ case GL.GL_UNSIGNED_BYTE:
+ return "GL_UNSIGNED_BYTE";
+ case GL.GL_BYTE:
+ return "GL_BYTE";
+ case GL.GL_UNSIGNED_SHORT:
+ return "GL_UNSIGNED_SHORT";
+ case GL.GL_SHORT:
+ return "GL_SHORT";
+ case GL.GL_FLOAT:
+ return "GL_FLOAT";
+ case GL.GL_FIXED:
+ return "GL_FIXED";
+ case javax.media.opengl.GL2ES2.GL_INT:
+ return "GL_INT";
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ return "GL_UNSIGNED_INT";
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ return "GL_DOUBLE";
+ case javax.media.opengl.GL2.GL_2_BYTES:
+ return "GL_2_BYTES";
+ case javax.media.opengl.GL2.GL_3_BYTES:
+ return "GL_3_BYTES";
+ case javax.media.opengl.GL2.GL_4_BYTES:
+ return "GL_4_BYTES";
+ }
+ return null;
+ }
+
+ public static String getGLArrayName(int array) {
+ switch(array) {
+ case GLPointerFunc.GL_VERTEX_ARRAY:
+ return "GL_VERTEX_ARRAY";
+ case GLPointerFunc.GL_NORMAL_ARRAY:
+ return "GL_NORMAL_ARRAY";
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ return "GL_COLOR_ARRAY";
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ return "GL_TEXTURE_COORD_ARRAY";
}
+ return null;
}
public final String getGLImplBaseClassName() {
@@ -830,6 +913,10 @@ public class GLProfile {
return "GLProfile[" + profile + "/" + profileImpl + "]";
}
+ static {
+ JVMUtil.initSingleton();
+ }
+
// The intersection between desktop OpenGL and the union of the OpenGL ES profiles
// This is here only to avoid having separate GL2ES1Impl and GL2ES2Impl classes
private static final String GL2ES12 = "GL2ES12";
@@ -852,6 +939,12 @@ public class GLProfile {
/** All GLProfiles */
private static /*final*/ HashMap/*<String, GLProfile>*/ mappedProfiles;
+ static boolean initialized = false;
+
+ // Shutdown hook mechanism for the factory
+ private static boolean factoryShutdownHookRegistered = false;
+ private static Thread factoryShutdownHook = null;
+
/**
* Tries the profiles implementation and native libraries.
* Throws an GLException if no profile could be found at all.
@@ -988,58 +1081,22 @@ public class GLProfile {
}
}
- static {
- JVMUtil.initSingleton();
- }
-
- static boolean initialized = false;
-
- /**
- * 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>.
- */
- 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());
- }
+ private static synchronized void registerFactoryShutdownHook() {
+ if (factoryShutdownHookRegistered) {
+ return;
}
+ factoryShutdownHook = new Thread(new Runnable() {
+ public void run() {
+ GLDrawableFactory.shutdown();
+ }
+ });
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ Runtime.getRuntime().addShutdownHook(factoryShutdownHook);
+ return null;
+ }
+ });
+ factoryShutdownHookRegistered = true;
}
private static void validateInitialization() {
@@ -1064,6 +1121,16 @@ public class GLProfile {
return msg.toString();
}
+ private static final void glAvailabilityToString(StringBuffer sb, int major, int profile) {
+ String str = GLContext.getGLVersionAvailable(major, profile);
+ if(null==str) {
+ throw new GLException("Internal Error");
+ }
+ sb.append("[");
+ sb.append(str);
+ sb.append("]");
+ }
+
private static HashMap computeProfileMap() {
defaultGLProfile=null;
HashMap/*<String, GLProfile>*/ _mappedProfiles = new HashMap(GL_PROFILE_LIST_ALL.length);
@@ -1091,6 +1158,24 @@ public class GLProfile {
return _mappedProfiles;
}
+ private static final String getGLImplBaseClassName(String profileImpl) {
+ if ( GL4bc.equals(profileImpl) ||
+ GL4.equals(profileImpl) ||
+ GL3bc.equals(profileImpl) ||
+ GL3.equals(profileImpl) ||
+ GL2.equals(profileImpl) ) {
+ return "com.jogamp.opengl.impl.gl4.GL4bc";
+ } else if(GL2ES12.equals(profileImpl)) {
+ return "com.jogamp.opengl.impl.gl2es12.GL2ES12";
+ } else if(GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl)) {
+ return "com.jogamp.opengl.impl.es1.GLES1";
+ } else if(GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl)) {
+ return "com.jogamp.opengl.impl.es2.GLES2";
+ } else {
+ throw new GLException("unsupported profile \"" + profileImpl + "\"");
+ }
+ }
+
/**
* Returns the profile implementation
*/
@@ -1149,54 +1234,6 @@ public class GLProfile {
return null;
}
- /** @return {@link javax.media.nativewindow.NativeWindowFactory#isAWTAvailable()} and
- JOGL's AWT part */
- public static boolean isAWTAvailable() { return isAWTAvailable; }
-
- public static String getGLTypeName(int type) {
- switch (type) {
- case GL.GL_UNSIGNED_BYTE:
- return "GL_UNSIGNED_BYTE";
- case GL.GL_BYTE:
- return "GL_BYTE";
- case GL.GL_UNSIGNED_SHORT:
- return "GL_UNSIGNED_SHORT";
- case GL.GL_SHORT:
- return "GL_SHORT";
- case GL.GL_FLOAT:
- return "GL_FLOAT";
- case GL.GL_FIXED:
- return "GL_FIXED";
- case javax.media.opengl.GL2ES2.GL_INT:
- return "GL_INT";
- case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
- return "GL_UNSIGNED_INT";
- case javax.media.opengl.GL2.GL_DOUBLE:
- return "GL_DOUBLE";
- case javax.media.opengl.GL2.GL_2_BYTES:
- return "GL_2_BYTES";
- case javax.media.opengl.GL2.GL_3_BYTES:
- return "GL_3_BYTES";
- case javax.media.opengl.GL2.GL_4_BYTES:
- return "GL_4_BYTES";
- }
- return null;
- }
-
- public static String getGLArrayName(int array) {
- switch(array) {
- case GLPointerFunc.GL_VERTEX_ARRAY:
- return "GL_VERTEX_ARRAY";
- case GLPointerFunc.GL_NORMAL_ARRAY:
- return "GL_NORMAL_ARRAY";
- case GLPointerFunc.GL_COLOR_ARRAY:
- return "GL_COLOR_ARRAY";
- case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
- return "GL_TEXTURE_COORD_ARRAY";
- }
- return null;
- }
-
private GLProfile(String profile, String profileImpl) {
this.profile = profile;
this.profileImpl = profileImpl;