aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-04-16 05:50:55 +0200
committerSven Gothel <[email protected]>2013-04-16 05:50:55 +0200
commitff25c711fe4fa627004c57e0d308d06759156290 (patch)
treebccaf1561a0582b6567c064f45c2dc9f2a22596c /src
parent5b47372590ec715647ebbd75d70c41ec7a64485a (diff)
Fix Bug 705 - Cleanup & Generalize Commit 5b47372590ec715647ebbd75d70c41ec7a64485a ; Close X11 Display in isDeviceSupported()
- Moved GL vendor version parsing to GLVersionNumber - Moved X11Util.markAllDisplaysUnclosable() trigger into SharedResource creation of - X11GLXDrawableFactory - EGLDrawableFactory - GLProfile is back to pre 5b47372590ec715647ebbd75d70c41ec7a64485a, i.e. contains no quirk artifact (clean) - Close X11 Display in X11GLXDrawableFactory.isDeviceSupported() Regression of 9a4fcc7ea4ec61e4ceed791acced734ac04ea270 - TODO: Remove X11Util markAllDisplaysUnclosable detection code ? Notes to Martin: - Use TAB == 4 SPACES - No author names into source code, git commit log is enough. - No need to tag your edits, the diff is enough.
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java66
-rw-r--r--src/jogl/classes/com/jogamp/opengl/JoglVersion.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java18
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java25
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java62
-rw-r--r--src/jogl/classes/jogamp/opengl/GLVersionNumber.java77
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java12
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java5
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java73
-rwxr-xr-xsrc/test-native/make.sh2
10 files changed, 184 insertions, 162 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
index 7203ba214..0b136d460 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java
@@ -59,7 +59,7 @@ 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 happen on Nvidia Tegra2. FIXME: Constrain version. */
+ /** 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. */
public static final int GLSLBuggyDiscard = 5;
/**
@@ -81,41 +81,47 @@ public class GLRendererQuirks {
*/
public static final int GLFlushBeforeRelease = 7;
- //
- // The JVM for the following system crashes on the second call to glXDestroyContext after
- // XCloseDisplay has been called once.
- //
- // The following will crash the system:
- // XOpenDisplay(A), glXCreateNewContext(A), XOpenDisplay(B), glXCreateNewContext(B),
- // glXDestroyContext(A/B), XCloseDisplay(A/B), glXDestroyContext(B/A) (crash)
- //
- // Dell Latitude D520
- // Intel(R) Core(TM)2 CPU T7200
- // i810 Monitor driver
- // Platform LINUX / Linux 2.6.18.8-0.3-default (os), i386 (arch), GENERIC_ABI, 2 cores
- // Platform Java Version: 1.6.0_18, VM: Java HotSpot(TM) Server VM, Runtime: Java(TM) SE Runtime Environment
- // Platform Java Vendor: Sun Microsystems Inc., http://java.sun.com/, JavaSE: true, Java6: true, AWT enabled: true
- // GL Profile GLProfile[GL2/GL2.sw]
- // CTX VERSION 2.1 (Compatibility profile, FBO, software) - 2.1 Mesa 7.8.2
- // GL jogamp.opengl.gl4.GL4bcImpl@472d48
- // GL_VENDOR Brian Paul
- // GL_RENDERER Mesa X11
- // GL_VERSION 2.1 Mesa 7.8.2
- //
- // The error can be reproduced using a C code, thus the error is indpendent of Java and JOGL.
- // The work around is to close all the X11 displays upon exit for a "Mesa X11" version < 8.
- // At this moment, it is unknown if the error exists in versions greater than 7.
- //
- // Martin C. Hegedus, March 30, 2013
- //
- public static final int DontCloseX11DisplayConnection = 8;
+ /**
+ * Closing X11 displays may cause JVM crashes or X11 errors with some buggy drivers
+ * while being used in concert w/ OpenGL.
+ * <p>
+ * Some drivers may require X11 displays to be closed in the same order as they were created,
+ * some may not allow them to be closed at all while resources are being used somehow.
+ * </p>
+ * <p>
+ * Drivers known exposing such bug:
+ * <ul>
+ * <li>Mesa &lt; 8.0 _with_ X11 software renderer <code>Mesa X11</code>, not with GLX/DRI renderer.</li>
+ * <li>ATI proprietary Catalyst X11 driver (RENDERER vendor version):
+ * <ul>
+ * <li>8.78.6</li>
+ * <li>8.881</li>
+ * <li>8.911</li>
+ * <li>9.01.8</li>
+ * </ul></li>
+ * </ul>
+ * </p>
+ * <p>
+ * TODO: Validate whether Mesa's X11 driver exposes this bug w/ version >= 8, currently we assume not !
+ * Impact would be to set this quirk on all 'Mesa X11' software renderer!
+ * </p>
+ *
+ * <p>
+ * See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
+ * and {@link jogamp.nativewindow.x11.X11Util#ATI_HAS_XCLOSEDISPLAY_BUG}.
+ * </p>
+ * <p>
+ * See Bug 705 - https://jogamp.org/bugzilla/show_bug.cgi?id=705
+ * </p>
+ */
+ public static final int DontCloseX11Display = 8;
/** Number of quirks known. */
public static final int COUNT = 9;
private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
"NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
- "GLNonCompliant", "GLFlushBeforeRelease", "DontCloseX11DisplayConnection"
+ "GLNonCompliant", "GLFlushBeforeRelease", "DontCloseX11Display"
};
private final int _bitmask;
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 4246d74c7..11e76ef6f 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -160,9 +160,11 @@ public class JoglVersion extends JogampVersion {
sb.append(Platform.getNewline());
sb.append("GL Profile ").append(gl.getGLProfile());
sb.append(Platform.getNewline());
- sb.append("CTX VERSION ").append(gl.getContext().getGLVersion());
+ sb.append("GL Version ").append(ctx.getGLVersion()).append(" [GL ").append(ctx.getGLVersionNumber()).append(", vendor ").append(ctx.getGLVendorVersionNumber()).append("]");
sb.append(Platform.getNewline());
- sb.append("GL ").append(gl);
+ sb.append("Quirks ").append(ctx.getRendererQuirks());
+ sb.append(Platform.getNewline());
+ sb.append("Impl. class ").append(gl.getClass().getCanonicalName());
sb.append(Platform.getNewline());
sb.append("GL_VENDOR ").append(gl.glGetString(GL.GL_VENDOR));
sb.append(Platform.getNewline());
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index be947e5f5..23ca96504 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -53,6 +53,7 @@ import jogamp.opengl.GLContextImpl;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.VersionNumber;
+import com.jogamp.common.util.VersionNumberString;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.opengl.GLExtensions;
@@ -126,6 +127,8 @@ public abstract class GLContext {
/** Version 3.0. As an OpenGL version, it qualifies for {@link #isGL2()} only */
public static final VersionNumber Version30 = new VersionNumber(3, 0, 0);
+ protected static final VersionNumber Version80 = new VersionNumber(8, 0, 0);
+
/** <code>ARB_create_context</code> related: created via ARB_create_context. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IS_ARB_CREATED = 1 << 0;
/** <code>ARB_create_context</code> related: desktop compatibility profile. Cache key value. See {@link #isGLCompatibilityProfile()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
@@ -169,9 +172,11 @@ public abstract class GLContext {
protected VersionNumber ctxVersion;
protected int ctxOptions;
protected String ctxVersionString;
+ protected VersionNumberString ctxVendorVersion;
protected VersionNumber ctxGLSLVersion;
private int currentSwapInterval;
protected GLRendererQuirks glRendererQuirks;
+ private static final VersionNumberString nullVersion = new VersionNumberString(-1, -1, -1, "n/a");
/** Did the drawable association changed ? see {@link GLRendererQuirks#NoSetSwapIntervalPostRetarget} */
protected boolean drawableRetargeted;
@@ -181,7 +186,8 @@ public abstract class GLContext {
System.err.println(getThreadName() + ": GLContext.resetStates()");
// Thread.dumpStack();
}
- ctxVersion = new VersionNumber(-1, -1, -1);
+ ctxVersion = nullVersion;
+ ctxVendorVersion = nullVersion;
ctxOptions=0;
ctxVersionString=null;
ctxGLSLVersion=null;
@@ -521,14 +527,9 @@ public abstract class GLContext {
}
public final StringBuilder append(StringBuilder sb) {
- sb.append("OpenGL ");
- sb.append(getGLVersionMajor());
- sb.append(".");
- sb.append(getGLVersionMinor());
- sb.append(", options 0x");
+ sb.append("Version ").append(getGLVersion()).append(" [GL ").append(getGLVersionNumber()).append(", vendor ").append(getGLVendorVersionNumber());
+ sb.append("], options 0x");
sb.append(Integer.toHexString(ctxOptions));
- sb.append(", ");
- sb.append(getGLVersion());
sb.append(", this ");
sb.append(toHexString(hashCode()));
sb.append(", handle ");
@@ -667,6 +668,7 @@ public abstract class GLContext {
* @see #getGLSLVersionNumber()
**/
public final VersionNumber getGLVersionNumber() { return ctxVersion; }
+ public final VersionNumberString getGLVendorVersionNumber() { return ctxVendorVersion; }
public final boolean isGLCompatibilityProfile() { return ( 0 != ( CTX_PROFILE_COMPAT & ctxOptions ) ); }
public final boolean isGLCoreProfile() { return ( 0 != ( CTX_PROFILE_CORE & ctxOptions ) ); }
public final boolean isGLForwardCompatible() { return ( 0 != ( CTX_OPTION_FORWARD & ctxOptions ) ); }
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 54ed479a9..1b6af22d4 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -64,11 +64,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
-// Added to check if X11 Displays should be closed on exit
-// Martin C. Hegedus, March 30, 2013
-import com.jogamp.opengl.GLRendererQuirks;
-import jogamp.nativewindow.x11.X11Util;
-
/**
* Specifies the the OpenGL profile.
*
@@ -1530,26 +1525,6 @@ public class GLProfile {
final boolean addedDesktopProfile = null != defaultDesktopDevice ? initProfilesForDevice(defaultDesktopDevice) : false;
final boolean addedAnyProfile = addedEGLProfile || addedDesktopProfile ;
- // Added to check if X11 Displays should be closed on exit
- // NOTE: This checks defaultEGLDevice and defaultDesktopDevice to determine if XCloseDisplay should be called on exit
- // NOTE: These checks must be done after initProfilesForDevice since GLContext must set up the renderer quirks.
- // NOTE: At this point the shared resource has already opened a display, created a new context, made it current, and
- // released it. Let's cross our fingers that at this point in the code the context will not be destroyed and
- // the display closed under any circumstances.
- // NOTE: The checks can be tricked if the default screen is using a driver other than X11 and later a X11 Display,
- // such as a remote display, is opened. If this occurs then markAllDisplaysUnclosable will not have been
- // correctly set. Something to deal with at a later date.
- //
- // Martin C. Hegedus, March 30, 2013
- if (eglFactory != null && defaultEGLDevice != null &&
- eglFactory.hasRendererQuirk(defaultEGLDevice,GLRendererQuirks.DontCloseX11DisplayConnection) &&
- NativeWindowFactory.getNativeWindowType(true) == NativeWindowFactory.TYPE_X11)
- X11Util.markAllDisplaysUnclosable();
- if (desktopFactory != null && defaultDesktopDevice != null &&
- desktopFactory.hasRendererQuirk(defaultDesktopDevice,GLRendererQuirks.DontCloseX11DisplayConnection) &&
- NativeWindowFactory.getNativeWindowType(true) == NativeWindowFactory.TYPE_X11)
- X11Util.markAllDisplaysUnclosable();
-
if(DEBUG) {
System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 74bc59c7c..3657cacda 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -49,6 +49,7 @@ import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
+import com.jogamp.common.util.VersionNumberString;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.gluegen.runtime.FunctionAddressResolver;
import com.jogamp.gluegen.runtime.ProcAddressTable;
@@ -1023,7 +1024,7 @@ public abstract class GLContextImpl extends GLContext {
* If major > 0 || minor > 0 : Use passed values, determined at creation time
* Otherwise .. don't touch ..
*/
- private final void setContextVersion(int major, int minor, int ctp, boolean setVersionString) {
+ private final void setContextVersion(int major, int minor, int ctp, VersionNumberString glVendorVersion, boolean useGL) {
if ( 0 == ctp ) {
throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
@@ -1032,9 +1033,10 @@ public abstract class GLContextImpl extends GLContext {
throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
ctxVersion = new VersionNumber(major, minor, 0);
+ ctxVersionString = getGLVersion(major, minor, ctxOptions, glVersion);
+ ctxVendorVersion = glVendorVersion;
ctxOptions = ctp;
- if(setVersionString) {
- ctxVersionString = getGLVersion(major, minor, ctxOptions, gl.glGetString(GL.GL_VERSION));
+ if(useGL) {
ctxGLSLVersion = null;
if(major >= 2) { // >= ES2 || GL2.0
final String glslVersion = gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION);
@@ -1192,7 +1194,7 @@ public abstract class GLContextImpl extends GLContext {
*/
private static final VersionNumber getGLVersionNumber(int ctp, String glVersionStr) {
if( null != glVersionStr ) {
- final GLVersionNumber version = new GLVersionNumber(glVersionStr);
+ final GLVersionNumber version = GLVersionNumber.create(glVersionStr);
if ( version.isValid() ) {
int[] major = new int[] { version.getMajor() };
int[] minor = new int[] { version.getMinor() };
@@ -1384,7 +1386,9 @@ public abstract class GLContextImpl extends GLContext {
ctxProfileBits &= ~GLContext.CTX_IMPL_ES2_COMPAT;
}
- setRendererQuirks(major, minor, ctxProfileBits);
+ final VersionNumberString vendorVersion = GLVersionNumber.createVendorVersion(glVersion);
+
+ setRendererQuirks(major, minor, ctxProfileBits, vendorVersion);
if( strictMatch && glRendererQuirks.exist(GLRendererQuirks.GLNonCompliant) ) {
if(DEBUG) {
@@ -1445,7 +1449,7 @@ public abstract class GLContextImpl extends GLContext {
}
} else {
extensionAvailability = new ExtensionAvailabilityCache();
- setContextVersion(major, minor, ctxProfileBits, false); // pre-set of GL version, required for extension cache usage
+ setContextVersion(major, minor, ctxProfileBits, vendorVersion, false); // pre-set of GL version, required for extension cache usage
extensionAvailability.reset(this);
synchronized(mappedContextTypeObjectLock) {
mappedExtensionAvailabilityCache.put(contextFQN, extensionAvailability);
@@ -1469,7 +1473,7 @@ public abstract class GLContextImpl extends GLContext {
//
// Set GL Version (complete w/ version string)
//
- setContextVersion(major, minor, ctxProfileBits, true);
+ setContextVersion(major, minor, ctxProfileBits, vendorVersion, true);
setDefaultSwapInterval();
@@ -1481,7 +1485,7 @@ public abstract class GLContextImpl extends GLContext {
return true;
}
- private final void setRendererQuirks(int major, int minor, int ctp) {
+ private final void setRendererQuirks(int major, int minor, int ctp, VersionNumberString vendorVersion) {
int[] quirks = new int[GLRendererQuirks.COUNT];
int i = 0;
@@ -1555,6 +1559,7 @@ public abstract class GLContextImpl extends GLContext {
}
if( glRendererLowerCase.contains("intel(r)") && compatCtx && ( major>3 || major==3 && minor>=1 ) )
{
+ // FIXME: Apply vendor version constraints!
final int quirk = GLRendererQuirks.GLNonCompliant;
if(DEBUG) {
System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer);
@@ -1562,43 +1567,28 @@ public abstract class GLContextImpl extends GLContext {
quirks[i++] = quirk;
}
}
-
- //
- // Mesa RENDERER related quirks
- //
if( glRendererLowerCase.contains("mesa") ) {
- // Added March 30, 2013
- // Martin C. Hegedus
- if ( glRendererLowerCase.contains("x11") && getMesaMajorVersion(glVersion) < 8.0 ) {
- final int quirk = GLRendererQuirks.DontCloseX11DisplayConnection;
+ if ( glRendererLowerCase.contains("x11") && vendorVersion.compareTo(Version80) < 0 ) {
+ final int quirk = GLRendererQuirks.DontCloseX11Display;
if(DEBUG) {
- System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Mesa X11 < 8 : Renderer=" + glRenderer + ", Version=" +glVersion);
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer=" + glRenderer + ", Version=[vendor " + vendorVersion + ", GL " + glVersion+"]");
}
quirks[i++] = quirk;
- }
+ }
+ }
+ if( glRendererLowerCase.contains("ati technologies") || glRendererLowerCase.startsWith("ati ") ) {
+ {
+ final int quirk = GLRendererQuirks.DontCloseX11Display;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer=" + glRenderer);
+ }
+ quirks[i++] = quirk;
+ }
}
glRendererQuirks = new GLRendererQuirks(quirks, 0, i);
}
- // Added by Martin C. Hegedus, March 30, 2013
- private static final int getMesaMajorVersion(String version) {
- if (version == null || version.length() <= 0) return -1;
- String[] strings = version.trim().split("\\s+");
- if (strings.length <= 0) return -1;
- version = strings[strings.length-1];
- int index = version.indexOf(".");
- if (index == 0) return -1;
- if (index != -1) version = version.substring(0,index);
- try {
- Integer iNumber = new Integer(version);
- return (iNumber == null) ? -1 : iNumber.intValue();
- } catch (Throwable t) {
- return -1;
- }
- }
-
-
private static final boolean hasFBOImpl(int major, int ctp, ExtensionAvailabilityCache extCache) {
return ( 0 != (ctp & CTX_PROFILE_ES) && major >= 2 ) || // ES >= 2.0
diff --git a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
index 83815f7a4..1784cd772 100644
--- a/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
+++ b/src/jogl/classes/jogamp/opengl/GLVersionNumber.java
@@ -32,24 +32,23 @@ import java.util.StringTokenizer;
import javax.media.opengl.GLContext;
-import com.jogamp.common.util.VersionNumber;
+import com.jogamp.common.util.VersionNumberString;
/**
* A class for storing and comparing OpenGL version numbers.
* This only works for desktop OpenGL at the moment.
*/
-class GLVersionNumber extends VersionNumber {
+class GLVersionNumber extends VersionNumberString {
- protected boolean valid;
+ private final boolean valid;
- public GLVersionNumber(int majorRev, int minorRev, int subMinorRev) {
- super(majorRev, minorRev, subMinorRev);
- valid = true;
+ private GLVersionNumber(int[] val, String versionString, boolean valid) {
+ super(val[0], val[1], val[2], versionString);
+ this.valid = valid;
}
-
- public GLVersionNumber(String versionString) {
- super();
- valid = false;
+
+ public static GLVersionNumber create(String versionString) {
+ int[] val = new int[] { 0, 0, 0 };
try {
if (versionString.startsWith("GL_VERSION_")) {
StringTokenizer tok = new StringTokenizer(versionString, "_");
@@ -57,19 +56,19 @@ class GLVersionNumber extends VersionNumber {
tok.nextToken(); // VERSION_
if (!tok.hasMoreTokens()) {
val[0] = 0;
- return;
- }
- val[0] = Integer.valueOf(tok.nextToken()).intValue();
- if (!tok.hasMoreTokens()) {
- val[1] = 0;
- return;
- }
- val[1] = Integer.valueOf(tok.nextToken()).intValue();
- if (!tok.hasMoreTokens()) {
- val[2] = 0;
- return;
+ } else {
+ val[0] = Integer.valueOf(tok.nextToken()).intValue();
+ if (!tok.hasMoreTokens()) {
+ val[1] = 0;
+ } else {
+ val[1] = Integer.valueOf(tok.nextToken()).intValue();
+ if (!tok.hasMoreTokens()) {
+ val[2] = 0;
+ } else {
+ val[2] = Integer.valueOf(tok.nextToken()).intValue();
+ }
+ }
}
- val[2] = Integer.valueOf(tok.nextToken()).intValue();
} else {
int radix = 10;
if (versionString.length() > 2) {
@@ -105,7 +104,7 @@ class GLVersionNumber extends VersionNumber {
}
}
}
- valid = true;
+ return new GLVersionNumber(val, versionString, true);
} catch (Exception e) {
e.printStackTrace();
// FIXME: refactor desktop OpenGL dependencies and make this
@@ -118,11 +117,41 @@ class GLVersionNumber extends VersionNumber {
new IllegalArgumentException(
"Illegally formatted version identifier: \"" + versionString + "\"")
.initCause(e);
- */
+ */
}
+ return new GLVersionNumber(val, versionString, false);
}
public final boolean isValid() {
return valid;
}
+
+ /**
+ * Returns the optional vendor version at the end of the
+ * <code>GL_VERSION</code> string if exists, otherwise <code>null</code>.
+ * <pre>
+ * 2.1 Mesa 7.0.3-rc2 -> 7.0.3 (7.0.3-rc2)
+ * 4.2.12171 Compatibility Profile Context 9.01.8 -> 9.1.8 (9.01.8)
+ * 4.3.0 NVIDIA 310.32 -> 310.32 (310.32)
+ * </pre>
+ */
+ public static final VersionNumberString createVendorVersion(String versionString) {
+ if (versionString == null || versionString.length() <= 0) {
+ return null;
+ }
+ final String[] strings = versionString.trim().split("\\s+");
+ if ( strings.length <= 0 ) {
+ return null;
+ }
+ // Test all segments backwards from [len-1..1], skipping the 1st entry (GL version)
+ // If a segment represents a valid VersionNumber - use it.
+ for(int i=strings.length-1; i>=1; i--) {
+ final String s = strings[i];
+ final VersionNumberString version = new VersionNumberString(s, ".");
+ if( !version.isZero() ) {
+ return version;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index be3729a7d..9b87860cb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -113,6 +113,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// Check for other underlying stuff ..
if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
+ hasX11 = true;
try {
ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
} catch (Exception jre) { /* n/a .. */ }
@@ -262,6 +263,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
private EGLGraphicsDevice defaultDevice = null;
private SharedResource defaultSharedResource = null;
private boolean isANGLE = false;
+ private boolean hasX11 = false;
static class SharedResource {
private final EGLGraphicsDevice device;
@@ -568,6 +570,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// avoid exception due to double 'set' - carefull exception of the rule.
EGLContext.setAvailableGLVersionsSet(adevice);
}
+ if( hasX11 ) {
+ handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksES2[0]);
+ }
final SharedResource sr = new SharedResource(defaultDevice, madeCurrentES1, hasPBufferES1[0], rendererQuirksES1[0], ctpES1[0],
madeCurrentES2, hasPBufferES2[0], rendererQuirksES2[0], ctpES2[0]);
@@ -582,6 +588,12 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
return sr;
}
+
+ private void handleDontCloseX11DisplayQuirk(GLRendererQuirks quirks) {
+ if( null != quirks && quirks.exist( GLRendererQuirks.DontCloseX11Display ) ) {
+ jogamp.nativewindow.x11.X11Util.markAllDisplaysUnclosable();
+ }
+ }
@Override
protected final Thread getSharedResourceThread() {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 2f3940baa..9486b5875 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -73,6 +73,7 @@ import jogamp.opengl.SharedResourceRunner;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
+import com.jogamp.opengl.GLRendererQuirks;
public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
@@ -236,6 +237,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
res = GLXUtil.isGLXAvailableOnServer(x11Device);
} finally {
x11Device.unlock();
+ x11Device.close();
}
if(DEBUG) {
System.err.println("GLX "+(res ? "is" : "not")+" available on device/server: "+x11Device);
@@ -276,6 +278,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
} finally {
sharedContext.release();
}
+ if( sharedContext.hasRendererQuirk( GLRendererQuirks.DontCloseX11Display ) ) {
+ X11Util.markAllDisplaysUnclosable();
+ }
if (DEBUG) {
System.err.println("SharedDevice: " + sharedDevice);
System.err.println("SharedScreen: " + sharedScreen);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 2fb780fa2..e28aff116 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -82,6 +82,9 @@ public class X11Util implements ToolkitProperties {
* </p>
*/
public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG", true);
+
+ /** See {@link #ATI_HAS_XCLOSEDISPLAY_BUG}. */
+ public static final boolean HAS_XCLOSEDISPLAY_BUG = Debug.isPropertyDefined("nativewindow.debug.X11Util.HAS_XCLOSEDISPLAY_BUG", true);
/**
* See Bug 623 - https://jogamp.org/bugzilla/show_bug.cgi?id=623
@@ -137,14 +140,11 @@ public class X11Util implements ToolkitProperties {
hasX11_EXTENSION_ATIFGLRXDRI = false;
hasX11_EXTENSION_ATIFGLEXTENSION = false;
}
- hasThreadingIssues = ATI_HAS_MULTITHREADING_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION );
- // A check on nativewindow.debug.X11Util.HasX11CloseDisplayBug added March 30, 2013
- // Martin C. Hegedus
- if (!markAllDisplaysUnclosable) {
- markAllDisplaysUnclosable = ATI_HAS_XCLOSEDISPLAY_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION );
- if (Debug.isPropertyDefined("nativewindow.debug.X11Util.HasX11CloseDisplayBug", true))
- markAllDisplaysUnclosable = true;
- }
+ final boolean isATIFGLRX = hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION ;
+ hasThreadingIssues = ATI_HAS_MULTITHREADING_BUG && isATIFGLRX;
+ if ( !markAllDisplaysUnclosable ) {
+ markAllDisplaysUnclosable = ( ATI_HAS_XCLOSEDISPLAY_BUG && isATIFGLRX ) || HAS_XCLOSEDISPLAY_BUG;
+ }
if(DEBUG) {
System.err.println("X11Util.initSingleton(): OK "+isInitOK+"]"+
@@ -184,10 +184,10 @@ public class X11Util implements ToolkitProperties {
synchronized(X11Util.class) {
if(isInit) {
final boolean isJVMShuttingDown = NativeWindowFactory.isJVMShuttingDown() ;
- // Modified March 30, 2013 so output is not created under "expected" circumstances
- // Martin C. Hegedus
- if(DEBUG || ((openDisplayMap.size() > 0 || reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0) &&
- !(reusableDisplayList.size() == pendingDisplayList.size() && markAllDisplaysUnclosable))) {
+ if( DEBUG ||
+ ( ( openDisplayMap.size() > 0 || reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0 ) &&
+ ( reusableDisplayList.size() != pendingDisplayList.size() || !markAllDisplaysUnclosable )
+ ) ) {
System.err.println("X11Util.Display: Shutdown (JVM shutdown: "+isJVMShuttingDown+
", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
", reusable (open, marked uncloseable): "+reusableDisplayList.size()+
@@ -250,21 +250,22 @@ public class X11Util implements ToolkitProperties {
public static String getNullDisplayName() {
return nullDisplayName;
}
-
- // Added March 30, 2013
- // Martin C. Hegedus
+
public static void markAllDisplaysUnclosable() {
synchronized(globalLock) {
- markAllDisplaysUnclosable = true;
- for(int i=0; i<openDisplayList.size(); i++)
- openDisplayList.get(i).setUncloseable(true);
- for(int i=0; i<reusableDisplayList.size(); i++)
- reusableDisplayList.get(i).setUncloseable(true);
- for(int i=0; i<pendingDisplayList.size(); i++)
- pendingDisplayList.get(i).setUncloseable(true);
- }
+ markAllDisplaysUnclosable = true;
+ for(int i=0; i<openDisplayList.size(); i++) {
+ openDisplayList.get(i).setUncloseable(true);
+ }
+ for(int i=0; i<reusableDisplayList.size(); i++) {
+ reusableDisplayList.get(i).setUncloseable(true);
+ }
+ for(int i=0; i<pendingDisplayList.size(); i++) {
+ pendingDisplayList.get(i).setUncloseable(true);
+ }
+ }
}
-
+
public static boolean getMarkAllDisplaysUnclosable() {
return markAllDisplaysUnclosable;
}
@@ -349,11 +350,9 @@ public class X11Util implements ToolkitProperties {
XCloseDisplay(ndpy.getHandle());
num++;
}
- // Added DEBUG statement around print statement, March 30, 2013
- // Martin C. Hegedus
- if(DEBUG) {
- System.err.println("X11Util.closePendingDisplayConnections(): Closed "+num+" pending display connections");
- }
+ if(DEBUG) {
+ System.err.println("X11Util.closePendingDisplayConnections(): Closed "+num+" pending display connections");
+ }
}
}
return num;
@@ -473,10 +472,8 @@ public class X11Util implements ToolkitProperties {
}
public static void closeDisplay(long handle) {
- NamedDisplay namedDpy;
-
synchronized(globalLock) {
- namedDpy = (NamedDisplay) openDisplayMap.remove(handle);
+ final NamedDisplay namedDpy = (NamedDisplay) openDisplayMap.remove(handle);
if(null==namedDpy) {
X11Util.dumpPendingDisplayConnections();
throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped. Thread "+Thread.currentThread().getName());
@@ -488,10 +485,12 @@ public class X11Util implements ToolkitProperties {
namedDpy.removeRef();
if(!openDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
-
- // Modified March 30, 2013
- // Martin C. Hegedus
- if(!(markAllDisplaysUnclosable || namedDpy.isUncloseable())) {
+
+ if( markAllDisplaysUnclosable ) {
+ // if set-mark 'slipped' this one .. just to be safe!
+ namedDpy.setUncloseable(true);
+ }
+ if( !namedDpy.isUncloseable() ) {
XCloseDisplay(namedDpy.getHandle());
pendingDisplayList.remove(namedDpy);
} else {
@@ -499,7 +498,7 @@ public class X11Util implements ToolkitProperties {
X11Lib.XSync(namedDpy.getHandle(), true); // flush output buffer and discard all events
reusableDisplayList.add(namedDpy);
}
-
+
if(DEBUG) {
System.err.println("X11Util.Display: Closed (real: "+(!namedDpy.isUncloseable())+") "+namedDpy+". Thread "+Thread.currentThread().getName());
}
diff --git a/src/test-native/make.sh b/src/test-native/make.sh
index 269f09c35..c6d47ff03 100755
--- a/src/test-native/make.sh
+++ b/src/test-native/make.sh
@@ -2,6 +2,8 @@
gcc -o displayMultiple01 displayMultiple01.c -lX11 -lGL
gcc -o displayMultiple02 displayMultiple02.c -lX11 -lGL
+gcc -o displayMultiple02_mch displayMultiple02_mch.c -lX11 -lGL
+gcc -o displayMultiple02_new_mch displayMultiple02_new_mch.c -lX11 -lGL
gcc -o glExtensionsListGL2 glExtensionsListGL2.c -lX11 -lGL
gcc -o glExtensionsListGL3 glExtensionsListGL3.c -lX11 -lGL
gcc -o contextRetargetDrawable01 contextRetargetDrawable01.c -lX11 -lGL