summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java83
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java8
-rw-r--r--src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java21
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java18
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java56
-rw-r--r--src/jogl/classes/jogamp/opengl/DesktopGLDynamicLibraryBundleInfo.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java46
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java24
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java43
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDynamicLookupHelper.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java3
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java12
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java38
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java37
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java31
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java31
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java4
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java98
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java39
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java16
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java11
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java15
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java45
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java45
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java53
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java6
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java3
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java46
40 files changed, 591 insertions, 298 deletions
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
index 809c6783d..075c8bfd8 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
@@ -454,34 +454,69 @@ public class GLEmitter extends ProcAddressEmitter {
return (GLConfiguration) getConfig();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
protected void endProcAddressTable() throws Exception {
PrintWriter w = tableWriter;
-
- w.println(" /**");
- w.println(" * This is a convenience method to get (by name) the native function");
- w.println(" * pointer for a given function. It lets you avoid having to");
- w.println(" * manually compute the "" + PROCADDRESS_VAR_PREFIX + " + ");
- w.println(" * <functionName>" member variable name and look it up via");
- w.println(" * reflection; it also will throw an exception if you try to get the");
- w.println(" * address of an unknown function, or one that is statically linked");
- w.println(" * and therefore does not have a function pointer in this table.");
- w.println(" *");
- w.println(" * @throws RuntimeException if the function pointer was not found in");
- w.println(" * this table, either because the function was unknown or because");
- w.println(" * it was statically linked.");
- w.println(" */");
- w.println(" public long getAddressFor(String functionNameUsr) {");
- w.println(" String functionNameBase = "+GLNameResolver.class.getName()+".normalizeVEN(com.jogamp.gluegen.runtime.opengl.GLNameResolver.normalizeARB(functionNameUsr, true), true);");
- w.println(" String addressFieldNameBase = PROCADDRESS_VAR_PREFIX + functionNameBase;");
- w.println(" java.lang.reflect.Field addressField = null;");
- w.println(" int funcNamePermNum = "+GLNameResolver.class.getName()+".getFuncNamePermutationNumber(functionNameBase);");
- w.println(" for(int i = 0; null==addressField && i < funcNamePermNum; i++) {");
- w.println(" String addressFieldName = "+GLNameResolver.class.getName()+".getFuncNamePermutation(addressFieldNameBase, i);");
- w.println(" try {");
- w.println(" addressField = getClass().getField(addressFieldName);");
- w.println(" } catch (Exception e) { }");
+
+ w.println(" @Override");
+ w.println(" protected boolean isFunctionAvailableImpl(String functionNameUsr) throws IllegalArgumentException {");
+ w.println(" final String functionNameBase = "+GLNameResolver.class.getName()+".normalizeVEN(com.jogamp.gluegen.runtime.opengl.GLNameResolver.normalizeARB(functionNameUsr, true), true);");
+ w.println(" final String addressFieldNameBase = \"" + PROCADDRESS_VAR_PREFIX + "\" + functionNameBase;");
+ w.println(" final int funcNamePermNum = "+GLNameResolver.class.getName()+".getFuncNamePermutationNumber(functionNameBase);");
+ w.println(" final java.lang.reflect.Field addressField = java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<java.lang.reflect.Field>() {");
+ w.println(" public final java.lang.reflect.Field run() {");
+ w.println(" java.lang.reflect.Field addressField = null;");
+ w.println(" for(int i = 0; i < funcNamePermNum; i++) {");
+ w.println(" final String addressFieldName = "+GLNameResolver.class.getName()+".getFuncNamePermutation(addressFieldNameBase, i);");
+ w.println(" try {");
+ w.println(" addressField = "+tableClassName+".class.getDeclaredField( addressFieldName );");
+ w.println(" addressField.setAccessible(true); // we need to read the protected value!");
+ w.println(" return addressField;");
+ w.println(" } catch (NoSuchFieldException ex) { }");
+ w.println(" }");
+ w.println(" return null;");
+ w.println(" } } );");
+ w.println();
+ w.println(" if(null==addressField) {");
+ w.println(" // The user is calling a bogus function or one which is not");
+ w.println(" // runtime linked");
+ w.println(" throw new RuntimeException(");
+ w.println(" \"WARNING: Address field query failed for \\\"\" + functionNameBase + \"\\\"/\\\"\" + functionNameUsr +");
+ w.println(" \"\\\"; it's either statically linked or address field is not a known \" +");
+ w.println(" \"function\");");
+ w.println(" } ");
+ w.println(" try {");
+ w.println(" return 0 != addressField.getLong(this);");
+ w.println(" } catch (Exception e) {");
+ w.println(" throw new RuntimeException(");
+ w.println(" \"WARNING: Address query failed for \\\"\" + functionNameBase + \"\\\"/\\\"\" + functionNameUsr +");
+ w.println(" \"\\\"; it's either statically linked or is not a known \" +");
+ w.println(" \"function\", e);");
w.println(" }");
+ w.println(" }");
+
+ w.println(" @Override");
+ w.println(" public long getAddressFor(String functionNameUsr) throws SecurityException, IllegalArgumentException {");
+ w.println(" SecurityUtil.checkAllLinkPermission();");
+ w.println(" final String functionNameBase = "+GLNameResolver.class.getName()+".normalizeVEN(com.jogamp.gluegen.runtime.opengl.GLNameResolver.normalizeARB(functionNameUsr, true), true);");
+ w.println(" final String addressFieldNameBase = \"" + PROCADDRESS_VAR_PREFIX + "\" + functionNameBase;");
+ w.println(" final int funcNamePermNum = "+GLNameResolver.class.getName()+".getFuncNamePermutationNumber(functionNameBase);");
+ w.println(" final java.lang.reflect.Field addressField = java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<java.lang.reflect.Field>() {");
+ w.println(" public final java.lang.reflect.Field run() {");
+ w.println(" java.lang.reflect.Field addressField = null;");
+ w.println(" for(int i = 0; i < funcNamePermNum; i++) {");
+ w.println(" final String addressFieldName = "+GLNameResolver.class.getName()+".getFuncNamePermutation(addressFieldNameBase, i);");
+ w.println(" try {");
+ w.println(" addressField = "+tableClassName+".class.getDeclaredField( addressFieldName );");
+ w.println(" addressField.setAccessible(true); // we need to read the protected value!");
+ w.println(" return addressField;");
+ w.println(" } catch (NoSuchFieldException ex) { }");
+ w.println(" }");
+ w.println(" return null;");
+ w.println(" } } );");
w.println();
w.println(" if(null==addressField) {");
w.println(" // The user is calling a bogus function or one which is not");
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 36893f5ec..9fe74ee97 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -73,7 +73,13 @@ public class GLRendererQuirks {
* <p>
* Mesa >= 9.0 (?), Intel driver, OpenGL 3.1 compatibility context is not compliant:
* <pre>
- * GL_RENDERER: Mesa DRI Intel(R) Sandybridge Desktop
+ * GL_RENDERER: 'Mesa .* Intel(R) Sandybridge Desktop'
+ * </pre>
+ * </p>
+ * <p>
+ * Mesa >= 9.0 (?), AMD driver, OpenGL 3.1 core and compatibility context is not compliant:
+ * <pre>
+ * GL_RENDERER: 'Gallium 0.4 on AMD RS880'
* </pre>
* </p>
*/
diff --git a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
index d160eccff..ca4846939 100644
--- a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
@@ -39,8 +39,8 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
-public class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
- private static List<String> glueLibNames;
+public final class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
+ private static final List<String> glueLibNames;
static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
@@ -69,11 +69,16 @@ public class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
/** Make Cg symbols available to CgGL */
@Override
- public boolean shallLinkGlobal() { return true; }
+ public final boolean shallLinkGlobal() { return true; }
- /** default **/
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Returns <code>false</code>.
+ * </p>
+ */
@Override
- public boolean shallLookupGlobal() { return false; }
+ public final boolean shallLookupGlobal() { return false; }
/** Tool has none **/
@Override
@@ -88,12 +93,12 @@ public class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
@Override
- public boolean useToolGetProcAdressFirst(String funcName) {
+ public final boolean useToolGetProcAdressFirst(String funcName) {
return false;
}
@Override
- public List<List<String>> getToolLibNames() {
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> libsCg = new ArrayList<String>();
libsCg.add("Cg");
@@ -112,7 +117,7 @@ public class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
@Override
- public RunnableExecutor getLibLoaderExecutor() {
+ public final RunnableExecutor getLibLoaderExecutor() {
return DynamicLibraryBundle.getDefaultRunnableExecutor();
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
index 26d299663..8de178e49 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
@@ -165,6 +165,6 @@ class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl {
};
public boolean blockUntilDone(Thread thread) {
- return ((Thread.currentThread() != thread) && !EventQueue.isDispatchThread());
+ return Thread.currentThread() != thread && !EventQueue.isDispatchThread();
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index 837fc84bd..ef92100ad 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -115,6 +115,10 @@ public abstract class AnimatorBase implements GLAnimatorControl {
drawablesEmpty = true;
}
+ private static final boolean useAWTAnimatorImpl(int modeBits) {
+ return 0 != ( MODE_EXPECT_AWT_RENDERING_THREAD & modeBits ) && null != awtAnimatorImplClazz;
+ }
+
/**
* Initializes implementation details post setup,
* invoked at {@link #add(GLAutoDrawable)}, {@link #start()}, ..
@@ -125,9 +129,9 @@ public abstract class AnimatorBase implements GLAnimatorControl {
*
* @throws GLException if Animator is {@link #isStarted()}
*/
- protected void initImpl(boolean force) {
+ protected synchronized void initImpl(boolean force) {
if( force || null == impl ) {
- if( 0 != ( MODE_EXPECT_AWT_RENDERING_THREAD & modeBits ) && null != awtAnimatorImplClazz ) {
+ if( useAWTAnimatorImpl( modeBits ) ) {
try {
impl = (AnimatorImpl) awtAnimatorImplClazz.newInstance();
baseName = getBaseName("AWT");
@@ -150,20 +154,20 @@ public abstract class AnimatorBase implements GLAnimatorControl {
* @param enable
* @param bitValues
*
- * @throws GLException if Animator is {@link #isStarted()}
+ * @throws GLException if Animator is {@link #isStarted()} and {@link #MODE_EXPECT_AWT_RENDERING_THREAD} about to change
* @see AnimatorBase#MODE_EXPECT_AWT_RENDERING_THREAD
*/
public synchronized void setModeBits(boolean enable, int bitValues) throws GLException {
- if( isStarted() ) {
- throw new GLException("Animator already started");
- }
final int _oldModeBits = modeBits;
if(enable) {
modeBits |= bitValues;
} else {
modeBits &= ~bitValues;
}
- if( _oldModeBits != modeBits ) {
+ if( useAWTAnimatorImpl( _oldModeBits ) != useAWTAnimatorImpl( modeBits ) ) {
+ if( isStarted() ) {
+ throw new GLException("Animator already started");
+ }
initImpl(true);
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
index 23b0845ee..bbd2951b9 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
@@ -61,6 +61,6 @@ class DefaultAnimatorImpl implements AnimatorBase.AnimatorImpl {
}
public boolean blockUntilDone(Thread thread) {
- return (Thread.currentThread() != thread);
+ return Thread.currentThread() != thread;
}
}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 55ad85c9c..f1d8ff95e 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -40,8 +40,6 @@
package javax.media.opengl;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
@@ -118,13 +116,8 @@ public abstract class GLDrawableFactory {
private static GLDrawableFactory eglFactory;
private static GLDrawableFactory nativeOSFactory;
- protected static ArrayList<GLDrawableFactory> glDrawableFactories = new ArrayList<GLDrawableFactory>();
-
- // Shutdown hook mechanism for the factory
- private static boolean factoryShutdownHookRegistered = false;
- private static Thread factoryShutdownHook = null;
- private static volatile boolean isJVMShuttingDown = false;
-
+ private static ArrayList<GLDrawableFactory> glDrawableFactories = new ArrayList<GLDrawableFactory>();
+
/**
* Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
*/
@@ -139,7 +132,12 @@ public abstract class GLDrawableFactory {
}
}
private static final void initSingletonImpl() {
- registerFactoryShutdownHook();
+ NativeWindowFactory.initSingleton();
+ NativeWindowFactory.addCustomShutdownHook(false /* head */, new Runnable() {
+ public void run() {
+ shutdown0();
+ }
+ });
final String nwt = NativeWindowFactory.getNativeWindowType(true);
GLDrawableFactory tmp = null;
@@ -199,23 +197,31 @@ public abstract class GLDrawableFactory {
synchronized (GLDrawableFactory.class) {
if (isInit) {
isInit=false;
- shutdownImpl();
+ shutdown0();
}
}
}
}
- private static void shutdownImpl() {
+ private static void shutdown0() {
// 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++) {
+ final int gldfCount = glDrawableFactories.size();
+ if( DEBUG ) {
+ System.err.println("GLDrawableFactory.shutdownAll "+gldfCount+" instances, on thread "+getThreadName());
+ }
+ for(int i=0; i<gldfCount; i++) {
final GLDrawableFactory gldf = glDrawableFactories.get(i);
+ if( DEBUG ) {
+ System.err.println("GLDrawableFactory.shutdownAll["+(i+1)+"/"+gldfCount+"]: "+gldf.getClass().getName());
+ }
try {
+ gldf.resetDisplayGamma();
gldf.destroy();
} catch (Throwable t) {
- System.err.println("GLDrawableFactory.shutdownImpl: Catched Exception during shutdown of "+gldf.getClass().getName());
+ System.err.println("GLDrawableFactory.shutdownImpl: Catched "+t.getClass().getName()+" during factory shutdown #"+(i+1)+"/"+gldfCount+" "+gldf.getClass().getName());
if( DEBUG ) {
t.printStackTrace();
}
@@ -228,28 +234,8 @@ public abstract class GLDrawableFactory {
eglFactory = null;
}
GLContext.shutdown();
- NativeWindowFactory.shutdown(isJVMShuttingDown);
}
- private static synchronized void registerFactoryShutdownHook() {
- if (factoryShutdownHookRegistered) {
- return;
- }
- factoryShutdownHook = new Thread(new Runnable() {
- public void run() {
- isJVMShuttingDown = true;
- GLDrawableFactory.shutdownImpl();
- }
- });
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- Runtime.getRuntime().addShutdownHook(factoryShutdownHook);
- return null;
- }
- });
- factoryShutdownHookRegistered = true;
- }
-
protected GLDrawableFactory() {
synchronized(glDrawableFactories) {
glDrawableFactories.add(this);
@@ -266,6 +252,8 @@ public abstract class GLDrawableFactory {
protected abstract void destroy();
+ public abstract void resetDisplayGamma();
+
/**
* Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection},
* {@link AbstractGraphicsDevice#getUnitID() unit ID} and {@link AbstractGraphicsDevice#getUniqueID() unique ID name}. for this factory<br>
diff --git a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLibraryBundleInfo.java
index f77f1135b..ef9477a31 100644
--- a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLibraryBundleInfo.java
@@ -32,7 +32,7 @@ import java.util.List;
import java.util.ArrayList;
public abstract class DesktopGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
- private static List<String> glueLibNames;
+ private static final List<String> glueLibNames;
static {
glueLibNames = new ArrayList<String>();
@@ -49,7 +49,7 @@ public abstract class DesktopGLDynamicLibraryBundleInfo extends GLDynamicLibrary
}
@Override
- public boolean useToolGetProcAdressFirst(String funcName) {
+ public final boolean useToolGetProcAdressFirst(String funcName) {
return true;
}
diff --git a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
index ff49303ca..8eb3468ed 100644
--- a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
+++ b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
@@ -37,9 +37,9 @@ public class DesktopGLDynamicLookupHelper extends GLDynamicLookupHelper {
super(info);
}
- public DesktopGLDynamicLibraryBundleInfo getDesktopGLBundleInfo() { return (DesktopGLDynamicLibraryBundleInfo) getBundleInfo(); }
+ public final DesktopGLDynamicLibraryBundleInfo getDesktopGLBundleInfo() { return (DesktopGLDynamicLibraryBundleInfo) getBundleInfo(); }
- public synchronized boolean loadGLULibrary() {
+ public final synchronized boolean loadGLULibrary() {
/** hacky code .. where all platform GLU libs are tried ..*/
if(null==gluLib) {
List<String> gluLibNames = new ArrayList<String>();
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index cab629c3a..d6f97662e 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -42,6 +42,8 @@ package jogamp.opengl;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
@@ -1144,10 +1146,15 @@ public abstract class GLContextImpl extends GLContext {
/** Helper routine which resets a ProcAddressTable generated by the
GLEmitter by looking up anew all of its function pointers. */
- protected final void resetProcAddressTable(ProcAddressTable table) {
- table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
+ protected final void resetProcAddressTable(final ProcAddressTable table) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
+ return null;
+ }
+ } );
}
-
+
private final boolean initGLRendererAndGLVersionStrings() {
final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString");
@@ -1508,6 +1515,8 @@ public abstract class GLContextImpl extends GLContext {
int i = 0;
final String MesaSP = "Mesa ";
+ final String MesaRendererAMDsp = " AMD ";
+ final String MesaRendererIntelsp = "Intel(R)";
final boolean hwAccel = 0 == ( ctp & GLContext.CTX_IMPL_ACCEL_SOFT );
final boolean compatCtx = 0 != ( ctp & GLContext.CTX_PROFILE_COMPAT );
final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium ");
@@ -1632,7 +1641,7 @@ public abstract class GLContextImpl extends GLContext {
}
quirks[i++] = quirk;
}
- if( hwAccel /* glRenderer.contains("Intel(R)") || glRenderer.contains("AMD ") */ )
+ if( hwAccel /* glRenderer.contains( MesaRendererIntelsp ) || glRenderer.contains( MesaRendererAMDsp ) */ )
{
final int quirk = GLRendererQuirks.NoDoubleBufferedPBuffer;
if(DEBUG) {
@@ -1640,7 +1649,9 @@ public abstract class GLContextImpl extends GLContext {
}
quirks[i++] = quirk;
}
- if( glRenderer.contains("Intel(R)") && compatCtx && ( major > 3 || major == 3 && minor >= 1 ) )
+ if( ( (glRenderer.contains( MesaRendererIntelsp ) && compatCtx) || glRenderer.contains( MesaRendererAMDsp ) ) &&
+ ( major > 3 || major == 3 && minor >= 1 )
+ )
{
// FIXME: Apply vendor version constraints!
final int quirk = GLRendererQuirks.GLNonCompliant;
@@ -1748,7 +1759,7 @@ public abstract class GLContextImpl extends GLContext {
// Check GL 1st (cached)
if(null!=glProcAddressTable) { // null if this context wasn't not created
try {
- if(0!=glProcAddressTable.getAddressFor(glFunctionName)) {
+ if( glProcAddressTable.isFunctionAvailable( glFunctionName ) ) {
return true;
}
} catch (Exception e) {}
@@ -1758,27 +1769,24 @@ public abstract class GLContextImpl extends GLContext {
final ProcAddressTable pTable = getPlatformExtProcAddressTable();
if(null!=pTable) {
try {
- if(0!=pTable.getAddressFor(glFunctionName)) {
+ if( pTable.isFunctionAvailable( glFunctionName ) ) {
return true;
}
} catch (Exception e) {}
}
// dynamic function lookup at last incl name aliasing (not cached)
- DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper();
- String tmpBase = GLNameResolver.normalizeVEN(GLNameResolver.normalizeARB(glFunctionName, true), true);
- long addr = 0;
+ final DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper();
+ final String tmpBase = GLNameResolver.normalizeVEN(GLNameResolver.normalizeARB(glFunctionName, true), true);
+ boolean res = false;
int variants = GLNameResolver.getFuncNamePermutationNumber(tmpBase);
- for(int i = 0; 0==addr && i < variants; i++) {
- String tmp = GLNameResolver.getFuncNamePermutation(tmpBase, i);
+ for(int i = 0; !res && i < variants; i++) {
+ final String tmp = GLNameResolver.getFuncNamePermutation(tmpBase, i);
try {
- addr = dynLookup.dynamicLookupFunction(tmp);
+ res = dynLookup.isFunctionAvailable(tmp);
} catch (Exception e) { }
}
- if(0!=addr) {
- return true;
- }
- return false;
+ return res;
}
@Override
@@ -2078,8 +2086,8 @@ public abstract class GLContextImpl extends GLContext {
}
/** Internal bootstraping glGetString(GL_RENDERER) */
- protected static native String glGetStringInt(int name, long procAddress);
+ private static native String glGetStringInt(int name, long procAddress);
/** Internal bootstraping glGetIntegerv(..) for version */
- protected static native void glGetIntegervInt(int pname, int[] params, int params_offset, long procAddress);
+ private static native void glGetIntegervInt(int pname, int[] params, int params_offset, long procAddress);
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
index 0000e6199..10cdd512e 100644
--- a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
+++ b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
@@ -27,6 +27,8 @@
*/
package jogamp.opengl;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import javax.media.nativewindow.NativeWindowException;
@@ -39,8 +41,6 @@ import com.jogamp.common.os.Platform;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.opengl.GLExtensions;
-import jogamp.opengl.gl4.GL4bcProcAddressTable;
-
/**
* The GLDebugMessageHandler, handling <i>GL_ARB_debug_output</i> or <i>GL_AMD_debug_output</i>
* debug messages.<br>
@@ -107,6 +107,18 @@ public class GLDebugMessageHandler {
}
}
+ private final long getAddressFor(final ProcAddressTable table, final String functionName) {
+ return AccessController.doPrivileged(new PrivilegedAction<Long>() {
+ public Long run() {
+ try {
+ return Long.valueOf( table.getAddressFor(functionName) );
+ } catch (IllegalArgumentException iae) {
+ return Long.valueOf(0);
+ }
+ }
+ } ).longValue();
+ }
+
public void init() {
ctx.validateCurrent();
if( isAvailable()) {
@@ -148,17 +160,17 @@ public class GLDebugMessageHandler {
}
final ProcAddressTable procAddressTable = ctx.getGLProcAddressTable();
- if( procAddressTable instanceof GL4bcProcAddressTable) {
- final GL4bcProcAddressTable desktopProcAddressTable = (GL4bcProcAddressTable)procAddressTable;
+ if( !ctx.isGLES1() && !ctx.isGLES2() ) {
switch(extType) {
case EXT_ARB:
- glDebugMessageCallbackProcAddress = desktopProcAddressTable._addressof_glDebugMessageCallbackARB;
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallbackARB");
break;
case EXT_AMD:
- glDebugMessageCallbackProcAddress = desktopProcAddressTable._addressof_glDebugMessageCallbackAMD;
+ glDebugMessageCallbackProcAddress = getAddressFor(procAddressTable, "glDebugMessageCallbackAMD");
break;
}
} else {
+ glDebugMessageCallbackProcAddress = 0;
if(DEBUG) {
System.err.println("Non desktop context not supported");
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index 06e856d41..4ac413545 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -575,16 +575,16 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
rampEntry = 0.0f;
gammaRamp[i] = rampEntry;
}
- registerGammaShutdownHook();
+ needsGammaRampReset = true;
return setGammaRamp(gammaRamp);
}
+ @Override
public synchronized void resetDisplayGamma() {
- if (gammaShutdownHook == null) {
- throw new IllegalArgumentException("Should not call this unless setDisplayGamma called first");
+ if( needsGammaRampReset ) {
+ resetGammaRamp(originalGammaRamp);
+ needsGammaRampReset = false;
}
- resetGammaRamp(originalGammaRamp);
- unregisterGammaShutdownHook();
}
//------------------------------------------------------
@@ -616,35 +616,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
// Shutdown hook mechanism for resetting gamma
- private boolean gammaShutdownHookRegistered;
- private Thread gammaShutdownHook;
- private Buffer originalGammaRamp;
- private synchronized void registerGammaShutdownHook() {
- if (gammaShutdownHookRegistered)
- return;
- if (gammaShutdownHook == null) {
- gammaShutdownHook = new Thread(new Runnable() {
- @Override
- public void run() {
- synchronized (GLDrawableFactoryImpl.this) {
- resetGammaRamp(originalGammaRamp);
- }
- }
- });
- originalGammaRamp = getGammaRamp();
- }
- Runtime.getRuntime().addShutdownHook(gammaShutdownHook);
- gammaShutdownHookRegistered = true;
- }
-
- private synchronized void unregisterGammaShutdownHook() {
- if (!gammaShutdownHookRegistered)
- return;
- if (gammaShutdownHook == null) {
- throw new InternalError("Error in gamma shutdown hook logic");
- }
- Runtime.getRuntime().removeShutdownHook(gammaShutdownHook);
- gammaShutdownHookRegistered = false;
- // Leave the original gamma ramp data alone
- }
+ private volatile Buffer originalGammaRamp;
+ private volatile boolean needsGammaRampReset = false;
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
index a2e3b3175..8ba9f617b 100644
--- a/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/GLDynamicLibraryBundleInfo.java
@@ -46,16 +46,19 @@ public abstract class GLDynamicLibraryBundleInfo implements DynamicLibraryBundle
* </pre>
* </p>
*/
- public boolean shallLinkGlobal() { return true; }
+ public final boolean shallLinkGlobal() { return true; }
/**
- * Default value: <code>false</code>.
- */
+ * {@inheritDoc}
+ * <p>
+ * Returns <code>false</code>.
+ * </p>
+ */
@Override
public boolean shallLookupGlobal() { return false; }
@Override
- public RunnableExecutor getLibLoaderExecutor() {
+ public final RunnableExecutor getLibLoaderExecutor() {
return DynamicLibraryBundle.getDefaultRunnableExecutor();
}
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDynamicLookupHelper.java b/src/jogl/classes/jogamp/opengl/GLDynamicLookupHelper.java
index d2dac8148..1ed73f15e 100644
--- a/src/jogl/classes/jogamp/opengl/GLDynamicLookupHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDynamicLookupHelper.java
@@ -36,7 +36,7 @@ public class GLDynamicLookupHelper extends DynamicLibraryBundle {
super(info);
}
- public GLDynamicLibraryBundleInfo getGLBundleInfo() { return (GLDynamicLibraryBundleInfo) getBundleInfo(); }
+ public final GLDynamicLibraryBundleInfo getGLBundleInfo() { return (GLDynamicLibraryBundleInfo) getBundleInfo(); }
/** NOP per default */
public boolean loadGLULibrary() { return false; }
diff --git a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
index 771d16d46..3d59d1d53 100644
--- a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
@@ -36,8 +36,8 @@ import jogamp.opengl.*;
* Implementation of the DynamicLookupHelper for Desktop ES2 (AMD, ..)
* where EGL and ES2 functions reside within the desktop OpenGL library.
*/
-public class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
- static List<String> glueLibNames;
+public final class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
+ static final List<String> glueLibNames;
static {
glueLibNames = new ArrayList<String>();
glueLibNames.add("jogl_mobile");
@@ -61,7 +61,7 @@ public class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleIn
return true;
}
- public List<List<String>> getToolLibNames() {
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> libsGL = new ArrayList<String>();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 2b8ca31c9..b54ed6599 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -259,8 +259,7 @@ public class EGLContext extends GLContextImpl {
protected final StringBuilder getPlatformExtensionsStringImpl() {
StringBuilder sb = new StringBuilder();
if (!eglQueryStringInitialized) {
- eglQueryStringAvailable =
- getDrawableImpl().getGLDynamicLookupHelper().dynamicLookupFunction("eglQueryString") != 0;
+ eglQueryStringAvailable = getDrawableImpl().getGLDynamicLookupHelper().isFunctionAvailable("eglQueryString");
eglQueryStringInitialized = true;
}
if (eglQueryStringAvailable) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index adb78b3b9..79d1fad62 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -91,9 +91,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
private static final boolean isANGLE(GLDynamicLookupHelper dl) {
if(Platform.OSType.WINDOWS == Platform.OS_TYPE) {
- final boolean r = 0 != dl.dynamicLookupFunction("eglQuerySurfacePointerANGLE") ||
- 0 != dl.dynamicLookupFunction("glBlitFramebufferANGLE") ||
- 0 != dl.dynamicLookupFunction("glRenderbufferStorageMultisampleANGLE");
+ final boolean r = dl.isFunctionAvailable("eglQuerySurfacePointerANGLE") ||
+ dl.isFunctionAvailable("glBlitFramebufferANGLE") ||
+ dl.isFunctionAvailable("glRenderbufferStorageMultisampleANGLE");
return r;
} else {
return false;
@@ -101,9 +101,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
private static final boolean includesES1(GLDynamicLookupHelper dl) {
- return 0 != dl.dynamicLookupFunction("glLoadIdentity") &&
- 0 != dl.dynamicLookupFunction("glEnableClientState") &&
- 0 != dl.dynamicLookupFunction("glColorPointer");
+ return dl.isFunctionAvailable("glLoadIdentity") &&
+ dl.isFunctionAvailable("glEnableClientState") &&
+ dl.isFunctionAvailable("glColorPointer");
}
public EGLDrawableFactory() {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
index 26b199ea2..9f4a4d2c2 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
@@ -42,7 +42,7 @@ import jogamp.opengl.*;
* Currently two implementations exist, one for ES1 and one for ES2.
*/
public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
- static List<String> glueLibNames;
+ static final List<String> glueLibNames;
static {
glueLibNames = new ArrayList<String>();
glueLibNames.add("jogl_mobile");
@@ -57,7 +57,7 @@ public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundle
* and <code>false</code> otherwise.
*/
@Override
- public boolean shallLookupGlobal() {
+ public final boolean shallLookupGlobal() {
if ( Platform.OSType.ANDROID == Platform.OS_TYPE ) {
// Android requires global symbol lookup
return true;
@@ -88,7 +88,7 @@ public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundle
}
}
- protected List<String> getEGLLibNamesList() {
+ protected final List<String> getEGLLibNamesList() {
List<String> eglLibNames = new ArrayList<String>();
// this is the default EGL lib name, according to the spec
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
index 0a373eb7f..dd3d6faea 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
@@ -30,12 +30,12 @@ package jogamp.opengl.egl;
import java.util.*;
-public class EGLES1DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
+public final class EGLES1DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
protected EGLES1DynamicLibraryBundleInfo() {
super();
}
- public List<List<String>> getToolLibNames() {
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
{
final List<String> libsGL = new ArrayList<String>();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
index d4ee852b1..d83acdb6b 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
@@ -30,12 +30,12 @@ package jogamp.opengl.egl;
import java.util.*;
-public class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
+public final class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
protected EGLES2DynamicLibraryBundleInfo() {
super();
}
- public List<List<String>> getToolLibNames() {
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
{
final List<String> libsGL = new ArrayList<String>();
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java
index 03ec94db6..f8c874a53 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java
@@ -31,13 +31,13 @@ package jogamp.opengl.macosx.cgl;
import jogamp.opengl.*;
import java.util.*;
-public class MacOSXCGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo {
+public final class MacOSXCGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo {
protected MacOSXCGLDynamicLibraryBundleInfo() {
super();
}
@Override
- public List<List<String>> getToolLibNames() {
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> libsGL = new ArrayList<String>();
libsGL.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib");
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
index 0971ac78e..852e5149c 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
@@ -55,10 +55,10 @@ import com.jogamp.common.util.RunnableExecutor;
* Tue Feb 28 12:07:53 2012 322537478b63c6bc01e640643550ff539864d790 minor 1 -> 2
*/
class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
- private static List<String> glueLibNames = new ArrayList<String>(); // none
+ private static final List<String> glueLibNames = new ArrayList<String>(); // none
private static final int symbolCount = 32;
- private static String[] symbolNames = {
+ private static final String[] symbolNames = {
"avcodec_version",
"avformat_version",
/* 3 */ "avutil_version",
@@ -100,7 +100,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
};
// alternate symbol names
- private static String[][] altSymbolNames = {
+ private static final String[][] altSymbolNames = {
{ "avcodec_open", "avcodec_open2" }, // old, 53.6.0
{ "avcodec_decode_audio3", "avcodec_decode_audio4" }, // old, 53.25.0
{ "av_close_input_file", "avformat_close_input" }, // old, 53.17.0
@@ -108,7 +108,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
};
// optional symbol names
- private static String[] optionalSymbolNames = {
+ private static final String[] optionalSymbolNames = {
"avformat_free_context", // 52.96.0 (opt)
"avformat_network_init", // 53.13.0 (opt)
"avformat_network_deinit", // 53.13.0 (opt)
@@ -134,7 +134,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
static boolean initSingleton() { return ready; }
- private static boolean initSymbols() {
+ private static final boolean initSymbols() {
final DynamicLibraryBundle dl = AccessController.doPrivileged(new PrivilegedAction<DynamicLibraryBundle>() {
public DynamicLibraryBundle run() {
return new DynamicLibraryBundle(new FFMPEGDynamicLibraryBundleInfo());
@@ -172,9 +172,13 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
// lookup
- for(int i = 0; i<symbolCount; i++) {
- symbolAddr[i] = dl.dynamicLookupFunction(symbolNames[i]);
- }
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ for(int i = 0; i<symbolCount; i++) {
+ symbolAddr[i] = dl.dynamicLookupFunction(symbolNames[i]);
+ }
+ return null;
+ } } );
// validate results
for(int i = 0; i<symbolCount; i++) {
@@ -212,10 +216,18 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
@Override
- public boolean shallLinkGlobal() { return true; }
+ public final boolean shallLinkGlobal() { return true; }
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Returns <code>true</code>.
+ * </p>
+ */
@Override
- public boolean shallLookupGlobal() { return true; }
+ public final boolean shallLookupGlobal() {
+ return true;
+ }
@Override
public final List<String> getGlueLibNames() {
@@ -223,7 +235,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
@Override
- public List<List<String>> getToolLibNames() {
+ public final List<List<String>> getToolLibNames() {
List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> avutil = new ArrayList<String>();
@@ -280,12 +292,12 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
@Override
- public boolean useToolGetProcAdressFirst(String funcName) {
+ public final boolean useToolGetProcAdressFirst(String funcName) {
return false;
}
@Override
- public RunnableExecutor getLibLoaderExecutor() {
+ public final RunnableExecutor getLibLoaderExecutor() {
return DynamicLibraryBundle.getDefaultRunnableExecutor();
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
index 972cf0642..9ae1541f9 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
@@ -31,6 +31,8 @@ package jogamp.opengl.util.av.impl;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
@@ -46,9 +48,6 @@ import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureSequence;
import jogamp.opengl.GLContextImpl;
-import jogamp.opengl.es1.GLES1ProcAddressTable;
-import jogamp.opengl.es2.GLES2ProcAddressTable;
-import jogamp.opengl.gl4.GL4bcProcAddressTable;
import jogamp.opengl.util.av.AudioSink;
import jogamp.opengl.util.av.JavaSoundAudioSink;
import jogamp.opengl.util.av.NullAudioSink;
@@ -225,18 +224,30 @@ public class FFMPEGMediaPlayer extends EGLMediaPlayerImpl {
}
setTextureFormat(tif, tf);
setTextureType(GL.GL_UNSIGNED_BYTE);
- GLContextImpl ctx = (GLContextImpl)gl.getContext();
- ProcAddressTable pt = ctx.getGLProcAddressTable();
- if(pt instanceof GLES2ProcAddressTable) {
- procAddrGLTexSubImage2D = ((GLES2ProcAddressTable)pt)._addressof_glTexSubImage2D;
- } else if(pt instanceof GLES1ProcAddressTable) {
- procAddrGLTexSubImage2D = ((GLES1ProcAddressTable)pt)._addressof_glTexSubImage2D;
- } else if(pt instanceof GL4bcProcAddressTable) {
- procAddrGLTexSubImage2D = ((GL4bcProcAddressTable)pt)._addressof_glTexSubImage2D;
- } else {
- throw new InternalError("Unknown ProcAddressTable: "+pt.getClass().getName()+" of "+ctx.getClass().getName());
+ final GLContextImpl ctx = (GLContextImpl)gl.getContext();
+ final ProcAddressTable pt = ctx.getGLProcAddressTable();
+ procAddrGLTexSubImage2D = getAddressFor(pt, "glTexSubImage2D");
+ if( 0 == procAddrGLTexSubImage2D ) {
+ throw new InternalError("glTexSubImage2D n/a in ProcAddressTable: "+pt.getClass().getName()+" of "+ctx.getGLVersion());
}
}
+
+ /**
+ * Catches IllegalArgumentException and returns 0 if functionName is n/a,
+ * otherwise the ProcAddressTable's field value.
+ */
+ private final long getAddressFor(final ProcAddressTable table, final String functionName) {
+ return AccessController.doPrivileged(new PrivilegedAction<Long>() {
+ public Long run() {
+ try {
+ return Long.valueOf( table.getAddressFor(functionName) );
+ } catch (IllegalArgumentException iae) {
+ return Long.valueOf(0);
+ }
+ }
+ } ).longValue();
+ }
+
private class AudioFrame {
final byte[] sampleData;
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 5fb01d1a3..45edda516 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -43,6 +43,8 @@ package jogamp.opengl.windows.wgl;
import java.nio.Buffer;
import java.nio.ShortBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -88,19 +90,24 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
super();
synchronized(WindowsWGLDrawableFactory.class) {
- if(null==windowsWGLDynamicLookupHelper) {
- DesktopGLDynamicLookupHelper tmp = null;
- try {
- tmp = new DesktopGLDynamicLookupHelper(new WindowsWGLDynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
+ if( null == windowsWGLDynamicLookupHelper ) {
+ windowsWGLDynamicLookupHelper = AccessController.doPrivileged(new PrivilegedAction<DesktopGLDynamicLookupHelper>() {
+ public DesktopGLDynamicLookupHelper run() {
+ DesktopGLDynamicLookupHelper tmp;
+ try {
+ tmp = new DesktopGLDynamicLookupHelper(new WindowsWGLDynamicLibraryBundleInfo());
+ if(null!=tmp && tmp.isLibComplete()) {
+ WGL.getWGLProcAddressTable().reset(tmp);
+ }
+ } catch (Exception ex) {
+ tmp = null;
+ if(DEBUG) {
+ ex.printStackTrace();
+ }
+ }
+ return tmp;
}
- }
- if(null!=tmp && tmp.isLibComplete()) {
- windowsWGLDynamicLookupHelper = tmp;
- WGL.getWGLProcAddressTable().reset(windowsWGLDynamicLookupHelper);
- }
+ } );
}
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java
index a553bd4c2..7ec6c50f8 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java
@@ -31,13 +31,13 @@ package jogamp.opengl.windows.wgl;
import jogamp.opengl.*;
import java.util.*;
-public class WindowsWGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo {
+public final class WindowsWGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo {
protected WindowsWGLDynamicLibraryBundleInfo() {
super();
}
@Override
- public List<List<String>> getToolLibNames() {
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> libsGL = new ArrayList<String>();
libsGL.add("OpenGL32");
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 394293bc0..b3b02e23f 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -39,6 +39,8 @@ package jogamp.opengl.x11.glx;
import java.nio.Buffer;
import java.nio.ShortBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -91,19 +93,24 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
super();
synchronized(X11GLXDrawableFactory.class) {
- if(null==x11GLXDynamicLookupHelper) {
- DesktopGLDynamicLookupHelper tmp = null;
- try {
- tmp = new DesktopGLDynamicLookupHelper(new X11GLXDynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
+ if( null == x11GLXDynamicLookupHelper ) {
+ x11GLXDynamicLookupHelper = AccessController.doPrivileged(new PrivilegedAction<DesktopGLDynamicLookupHelper>() {
+ public DesktopGLDynamicLookupHelper run() {
+ DesktopGLDynamicLookupHelper tmp;
+ try {
+ tmp = new DesktopGLDynamicLookupHelper(new X11GLXDynamicLibraryBundleInfo());
+ if(null!=tmp && tmp.isLibComplete()) {
+ GLX.getGLXProcAddressTable().reset(tmp);
+ }
+ } catch (Exception ex) {
+ tmp = null;
+ if(DEBUG) {
+ ex.printStackTrace();
+ }
+ }
+ return tmp;
}
- }
- if(null!=tmp && tmp.isLibComplete()) {
- x11GLXDynamicLookupHelper = tmp;
- GLX.getGLXProcAddressTable().reset(x11GLXDynamicLookupHelper);
- }
+ } );
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java
index 6083f209c..f25f7ae2c 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java
@@ -31,13 +31,13 @@ package jogamp.opengl.x11.glx;
import jogamp.opengl.*;
import java.util.*;
-public class X11GLXDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo {
+public final class X11GLXDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo {
protected X11GLXDynamicLibraryBundleInfo() {
super();
}
@Override
- public List<List<String>> getToolLibNames() {
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> libsGL = new ArrayList<String>();
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index b6a052253..bf37b8d0c 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -37,8 +37,10 @@ import java.io.File;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import jogamp.nativewindow.Debug;
@@ -108,7 +110,9 @@ public abstract class NativeWindowFactory {
private static boolean requiresToolkitLock;
private static boolean desktopHasThreadingIssues;
+ // Shutdown hook mechanism for the factory
private static volatile boolean isJVMShuttingDown = false;
+ private static final List<Runnable> customShutdownHooks = new ArrayList<Runnable>();
/** Creates a new NativeWindowFactory instance. End users do not
need to call this method. */
@@ -160,6 +164,11 @@ public abstract class NativeWindowFactory {
Platform.initSingleton(); // last resort ..
_DEBUG[0] = Debug.debug("NativeWindow");
_tmp[0] = Debug.getProperty("nativewindow.ws.name", true);
+ Runtime.getRuntime().addShutdownHook(
+ new Thread(new Runnable() {
+ public void run() {
+ NativeWindowFactory.shutdown(true);
+ } }, "NativeWindowFactory_ShutdownHook" ) ) ;
return null;
} } ) ;
@@ -204,6 +213,72 @@ public abstract class NativeWindowFactory {
}
}
+ /** Returns true if the JVM is shutting down, otherwise false. */
+ public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; }
+
+ /**
+ * Add a custom shutdown hook to be performed at JVM shutdown before shutting down NativeWindowFactory instance.
+ *
+ * @param head if true add runnable at the start, otherwise at the end
+ * @param runnable runnable to be added.
+ */
+ public static void addCustomShutdownHook(boolean head, Runnable runnable) {
+ synchronized( customShutdownHooks ) {
+ if( !customShutdownHooks.contains( runnable ) ) {
+ if( head ) {
+ customShutdownHooks.add(0, runnable);
+ } else {
+ customShutdownHooks.add( runnable );
+ }
+ }
+ }
+ }
+
+ /**
+ * Cleanup resources at JVM shutdown
+ */
+ public static synchronized void shutdown(boolean _isJVMShuttingDown) {
+ isJVMShuttingDown = _isJVMShuttingDown;
+ if(DEBUG) {
+ System.err.println("NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown+", on thread "+Thread.currentThread().getName());
+ }
+ synchronized(customShutdownHooks) {
+ final int cshCount = customShutdownHooks.size();
+ for(int i=0; i < cshCount; i++) {
+ try {
+ if( DEBUG ) {
+ System.err.println("NativeWindowFactory.shutdown - customShutdownHook #"+(i+1)+"/"+cshCount);
+ }
+ customShutdownHooks.get(i).run();
+ } catch(Throwable t) {
+ System.err.println("NativeWindowFactory.shutdown: Catched "+t.getClass().getName()+" during customShutdownHook #"+(i+1)+"/"+cshCount);
+ if( DEBUG ) {
+ t.printStackTrace();
+ }
+ }
+ }
+ customShutdownHooks.clear();
+ }
+ if(DEBUG) {
+ System.err.println("NativeWindowFactory.shutdown(): Post customShutdownHook");
+ }
+
+ if(initialized) {
+ initialized = false;
+ if(null != registeredFactories) {
+ registeredFactories.clear();
+ registeredFactories = null;
+ }
+ GraphicsConfigurationFactory.shutdown();
+ }
+
+ shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown
+ // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown);
+ }
+ }
+
private static void shutdownNativeImpl(final ClassLoader cl) {
final String clazzName;
if( TYPE_X11 == nativeWindowingTypePure ) {
@@ -310,29 +385,6 @@ public abstract class NativeWindowFactory {
}
}
- 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(null != registeredFactories) {
- registeredFactories.clear();
- registeredFactories = null;
- }
- GraphicsConfigurationFactory.shutdown();
- }
- shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown
- // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet
- 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/awt/AWTMisc.java b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java
index d77cd75ef..2524f107a 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java
@@ -27,6 +27,7 @@
*/
package jogamp.nativewindow.awt;
+import java.awt.FocusTraversalPolicy;
import java.awt.Window;
import java.awt.Component;
import java.awt.Container;
@@ -68,6 +69,44 @@ public class AWTMisc {
return (Container) c;
}
+ public static Component getNextFocus(Component comp) {
+ Container focusContainer = comp.getFocusCycleRootAncestor();
+ while ( focusContainer != null &&
+ ( !focusContainer.isShowing() || !focusContainer.isFocusable() || !focusContainer.isEnabled() ) )
+ {
+ comp = focusContainer;
+ focusContainer = comp.getFocusCycleRootAncestor();
+ }
+ Component next = null;
+ if (focusContainer != null) {
+ final FocusTraversalPolicy policy = focusContainer.getFocusTraversalPolicy();
+ next = policy.getComponentAfter(focusContainer, comp);
+ if (next == null) {
+ next = policy.getDefaultComponent(focusContainer);
+ }
+ }
+ return next;
+ }
+
+ public static Component getPrevFocus(Component comp) {
+ Container focusContainer = comp.getFocusCycleRootAncestor();
+ while ( focusContainer != null &&
+ ( !focusContainer.isShowing() || !focusContainer.isFocusable() || !focusContainer.isEnabled() ) )
+ {
+ comp = focusContainer;
+ focusContainer = comp.getFocusCycleRootAncestor();
+ }
+ Component prev = null;
+ if (focusContainer != null) {
+ final FocusTraversalPolicy policy = focusContainer.getFocusTraversalPolicy();
+ prev = policy.getComponentBefore(focusContainer, comp);
+ if (prev == null) {
+ prev = policy.getDefaultComponent(focusContainer);
+ }
+ }
+ return prev;
+ }
+
/**
* Issue this when your non AWT toolkit gains focus to clear AWT menu path
*/
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 2d9c42e09..bbc58b73a 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -98,10 +98,10 @@ public class X11Util implements ToolkitProperties {
private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.isPropertyDefined("nativewindow.debug.X11Util.TraceDisplayLifecycle", true);
private static String nullDisplayName = null;
private static volatile boolean isInit = false;
- private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues
+ private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues, or GLRendererQuirks.DontCloseX11Display
private static boolean hasThreadingIssues = false; // ATI/AMD X11 driver issues
- private static Object setX11ErrorHandlerLock = new Object();
+ private static final Object setX11ErrorHandlerLock = new Object();
private static final String X11_EXTENSION_ATIFGLRXDRI = "ATIFGLRXDRI";
private static final String X11_EXTENSION_ATIFGLEXTENSION = "ATIFGLEXTENSION";
@@ -207,12 +207,12 @@ public class X11Util implements ToolkitProperties {
}
}
- 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();
+ // Only at JVM shutdown time, since AWT impl. seems to
+ // dislike closing of X11 Display's (w/ ATI driver).
+ if( isJVMShuttingDown ) {
+ synchronized(globalLock) {
+ isInit = false;
+ closePendingDisplayConnections();
openDisplayList.clear();
reusableDisplayList.clear();
pendingDisplayList.clear();
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 993aa33eb..d6ddd9613 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -178,7 +178,7 @@ public abstract class Display {
public abstract void dispatchMessages();
// Global Displays
- protected static ArrayList<Display> displayList = new ArrayList<Display>();
+ protected static final ArrayList<Display> displayList = new ArrayList<Display>();
protected static int displaysActive = 0;
public static void dumpDisplayList(String prefix) {
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 65b44b141..dd8939e43 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -31,6 +31,7 @@ package com.jogamp.newt.awt;
import java.awt.AWTKeyStroke;
import java.awt.Canvas;
+import java.awt.Component;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.KeyboardFocusManager;
@@ -222,18 +223,20 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
final Set<AWTKeyStroke> fwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
final Set<AWTKeyStroke> bwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
if(fwdKeys.contains(ks)) {
+ final Component nextFocus = AWTMisc.getNextFocus(NewtCanvasAWT.this);
if(DEBUG) {
- System.err.println("NewtCanvasAWT.focusKey (fwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner());
+ System.err.println("NewtCanvasAWT.focusKey (fwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner()+", hasFocus: "+hasFocus()+", nextFocus "+nextFocus);
}
// Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
- NewtCanvasAWT.this.transferFocus();
+ nextFocus.requestFocus();
suppress = true;
} else if(bwdKeys.contains(ks)) {
+ final Component prevFocus = AWTMisc.getPrevFocus(NewtCanvasAWT.this);
if(DEBUG) {
- System.err.println("NewtCanvasAWT.focusKey (bwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner());
+ System.err.println("NewtCanvasAWT.focusKey (bwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner()+", hasFocus: "+hasFocus()+", prevFocus "+prevFocus);
}
// Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
- NewtCanvasAWT.this.transferFocusBackward();
+ prevFocus.requestFocus();
suppress = true;
}
}
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 1500d48e6..345d92bc1 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -79,11 +79,16 @@ import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.WindowUpdateEvent;
import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.GLStateKeeper;
/**
* An implementation of {@link GLAutoDrawable} and {@link Window} interface,
* using a delegated {@link Window} instance, which may be an aggregation (lifecycle: created and destroyed).
* <P>
+ * This implementation supports {@link GLStateKeeper GL state preservation},
+ * hence {@link #isGLStatePreservationSupported()} returns <code>true</code>.
+ * </P>
+ * <P>
* This implementation does not make the OpenGL context current<br>
* before calling the various input EventListener callbacks, ie {@link com.jogamp.newt.event.MouseListener} etc.<br>
* This design decision is made in favor of a more performant and simplified
@@ -433,8 +438,8 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
@Override
- public void preserveGLStateAtDestroy() {
- GLWindow.this.preserveGLStateAtDestroy(true);
+ public void preserveGLStateAtDestroy(boolean value) {
+ GLWindow.this.preserveGLStateAtDestroy(value);
}
@Override
@@ -579,6 +584,12 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * GLWindow supports GL state preservation, hence returns <code>true</code>.
+ * </p>
+ */
@Override
public final boolean isGLStatePreservationSupported() { return true; }
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index d4842ba2f..3edb532db 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -45,10 +45,24 @@ import java.util.ArrayList;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
public abstract class DisplayImpl extends Display {
private static int serialno = 1;
+ static {
+ NativeWindowFactory.addCustomShutdownHook(true /* head */, new Runnable() {
+ public void run() {
+ WindowImpl.shutdownAll();
+ ScreenImpl.shutdownAll();
+ DisplayImpl.shutdownAll();
+ }
+ });
+ }
+
+ /** Ensure static init has been run. */
+ /* pp */static void initSingleton() { }
+
private static Class<?> getDisplayClass(String type)
throws ClassNotFoundException
{
@@ -232,11 +246,10 @@ public abstract class DisplayImpl extends Display {
if(DEBUG) {
System.err.println("Display.destroy(): "+this+" "+getThreadName());
}
- final AbstractGraphicsDevice f_aDevice = aDevice;
final DisplayImpl f_dpy = this;
- removeEDT( new Runnable() {
+ removeEDT( new Runnable() { // blocks!
public void run() {
- if ( null != f_aDevice ) {
+ if ( null != aDevice ) {
f_dpy.closeNativeImpl();
}
}
@@ -247,6 +260,32 @@ public abstract class DisplayImpl extends Display {
dumpDisplayList("Display.destroy("+getFQName()+") END");
}
}
+
+ /** Maybe utilized at a shutdown hook, impl. does not synchronize, however the EDT removal blocks. */
+ /* pp */ static final void shutdownAll() {
+ final int dCount = displayList.size();
+ if(DEBUG) {
+ dumpDisplayList("Display.shutdownAll "+dCount+" instances, on thread "+getThreadName());
+ }
+ for(int i=0; i<dCount && displayList.size()>0; i++) { // be safe ..
+ final DisplayImpl d = (DisplayImpl) displayList.remove(0);
+ if(0 < displaysActive) {
+ displaysActive--;
+ }
+ if(DEBUG) {
+ System.err.println("Display.shutdownAll["+(i+1)+"/"+dCount+"]: "+d);
+ }
+ d.removeEDT( new Runnable() {
+ public void run() {
+ if ( null != d.getGraphicsDevice() ) {
+ d.closeNativeImpl();
+ }
+ }
+ } );
+ d.aDevice = null;
+ d.refCount=0;
+ }
+ }
public synchronized final int addReference() {
if(DEBUG) {
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 7edf7b63a..f63d1499e 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -34,8 +34,6 @@
package jogamp.newt;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -64,6 +62,13 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
public static final int default_sm_rate = 60;
public static final int default_sm_rotation = 0;
+ static {
+ DisplayImpl.initSingleton();
+ }
+
+ /** Ensure static init has been run. */
+ /* pp */static void initSingleton() { }
+
protected DisplayImpl display;
protected int screen_idx;
protected String fqname;
@@ -77,15 +82,6 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
private long tCreated; // creationTime
- static {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- registerShutdownHook();
- return null;
- }
- });
- }
-
private static Class<?> getScreenClass(String type) throws ClassNotFoundException
{
final Class<?> screenClass = NewtFactory.getCustomClass(type, "ScreenDriver");
@@ -660,23 +656,18 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
ScreenMonitorState.unmapScreenMonitorStateUnlocked(getFQName());
}
}
- private static final void shutdownAll() {
- for(int i=0; i < screenList.size(); i++) {
- ((ScreenImpl)screenList.get(i)).shutdown();
- }
- }
- private static synchronized void registerShutdownHook() {
- final Thread shutdownHook = new Thread(new Runnable() {
- public void run() {
- ScreenImpl.shutdownAll();
- }
- });
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- Runtime.getRuntime().addShutdownHook(shutdownHook);
- return null;
+ /** pp */ static final void shutdownAll() {
+ final int sCount = screenList.size();
+ if(DEBUG) {
+ System.err.println("Screen.shutdownAll "+sCount+" instances, on thread "+Display.getThreadName());
+ }
+ for(int i=0; i<sCount && screenList.size()>0; i++) { // be safe ..
+ final ScreenImpl s = (ScreenImpl) screenList.remove(0);
+ if(DEBUG) {
+ System.err.println("Screen.shutdownAll["+(i+1)+"/"+sCount+"]: "+s);
}
- });
+ s.shutdown();
+ }
}
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index dca287c6b..1ac97b07c 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -82,6 +82,27 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
{
public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
+ protected static final ArrayList<WindowImpl> windowList = new ArrayList<WindowImpl>();
+
+ static {
+ ScreenImpl.initSingleton();
+ }
+
+ /** Maybe utilized at a shutdown hook, impl. does not synchronize, however the Window destruction and EDT removal blocks. */
+ public static final void shutdownAll() {
+ final int wCount = windowList.size();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.shutdownAll "+wCount+" instances, on thread "+getThreadName());
+ }
+ for(int i=0; i<wCount && windowList.size()>0; i++) { // be safe ..
+ final WindowImpl w = windowList.remove(0);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.shutdownAll["+(i+1)+"/"+wCount+"]: "+toHexString(w.getWindowHandle()));
+ }
+ w.markInvalid();
+ }
+ }
+
/** Timeout of queued events (repaint and resize) */
static final long QUEUED_EVENT_TO = 1200; // ms
@@ -186,6 +207,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
window.screen = (ScreenImpl) screen;
window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
window.instantiationFinished();
+ synchronized( windowList ) {
+ windowList.add(window);
+ }
return window;
} catch (Throwable t) {
t.printStackTrace();
@@ -207,12 +231,27 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
WindowImpl window = (WindowImpl) ReflectionUtil.createInstance( windowClass, cstrArgumentTypes, cstrArguments ) ;
window.screen = (ScreenImpl) screen;
window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
+ window.instantiationFinished();
+ synchronized( windowList ) {
+ windowList.add(window);
+ }
return window;
} catch (Throwable t) {
throw new NativeWindowException(t);
}
}
+ /** Fast invalidation of instance w/o any blocking function call. */
+ private final void markInvalid() {
+ setWindowHandle(0);
+ visible = false;
+ fullscreen = false;
+ fullscreenMonitors = null;
+ fullscreenUseMainMonitor = true;
+ hasFocus = false;
+ parentWindowHandle = 0;
+ }
+
protected final void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg) {
config = cfg;
}
@@ -233,9 +272,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
/**
* Notifies the receiver to preserve resources (GL, ..)
- * for the next destroy*() calls (only).
+ * for the next destroy*() calls (only), if supported and if <code>value</code> is <code>true</code>, otherwise clears preservation flag.
+ * @param value <code>true</code> to set the one-shot preservation if supported, otherwise clears it.
*/
- void preserveGLStateAtDestroy();
+ void preserveGLStateAtDestroy(boolean value);
/**
* Invoked before Window destroy action,
@@ -995,13 +1035,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public void destroy() {
+ synchronized( windowList ) {
+ windowList.remove(this);
+ }
visible = false; // Immediately mark synchronized visibility flag, avoiding possible recreation
runOnEDTIfAvail(true, destroyAction);
}
protected void destroy(boolean preserveResources) {
- if( preserveResources && null != WindowImpl.this.lifecycleHook ) {
- WindowImpl.this.lifecycleHook.preserveGLStateAtDestroy();
+ if( null != lifecycleHook ) {
+ lifecycleHook.preserveGLStateAtDestroy( preserveResources );
}
destroy();
}
@@ -1108,7 +1151,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
// Destroy this window and use parent's Screen.
// It may be created properly when the parent is made visible.
- destroy(false);
+ destroy( false );
setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
} else if(newParentWindow != getParent()) {
diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 4fe025ec4..88d06f69c 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -57,10 +57,8 @@ public class DisplayDriver extends DisplayImpl {
}
}
- public static void initSingleton() {
- // just exist to ensure static init has been run
- }
-
+ /** Ensure static init has been run. */
+ /* pp */static void initSingleton() { }
public DisplayDriver() {
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index b8b13939b..e1373bba5 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -60,6 +60,9 @@ public class ScreenDriver extends ScreenImpl {
DisplayDriver.initSingleton();
}
+ /** Ensure static init has been run. */
+ /* pp */static void initSingleton() { }
+
public ScreenDriver() {
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index c752977a9..786587d65 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -59,7 +59,7 @@ public class WindowDriver extends WindowImpl {
private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7;
static {
- DisplayDriver.initSingleton();
+ ScreenDriver.initSingleton();
}
public WindowDriver() {
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 0756399c1..a876b5c96 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
@@ -90,6 +90,8 @@ public class TestGearsES2NEWT extends UITestCase {
static boolean mainRun = false;
static boolean exclusiveContext = false;
static boolean useAnimator = true;
+ static enum SysExit { none, testExit, testError, displayExit, displayError };
+ static SysExit sysExit = SysExit.none;
@BeforeClass
public static void initClass() {
@@ -272,6 +274,36 @@ public class TestGearsES2NEWT extends UITestCase {
Assert.assertEquals(exclusiveContext ? animator.getThread() : null, glWindow.getExclusiveContextThread());
}
+ if( SysExit.displayError == sysExit || SysExit.displayExit == sysExit ) {
+ glWindow.addGLEventListener(new GLEventListener() {
+
+ @Override
+ public void init(GLAutoDrawable drawable) {}
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) { }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ final GLAnimatorControl anim = drawable.getAnimator();
+ if( null != anim && anim.isAnimating() ) {
+ if( anim.getTotalFPSDuration() >= duration/2 ) {
+ if( SysExit.displayError == sysExit ) {
+ throw new Error("test error send from GLEventListener");
+ } else if ( SysExit.displayExit == sysExit ) {
+ System.err.println("exit(0) send from GLEventListener");
+ System.exit(0);
+ }
+ }
+ } else {
+ System.exit(0);
+ }
+ }
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+ });
+ }
+
glWindow.setVisible(true);
if( useAnimator ) {
animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
@@ -296,6 +328,16 @@ public class TestGearsES2NEWT extends UITestCase {
while(!quitAdapter.shouldQuit() && t1-t0<duration) {
Thread.sleep(100);
t1 = System.currentTimeMillis();
+ if( t1-t0 >= duration/2 ) {
+ if( SysExit.testError == sysExit || SysExit.testExit == sysExit ) {
+ if( SysExit.testError == sysExit ) {
+ throw new Error("test error send from test thread");
+ } else if ( SysExit.testExit == sysExit ) {
+ System.err.println("exit(0) send from test thread");
+ System.exit(0);
+ }
+ }
+ }
}
if( useAnimator ) {
@@ -429,6 +471,9 @@ public class TestGearsES2NEWT extends UITestCase {
loops = MiscUtils.atoi(args[i], 1);
} else if(args[i].equals("-loop-shutdown")) {
loop_shutdown = true;
+ } else if(args[i].equals("-sysExit")) {
+ i++;
+ sysExit = SysExit.valueOf(args[i]);
}
}
wsize = new Dimension(w, h);
@@ -458,6 +503,7 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("swapInterval "+swapInterval);
System.err.println("exclusiveContext "+exclusiveContext);
System.err.println("useAnimator "+useAnimator);
+ System.err.println("sysExitWithin "+sysExit);
if(waitForKey) {
UITestCase.waitForKey("Start");