diff options
author | Sven Gothel <[email protected]> | 2012-10-02 07:28:00 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-10-02 07:28:00 +0200 |
commit | 7c333e3e2574879465719ed968112b27255368d4 (patch) | |
tree | f9c81117469fe10d23c106bb46151a3451169e3f /src/jogl/classes/jogamp/opengl/x11 | |
parent | 0790108ca9c2a6a6d494e5017589fe083c518e23 (diff) |
Relax Bug 613 workaround of commit 92398025abdabb2fdef0d78edd41e730991a6f94
Utilizing a GlobalToolkitLock in general to lock the display connection results in deadlock
situations where locked surfaces signal other [offscreen] surfaces to render.
We have to see whether we find a better solution, for now sporadic XCB assertion still happen.
But it is preferrable to point to the root cause, then to jumping through hoops to complicate locking
or even to deadlock.
Locking:
- X11GLXGraphicsConfigurationFactory add missing device locking in:
- getAvailableCapabilities
- chooseGraphicsConfigurationStatic
- Newt/X11Window: Discard display events after window close.
Relax ATI XCB/threading bug workaround:
- ToolkitProperties: requiresGlobalToolkitLock() -> hasThreadingIssues()
- NativeWindowFactory: Don't use GlobalToolkitLock in case of 'threadingIssues' the impact is too severe (see above)
- NativeWindowFactory: Add getGlobalToolkitLockIfRequired(): To be used for small code blocks.
If having 'threadingIssues' a GlobalToolkitLock is returned, otherwise NullToolkitLock.
- X11GLXContext: [create/destroy]ContextARBImpl: Use 'NativeWindowFactory.getGlobalToolkitLockIfRequired()' for extra locking
Misc Cleanup:
- *DrawableFactory createMutableSurface: Also create new device if type is not suitable
- *DrawableFactory createDummySurfaceImpl: Pass chosenCaps and use it (preserves orig. requested user caps)
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/x11')
3 files changed, 55 insertions, 32 deletions
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java index 72ddd2693..f7389d42e 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -48,6 +48,8 @@ import java.util.Map; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.ToolkitLock; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; @@ -180,11 +182,16 @@ public abstract class X11GLXContext extends GLContextImpl { @Override protected void destroyContextARBImpl(long ctx) { - X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration(); - long display = config.getScreen().getDevice().getHandle(); - - glXMakeContextCurrent(display, 0, 0, 0); - GLX.glXDestroyContext(display, ctx); + final ToolkitLock tkLock = NativeWindowFactory.getGlobalToolkitLockIfRequired(); + tkLock.lock(); + try { + long display = drawable.getNativeSurface().getDisplayHandle(); + + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, ctx); + } finally { + tkLock.unlock(); + } } private static final int ctx_arb_attribs_idx_major = 0; private static final int ctx_arb_attribs_idx_minor = 2; @@ -243,6 +250,8 @@ public abstract class X11GLXContext extends GLContextImpl { AbstractGraphicsDevice device = config.getScreen().getDevice(); final long display = device.getHandle(); + final ToolkitLock tkLock = NativeWindowFactory.getGlobalToolkitLockIfRequired(); + tkLock.lock(); try { // critical path, a remote display might not support this command, // hence we need to catch the X11 Error within this block. @@ -253,7 +262,10 @@ public abstract class X11GLXContext extends GLContextImpl { Throwable t = new Throwable(getThreadName()+": Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); t.printStackTrace(); } + } finally { + tkLock.unlock(); } + if(0!=ctx) { if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), ctx)) { if(DEBUG) { @@ -420,7 +432,7 @@ public abstract class X11GLXContext extends GLContextImpl { @Override protected void destroyImpl() throws GLException { - GLX.glXDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle); + destroyContextARBImpl(contextHandle); } @Override diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java index 018f6a6ea..e38aabef8 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java @@ -229,7 +229,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { @Override public SharedResourceRunner.Resource createSharedResource(String connection) { - final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true); + final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */); sharedDevice.lock(); try { final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, sharedDevice.getDefaultScreen()); @@ -246,8 +246,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } - - final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64)); + + final GLCapabilitiesImmutable caps = new GLCapabilities(glp); + final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64)); sharedDrawable.setRealized(true); final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null); @@ -499,11 +500,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { final X11GraphicsDevice device; - if(createNewDevice) { - // Null X11 resource locking, due to private non-shared Display handle - device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true); + if( createNewDevice || !(deviceReq instanceof X11GraphicsDevice) ) { + device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true /* owner */); } else { - device = (X11GraphicsDevice)deviceReq; + device = (X11GraphicsDevice) deviceReq; } final X11GraphicsScreen screen = new X11GraphicsScreen(device, device.getDefaultScreen()); final X11GLXGraphicsConfiguration config = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED); @@ -512,17 +512,17 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } return new WrappedSurface(config, 0, upstreamHook, createNewDevice); } - + @Override public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, - GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { - final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps); + GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new X11DummyUpstreamSurfaceHook(width, height)); } @Override protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) { - final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true); + final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true /* owner */); final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx); final int xvisualID = X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle); if(VisualIDHolder.VID_UNDEFINED == xvisualID) { diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java index ef2d3283d..8ac324205 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -127,16 +127,22 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF throw new GLException("Shared resource for device n/a: "+device); } final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen(); - final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(sharedScreen.getDevice()); + final X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice(); + final boolean isMultisampleAvailable = sharedResource.isGLXMultisampleAvailable(); final GLProfile glp = GLProfile.getDefault(device); List<GLCapabilitiesImmutable> availableCaps = null; - - if( sharedResource.isGLXVersionGreaterEqualOneThree() ) { - availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable); - } - if( null == availableCaps || availableCaps.isEmpty() ) { - availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable); + + sharedDevice.lock(); + try { + if( sharedResource.isGLXVersionGreaterEqualOneThree() ) { + availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable); + } + if( null == availableCaps || availableCaps.isEmpty() ) { + availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable); + } + } finally { + sharedDevice.unlock(); } if( null != availableCaps && availableCaps.size() > 1 ) { Collections.sort(availableCaps, XVisualIDComparator); @@ -215,16 +221,21 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory, x11Device); final boolean usePBuffer = !capsChosen.isOnscreen() && capsChosen.isPBuffer(); - + X11GLXGraphicsConfiguration res = null; - if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) { - res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID); - } - if(null==res) { - if(usePBuffer) { - throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen); + x11Device.lock(); + try { + if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) { + res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID); + } + if(null==res) { + if(usePBuffer) { + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen); + } + res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID); } - res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID); + } finally { + x11Device.unlock(); } if(null==res) { throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for visualID "+toHexString(xvisualID)+", "+x11Screen+", "+capsChosen); |