diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/egl/EGLContext.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/egl/EGLContext.java | 254 |
1 files changed, 153 insertions, 101 deletions
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java index f5f9f62c4..f89ded4f6 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2011 JogAmp Community. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A @@ -29,7 +29,7 @@ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * + * * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ @@ -42,7 +42,9 @@ import java.util.Map; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; @@ -50,11 +52,12 @@ import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableImpl; import com.jogamp.common.nio.Buffers; -import com.jogamp.common.os.Platform; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; +import com.jogamp.nativewindow.egl.EGLGraphicsDevice; +import com.jogamp.opengl.GLRendererQuirks; -public abstract class EGLContext extends GLContextImpl { +public class EGLContext extends GLContextImpl { private boolean eglQueryStringInitialized; private boolean eglQueryStringAvailable; private EGLExt _eglExt; @@ -68,14 +71,15 @@ public abstract class EGLContext extends GLContextImpl { } @Override - protected void resetStates() { + protected void resetStates(boolean isInit) { eglQueryStringInitialized = false; eglQueryStringAvailable = false; eglExtProcAddressTable = null; // no inner state _eglExt = null; - super.resetStates(); + super.resetStates(isInit); } - + + @Override public Object getPlatformGLExtensions() { return getEGLExt(); } @@ -87,6 +91,7 @@ public abstract class EGLContext extends GLContextImpl { return _eglExt; } + @Override public final ProcAddressTable getPlatformExtProcAddressTable() { return eglExtProcAddressTable; } @@ -95,75 +100,80 @@ public abstract class EGLContext extends GLContextImpl { return eglExtProcAddressTable; } + @Override protected Map<String, String> getFunctionNameMap() { return null; } + @Override protected Map<String, String> getExtensionNameMap() { return null; } + @Override public final boolean isGLReadDrawableAvailable() { return true; } + @Override protected void makeCurrentImpl() throws GLException { - if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) { - throw new GLException("drawable not properly initialized, NO DISPLAY: "+drawable); - } if (EGL.eglGetCurrentContext() != contextHandle) { - if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), - drawable.getHandle(), - drawableRead.getHandle(), - contextHandle)) { - throw new GLException("Error making context 0x" + - Long.toHexString(contextHandle) + " current: error code 0x" + Integer.toHexString(EGL.eglGetError())); + final long dpy = drawable.getNativeSurface().getDisplayHandle(); + if (!EGL.eglMakeCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Error making context " + toHexString(contextHandle) + + " current on Thread " + getThreadName() + + " with display " + toHexString(dpy) + + ", drawableWrite " + toHexString(drawable.getHandle()) + + ", drawableRead "+ toHexString(drawableRead.getHandle()) + + " - Error code " + toHexString(EGL.eglGetError()) + ", " + this); } } } + @Override protected void releaseImpl() throws GLException { - if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), - EGL.EGL_NO_SURFACE, - EGL.EGL_NO_SURFACE, - EGL.EGL_NO_CONTEXT)) { - throw new GLException("Error freeing OpenGL context 0x" + - Long.toHexString(contextHandle) + ": error code 0x" + Integer.toHexString(EGL.eglGetError())); + if (!EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_NO_SURFACE, EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT)) { + throw new GLException("Error freeing OpenGL context " + toHexString(contextHandle) + + ": error code " + toHexString(EGL.eglGetError())); } } + @Override protected void destroyImpl() throws GLException { - if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), contextHandle)) { - final int eglError = EGL.eglGetError(); - if(EGL.EGL_SUCCESS != eglError) { /* oops, Mesa EGL impl. may return false, but has no EGL error */ - throw new GLException("Error destroying OpenGL context 0x" + - Long.toHexString(contextHandle) + ": error code 0x" + Integer.toHexString(eglError)); - } - } + destroyContextARBImpl(contextHandle); } + @Override protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { return 0; // FIXME } + @Override protected void destroyContextARBImpl(long _context) { - // FIXME + if (!EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), _context)) { + final int eglError = EGL.eglGetError(); + if(EGL.EGL_SUCCESS != eglError) { /* oops, Mesa EGL impl. may return false, but has no EGL error */ + throw new GLException("Error destroying OpenGL context " + toHexString(_context) + + ": error code " + toHexString(eglError)); + } + } } - protected boolean createImpl(GLContextImpl shareWith) throws GLException { - long eglDisplay = ((EGLDrawable)drawable).getDisplay(); - EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration(); - GLProfile glProfile = drawable.getGLProfile(); - long eglConfig = config.getNativeConfig(); - long shareWithHandle = EGL.EGL_NO_CONTEXT; - - if (eglDisplay == 0) { + @Override + protected boolean createImpl(final long shareWithHandle) throws GLException { + final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration(); + final long eglDisplay = config.getScreen().getDevice().getHandle(); + final GLProfile glProfile = drawable.getGLProfile(); + final long eglConfig = config.getNativeConfig(); + // 0 == EGL.EGL_NO_CONTEXT; + + if ( 0 == eglDisplay ) { throw new GLException("Error: attempted to create an OpenGL context without a display connection"); } - if (eglConfig == 0) { + if ( 0 == eglConfig ) { throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration"); } try { // might be unavailable on EGL < 1.2 - if(!EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API)) { - throw new GLException("Catched: eglBindAPI to ES failed , error 0x"+Integer.toHexString(EGL.eglGetError())); + if( !EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API) ) { + throw new GLException("Catched: eglBindAPI to ES failed , error "+toHexString(EGL.eglGetError())); } } catch (GLException glex) { if (DEBUG) { @@ -171,26 +181,29 @@ public abstract class EGLContext extends GLContextImpl { } } - if (shareWith != null) { - shareWithHandle = shareWith.getHandle(); - if (shareWithHandle == 0) { - throw new GLException("GLContextShareSet returned an invalid OpenGL context"); - } - } + // Cannot check extension 'EGL_KHR_create_context' before having one current! - final IntBuffer contextAttrsNIO; + final IntBuffer contextAttrsNIO; + final int contextVersionReq, contextVersionAttr; { - final int[] contextAttrs = new int[] { - EGL.EGL_CONTEXT_CLIENT_VERSION, -1, - EGL.EGL_NONE - }; - if (glProfile.usesNativeGLES2()) { - contextAttrs[1] = 2; - } else if (glProfile.usesNativeGLES1()) { - contextAttrs[1] = 1; + if ( glProfile.usesNativeGLES3() ) { + contextVersionReq = 3; + if( GLRendererQuirks.existStickyDeviceQuirk( GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config) ) { + contextVersionAttr = 2; + } else { + contextVersionAttr = 3; + } + } else if ( glProfile.usesNativeGLES2() ) { + contextVersionReq = 2; + contextVersionAttr = 2; + } else if ( glProfile.usesNativeGLES1() ) { + contextVersionReq = 1; + contextVersionAttr = 1; } else { throw new GLException("Error creating OpenGL context - invalid GLProfile: "+glProfile); } + // EGLExt.EGL_CONTEXT_MAJOR_VERSION_KHR == EGL.EGL_CONTEXT_CLIENT_VERSION + final int[] contextAttrs = new int[] { EGL.EGL_CONTEXT_CLIENT_VERSION, contextVersionAttr, EGL.EGL_NONE }; contextAttrsNIO = Buffers.newDirectIntBuffer(contextAttrs); } contextHandle = EGL.eglCreateContext(eglDisplay, eglConfig, shareWithHandle, contextAttrsNIO); @@ -200,31 +213,32 @@ public abstract class EGLContext extends GLContextImpl { } if (DEBUG) { System.err.println(getThreadName() + ": Created OpenGL context 0x" + - Long.toHexString(contextHandle) + + Long.toHexString(contextHandle) + ",\n\twrite surface 0x" + Long.toHexString(drawable.getHandle()) + ",\n\tread surface 0x" + Long.toHexString(drawableRead.getHandle())+ ",\n\t"+this+ ",\n\tsharing with 0x" + Long.toHexString(shareWithHandle)); } - if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), - drawable.getHandle(), - drawableRead.getHandle(), - contextHandle)) { - throw new GLException("Error making context 0x" + - Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError()); + if (!EGL.eglMakeCurrent(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Error making context " + + toHexString(contextHandle) + " current: error code " + toHexString(EGL.eglGetError())); } - int ctp = CTX_PROFILE_ES; - int major; - if(glProfile.usesNativeGLES2()) { - ctp |= CTX_IMPL_ES2_COMPAT; - major = 2; - } else { - major = 1; + if( !setGLFunctionAvailability(true, contextVersionReq, 0, CTX_PROFILE_ES, + true /* strictMatch */, // always req. strict match + false /* withinGLVersionsMapping */) ) { + if(DEBUG) { + System.err.println(getThreadName() + ": createImpl: setGLFunctionAvailability FAILED delete "+toHexString(contextHandle)); + } + EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_NO_SURFACE, EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT); + EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle); + contextHandle = 0; + return false; + } else { + return true; } - setGLFunctionAvailability(true, major, 0, ctp); - return true; } + @Override protected final void updateGLXProcAddressTable() { final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration(); final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); @@ -255,17 +269,16 @@ public abstract class EGLContext extends GLContextImpl { } } } - + + @Override protected final StringBuilder getPlatformExtensionsStringImpl() { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(); if (!eglQueryStringInitialized) { - eglQueryStringAvailable = - getDrawableImpl().getGLDynamicLookupHelper().dynamicLookupFunction("eglQueryString") != 0; + eglQueryStringAvailable = getDrawableImpl().getGLDynamicLookupHelper().isFunctionAvailable("eglQueryString"); eglQueryStringInitialized = true; } if (eglQueryStringAvailable) { - final String ret = EGL.eglQueryString(((EGLDrawable)drawable).getDisplay(), - EGL.EGL_EXTENSIONS); + final String ret = EGL.eglQueryString(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_EXTENSIONS); if (DEBUG) { System.err.println("EGL extensions: " + ret); } @@ -276,22 +289,63 @@ public abstract class EGLContext extends GLContextImpl { @Override protected boolean setSwapIntervalImpl(int interval) { - // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // eglSwapInterval(..) issued: - // Android 4.0.3 / Pandaboard ES / PowerVR SGX 540: crashes - // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if( Platform.OSType.ANDROID == Platform.getOSType() && getGLRendererString(true).contains("powervr") ) { - if(DEBUG) { - System.err.println("Ignored: eglSwapInterval("+interval+") - cause: OS "+Platform.getOSType() + " / Renderer " + getGLRendererString(false)); - } + if( hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) { return false; } - return EGL.eglSwapInterval(((EGLDrawable)drawable).getDisplay(), interval); + return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval); } - public abstract void bindPbufferToTexture(); + // + // Accessible .. + // - public abstract void releasePbufferFromTexture(); + /* pp */ void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) { + mapStaticGLVersion(device, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + } + /* pp */ int getContextOptions() { return ctxOptions; } + /* pp */ static void mapStaticGLESVersion(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps) { + final GLProfile glp = caps.getGLProfile(); + final int[] reqMajorCTP = new int[2]; + GLContext.getRequestMajorAndCompat(glp, reqMajorCTP); + if( glp.isGLES() ) { + if( reqMajorCTP[0] >= 3 ) { + reqMajorCTP[1] |= GLContext.CTX_IMPL_ES3_COMPAT | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ; + } else if( reqMajorCTP[0] >= 2 ) { + reqMajorCTP[1] |= GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ; + } + } + if( !caps.getHardwareAccelerated() ) { + reqMajorCTP[1] |= GLContext.CTX_IMPL_ACCEL_SOFT; + } + mapStaticGLVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]); + } + /* pp */ static void mapStaticGLVersion(AbstractGraphicsDevice device, int major, int minor, int ctp) { + if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) { + // ES1, ES2, ES3, .. + mapStaticGLVersion(device, major /* reqMajor */, major, minor, ctp); + if( 3 == major ) { + // map ES2 -> ES3 + mapStaticGLVersion(device, 2 /* reqMajor */, major, minor, ctp); + } + } + } + private static void mapStaticGLVersion(AbstractGraphicsDevice device, int reqMajor, int major, int minor, 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); + GLContext.mapAvailableGLVersion(eglDevice, reqMajor, GLContext.CTX_PROFILE_ES, major, minor, ctp); + } + } + protected static String getGLVersion(int major, int minor, int ctp, String gl_version) { + return GLContext.getGLVersion(major, minor, ctp, gl_version); + } + + protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) { + return GLContext.getAvailableGLVersionsSet(device); + } + protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) { + GLContext.setAvailableGLVersionsSet(device); + } protected static String toHexString(int hex) { return GLContext.toHexString(hex); @@ -299,25 +353,23 @@ public abstract class EGLContext extends GLContextImpl { protected static String toHexString(long hex) { return GLContext.toHexString(hex); } - + //---------------------------------------------------------------------- // Currently unimplemented stuff // + @Override protected void copyImpl(GLContext source, int mask) throws GLException { throw new GLException("Not yet implemented"); } - - public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { - throw new GLException("Should not call this"); - } - - public boolean offscreenImageNeedsVerticalFlip() { + @Override + public final ByteBuffer glAllocateMemoryNV(int size, float readFrequency, float writeFrequency, float priority) { throw new GLException("Should not call this"); } - public int getOffscreenContextPixelDataType() { + @Override + public final void glFreeMemoryNV(ByteBuffer pointer) { throw new GLException("Should not call this"); } } |