diff options
author | Sven Gothel <[email protected]> | 2015-01-23 15:13:10 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-01-23 15:13:10 +0100 |
commit | 38baef0371fc55405779590d503f6e0de10fa9cc (patch) | |
tree | 582a1325b9da2502db3426321f4b602d60d587de | |
parent | ec138f2f5c38a677d840e8719292031d91befaa8 (diff) |
Bug 896: Refine criteria to allow OpenGL API usage for EGL
It has been experienced w/ Mesa 10.3.2 (EGL 1.4/Gallium)
that even though initial OpenGL context can be created w/o 'EGL_KHR_create_context',
switching the API via 'eglBindAPI(EGL_OpenGL_API)' the latter 'eglCreateContext(..)' fails w/ EGL_BAD_ACCESS.
Hence we require both: OpenGL API support _and_ 'EGL_KHR_create_context'.
FIXME: Evaluate this issue in more detail!
FIXME: Utilization of eglBindAPI(..) must be re-evaluated in case we mix ES w/ OpenGL, see EGL 1.4 spec.
This is due to new semantics, i.e. API is bound on a per thread base,
hence it must be switched before makeCurrent w/ different APIs, see:
eglWaitClient();
3 files changed, 50 insertions, 26 deletions
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java index f7f477aac..fe01fbc8c 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java @@ -170,7 +170,9 @@ public class EGLContext extends GLContextImpl { final long eglConfig = config.getNativeConfig(); final EGLDrawableFactory factory = (EGLDrawableFactory) drawable.getFactoryImpl(); - final boolean useKHRCreateContext = !GLProfile.disableOpenGLARBContext && factory.hasDefaultDeviceKHRCreateContext(); + final boolean hasOpenGLAPISupport = factory.hasOpenGLAPISupport(); + final boolean useKHRCreateContext = factory.hasDefaultDeviceKHRCreateContext(); + final boolean allowOpenGLAPI = hasOpenGLAPISupport && useKHRCreateContext; final boolean ctDesktopGL = 0 == ( GLContext.CTX_PROFILE_ES & ctp ); final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ; @@ -178,7 +180,9 @@ public class EGLContext extends GLContextImpl { if(DEBUG) { System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: Start "+getGLVersion(reqMajor, reqMinor, ctp, "@creation") + + ", hasOpenGLAPISupport "+hasOpenGLAPISupport + ", useKHRCreateContext "+useKHRCreateContext + + ", allowOpenGLAPI "+allowOpenGLAPI + ", device "+device); } if ( 0 == eglDisplay ) { @@ -188,14 +192,31 @@ public class EGLContext extends GLContextImpl { throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration"); } - if( !useKHRCreateContext && ctDesktopGL ) { + /** + * It has been experienced w/ Mesa 10.3.2 (EGL 1.4/Gallium) + * that even though initial OpenGL context can be created w/o 'EGL_KHR_create_context', + * switching the API via 'eglBindAPI(EGL_OpenGL_API)' the latter 'eglCreateContext(..)' fails w/ EGL_BAD_ACCESS. + * Hence we require both: OpenGL API support _and_ 'EGL_KHR_create_context'. + * + * FIXME: Evaluate this issue in more detail! + * + * FIXME: Utilization of eglBindAPI(..) must be re-evaluated in case we mix ES w/ OpenGL, see EGL 1.4 spec. + * This is due to new semantics, i.e. API is bound on a per thread base, + * hence it must be switched before makeCurrent w/ different APIs, see: + * eglWaitClient(); + */ + if( ctDesktopGL && !allowOpenGLAPI ) { + // if( ctDesktopGL && !hasOpenGLAPISupport ) { if(DEBUG) { System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: DesktopGL not avail "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")); } return 0; // n/a } + try { - // might be unavailable on EGL < 1.2 + if( allowOpenGLAPI && device.getEGLVersion().compareTo(Version1_2) >= 0 ) { + EGL.eglWaitClient(); // EGL >= 1.2 + } if( !EGL.eglBindAPI( ctDesktopGL ? EGL.EGL_OPENGL_API : EGL.EGL_OPENGL_ES_API) ) { throw new GLException("Caught: eglBindAPI to "+(ctDesktopGL ? "ES" : "GL")+" failed , error "+toHexString(EGL.eglGetError())+" - "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")); } @@ -425,8 +446,8 @@ public class EGLContext extends GLContextImpl { // Accessible .. // - /* pp */ void mapCurrentAvailableGLVersion(final AbstractGraphicsDevice device) { - mapStaticGLVersion(device, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + /* pp */ void mapCurrentAvailableGLESVersion(final AbstractGraphicsDevice device) { + mapStaticGLESVersion(device, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); } /* pp */ int getContextOptions() { return ctxOptions; } /* pp */ static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final GLCapabilitiesImmutable caps) { @@ -443,19 +464,19 @@ public class EGLContext extends GLContextImpl { if( !caps.getHardwareAccelerated() ) { reqMajorCTP[1] |= GLContext.CTX_IMPL_ACCEL_SOFT; } - mapStaticGLVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]); + mapStaticGLESVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]); } - /* pp */ static void mapStaticGLVersion(final AbstractGraphicsDevice device, final int major, final int minor, final int ctp) { + /* pp */ static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final int major, final int minor, final int ctp) { if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) { // ES1, ES2, ES3, .. - mapStaticGLVersion(device, major /* reqMajor */, major, minor, ctp); + mapStaticGLESVersion(device, major /* reqMajor */, major, minor, ctp); if( 3 == major ) { // map ES2 -> ES3 - mapStaticGLVersion(device, 2 /* reqMajor */, major, minor, ctp); + mapStaticGLESVersion(device, 2 /* reqMajor */, major, minor, ctp); } } } - private static void mapStaticGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int major, final int minor, final int ctp) { + private static void mapStaticGLESVersion(final AbstractGraphicsDevice device, final int reqMajor, final int major, final int minor, final int ctp) { GLContext.mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_ES, major, minor, ctp); if(! ( device instanceof EGLGraphicsDevice ) ) { final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(device.getHandle(), EGL.EGL_NO_DISPLAY, device.getConnection(), device.getUnitID(), null); diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java index 55f6248c8..68f5b57ee 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -134,15 +134,17 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { final boolean hasEGL_1_4 = version.compareTo(GLContext.Version1_4) >= 0; final boolean hasEGL_1_5 = version.compareTo(GLContext.Version1_5) >= 0; { - final String eglClientAPIStr = EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS); - final String[] eglClientAPIs = eglClientAPIStr.split("\\s"); boolean _hasGLAPI = false; - for(int i=eglClientAPIs.length-1; i>=0; i--) { - _hasGLAPI = eglClientAPIs[i].equals("OpenGL"); + final String eglClientAPIStr = EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS); + if( hasEGL_1_4 ) { + final String[] eglClientAPIs = eglClientAPIStr.split("\\s"); + for(int i=eglClientAPIs.length-1; i>=0; i--) { + _hasGLAPI = eglClientAPIs[i].equals("OpenGL"); + } } hasGLAPI = _hasGLAPI; if(DEBUG) { - System.err.println(" Client APIs: "+eglClientAPIStr+"; has OpenGL "+hasGLAPI); + System.err.println(" Client APIs: "+eglClientAPIStr+"; has EGL 1.4 "+hasEGL_1_4+" -> has OpenGL "+hasGLAPI); } } { @@ -153,6 +155,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { hasKHRSurfaceless = true; } else { if( hasEGL_1_4 ) { + // requires EGL 1.4 hasKHRCreateContext = extensions.contains("EGL_KHR_create_context"); } else { hasKHRCreateContext = false; @@ -532,7 +535,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { boolean madeCurrentGLn = false; if( null != eglGLnDynamicLookupHelper ) { - // OpenGL 3.1 core -> GL3 + // OpenGL 3.1 core -> GL3, will utilize normal desktop profile mapping final int[] major = { 3 }; final int[] minor = { 1 }; // FIXME: No minor version probing for ES currently! madeCurrentGLn = mapAvailableEGLESConfig(adevice, major, minor, @@ -540,6 +543,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } else { madeCurrentGLn = false; } + EGLContext.setAvailableGLVersionsSet(adevice, true); + if( null != eglES1DynamicLookupHelper ) { final int[] major = { 1 }; final int[] minor = { 0 }; @@ -569,11 +574,6 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } } - if( !EGLContext.getAvailableGLVersionsSet(adevice) ) { - // Even though we override the non EGL native mapping intentionally, - // avoid exception due to double 'set' - careful exception of the rule. - EGLContext.setAvailableGLVersionsSet(adevice, true); - } if( hasX11 ) { handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]); handleDontCloseX11DisplayQuirk(rendererQuirksES3ES2[0]); @@ -727,9 +727,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { // context.isCurrent() ! final String glVersionString = context.getGL().glGetString(GL.GL_VERSION); if(null != glVersionString) { - context.mapCurrentAvailableGLVersion(eglDevice); + context.mapCurrentAvailableGLESVersion(eglDevice); if(eglDevice != adevice) { - context.mapCurrentAvailableGLVersion(adevice); + context.mapCurrentAvailableGLESVersion(adevice); } if( eglFeatures.hasKHRSurfaceless && @@ -834,6 +834,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { public final boolean hasDefaultDeviceKHRCreateContext() { return defaultDeviceEGLFeatures.hasKHRCreateContext; } + public final boolean hasOpenGLAPISupport() { + return defaultDeviceEGLFeatures.hasGLAPI; + } @Override public final AbstractGraphicsDevice getDefaultDevice() { diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java index 92e13dc61..1af7ffaa0 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java @@ -51,7 +51,7 @@ import com.jogamp.opengl.egl.EGL; * </pre> */ public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize { - protected static final boolean DEBUG = EGLDrawableFactory.DEBUG; + private static final boolean DEBUG = EGLDrawableFactory.DEBUG; private final NativeSurface upstreamSurface; private final UpstreamSurfaceHook.MutableSize upstreamSurfaceHookMutableSize; @@ -231,8 +231,8 @@ public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize { @Override public final void destroy(final ProxySurface surface) { - if(EGLDrawableFactory.DEBUG) { - System.err.println("EGLUpstreamSurfaceHook.destroy("+surface.getClass().getSimpleName()+"): "+this); + if(DEBUG) { + System.err.println(getThreadName() + ": EGLUpstreamSurfaceHook.destroy("+surface.getClass().getSimpleName()+"): "+this); } surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ); if(upstreamSurface instanceof ProxySurface) { |