aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/scripts/tests.sh35
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java51
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java54
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java184
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java18
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java2
6 files changed, 234 insertions, 110 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 6bc1d4eb3..1b93ff7ae 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -109,7 +109,6 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLBufferObjectTracker -Djogl.debug.GLArrayData -Djogl.debug.TraceGL -Djogl.debug.DebugGL"
#D_ARGS="-Djogl.debug.GLSLCode"
#D_ARGS="-Djogl.debug.GLSLCode -Djogl.debug.DebugGL"
- #D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.JAWT -Dnewt.debug.Window"
#D_ARGS="-Dnativewindow.debug.JAWT -Djogl.debug.GLCanvas"
#D_ARGS="-Dnativewindow.debug.JAWT -Djogamp.debug.TaskBase.TraceSource"
@@ -131,13 +130,10 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLDrawable -Dnativewindow.debug.X11Util -Dnativewindow.debug.NativeWindow -Dnewt.debug.Display -Dnewt.debug.Screen -Dnewt.debug.Window"
#D_ARGS="-Djogl.debug.Animator -Djogl.debug.GLDrawable -Dnativewindow.debug.NativeWindow"
#D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
- #D_ARGS="-Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.GLCanvas"
#D_ARGS="-Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLEventListenerState"
#D_ARGS="-Djogl.fbo.force.none"
- #D_ARGS="-Djogl.debug.EGLDrawableFactory.DontQuery -Djogl.debug.GLDrawable"
- #D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.DebugGL"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode -Djogl.debug.GLSLState"
@@ -146,30 +142,29 @@ function jrun() {
#D_ARGS="-Djogl.1thread=false -Djogl.debug.Threading"
#D_ARGS="-Djogl.1thread=true -Djogl.debug.Threading"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all"
- #D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
- #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.AudioSink"
- #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.GLMediaPlayer.Native"
- #D_ARGS="-Djogl.debug.GLMediaPlayer"
- #D_ARGS="-Djogl.debug.GLMediaPlayer.StreamWorker.delay=25 -Djogl.debug.GLMediaPlayer"
- #D_ARGS="-Djogl.debug.GLMediaPlayer.Native"
#D_ARGS="-Djogl.debug.AudioSink"
#D_ARGS="-Djogl.debug.GLArrayData"
- #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
- #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util"
#D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window"
#D_ARGS="-Dnewt.debug.Screen"
#D_ARGS="-Dnewt.test.Screen.disableRandR13"
#D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen"
#D_ARGS="-Dnewt.debug.Screen -Djogl.debug.Animator"
#D_ARGS="-Djogamp.debug.ProcAddressHelper -Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.Lookup -Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil"
+ #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
+ #D_ARGS="-Djogl.debug.GLProfile"
#D_ARGS="-Djogl.debug.GLContext -Djogamp.debug.NativeLibrary -Djogamp.debug.JNILibLoader -Djogl.debug.DebugGL -Djogl.debug.GLDebugMessageHandler"
#D_ARGS="-Dnewt.debug.MainThread"
#D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Dnativewindow.debug.NativeWindow"
#D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Animator -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.GLContext.TraceSwitch"
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.ExtensionAvailabilityCache"
- #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable -Djogl.debug.EGLDisplayUtil"
- #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
- #D_ARGS="-Djogl.debug.GLProfile"
+ #D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogamp.debug.ProcAddressHelper -Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.Lookup -Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil"
+ #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable -Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsDevice"
+ #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable -Djogl.debug.EGLDisplayUtil -Djogl.debug.EGLDrawableFactory.QueryNativeTK"
+ #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util"
+ #D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.EGLDisplayUtil -Djogl.debug.GLDrawable"
#D_ARGS="-Dnativewindow.debug.NativeWindow -Dnewt.debug.Window -Dnewt.debug.Screen -Dnewt.debug.Display"
#D_ARGS="-Djogl.debug.GLCanvas -Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.Animator"
#D_ARGS="-Dnewt.debug.Display -Dnewt.debug.EDT -Dnewt.debug.Window"
@@ -244,6 +239,12 @@ function jrun() {
#X_ARGS="-verbose:jni"
#X_ARGS="-Xrs"
#X_ARGS="-Dsun.awt.disableMixing=true"
+ #D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
+ #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.AudioSink"
+ #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.GLMediaPlayer.Native"
+ #D_ARGS="-Djogl.debug.GLMediaPlayer"
+ #D_ARGS="-Djogl.debug.GLMediaPlayer.StreamWorker.delay=25 -Djogl.debug.GLMediaPlayer"
+ #D_ARGS="-Djogl.debug.GLMediaPlayer.Native"
if [ $awton -eq 1 ] ; then
export CLASSPATH=$JOGAMP_ALL_AWT_CLASSPATH
@@ -332,7 +333,7 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NEWT $*
#testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $*
@@ -400,7 +401,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT0 $*
-testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT3 $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT3 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestBug669RecursiveGLContext01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestBug669RecursiveGLContext02NEWT $*
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index daa0d94dd..0ac0c0f03 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -31,6 +31,8 @@ import java.util.IdentityHashMap;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.common.os.Platform;
+
import jogamp.opengl.egl.EGL;
import jogamp.opengl.egl.EGLExt;
@@ -70,7 +72,13 @@ public class GLRendererQuirks {
/** SIGSEGV on setSwapInterval() after changing the context's drawable w/ 'Mesa 8.0.4' dri2SetSwapInterval/DRI2 (soft & intel) */
public static final int NoSetSwapIntervalPostRetarget = 4;
- /** GLSL <code>discard</code> command leads to undefined behavior or won't get compiled if being used. Appears to <i>have</i> happened on Nvidia Tegra2, but seems to be fine now. FIXME: Constrain version. */
+ /**
+ * GLSL <code>discard</code> command leads to undefined behavior or won't get compiled if being used.
+ * <p>
+ * Appears to <i>have</i> happened on Nvidia Tegra2, but seems to be fine now.<br/>
+ * FIXME: Constrain version.
+ * </p>
+ */
public static final int GLSLBuggyDiscard = 5;
/**
@@ -256,15 +264,36 @@ public class GLRendererQuirks {
*/
public static final int GLES3ViaEGLES2Config = 15;
+ /**
+ * Bug 948 - NVIDIA 331.38 (Linux X11) EGL impl. only supports _one_ EGL Device via {@link EGL#eglGetDisplay(long)}.
+ * <p>
+ * Subsequent calls to {@link EGL#eglGetDisplay(long)} fail.
+ * </p>
+ * <p>
+ * Reusing global EGL display works.
+ * </p>
+ * <ul>
+ * <li>EGL_VENDOR NVIDIA</li>
+ * <li>EGL_VERSION 1.4</li>
+ * <li>GL_VENDOR NVIDIA Corporation</li>
+ * <li>Platform X11</li>
+ * <li>CPU Family {@link Platform.CPUFamily#X86}</li>
+ * </ul>
+ * <p>
+ * FIXME: Constrain driver version.
+ * </p>
+ */
+ public static final int SingletonEGLDisplayOnly = 16;
+
/** Number of quirks known. */
- public static final int COUNT = 16;
+ public static final int COUNT = 17;
private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
"NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
"GLNonCompliant", "GLFlushBeforeRelease", "DontCloseX11Display",
"NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext",
"NoFullFBOSupport", "GLSLNonCompliant", "GL4NeedsGL3Request",
- "GLSharedContextBuggy", "GLES3ViaEGLES2Config"
+ "GLSharedContextBuggy", "GLES3ViaEGLES2Config", "SingletonEGLDisplayOnly"
};
private static final IdentityHashMap<String, GLRendererQuirks> stickyDeviceQuirks = new IdentityHashMap<String, GLRendererQuirks>();
@@ -272,8 +301,12 @@ public class GLRendererQuirks {
/**
* Retrieval of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
* <p>
+ * The {@link AbstractGraphicsDevice}s are mapped via their {@link AbstractGraphicsDevice#getUniqueID()}.
+ * </p>
+ * <p>
* Not thread safe.
* </p>
+ * @see #areSameStickyDevice(AbstractGraphicsDevice, AbstractGraphicsDevice)
*/
public static GLRendererQuirks getStickyDeviceQuirks(AbstractGraphicsDevice device) {
final String key = device.getUniqueID();
@@ -289,10 +322,19 @@ public class GLRendererQuirks {
}
/**
+ * Returns true if both devices have the same {@link AbstractGraphicsDevice#getUniqueID()},
+ * otherwise false.
+ */
+ public static boolean areSameStickyDevice(AbstractGraphicsDevice device1, AbstractGraphicsDevice device2) {
+ return device1.getUniqueID() == device2.getUniqueID();
+ }
+
+ /**
* {@link #addQuirks(int[], int, int) Adding given quirks} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
* <p>
* Not thread safe.
* </p>
+ * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static void addStickyDeviceQuirks(AbstractGraphicsDevice device, int[] quirks, int offset, int len) throws IllegalArgumentException {
final GLRendererQuirks sq = getStickyDeviceQuirks(device);
@@ -303,6 +345,7 @@ public class GLRendererQuirks {
* <p>
* Not thread safe.
* </p>
+ * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static void addStickyDeviceQuirks(AbstractGraphicsDevice device, GLRendererQuirks quirks) throws IllegalArgumentException {
final GLRendererQuirks sq = getStickyDeviceQuirks(device);
@@ -313,6 +356,7 @@ public class GLRendererQuirks {
* <p>
* Not thread safe. However, use after changing the sticky quirks is safe.
* </p>
+ * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static boolean existStickyDeviceQuirk(AbstractGraphicsDevice device, int quirk) {
return getStickyDeviceQuirks(device).exist(quirk);
@@ -323,6 +367,7 @@ public class GLRendererQuirks {
* <p>
* Not thread safe. However, use after changing the sticky quirks is safe.
* </p>
+ * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static void pushStickyDeviceQuirks(AbstractGraphicsDevice device, GLRendererQuirks dest) {
dest.addQuirks(getStickyDeviceQuirks(device));
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 417dbd011..652fc6ba9 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -1548,7 +1548,9 @@ public abstract class GLContextImpl extends GLContext {
final VersionNumberString vendorVersion = GLVersionNumber.createVendorVersion(glVersion);
- setRendererQuirks(adevice, reqGLVersion.getMajor(), reqGLVersion.getMinor(), reqCtxProfileBits, major, minor, ctxProfileBits, vendorVersion, withinGLVersionsMapping);
+ setRendererQuirks(adevice, getDrawableImpl().getFactoryImpl(),
+ reqGLVersion.getMajor(), reqGLVersion.getMinor(), reqCtxProfileBits,
+ major, minor, ctxProfileBits, vendorVersion, withinGLVersionsMapping);
if( strictMatch && glRendererQuirks.exist(GLRendererQuirks.GLNonCompliant) ) {
if(DEBUG) {
@@ -1665,7 +1667,7 @@ public abstract class GLContextImpl extends GLContext {
return true;
}
- private final void setRendererQuirks(final AbstractGraphicsDevice adevice,
+ private final void setRendererQuirks(final AbstractGraphicsDevice adevice, final GLDrawableFactoryImpl factory,
int reqMajor, int reqMinor, int reqCTP,
int major, int minor, int ctp, final VersionNumberString vendorVersion,
boolean withinGLVersionsMapping) {
@@ -1688,16 +1690,26 @@ public abstract class GLContextImpl extends GLContext {
// General Quirks
//
if( esCtx ) {
- final int quirk = GLRendererQuirks.GLES3ViaEGLES2Config;
- if( GLRendererQuirks.existStickyDeviceQuirk( GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config) ) {
- // Merge default sticky quirk!
+ if( 2 == reqMajor && 2 < major ) {
+ final int quirk = GLRendererQuirks.GLES3ViaEGLES2Config;
if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Default EGL Device");
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: ES req "+reqMajor+" and 2 < "+major);
}
quirks[i++] = quirk;
- } else if( 2 == reqMajor && 2 < major ) {
+ if( withinGLVersionsMapping ) {
+ // Thread safe due to single threaded initialization!
+ GLRendererQuirks.addStickyDeviceQuirks(adevice, quirks, i-1, 1);
+ } else {
+ // FIXME: Remove when moving EGL/ES to ARB ctx creation
+ synchronized(GLContextImpl.class) {
+ GLRendererQuirks.addStickyDeviceQuirks(adevice, quirks, i-1, 1);
+ }
+ }
+ }
+ if( isX11 && isDriverNVIDIAGeForce && Platform.CPUFamily.X86 == Platform.getCPUFamily() ) {
+ final int quirk = GLRendererQuirks.SingletonEGLDisplayOnly;
if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: ES req "+reqMajor+" and 2 < "+major);
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: ES, X11, CPUFamily AMD/Intel, [Vendor "+glVendor+" or Renderer "+glRenderer+"]");
}
quirks[i++] = quirk;
if( withinGLVersionsMapping ) {
@@ -1794,14 +1806,14 @@ public abstract class GLContextImpl extends GLContext {
if( glRenderer.contains("PowerVR") ) {
final int quirk = GLRendererQuirks.NoSetSwapInterval;
if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + ", Renderer " + glRenderer);
}
quirks[i++] = quirk;
}
if( glRenderer.contains("Immersion.16") ) {
final int quirk = GLRendererQuirks.GLSharedContextBuggy;
if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + " / Renderer " + glRenderer);
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: OS "+Platform.getOSType() + ", Renderer " + glRenderer);
}
quirks[i++] = quirk;
}
@@ -1906,9 +1918,27 @@ public abstract class GLContextImpl extends GLContext {
}
glRendererQuirks = new GLRendererQuirks(quirks, 0, i);
- GLRendererQuirks.pushStickyDeviceQuirks(adevice, glRendererQuirks); // Thread safe due to single threaded initialization!
if(DEBUG) {
- System.err.println("Quirks local: "+glRendererQuirks);
+ System.err.println("Quirks local.0: "+glRendererQuirks);
+ }
+ {
+ // Merge sticky quirks, thread safe due to single threaded initialization!
+ GLRendererQuirks.pushStickyDeviceQuirks(adevice, glRendererQuirks);
+
+ final AbstractGraphicsDevice factoryDefaultDevice = factory.getDefaultDevice();
+ if( !GLRendererQuirks.areSameStickyDevice(factoryDefaultDevice, adevice) ) {
+ GLRendererQuirks.pushStickyDeviceQuirks(factoryDefaultDevice, glRendererQuirks);
+ }
+ if( esCtx ) {
+ final AbstractGraphicsDevice eglFactoryDefaultDevice = GLDrawableFactory.getEGLFactory().getDefaultDevice();
+ if( !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, adevice) &&
+ !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, factoryDefaultDevice) ) {
+ GLRendererQuirks.pushStickyDeviceQuirks(eglFactoryDefaultDevice, glRendererQuirks);
+ }
+ }
+ }
+ if(DEBUG) {
+ System.err.println("Quirks local.X: "+glRendererQuirks);
System.err.println("Quirks sticky on "+adevice+": "+GLRendererQuirks.getStickyDeviceQuirks(adevice));
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index a1899e032..c5f76f667 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -49,57 +49,120 @@ import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
* and <code>eglTerminate(..)</code> is issued only for the last call.
* <p>
* This class is required, due to implementation bugs within EGL where {@link EGL#eglTerminate(long)}
- * does not mark the resource for deletion when still in use, bug releases them immediatly.
+ * does not mark the resource for deletion when still in use, bug releases them immediately.
* </p>
*/
public class EGLDisplayUtil {
- protected static final boolean DEBUG = Debug.debug("EGLDisplayUtil");
+ private static final boolean DEBUG = Debug.debug("EGLDisplayUtil");
+ private static boolean useSingletonEGLDisplay = false;
+ private static EGLDisplayRef singletonEGLDisplay = null;
- private static class DpyCounter {
+ private static class EGLDisplayRef {
final long eglDisplay;
final Throwable createdStack;
- int refCount;
+ int initRefCount;
- private DpyCounter(long eglDisplay) {
+ /**
+ * Returns an already opened {@link EGLDisplayRef} or opens a new {@link EGLDisplayRef}.
+ * <p>
+ * Opened {@link EGLDisplayRef}s are mapped against their <code>eglDisplay</code> handle.
+ * </p>
+ * <p>
+ * Method utilizes {@link EGLDisplayRef}'s reference counter, i.e. increases it.
+ * </p>
+ * <p>
+ * An {@link EGLDisplayRef} is <i>opened</i> via {@link EGL#eglInitialize(long, IntBuffer, IntBuffer)}.
+ * </p>
+ */
+ static EGLDisplayRef getOrCreateOpened(final long eglDisplay, final IntBuffer major, final IntBuffer minor) {
+ EGLDisplayRef o = (EGLDisplayRef) openEGLDisplays.get(eglDisplay);
+ if( null == o ) {
+ if( EGL.eglInitialize(eglDisplay, major, minor) ) {
+ final EGLDisplayRef n = new EGLDisplayRef(eglDisplay);
+ openEGLDisplays.put(eglDisplay, n);
+ n.initRefCount++;
+ if( null == singletonEGLDisplay ) {
+ singletonEGLDisplay = n;
+ }
+ return n;
+ } else {
+ return null;
+ }
+ } else {
+ o.initRefCount++;
+ return o;
+ }
+ }
+
+ /**
+ * Closes an already opened {@link EGLDisplayRef}.
+ * <p>
+ * Method decreases a reference counter and closes the {@link EGLDisplayRef} if it reaches zero.
+ * </p>
+ * <p>
+ * An {@link EGLDisplayRef} is <i>closed</i> via {@link EGL#eglTerminate(long)}.
+ * </p>
+ */
+ static EGLDisplayRef closeOpened(final long eglDisplay, final boolean[] res) {
+ final EGLDisplayRef o = (EGLDisplayRef) openEGLDisplays.get(eglDisplay);
+ res[0] = true;
+ if( null != o ) {
+ if( 0 < o.initRefCount ) { // no negative refCount
+ o.initRefCount--;
+ if( 0 == o.initRefCount ) {
+ res[0] = EGL.eglTerminate(eglDisplay);
+ if( o == singletonEGLDisplay ) {
+ singletonEGLDisplay = null;
+ }
+ }
+ }
+ if( 0 >= o.initRefCount ) {
+ openEGLDisplays.remove(eglDisplay);
+ }
+ }
+ return o;
+ }
+
+ private EGLDisplayRef(long eglDisplay) {
this.eglDisplay = eglDisplay;
- this.refCount = 0;
+ this.initRefCount = 0;
this.createdStack = DEBUG ? new Throwable() : null;
}
@Override
public String toString() {
- return "EGLDisplay[0x"+Long.toHexString(eglDisplay)+": refCnt "+refCount+"]";
+ return "EGLDisplayRef[0x"+Long.toHexString(eglDisplay)+": refCnt "+initRefCount+"]";
}
}
- static final LongObjectHashMap eglDisplayCounter;
+ private static final LongObjectHashMap openEGLDisplays;
static {
- eglDisplayCounter = new LongObjectHashMap();
- eglDisplayCounter.setKeyNotFoundValue(null);
+ openEGLDisplays = new LongObjectHashMap();
+ openEGLDisplays.setKeyNotFoundValue(null);
}
/**
* @return number of unclosed EGL Displays.<br>
*/
public static int shutdown(boolean verbose) {
- if(DEBUG || verbose || eglDisplayCounter.size() > 0 ) {
- System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+eglDisplayCounter.size()+")");
+ if(DEBUG || verbose || openEGLDisplays.size() > 0 ) {
+ System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+openEGLDisplays.size()+")");
if(DEBUG) {
Thread.dumpStack();
}
- if( eglDisplayCounter.size() > 0) {
+ if( openEGLDisplays.size() > 0) {
dumpOpenDisplayConnections();
}
}
- return eglDisplayCounter.size();
+ return openEGLDisplays.size();
}
public static void dumpOpenDisplayConnections() {
- System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+eglDisplayCounter.size());
+ System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+openEGLDisplays.size());
int i=0;
- for(Iterator<LongObjectHashMap.Entry> iter = eglDisplayCounter.iterator(); iter.hasNext(); i++) {
+ for(Iterator<LongObjectHashMap.Entry> iter = openEGLDisplays.iterator(); iter.hasNext(); i++) {
final LongObjectHashMap.Entry e = iter.next();
- final DpyCounter v = (DpyCounter) e.value;
+ final EGLDisplayRef v = (EGLDisplayRef) e.value;
System.err.println("EGLDisplayUtil: Open["+i+"]: 0x"+Long.toHexString(e.key)+": "+v);
if(null != v.createdStack) {
v.createdStack.printStackTrace();
@@ -107,12 +170,22 @@ public class EGLDisplayUtil {
}
}
- public static long eglGetDisplay(long nativeDisplay_id) {
+ /* pp */ static synchronized void setSingletonEGLDisplayOnly(boolean v) { useSingletonEGLDisplay = v; }
+
+ private static synchronized long eglGetDisplay(long nativeDisplay_id) {
+ if( useSingletonEGLDisplay && null != singletonEGLDisplay ) {
+ if(DEBUG) {
+ System.err.println("EGLDisplayUtil.eglGetDisplay.s: eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
+ EGLContext.toHexString(singletonEGLDisplay.eglDisplay)+
+ ", "+((EGL.EGL_NO_DISPLAY != singletonEGLDisplay.eglDisplay)?"OK":"Failed")+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
+ }
+ return singletonEGLDisplay.eglDisplay;
+ }
final long eglDisplay = EGL.eglGetDisplay(nativeDisplay_id);
if(DEBUG) {
- System.err.println("EGLDisplayUtil.eglGetDisplay(): eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
+ System.err.println("EGLDisplayUtil.eglGetDisplay.X: eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
EGLContext.toHexString(eglDisplay)+
- ", "+((EGL.EGL_NO_DISPLAY != eglDisplay)?"OK":"Failed"));
+ ", "+((EGL.EGL_NO_DISPLAY != eglDisplay)?"OK":"Failed")+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
}
return eglDisplay;
}
@@ -125,39 +198,16 @@ public class EGLDisplayUtil {
*
* @see EGL#eglInitialize(long, IntBuffer, IntBuffer)
*/
- public static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor) {
+ private static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor) {
if( EGL.EGL_NO_DISPLAY == eglDisplay) {
return false;
}
- final int refCnt;
- final DpyCounter d;
- {
- DpyCounter _d = (DpyCounter) eglDisplayCounter.get(eglDisplay);
- if(null == _d) {
- _d = new DpyCounter(eglDisplay);
- refCnt = 1; // 1st init
- } else {
- refCnt = _d.refCount + 1;
- }
- d = _d;
- }
- final boolean res;
- if(1==refCnt) { // only initialize once
- res = EGL.eglInitialize(eglDisplay, major, minor);
- } else {
- res = true;
- }
- if(res) { // update refCount and map if successfully initialized, only
- d.refCount = refCnt;
- if(1 == refCnt) {
- eglDisplayCounter.put(eglDisplay, d);
- }
- }
+ final EGLDisplayRef d = EGLDisplayRef.getOrCreateOpened(eglDisplay, major, minor);
if(DEBUG) {
- System.err.println("EGLDisplayUtil.eglInitialize("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+", "+d+" = "+res);
+ System.err.println("EGLDisplayUtil.eglInitialize("+EGLContext.toHexString(eglDisplay)+" ...): "+d+" = "+(null != d)+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
// Thread.dumpStack();
}
- return res;
+ return null != d;
}
/**
@@ -172,14 +222,14 @@ public class EGLDisplayUtil {
* @see #eglGetDisplay(long)
* @see #eglInitialize(long, IntBuffer, IntBuffer)
*/
- public static synchronized int eglGetDisplayAndInitialize(long nativeDisplayID, long[] eglDisplay, int[] eglErr, IntBuffer major, IntBuffer minor) {
+ private static synchronized int eglGetDisplayAndInitialize(long nativeDisplayID, long[] eglDisplay, int[] eglErr, IntBuffer major, IntBuffer minor) {
eglDisplay[0] = EGL.EGL_NO_DISPLAY;
- final long _eglDisplay = EGLDisplayUtil.eglGetDisplay( nativeDisplayID );
+ final long _eglDisplay = eglGetDisplay( nativeDisplayID );
if ( EGL.EGL_NO_DISPLAY == _eglDisplay ) {
eglErr[0] = EGL.eglGetError();
return EGL.EGL_BAD_DISPLAY;
}
- if ( !EGLDisplayUtil.eglInitialize( _eglDisplay, major, minor) ) {
+ if ( !eglInitialize( _eglDisplay, major, minor) ) {
eglErr[0] = EGL.eglGetError();
return EGL.EGL_NOT_INITIALIZED;
}
@@ -197,7 +247,7 @@ public class EGLDisplayUtil {
* @return the initialized EGL display ID
* @throws GLException if not successful
*/
- public static synchronized long eglGetDisplayAndInitialize(long[] nativeDisplayID) {
+ private static synchronized long eglGetDisplayAndInitialize(long[] nativeDisplayID) {
final long[] eglDisplay = new long[1];
final int[] eglError = new int[1];
int eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(nativeDisplayID[0], eglDisplay, eglError, null, null);
@@ -221,40 +271,20 @@ public class EGLDisplayUtil {
* @param eglDisplay the EGL display handle
* @return true if the eglDisplay is valid and it's reference counter becomes zero and {@link EGL#eglTerminate(long)} was successful, otherwise false
*/
- public static synchronized boolean eglTerminate(long eglDisplay) {
+ private static synchronized boolean eglTerminate(long eglDisplay) {
if( EGL.EGL_NO_DISPLAY == eglDisplay) {
return false;
}
- final boolean res;
- final int refCnt;
- final DpyCounter d;
- {
- DpyCounter _d = (DpyCounter) eglDisplayCounter.get(eglDisplay);
- if(null == _d) {
- _d = null;
- refCnt = -1; // n/a
- } else {
- refCnt = _d.refCount - 1; // 1 - 1 = 0 -> final terminate
- }
- d = _d;
- }
- if( 0 == refCnt ) { // no terminate if still in use or already terminated
- res = EGL.eglTerminate(eglDisplay);
- eglDisplayCounter.remove(eglDisplay);
- } else {
- if(0 < refCnt) { // no negative refCount
- d.refCount = refCnt;
- }
- res = true;
- }
+ final boolean[] res = new boolean[1];
+ final EGLDisplayRef d = EGLDisplayRef.closeOpened(eglDisplay, res);
if(DEBUG) {
- System.err.println("EGLDisplayUtil.eglTerminate("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ System.err.println("EGLDisplayUtil.eglTerminate.X("+EGLContext.toHexString(eglDisplay)+" ...): "+d+" = "+res[0]+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
// Thread.dumpStack();
}
- return res;
+ return res[0];
}
- public static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
+ private static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
@Override
public long eglGetAndInitDisplay(long[] nativeDisplayID) {
return eglGetDisplayAndInitialize(nativeDisplayID);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 3651d71a9..65ce98e07 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -361,6 +361,13 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return new ArrayList<GLCapabilitiesImmutable>(0);
}
+ private static void dumpEGLInfo(final String prefix, final long eglDisplay) {
+ final String eglVendor = EGL.eglQueryString(eglDisplay, EGL.EGL_VENDOR);
+ final String eglClientAPIs = EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS);
+ final String eglVersion = EGL.eglQueryString(eglDisplay, EGL.EGL_VERSION);
+ System.err.println(prefix+"EGL vendor "+eglVendor+", version "+eglVersion+", clientAPIs "+eglClientAPIs);
+ }
+
private boolean mapAvailableEGLESConfig(AbstractGraphicsDevice adevice, int[] esProfile,
boolean[] hasPBuffer, GLRendererQuirks[] rendererQuirks, int[] ctp) {
final String profileString;
@@ -404,6 +411,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// In this branch, any non EGL device is mapped to EGL default shared resources (default behavior).
// Only one default shared resource instance is ever be created.
defaultDevice.open();
+ if( DEBUG ) {
+ dumpEGLInfo("EGLDrawableFactory.mapAvailableEGLESConfig: ", defaultDevice.getHandle());
+ }
+
final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(defaultDevice, reqCapsPBuffer);
hasPBuffer[0] = availablePBufferCapsL.size() > 0;
@@ -475,6 +486,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
surface = upstreamSurface;
eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
eglDevice.open();
+ if( DEBUG ) {
+ dumpEGLInfo("EGLDrawableFactory.mapAvailableEGLESConfig: ", eglDevice.getHandle());
+ }
hasPBuffer[0] = true;
}
@@ -533,6 +547,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
}
}
+ if( null != rendererQuirks[0] && rendererQuirks[0].exist(GLRendererQuirks.SingletonEGLDisplayOnly) ) {
+ EGLDisplayUtil.setSingletonEGLDisplayOnly(true);
+ }
+
return success;
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index f916a8ef3..15ff2b1ac 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -247,7 +247,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
* Returns a unique String object using {@link String#intern()} for the given arguments,
* which object reference itself can be used as a key.
*/
- protected static String getUniqueID(String type, String connection, int unitID) {
+ private static String getUniqueID(String type, String connection, int unitID) {
final String r = (type + separator + connection + separator + unitID).intern();
return r.intern();
}