aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
parentbe82dc62e22bbbb76acd7af889908a272bda6d09 (diff)
Promoted the shutdown hook from GLDrawableFactoryImpl to GLProfile.
Each GLDrawableFactory implementation provides a shutdownInstance() method, issued by GLProfile.
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java35
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java5
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java182
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java48
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java285
8 files changed, 337 insertions, 225 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
index c0e554889..6837949d3 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
@@ -43,7 +43,6 @@ package com.jogamp.opengl.impl;
import java.nio.*;
import javax.media.nativewindow.*;
import javax.media.opengl.*;
-import java.security.*;
/** Extends GLDrawableFactory with a few methods for handling
typically software-accelerated offscreen rendering (Device
@@ -53,6 +52,10 @@ import java.security.*;
public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
+ protected GLDrawableFactoryImpl() {
+ super();
+ }
+
/**
* Returns the GLDynamicLookupHelper
* @param profile if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2,
@@ -224,36 +227,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//
protected abstract GLDrawableImpl getSharedDrawable();
protected abstract GLContextImpl getSharedContext();
- protected abstract void shutdown();
-
- // Shutdown hook mechanism for the factory
- private boolean factoryShutdownHookRegistered;
- private Thread factoryShutdownHook;
- private synchronized void registerFactoryShutdownHook() {
- if (factoryShutdownHookRegistered)
- return;
- if (factoryShutdownHook == null) {
- factoryShutdownHook = new Thread(new Runnable() {
- public void run() {
- synchronized (GLDrawableFactoryImpl.this) {
- shutdown();
- }
- }
- });
- }
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- Runtime.getRuntime().addShutdownHook(factoryShutdownHook);
- return null;
- }
- });
- factoryShutdownHookRegistered = true;
- }
-
- protected GLDrawableFactoryImpl() {
- super();
- registerFactoryShutdownHook();
- }
protected void maybeDoSingleThreadedWorkaround(Runnable action) {
if (Threading.isSingleThreaded() &&
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 83e85b922..deb659ddf 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
@@ -111,7 +111,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
}
- protected void shutdown() {}
+ protected void shutdownInstance() {}
protected final GLDrawableImpl getSharedDrawable() { return null; }
protected final GLContextImpl getSharedContext() { return 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 47e0e656f..f108ab327 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
@@ -84,7 +84,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
} catch (JogampRuntimeException jre) { /* n/a .. */ }
}
- protected void shutdown() {}
+ protected void shutdownInstance() {}
protected final GLDrawableImpl getSharedDrawable() { return null; }
protected final GLContextImpl getSharedContext() { return null; }
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java
index eff01ca18..4a80990cb 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java
@@ -39,13 +39,8 @@
package com.jogamp.opengl.impl.macosx.cgl.awt;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.*;
-import java.util.*;
import javax.media.nativewindow.*;
import javax.media.opengl.*;
-import com.jogamp.opengl.impl.*;
-import com.jogamp.opengl.impl.awt.*;
import com.jogamp.opengl.impl.macosx.cgl.*;
public class MacOSXAWTCGLDrawableFactory extends MacOSXCGLDrawableFactory {
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 409e914b0..f59fb78c9 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
@@ -43,7 +43,6 @@ package com.jogamp.opengl.impl.windows.wgl;
import java.nio.*;
import java.util.*;
import javax.media.nativewindow.*;
-import javax.media.nativewindow.windows.*;
import javax.media.opengl.*;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
@@ -118,7 +117,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
return sharedContext;
}
- protected void shutdown() {
+ protected void shutdownInstance() {
if (DEBUG) {
System.err.println("!!! Shutdown Shared:");
System.err.println("!!! CTX : "+sharedContext);
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 2828a90f1..82f57f33e 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
@@ -82,38 +82,11 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
} catch (JogampRuntimeException jre) { /* n/a .. */ }
// init shared resources ..
+ sharedResourcesRunner = new SharedResourcesRunner();
+ sharedResourcesThread = new Thread(sharedResourcesRunner, Thread.currentThread().getName()+"-SharedResourcesRunner");
+ sharedResourcesThread.start();
+ sharedResourcesRunner.waitUntilInitialized();
- long tlsDisplay = X11Util.createThreadLocalDisplay(null);
- X11Util.lockDefaultToolkit(tlsDisplay); // OK
- 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.unlockDefaultToolkit(tlsDisplay); // OK
- }
if (DEBUG) {
System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA);
System.err.println("!!! SharedScreen: "+sharedScreen);
@@ -121,7 +94,124 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
}
- private X11GraphicsScreen sharedScreen;
+ class SharedResourcesRunner implements Runnable {
+ boolean initialized = false;
+ boolean released = false;
+ boolean shouldRelease = false;
+
+ public void waitUntilInitialized() {
+ synchronized (this) {
+ while (!this.initialized) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ }
+ }
+
+ public void releaseAndWait() {
+ synchronized (this) {
+ this.shouldRelease = true;
+ this.notifyAll();
+
+ while (!this.released) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ }
+ }
+
+ public void run() {
+ String threadName = Thread.currentThread().getName();
+ synchronized (this) {
+ if (DEBUG) {
+ System.err.println(threadName+ " initializing START");
+ }
+ long tlsDisplay = X11Util.createDisplay(null);
+ X11Util.lockDefaultToolkit(tlsDisplay); // OK
+ 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.markDisplayUncloseable(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.unlockDefaultToolkit(tlsDisplay); // OK
+ }
+
+ if (DEBUG) {
+ System.err.println(threadName+ " initializing DONE");
+ }
+ initialized = true;
+ notifyAll();
+ }
+
+ if (DEBUG) {
+ System.err.println(threadName+ " release WAIT");
+ }
+
+ synchronized(this) {
+ while (!this.shouldRelease) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ if (DEBUG) {
+ System.err.println(threadName+ " release START");
+ }
+ if (null != sharedContext) {
+ // may cause JVM SIGSEGV: sharedContext.destroy();
+ sharedContext = null;
+ }
+
+ if (null != sharedDrawable) {
+ // may cause JVM SIGSEGV: sharedDrawable.destroy();
+ sharedDrawable = null;
+ }
+ if (null != sharedScreen) {
+ // may cause JVM SIGSEGV:
+ X11Util.closeDisplay(sharedScreen.getDevice().getHandle());
+ sharedScreen = null;
+ }
+
+ if (DEBUG) {
+ System.err.println(threadName+ " release END");
+ }
+ released = true;
+ notifyAll();
+ }
+ }
+ }
+
+ Thread sharedResourcesThread = null;
+ SharedResourcesRunner sharedResourcesRunner=null;
+ private X11GraphicsScreen sharedScreen=null;
+ private X11DummyGLXDrawable sharedDrawable=null;
+ private X11GLXContext sharedContext=null;
private String vendorName;
private boolean isVendorATI;
private boolean isVendorNVIDIA;
@@ -130,9 +220,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
protected boolean isVendorATI() { return isVendorATI; }
protected boolean isVendorNVIDIA() { return isVendorNVIDIA; }
- private X11DummyGLXDrawable sharedDrawable=null;
- private X11GLXContext sharedContext=null;
-
protected final GLDrawableImpl getSharedDrawable() {
return sharedDrawable;
}
@@ -141,7 +228,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return sharedContext;
}
- protected void shutdown() {
+ protected void shutdownInstance() {
if (DEBUG) {
System.err.println("!!! Shutdown Shared:");
System.err.println("!!! CTX : "+sharedContext);
@@ -149,22 +236,21 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
System.err.println("!!! Screen : "+sharedScreen);
}
- // don't free native resources from this point on,
- // since we might be in a critical shutdown hook sequence
+ // may cause JVM SIGSEGV ?
+ // X11Util.closePendingDisplayConnections();
- if(null!=sharedContext) {
- // may cause deadlock: sharedContext.destroy();
- sharedContext=null;
- }
+ sharedResourcesRunner.releaseAndWait();
- if(null!=sharedDrawable) {
- // may cause deadlock: sharedDrawable.destroy();
- sharedDrawable=null;
+ if(X11Util.getOpenDisplayConnectionNumber() > 0) {
+ System.err.println("X11GLXDrawableFactory.shutdown(): Open (no close attempt) X11 Display Connection");
+ X11Util.dumpOpenDisplayConnections();
}
- if(null!=sharedScreen) {
- // may cause deadlock: X11Util.closeThreadLocalDisplay(sharedScreen.getDevice().getHandle());
- sharedScreen = null;
+
+ if(X11Util.getPendingDisplayConnectionNumber()>0) {
+ System.err.println("X11GLXDrawableFactory.shutdown(): Pending X11 Display Connection");
+ X11Util.dumpPendingDisplayConnections();
}
+
// don't close pending XDisplay, since this might be a different thread as the opener
X11Util.shutdown( false, DEBUG );
}
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;