diff options
author | Martin Hegedus <[email protected]> | 2013-04-02 09:31:41 -0700 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-04-15 15:46:47 +0200 |
commit | 5b47372590ec715647ebbd75d70c41ec7a64485a (patch) | |
tree | 662ebf0af203cf10a48f66cb9777cf8e9400da6b | |
parent | 9104faa11c256cbe8687122bba3c54dbb398b4e0 (diff) |
Fix Bug 705 - Make Mesa X11 driver < 8.0 use new Quirk DontCloseX11DisplayConnection
4 files changed, 121 insertions, 6 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java index 715511d1b..7203ba214 100644 --- a/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java +++ b/src/jogl/classes/com/jogamp/opengl/GLRendererQuirks.java @@ -81,12 +81,41 @@ 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; + /** Number of quirks known. */ - public static final int COUNT = 8; + public static final int COUNT = 9; private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval", "NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard", - "GLNonCompliant", "GLFlushBeforeRelease" + "GLNonCompliant", "GLFlushBeforeRelease", "DontCloseX11DisplayConnection" }; private final int _bitmask; diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 25bba1725..54ed479a9 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -64,6 +64,11 @@ 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. * @@ -1524,6 +1529,26 @@ public class GLProfile { final boolean addedEGLProfile = null != defaultEGLDevice ? initProfilesForDevice(defaultEGLDevice) : false; 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+")"); diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 9f7c9cf57..74bc59c7c 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -1562,9 +1562,41 @@ 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(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Mesa X11 < 8 : Renderer=" + glRenderer + ", Version=" +glVersion); + } + 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) { diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index c771cd67a..2fb780fa2 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -138,7 +138,13 @@ public class X11Util implements ToolkitProperties { hasX11_EXTENSION_ATIFGLEXTENSION = false; } hasThreadingIssues = ATI_HAS_MULTITHREADING_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION ); - markAllDisplaysUnclosable = ATI_HAS_XCLOSEDISPLAY_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; + } if(DEBUG) { System.err.println("X11Util.initSingleton(): OK "+isInitOK+"]"+ @@ -178,7 +184,10 @@ public class X11Util implements ToolkitProperties { synchronized(X11Util.class) { if(isInit) { final boolean isJVMShuttingDown = NativeWindowFactory.isJVMShuttingDown() ; - if(DEBUG || openDisplayMap.size() > 0 || reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0) { + // 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))) { System.err.println("X11Util.Display: Shutdown (JVM shutdown: "+isJVMShuttingDown+ ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+ ", reusable (open, marked uncloseable): "+reusableDisplayList.size()+ @@ -242,6 +251,20 @@ public class X11Util implements ToolkitProperties { 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); + } + } + public static boolean getMarkAllDisplaysUnclosable() { return markAllDisplaysUnclosable; } @@ -326,7 +349,11 @@ public class X11Util implements ToolkitProperties { XCloseDisplay(ndpy.getHandle()); num++; } - System.err.println("X11Util.closePendingDisplayConnections(): Closed "+num+" pending display connections"); + // Added DEBUG statement around print statement, March 30, 2013 + // Martin C. Hegedus + if(DEBUG) { + System.err.println("X11Util.closePendingDisplayConnections(): Closed "+num+" pending display connections"); + } } } return num; @@ -462,7 +489,9 @@ public class X11Util implements ToolkitProperties { namedDpy.removeRef(); if(!openDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); } - if(!namedDpy.isUncloseable()) { + // Modified March 30, 2013 + // Martin C. Hegedus + if(!(markAllDisplaysUnclosable || namedDpy.isUncloseable())) { XCloseDisplay(namedDpy.getHandle()); pendingDisplayList.remove(namedDpy); } else { |