diff options
author | Sven Gothel <[email protected]> | 2010-04-15 03:44:12 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-04-15 03:44:12 +0200 |
commit | 2ae28d54858ff684bc2368e0476a7a357dc63432 (patch) | |
tree | 41524bc7be69f029d2b183128cc0c8b89ec4754c /src/jogl | |
parent | 2df3bea10859ee2f2c4b3622f3b610b17a5749d6 (diff) |
Further ATI (fglrx) X11Display bug workaround/cleanup
- See https://bugzilla.mozilla.org/show_bug.cgi?id=486277
- Calling XCloseDisplay occasionally leads to a SIGSEGV,
even thought the reference is valid and OK.
Workaround is not to close any X11Display,
but to hold them stashed and reuse them.
Since we already pipeline all X11Display's
via Nativewindow's X11Util, an added referenceCounter
and a global active/passive list solved this problem.
This workaround is only active in case 'isVendorATI()'.
NEWT/NativeWindow X11:
- Let XIOErrorHandler and invalid display references
fail hard with FatalError, otherwise we won't see
the stack trace - and those bugs are indeed fatal.
NativeWindow X11:
- Install XIOErrorHandler, which stays active.
- X11Util.X11Display:
- Add reference counter
- Add global active/passive list.
Passive if reference count == 0
and marked as 'un-closeable' (-> ATI).
Reusing passive members when create a new display.
-
JOGL:
- Use DeleteLocalRef() calls to free temp NIO buffer
in manual *Copied implementation.
- GLDrawableFactoryImpl: Be serious about the shutdown() semantics
- *GraphicsConfiguration:
- Fix the invalid Onscreen/PBuffer/Pixmap determination (X11/EGL/WGL)
- Just return null if not valid
- X11GLXGraphicsConfigurationFactory - FBConfig
- Determine recommendedIndex properly ..
- Don't bail out if a FBConfig is invalid ..
- Use Chooser in case nothing is recommended ..
- X11OffscreenGLXDrawable fixes bugs:
- wrong (int) cast of parent window in XCreatePixmap call
- setting display to zero too early in destruction, ie
before XCloseDisplay
- X11GLXDrawableFactory is using [singleton] shared dummy resources for
- Screen, Drawable and Context
which are utilized in case they are needed ..
They are removed at shutdown call
- GLXVersion gathering in GLXUtil now ..
- DefaultGLCapabilitiesChooser: Respect PBuffer selection
Tests:
- Add DrawableFactory shutdown()
- Add various Offscreen Capabilties
- Add Offscreen and non-pbuffer case
- JUnit Passed (Linux64bit: NVidia/ATI)
- demos.jrefract.JRefract passed (Linux64bit: NVidia/ATI)
Diffstat (limited to 'src/jogl')
14 files changed, 361 insertions, 134 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java index 35810678c..616640bad 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java @@ -54,13 +54,24 @@ import java.lang.reflect.*; public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { protected static final boolean DEBUG = Debug.debug("GLDrawableFactory"); + private boolean isValid = false; + public void shutdown() { + validate(); + isValid = false; + } + + protected final void validate() { + if(!isValid) { + throw new GLException("GLDrawableFactory is already shutdown!"); + } } //--------------------------------------------------------------------------- // Dispatching GLDrawable construction in respect to the NativeWindow Capabilities // public GLDrawable createGLDrawable(NativeWindow target) { + validate(); if (target == null) { throw new IllegalArgumentException("Null target"); } @@ -124,6 +135,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { GLCapabilitiesChooser chooser, int width, int height) { + validate(); if(height<=0 || height<=0) { throw new GLException("Width and height of pbuffer must be positive (were (" + width + ", " + height + "))"); @@ -139,6 +151,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { int width, int height, GLContext shareWith) { + validate(); return new GLPbufferImpl( (GLDrawableImpl) createGLPbufferDrawable(capabilities, chooser, height, height), shareWith); } @@ -155,6 +168,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { GLCapabilitiesChooser chooser, int width, int height) { + validate(); if(width<=0 || height<=0) { throw new GLException("Width and height of pbuffer must be positive (were (" + width + ", " + height + "))"); @@ -174,6 +188,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { protected GLDrawableFactoryImpl() { super(); + isValid = true; } protected void maybeDoSingleThreadedWorkaround(Runnable action) { @@ -279,6 +294,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { * out-of-bounds */ public boolean setDisplayGamma(float gamma, float brightness, float contrast) throws IllegalArgumentException { + validate(); if ((brightness < -1.0f) || (brightness > 1.0f)) { throw new IllegalArgumentException("Brightness must be between -1.0 and 1.0"); } @@ -311,6 +327,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { } public synchronized void resetDisplayGamma() { + validate(); if (gammaShutdownHook == null) { throw new IllegalArgumentException("Should not call this unless setDisplayGamma called first"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java index c8bc4fe0d..2d5154442 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java @@ -122,10 +122,11 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple if ( onscreen ) { res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ; } else { - res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) || usePBuffer ; - } - if ( usePBuffer ) { - res = res && ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ; + if ( usePBuffer ) { + res = ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ; + } else { + res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) ; + } } return res; @@ -187,17 +188,13 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple caps.setOnscreen( 0 != (val[0] & EGL.EGL_WINDOW_BIT) ); caps.setPBuffer ( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) ); } else { - throw new GLException("EGL_SURFACE_TYPE does not match !!!"); - } - } else { - if(relaxed) { if(DEBUG) { - System.err.println("Could not determine EGL_SURFACE_TYPE !!!"); + System.err.println("EGL_SURFACE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val[0] & EGL.EGL_WINDOW_BIT) )+", pbuffer "+( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) )+", pixmap "+( 0 != (val[0] & EGL.EGL_PIXMAP_BIT) )+")"); } return null; - } else { - throw new GLException("Could not determine EGL_SURFACE_TYPE !!!"); } + } else { + throw new GLException("Could not determine EGL_SURFACE_TYPE !!!"); } return caps; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java index 5b34e40e1..aed4012a4 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -412,14 +412,16 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio if ( onscreen ) { res = ( 0 != (val & WINDOW_BIT) ) ; } else { - res = ( 0 != (val & BITMAP_BIT) ) || usePBuffer ; - } - if ( usePBuffer ) { - res = res && ( 0 != (val & PBUFFER_BIT) ) ; + if ( usePBuffer ) { + res = ( 0 != (val & PBUFFER_BIT) ) ; + } else { + res = ( 0 != (val & BITMAP_BIT) ) ; + } } return res; } + public static GLCapabilities AttribList2GLCapabilities(GLProfile glp, int[] iattribs, int niattribs, int[] iresults, @@ -433,7 +435,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio res.setOnscreen( 0 != (drawableTypeBits & WINDOW_BIT) ); res.setPBuffer ( 0 != (drawableTypeBits & PBUFFER_BIT) ); } else { - throw new GLException("WGL DrawableType does not match !!!"); + if(DEBUG) { + System.err.println("WGL DrawableType does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (drawableTypeBits & WINDOW_BIT) )+", pbuffer "+( 0 != (drawableTypeBits & PBUFFER_BIT) )+", pixmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")"); + } + return null; } for (int i = 0; i < niattribs; i++) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index 55b30ef3a..1a375699c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -260,9 +260,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio } pixelFormat = 1; // default .. } else if ( pixelFormat > numFormats ) { - throw new GLException("Invalid result " + pixelFormat + - " from GLCapabilitiesChooser (should be between 1 and " + - numFormats + ")"); + // keep on going .. + if(DEBUG) { + System.err.println("GLCapabilitiesChooser specified invalid index (expected 1.." + numFormats + ", got "+pixelFormat+")"); + } + pixelFormat = 1; // default .. } } chosenCaps = availableCaps[pixelFormat-1]; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java index 99c54332f..e3c1381f8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java @@ -54,13 +54,55 @@ public class GLXUtil { /** Workaround for apparent issue with ATI's proprietary drivers where direct contexts still send GLX tokens for GL calls */ - public static boolean isVendorATI(long display) { + public static String getVendorName(long display) { try { X11Lib.XLockDisplay(display); - String vendor = GLX.glXGetClientString(display, GLX.GLX_VENDOR); - return vendor != null && vendor.startsWith("ATI") ; + return GLX.glXGetClientString(display, GLX.GLX_VENDOR); } finally { X11Lib.XUnlockDisplay(display); } } + + public static boolean isVendorNVIDIA(String vendor) { + return vendor != null && vendor.startsWith("NVIDIA") ; + } + + public static boolean isVendorATI(String vendor) { + return vendor != null && vendor.startsWith("ATI") ; + } + + public static boolean isVendorATI(long display) { + return isVendorATI(getVendorName(display)); + } + + public static boolean isVendorNVIDIA(long display) { + return isVendorNVIDIA(getVendorName(display)); + } + + public static void getGLXVersion(long display, int major[], int minor[]) { + if(0 == display) { + throw new GLException("null display handle"); + } + if(major.length<1||minor.length<1) { + throw new GLException("passed int arrays size is not >= 1"); + } + + if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) { + throw new GLException("glXQueryVersion failed"); + } + + // Work around bugs in ATI's Linux drivers where they report they + // only implement GLX version 1.2 on the server side + if (major[0] == 1 && minor[0] == 2) { + String str = GLX.glXGetClientString(display, GLX.GLX_VERSION); + try { + // e.g. "1.3" + major[0] = Integer.valueOf(str.substring(0, 1)).intValue(); + minor[0] = Integer.valueOf(str.substring(2, 3)).intValue(); + } catch (Exception e) { + major[0] = 1; + minor[0] = 2; + } + } + } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java index 097689967..a865e91e8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java @@ -42,6 +42,8 @@ import com.jogamp.nativewindow.impl.x11.*; public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { + // private long dummyWindow = 0; + /** * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277, * we cannot switch the Display as we please, @@ -57,12 +59,17 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilities caps = (GLCapabilities) config.getChosenCapabilities(); - long dpy = config.getScreen().getDevice().getHandle(); - int scrn = config.getScreen().getIndex(); - // System.out.println("X11DummyGLXDrawable: dpy "+toHexString(dpy)+", scrn "+scrn); + X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice(); + long dpy = device.getHandle(); + int scrn = screen.getIndex(); + // long visualID = config.getVisualID(); + // System.out.println("X11DummyGLXDrawable: dpy "+toHexString(dpy)+", scrn "+scrn+", visualID "+toHexString(visualID)); + X11Lib.XLockDisplay(dpy); try{ nw.setSurfaceHandle( X11Lib.RootWindow(dpy, scrn) ); + // dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID); + // nw.setSurfaceHandle( dummyWindow ); } finally { X11Lib.XUnlockDisplay(dpy); } @@ -80,6 +87,11 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { } public void destroy() { - // nothing to do, but allowed + /** + if(0!=dummyWindow) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + long dpy = config.getScreen().getDevice().getHandle(); + X11Lib.DestroyDummyWindow(dpy, dummyWindow); + } */ } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java index 055e7236c..142da672a 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -133,7 +133,7 @@ public abstract class X11GLXContext extends GLContextImpl { } GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities(); - isVendorATI = GLXUtil.isVendorATI(display); + isVendorATI = ((X11GLXDrawableFactory)(drawable.getFactoryImpl())).isVendorATI(); if(config.getFBConfigID()<0) { // not able to use FBConfig @@ -148,11 +148,11 @@ public abstract class X11GLXContext extends GLContextImpl { drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), context)) { - throw new GLException("Error making temp context (old2) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable); + throw new GLException("Error making temp context (old2) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); } setGLFunctionAvailability(true); if(DEBUG) { - System.err.println("X11GLXContext.createContext done (old2 ctx) 0x"+Long.toHexString(context)); + System.err.println("X11GLXContext.createContext done (old2 ctx) "+toHexString(context)); } } else { @@ -167,7 +167,7 @@ public abstract class X11GLXContext extends GLContextImpl { drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), temp_context)) { - throw new GLException("Error making temp context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable); + throw new GLException("Error making temp context (old) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); } setGLFunctionAvailability(true); @@ -182,7 +182,7 @@ public abstract class X11GLXContext extends GLContextImpl { // continue with temp context for GL < 3.0 context = temp_context; if(DEBUG) { - System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) 0x"+Long.toHexString(context)); + System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) "+toHexString(context)); } } else { GLXExt glXExt = getGLXExt(); @@ -209,7 +209,7 @@ public abstract class X11GLXContext extends GLContextImpl { /** * don't stricten requirements any further, even compatible would be fine * - } else { + else { attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB; attribs[8+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB; } @@ -228,7 +228,7 @@ public abstract class X11GLXContext extends GLContextImpl { GLX.glXDestroyContext(display, context); context = 0; } else if(DEBUG) { - System.err.println("X11GLXContext.createContext >= 3.2 available 0x"+Long.toHexString(context)); + System.err.println("X11GLXContext.createContext >= 3.2 available "+toHexString(context)); } } else { if(DEBUG) { @@ -261,7 +261,7 @@ public abstract class X11GLXContext extends GLContextImpl { GLX.glXDestroyContext(display, context); context = 0; } else if(DEBUG) { - System.err.println("X11GLXContext.createContext >= 3.0 available 0x"+Long.toHexString(context)); + System.err.println("X11GLXContext.createContext >= 3.0 available "+toHexString(context)); } } else { if(DEBUG) { @@ -285,10 +285,10 @@ public abstract class X11GLXContext extends GLContextImpl { context)) { GLX.glXMakeContextCurrent(display, 0, 0, 0); GLX.glXDestroyContext(display, temp_context); - throw new GLException("Error making context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable); + throw new GLException("Error making context (old) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); } if(DEBUG) { - System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) 0x"+Long.toHexString(context)); + System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) "+toHexString(context)); } } else { GLX.glXDestroyContext(display, temp_context); @@ -296,7 +296,7 @@ public abstract class X11GLXContext extends GLContextImpl { // need to update the GL func table .. updateGLProcAddressTable(); if(DEBUG) { - System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) 0x"+Long.toHexString(context)); + System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) "+toHexString(context)); } } } @@ -337,6 +337,8 @@ public abstract class X11GLXContext extends GLContextImpl { } protected int makeCurrentImplAfterLock() throws GLException { + long dpy = drawable.getNativeWindow().getDisplayHandle(); + getDrawableImpl().getFactoryImpl().lockToolkit(); try { if (drawable.getNativeWindow().getSurfaceHandle() == 0) { @@ -356,7 +358,7 @@ public abstract class X11GLXContext extends GLContextImpl { if (GLX.glXGetCurrentContext() != context) { - if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), + if (!GLX.glXMakeContextCurrent(dpy, drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), context)) { @@ -364,7 +366,7 @@ public abstract class X11GLXContext extends GLContextImpl { } if (DEBUG && (VERBOSE || created)) { System.err.println(getThreadName() + ": glXMakeCurrent(display " + - toHexString(drawable.getNativeWindow().getDisplayHandle()) + + toHexString(dpy)+ ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + ", drawableRead " + toHexString(drawableRead.getNativeWindow().getSurfaceHandle()) + ", context " + toHexString(context) + ") succeeded"); @@ -397,10 +399,10 @@ public abstract class X11GLXContext extends GLContextImpl { try { if (context != 0) { if (DEBUG) { - System.err.println("glXDestroyContext(0x" + - Long.toHexString(drawable.getNativeWindow().getDisplayHandle()) + - ", 0x" + - Long.toHexString(context) + ")"); + System.err.println("glXDestroyContext(" + + toHexString(drawable.getNativeWindow().getDisplayHandle()) + + ", " + + toHexString(context) + ")"); } GLX.glXDestroyContext(drawable.getNativeWindow().getDisplayHandle(), context); if (DEBUG) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 60ee431dc..eda480d5f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -48,6 +48,7 @@ import com.jogamp.nativewindow.impl.NWReflection; import com.jogamp.nativewindow.impl.x11.*; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper { + public X11GLXDrawableFactory() { super(); // Must initialize GLX support eagerly in case a pbuffer is the @@ -60,64 +61,121 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna NWReflection.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory", new Object[] {}); } catch (Throwable t) { } + + X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createThreadLocalDisplay(null)); + vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); + isVendorATI = GLXUtil.isVendorATI(vendorName); + isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); + if( isVendorATI() ) { + X11Util.markGlobalDisplayUndeletable(sharedDevice.getHandle()); // ATI hack .. + } + sharedScreen = new X11GraphicsScreen(sharedDevice, 0); + if (DEBUG) { + System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA); + System.err.println("!!! SharedScreen: "+sharedScreen); + } + } + + private X11GraphicsScreen sharedScreen; + private String vendorName; + private boolean isVendorATI; + private boolean isVendorNVIDIA; + + public String getVendorName() { return vendorName; } + public boolean isVendorATI() { return isVendorATI; } + public boolean isVendorNVIDIA() { return isVendorNVIDIA; } + + private X11DummyGLXDrawable sharedDrawable=null; + private GLContext sharedContext=null; + + private void initShared() { + if(null==sharedDrawable) { + X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle()); + sharedDrawable = new X11DummyGLXDrawable(sharedScreen, this, null); + sharedContext = sharedDrawable.createContext(null); + sharedContext.makeCurrent(); + sharedContext.release(); + X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle()); + if (DEBUG) { + System.err.println("!!! SharedContext: "+sharedContext); + } + } + } + + public void shutdown() { + super.shutdown(); + if (DEBUG) { + System.err.println("!!! Shutdown Shared:"); + System.err.println("!!! CTX : "+sharedContext); + System.err.println("!!! Drawable: "+sharedDrawable); + System.err.println("!!! Screen : "+sharedScreen); + Exception e = new Exception("Debug"); + e.printStackTrace(); + } + if(null!=sharedContext) { + sharedContext.destroy(); // implies release, if current + } + if(null!=sharedDrawable) { + sharedDrawable.destroy(); + } + if(null!=sharedScreen) { + X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice(); + if(null!=sharedDevice) { + X11Util.closeThreadLocalDisplay(null); + } + sharedScreen = null; + } + X11Util.shutdown( !isVendorATI(), DEBUG ); } public GLDrawableImpl createOnscreenDrawable(NativeWindow target) { + validate(); if (target == null) { throw new IllegalArgumentException("Null target"); } + if( isVendorATI() ) { + X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack .. + } return new X11OnscreenGLXDrawable(this, target); } protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) { + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + if( isVendorATI() ) { + X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack .. + } + initShared(); return new X11OffscreenGLXDrawable(this, target); } public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { + validate(); return glxVersionGreaterEqualThan(device, 1, 3); } private boolean glxVersionsQueried = false; private int glxVersionMajor=0, glxVersionMinor=0; public boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) { + validate(); if (!glxVersionsQueried) { if(null == device) { - GLContext ctx = GLContext.getCurrent(); - if( null != ctx) { - device = ctx.getGLDrawable().getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice(); - } + device = (X11GraphicsDevice) sharedScreen.getDevice(); } if(null == device) { - GLException gle = new GLException("FIXME: No AbstractGraphicsDevice (passed or queried via current context - Fallback to ThreadLocal Display .."); - gle.printStackTrace(); - - device = new X11GraphicsDevice(X11Util.getThreadLocalDisplay(null)); + throw new GLException("FIXME: No AbstractGraphicsDevice (passed or shared-device"); } long display = device.getHandle(); int[] major = new int[1]; int[] minor = new int[1]; - if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) { - throw new GLException("glXQueryVersion failed"); - } + GLXUtil.getGLXVersion(display, major, minor); if (DEBUG) { System.err.println("!!! GLX version: major " + major[0] + ", minor " + minor[0]); } - // Work around bugs in ATI's Linux drivers where they report they - // only implement GLX version 1.2 on the server side - if (major[0] == 1 && minor[0] == 2) { - String str = GLX.glXGetClientString(display, GLX.GLX_VERSION); - try { - major[0] = Integer.valueOf(str.substring(0, 1)).intValue(); - minor[0] = Integer.valueOf(str.substring(2, 3)).intValue(); - } catch (NumberFormatException nfe) { - major[0] = 1; - minor[0] = 2; - } - } - glxVersionMajor = major[0]; glxVersionMinor = minor[0]; glxVersionsQueried = true; @@ -127,8 +185,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) { GLDrawableImpl pbufferDrawable; - X11DummyGLXDrawable dummyDrawable=null; - GLContext dummyContext=null; /** * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277, @@ -136,21 +192,20 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna * The dummy context shall also use the same Display, * since switching Display in this regard is another ATI bug. */ - if( null == GLContext.getCurrent() ) { - X11GraphicsScreen screen = (X11GraphicsScreen) target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen(); - dummyDrawable = new X11DummyGLXDrawable(screen, this, null); - dummyContext = dummyDrawable.createContext(null); - dummyContext.makeCurrent(); + boolean usedSharedContext=false; + if( isVendorATI() && null == GLContext.getCurrent() ) { + initShared(); + sharedContext.makeCurrent(); + usedSharedContext=true; + } + if( isVendorATI() ) { + X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack .. } try { pbufferDrawable = new X11PbufferGLXDrawable(this, target); } finally { - if(null!=dummyContext) { - dummyContext.release(); - dummyContext.destroy(); - } - if(null!=dummyDrawable) { - dummyDrawable.destroy(); + if(usedSharedContext) { + sharedContext.release(); } } return pbufferDrawable; @@ -158,25 +213,30 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { - AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault(); - NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, screen)); + X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle()); + NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen)); + X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle()); nw.setSize(width, height); return nw; } public GLContext createExternalGLContext() { + validate(); return X11ExternalGLXContext.create(this, null); } public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) { + validate(); return canCreateGLPbuffer(device); } public GLDrawable createExternalGLDrawable() { + validate(); return X11ExternalGLXDrawable.create(this, null); } public void loadGLULibrary() { + validate(); X11Lib.dlopen("/usr/lib/libGLU.so"); } @@ -191,6 +251,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna } public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) { + validate(); return false; } @@ -210,9 +271,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna return gammaRampLength; } - long display = X11Util.getThreadLocalDefaultDisplay(); + long display = sharedScreen.getDevice().getHandle(); + + X11Lib.XLockDisplay(display); try { - X11Lib.XLockDisplay(display); int[] size = new int[1]; boolean res = X11Lib.XF86VidModeGetGammaRampSize(display, X11Lib.DefaultScreen(display), @@ -235,9 +297,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna rampData[i] = (short) (ramp[i] * 65535); } - long display = X11Util.getThreadLocalDefaultDisplay(); + long display = sharedScreen.getDevice().getHandle(); + X11Lib.XLockDisplay(display); try { - X11Lib.XLockDisplay(display); boolean res = X11Lib.XF86VidModeSetGammaRamp(display, X11Lib.DefaultScreen(display), rampData.length, @@ -262,9 +324,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna rampData.position(2 * size); rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); - long display = X11Util.getThreadLocalDefaultDisplay(); + long display = sharedScreen.getDevice().getHandle(); + X11Lib.XLockDisplay(display); try { - X11Lib.XLockDisplay(display); boolean res = X11Lib.XF86VidModeGetGammaRamp(display, X11Lib.DefaultScreen(display), size, @@ -298,9 +360,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna rampData.position(2 * size); rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); - long display = X11Util.getThreadLocalDefaultDisplay(); + long display = sharedScreen.getDevice().getHandle(); + X11Lib.XLockDisplay(display); try { - X11Lib.XLockDisplay(display); X11Lib.XF86VidModeSetGammaRamp(display, X11Lib.DefaultScreen(display), size, diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java index b3a6e5b8c..35daf0ae0 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java @@ -64,18 +64,18 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem int screen = x11Screen.getIndex(); long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID); if(0==fbcfg) { - throw new GLException("FBConfig null of 0x"+Integer.toHexString(fbcfgID)); + throw new GLException("FBConfig null of "+toHexString(fbcfgID)); } if(null==glp) { glp = GLProfile.getDefault(); } GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); if(null==caps) { - throw new GLException("GLCapabilities null of 0x"+Long.toHexString(fbcfg)); + throw new GLException("GLCapabilities null of "+toHexString(fbcfg)); } XVisualInfo xvi = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); if(null==xvi) { - throw new GLException("XVisualInfo null of 0x"+Long.toHexString(fbcfg)); + throw new GLException("XVisualInfo null of "+toHexString(fbcfg)); } return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID); } @@ -104,6 +104,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem } } + private static int nonZeroOrDontCare(int value) { + return value != 0 ? value : (int)GLX.GLX_DONT_CARE ; + } + public static int[] GLCapabilities2AttribList(GLCapabilities caps, boolean forFBAttr, boolean isMultisampleAvailable, @@ -222,10 +226,11 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem if ( onscreen ) { res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ; } else { - res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) || usePBuffer ; - } - if ( usePBuffer ) { - res = res && ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ; + if ( usePBuffer ) { + res = ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ; + } else { + res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) ; + } } return res; @@ -237,7 +242,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem int val; val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0); if (val != GLX.GLX_RGBA_BIT) { - throw new GLException("Visual does not support RGBA"); + if(DEBUG) { + System.err.println("FBConfig ("+toHexString(fbcfg)+") does not support RGBA: "+toHexString(val)); + } + return null; } GLCapabilities res = new GLCapabilities(glp); @@ -249,7 +257,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) ); res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) ); } else { - throw new GLException("GLX_DRAWABLE_TYPE does not match !!!"); + if(DEBUG) { + System.err.println("FBConfig ("+toHexString(fbcfg)+") GLX_DRAWABLE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val & GLX.GLX_WINDOW_BIT) )+", pbuffer "+( 0 != (val & GLX.GLX_PBUFFER_BIT) )+", pixmap "+( 0 != (val & GLX.GLX_PIXMAP_BIT) )+")"); + } + return null; } res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0); @@ -302,7 +313,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem } int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset); if (res != 0) { - throw new GLException("glXGetFBConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res)); + throw new GLException("glXGetFBConfig("+toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res)); } return tmp[tmp_offset]; } @@ -340,8 +351,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } if (DEBUG) { - System.err.println("!!! Fetched XVisualInfo for visual ID 0x" + Long.toHexString(visualID)); - System.err.println("!!! Resulting XVisualInfo: visualid = 0x" + Long.toHexString(res.getVisualid())); + System.err.println("!!! Fetched XVisualInfo for visual ID " + toHexString(visualID)); + System.err.println("!!! Resulting XVisualInfo: visualid = " + toHexString(res.getVisualid())); } return res; } @@ -350,11 +361,17 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem int[] tmp = new int[1]; int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); if (val == 0) { - throw new GLException("Visual does not support OpenGL"); + if(DEBUG) { + System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL"); + } + return null; } val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0); if (val == 0) { - throw new GLException("Visual does not support RGBA"); + if(DEBUG) { + System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA"); + } + return null; } GLCapabilities res = new GLCapabilities(glp); res.setOnscreen (onscreen); @@ -399,13 +416,21 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem } int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset); if (res != 0) { - throw new GLException("glXGetConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res)); + throw new GLException("glXGetConfig("+toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res)); } return tmp[tmp_offset]; } + public static String toHexString(int val) { + return "0x"+Integer.toHexString(val); + } + + public static String toHexString(long val) { + return "0x"+Long.toHexString(val); + } + public String toString() { - return "X11GLXGraphicsConfiguration["+getScreen()+", visualID 0x" + Long.toHexString(getVisualID()) + ", fbConfigID 0x" + Long.toHexString(fbConfigID) + + return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) + ",\n\trequested " + getRequestedCapabilities()+ ",\n\tchosen " + getChosenCapabilities()+ "]"; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 72551f928..477f2473c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -79,9 +79,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac // GLCapabilities capsFB = null; long display = x11Screen.getDevice().getHandle(); + + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + X11Lib.XLockDisplay(display); try { - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); @@ -154,14 +155,14 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac x11Screen); if(null==res) { if(usePBuffer) { - throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig"); + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+caps2); } res = chooseGraphicsConfigurationXVisual((GLCapabilities) caps2, (GLCapabilitiesChooser) chooser, x11Screen); } if(null==res) { - throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration"); + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for "+caps2); } if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+caps2+"): "+res); @@ -172,6 +173,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { + long recommendedFBConfig = 0; int recommendedIndex = -1; GLCapabilities[] caps = null; PointerBuffer fbcfgsL = null; @@ -186,37 +188,66 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac // AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); + + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + X11Lib.XLockDisplay(display); try { - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, display, screen); int[] count = { -1 }; + // determine the recommended FBConfig .. fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit()<1) { if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]); } - return null; + } else if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: "+toHexString(fbcfgsL.get(0))); + } + } else { + recommendedFBConfig = fbcfgsL.get(0); } - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) { + + // get all, glXChooseFBConfig(.. attribs==null ..) == glXGetFBConfig(..) + fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: 0x"+Long.toHexString(fbcfgsL.get(0))); + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); } return null; } - recommendedIndex = 0; // 1st match is always recommended .. + + // make GLCapabilities and seek the recommendedIndex caps = new GLCapabilities[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { - caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); + if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid: ("+x11Screen+","+capabilities+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } else { + caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), + false, onscreen, usePBuffer, isMultisampleAvailable); + if(caps[i]!=null && recommendedFBConfig==fbcfgsL.get(i)) { + recommendedIndex=i; + if (DEBUG) { + System.err.println("!!! glXChooseFBConfig recommended "+i+", "+caps[i]); + } + } + } } if(null==chooser) { - chosen = recommendedIndex; - } else { + chosen = recommendedIndex; // may still be -1 in case nothing was recommended (-1) + } + + if (chosen < 0) { + if(null==chooser) { + // nothing recommended .. so use our default implementation + chooser = new DefaultGLCapabilitiesChooser(); + } try { chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); } catch (NativeWindowException e) { @@ -231,9 +262,20 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first"); } - chosen = 0; // default .. + // seek first available one .. + for(chosen = 0; chosen < caps.length && caps[chosen]==null; chosen++) ; + if(chosen==caps.length) { + // give up .. + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out"); + } + return null; + } } else if (chosen >= caps.length) { - throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); + if(DEBUG) { + System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ", got "+chosen+")"); + } + return null; } retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen)); @@ -276,9 +318,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); + + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + X11Lib.XLockDisplay(display); try { - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, display, screen); @@ -290,7 +333,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac if (recommendedVis == null) { System.err.println("null visual"); } else { - System.err.println("visual id 0x" + Long.toHexString(recommendedVis.getVisualid())); + System.err.println("visual id " + toHexString(recommendedVis.getVisualid())); } } int[] count = new int[1]; @@ -326,7 +369,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); } if (infos[chosen] == null) { - throw new GLException("GLCapabilitiesChooser chose an invalid visual"); + throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]); } retXVisualInfo = XVisualInfo.create(infos[chosen]); } finally { @@ -335,5 +378,14 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac } return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1); } + + public static String toHexString(int val) { + return "0x"+Integer.toHexString(val); + } + + public static String toHexString(long val) { + return "0x"+Long.toHexString(val); + } + } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java index ea855d28d..41f012122 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java @@ -75,9 +75,9 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { int screen = aScreen.getIndex(); getFactoryImpl().lockToolkit(); + X11Lib.XLockDisplay(dpy); try { - X11Lib.XLockDisplay(dpy); - pixmap = X11Lib.XCreatePixmap(dpy, (int) X11Lib.RootWindow(dpy, screen), + pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen), component.getWidth(), component.getHeight(), bitsPerPixel); if (pixmap == 0) { throw new GLException("XCreatePixmap failed"); @@ -105,10 +105,10 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { NativeWindow nw = getNativeWindow(); long display = nw.getDisplayHandle(); - try { - getFactoryImpl().lockToolkit(); - X11Lib.XLockDisplay(display); + getFactoryImpl().lockToolkit(); + X11Lib.XLockDisplay(display); + try { long drawable = nw.getSurfaceHandle(); if (DEBUG) { System.err.println("Destroying pixmap " + toHexString(pixmap) + @@ -135,11 +135,11 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { X11Lib.XFreePixmap(display, pixmap); drawable = 0; pixmap = 0; - display = 0; ((SurfaceChangeable)nw).setSurfaceHandle(0); } finally { X11Lib.XUnlockDisplay(display); getFactoryImpl().unlockToolkit(); + display = 0; } } protected void swapBuffersImpl() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java index 63b350bd3..dc6c60664 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -92,7 +92,7 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration try { long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device); if(0==displayHandle) { - displayHandle = X11Util.getThreadLocalDefaultDisplay(); + displayHandle = X11Util.createThreadLocalDefaultDisplay(); if(DEBUG) { System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display"); } diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java index 8603c7184..c5ded88f6 100644 --- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java +++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java @@ -89,11 +89,17 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { int windowSystemRecommendedChoice) { GLCapabilities _desired = (GLCapabilities) desired; GLCapabilities[] _available = (GLCapabilities[]) available; + int availnum = 0; + + for (int i = 0; i < _available.length; i++) { + if(null != _available[i]) { availnum++; } + } if (DEBUG) { System.err.println("Desired: " + _desired); + System.err.println("Available: Valid " + availnum + "/" + _available.length); for (int i = 0; i < _available.length; i++) { - System.err.println("Available " + i + ": " + _available[i]); + System.err.println(i + ": " + _available[i]); } System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice); } @@ -132,6 +138,9 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { if (_desired.isOnscreen() != cur.isOnscreen()) { continue; } + if (_desired.isPBuffer() != cur.isPBuffer()) { + continue; + } if (_desired.getStereo() != cur.getStereo()) { continue; } diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index 71cb3cb3b..80c2c10e2 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -216,6 +216,7 @@ public abstract class GLDrawableFactory { /** * Returns true if it is possible to create a GLPbuffer. Some older * graphics cards do not have this capability. + * @param passing the device for the query, may be null */ public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device); @@ -278,6 +279,7 @@ public abstract class GLDrawableFactory { /** * Returns true if it is possible to create an external GLDrawable * object via {@link #createExternalGLDrawable}. + * @param passing the device for the query, may be null */ public abstract boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device); |