diff options
author | Sven Gothel <[email protected]> | 2014-12-07 04:03:02 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-12-07 04:03:02 +0100 |
commit | 35622a7cef4a28ce7e32bf008ef331d9a0d9e3e2 (patch) | |
tree | e688b4fcb141c0b6b026d20379fb0ba6dd60a256 /src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java | |
parent | 9ea218a5990b908e04235c407c0951c60df6ffba (diff) |
Bug 1068 - Allow GLContext creation and makeCurrent without default framebuffer (Part 2); Bug 896: EGL_KHR_create_context (Part 1)
Bug 1068 - Allow GLContext creation and makeCurrent without default framebuffer (Part 2)
Implement surfaceless context on EGL and GLX/X11
utilizing *UpstreamSurfacelessHook as introduced in
commit 9ea218a5990b908e04235c407c0951c60df6ffba.
Surfaceless context is probed during GL profile probing by default.
If available, it will be used for offscreen FBO drawables.
If probing fails, or is disabled,
the new GLRendererQuirks.NoSurfacelessCtx is set.
- GLProfile.disableSurfacelessContext disables
surfaceless context probing, set property 'jogl.disable.surfacelesscontext'
Tested:
- Mesa/EGL works,
- Mesa + NVidia w/ GLX fail on GNU/Linux): Fails NoSurfacelessCtx
- TODO: Windows impl. and more tests
+++
Bug 896: EGL_KHR_create_context (Part 1)
- Detect EGL_KHR_create_context capability and utilize if available.
- Implement EGLContext.createContextARBImpl(..),
allowing native DEBUG context usage, where available.
- EGL implements SharedResourceRunner, i.e. probing profiles
on dedicated thread using common interface.
- Probe desktop profile/context ability
in EGLDrawableFactory SharedResourceRunner,
Where EGLGLnDynamicLibraryBundleInfo covers EGL + desktop GL.
- TODO: Tests w/ capable implementation
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java | 118 |
1 files changed, 80 insertions, 38 deletions
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java index 8f614a326..b3cea1e34 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java @@ -64,6 +64,7 @@ import jogamp.nativewindow.WrappedSurface; import jogamp.nativewindow.x11.X11DummyUpstreamSurfaceHook; import jogamp.nativewindow.x11.X11Lib; import jogamp.nativewindow.x11.X11Util; +import jogamp.nativewindow.x11.X11UpstreamSurfacelessHook; import jogamp.opengl.DesktopGLDynamicLookupHelper; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableFactoryImpl; @@ -184,7 +185,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { SharedResource(final X11GraphicsDevice dev, final X11GraphicsScreen scrn, final GLDrawableImpl draw, final GLContextImpl ctx, - final VersionNumber glXServerVer, final String glXServerVendor, final boolean glXServerMultisampleAvail) { + final VersionNumber glXServerVer, final String glXServerVendor, + final boolean glXServerMultisampleAvail) { device = dev; screen = scrn; drawable = draw; @@ -198,7 +200,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { glXMultisampleAvailable = glXServerMultisampleAvail; } @Override - public final boolean isValid() { + public final boolean isAvailable() { return null != context; } @Override @@ -210,7 +212,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { @Override final public GLContextImpl getContext() { return context; } @Override - public GLRendererQuirks getRendererQuirks() { + public GLRendererQuirks getRendererQuirks(final GLProfile glp) { return null != context ? context.getRendererQuirks() : null; } @@ -229,12 +231,12 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { sharedMap.clear(); } @Override - public SharedResourceRunner.Resource mapPut(final String connection, final SharedResourceRunner.Resource resource) { - return sharedMap.put(connection, resource); + public SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) { + return sharedMap.put(device.getConnection(), resource); } @Override - public SharedResourceRunner.Resource mapGet(final String connection) { - return sharedMap.get(connection); + public SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) { + return sharedMap.get(device.getConnection()); } @Override public Collection<SharedResourceRunner.Resource> mapValues() { @@ -242,9 +244,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } @Override - public boolean isDeviceSupported(final String connection) { + public boolean isDeviceSupported(final AbstractGraphicsDevice device) { final boolean res; - final X11GraphicsDevice x11Device = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */); + final X11GraphicsDevice x11Device = new X11GraphicsDevice(X11Util.openDisplay(device.getConnection()), device.getUnitID(), true /* owner */); x11Device.lock(); try { res = GLXUtil.isGLXAvailableOnServer(x11Device); @@ -259,51 +261,88 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } @Override - public SharedResourceRunner.Resource createSharedResource(final String connection) { - final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */); - sharedDevice.lock(); + public SharedResourceRunner.Resource createSharedResource(final AbstractGraphicsDevice adevice) { + final X11GraphicsDevice x11Device = new X11GraphicsDevice(X11Util.openDisplay(adevice.getConnection()), adevice.getUnitID(), true /* owner */); + GLContextImpl context = null; + boolean contextIsCurrent = false; + x11Device.lock(); try { - final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, sharedDevice.getDefaultScreen()); + final X11GraphicsScreen screen = new X11GraphicsScreen(x11Device, x11Device.getDefaultScreen()); - GLXUtil.initGLXClientDataSingleton(sharedDevice); - final String glXServerVendorName = GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_VENDOR); - final boolean glXServerMultisampleAvailable = GLXUtil.isMultisampleAvailable(GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_EXTENSIONS)); + GLXUtil.initGLXClientDataSingleton(x11Device); + final String glXServerVendorName = GLX.glXQueryServerString(x11Device.getHandle(), 0, GLX.GLX_VENDOR); + final boolean glXServerMultisampleAvailable = GLXUtil.isMultisampleAvailable(GLX.glXQueryServerString(x11Device.getHandle(), 0, GLX.GLX_EXTENSIONS)); - final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false); + final GLProfile glp = GLProfile.get(x11Device, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false); if (null == glp) { - throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); + throw new GLException("Couldn't get default GLProfile for device: "+x11Device); } final GLCapabilitiesImmutable caps = new GLCapabilities(glp); - final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64)); - sharedDrawable.setRealized(true); - final X11GLCapabilities chosenCaps = (X11GLCapabilities) sharedDrawable.getChosenGLCapabilities(); + final GLDrawableImpl drawable = createOnscreenDrawableImpl(createDummySurfaceImpl(x11Device, false, caps, caps, null, 64, 64)); + drawable.setRealized(true); + final X11GLCapabilities chosenCaps = (X11GLCapabilities) drawable.getChosenGLCapabilities(); final boolean glxForcedOneOne = !chosenCaps.hasFBConfig(); final VersionNumber glXServerVersion; if( glxForcedOneOne ) { glXServerVersion = versionOneOne; } else { - glXServerVersion = GLXUtil.getGLXServerVersionNumber(sharedDevice); + glXServerVersion = GLXUtil.getGLXServerVersionNumber(x11Device); } - final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null); - if (null == sharedContext) { - throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable); + context = (GLContextImpl) drawable.createContext(null); + if (null == context) { + throw new GLException("Couldn't create shared context for drawable: "+drawable); } + contextIsCurrent = GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent(); + + final boolean noSurfacelessCtxQuirk = context.hasRendererQuirk(GLRendererQuirks.NoSurfacelessCtx); + boolean allowsSurfacelessCtx = false; - boolean madeCurrent = false; - sharedContext.makeCurrent(); - try { - madeCurrent = sharedContext.isCurrent(); - } finally { - sharedContext.release(); + if( contextIsCurrent && + context.getGLVersionNumber().compareTo(GLContext.Version3_0) >= 0 && + !noSurfacelessCtxQuirk ) + { + GLDrawableImpl zeroDrawable = null; + try { + final ProxySurface zeroSurface = createSurfacelessImpl(x11Device, true, caps, caps, null, 64, 64); + zeroDrawable = createOnscreenDrawableImpl(zeroSurface); + zeroDrawable.setRealized(true); + + // Since sharedContext is still current, + // will keep sharedContext current w/ zeroDrawable or throws GLException + context.setGLDrawable(zeroDrawable, false); + allowsSurfacelessCtx = true; // if setGLDrawable is successful, i.e. no GLException + + // switch back + context.setGLDrawable(drawable, false); + } catch (final Throwable t) { + if( DEBUG ) { + ExceptionUtils.dumpThrowable("", t); + } + } finally { + if( null != zeroDrawable ) { + zeroDrawable.setRealized(false); + } + } } - if( sharedContext.hasRendererQuirk( GLRendererQuirks.DontCloseX11Display ) ) { + if( context.hasRendererQuirk( GLRendererQuirks.DontCloseX11Display ) ) { X11Util.markAllDisplaysUnclosable(); } + if( !noSurfacelessCtxQuirk && !allowsSurfacelessCtx ) { + final int quirk = GLRendererQuirks.NoSurfacelessCtx; + if(DEBUG) { + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+" -> "+x11Device+": cause: probe"); + } + final GLRendererQuirks glrq = context.getRendererQuirks(); + if( null != glrq ) { + glrq.addQuirk(quirk); + } + GLRendererQuirks.addStickyDeviceQuirk(x11Device, quirk); + } if (DEBUG) { - System.err.println("SharedDevice: " + sharedDevice); - System.err.println("SharedScreen: " + sharedScreen); - System.err.println("SharedContext: " + sharedContext + ", madeCurrent " + madeCurrent); + System.err.println("SharedDevice: " + x11Device); + System.err.println("SharedScreen: " + screen); + System.err.println("SharedContext: " + context + ", madeCurrent " + contextIsCurrent); System.err.println("GLX Server Vendor: " + glXServerVendorName); System.err.println("GLX Server Version: " + glXServerVersion + ", forced "+glxForcedOneOne); System.err.println("GLX Server Multisample: " + glXServerMultisampleAvailable); @@ -311,13 +350,16 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { System.err.println("GLX Client Version: " + GLXUtil.getClientVersionNumber()); System.err.println("GLX Client Multisample: " + GLXUtil.isClientMultisampleAvailable()); } - return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, + return new SharedResource(x11Device, screen, drawable, context, glXServerVersion, glXServerVendorName, glXServerMultisampleAvailable && GLXUtil.isClientMultisampleAvailable()); } catch (final Throwable t) { - throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources for "+connection, t); + throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources for "+adevice, t); } finally { - sharedDevice.unlock(); + if ( contextIsCurrent ) { + context.release(); + } + x11Device.unlock(); } } |