diff options
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/GLContext.java | 43 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/GLContextImpl.java | 291 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/egl/EGLContext.java | 13 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java | 51 |
4 files changed, 274 insertions, 124 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/GLContext.java b/src/jogl/classes/com/jogamp/opengl/GLContext.java index 419c4f55d..258363e2e 100644 --- a/src/jogl/classes/com/jogamp/opengl/GLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/GLContext.java @@ -1603,6 +1603,12 @@ public abstract class GLContext { ( ( b8 & 0x000000FF ) << 16 ) | ( ( c16 & 0x0000FFFF ) ) ; } + protected static VersionNumber decomposeBits(final int bits32, final int[] ctp) { + final int major = ( bits32 & 0xFF000000 ) >>> 24 ; + final int minor = ( bits32 & 0x00FF0000 ) >>> 16 ; + ctp[0] = ( bits32 & 0x0000FFFF ) ; + return new VersionNumber(major, minor, 0); + } private static void validateProfileBits(final int bits, final String argName) { int num = 0; @@ -1666,16 +1672,7 @@ public abstract class GLContext { } /** - * Called by {@link jogamp.opengl.GLContextImpl#createContextARBMapVersionsAvailable(int,int)} not intended to be used by - * implementations. However, if {@link jogamp.opengl.GLContextImpl#createContextARB(long, boolean)} is not being used within - * {@link com.jogamp.opengl.GLDrawableFactory#getOrCreateSharedContext(com.jogamp.nativewindow.AbstractGraphicsDevice)}, - * GLProfile has to map the available versions. - * - * @param reqMajor Key Value either 1, 2, 3 or 4 - * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} - * @return the old mapped value - * - * @see #createContextARBMapVersionsAvailable + * @deprecated Use {@link GLContextImpl#mapAvailableGLVersion(AbstractGraphicsDevice, int, int, VersionNumber, int)} */ protected static Integer mapAvailableGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int profile, final int resMajor, final int resMinor, int resCtp) @@ -1688,7 +1685,6 @@ public abstract class GLContext { } if(DEBUG) { System.err.println(getThreadName() + ": createContextARB-MapGLVersions MAP "+device+": "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), profile).toString()+ ") -> "+getGLVersion(resMajor, resMinor, resCtp, null)); - // Thread.dumpStack(); } final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, profile); final Integer val = Integer.valueOf(composeBits(resMajor, resMinor, resCtp)); @@ -1704,19 +1700,17 @@ public abstract class GLContext { synchronized(deviceVersionAvailable) { final Set<String> keys = deviceVersionAvailable.keySet(); boolean needsSeparator = false; - for(final Iterator<String> i = keys.iterator(); i.hasNext(); ) { + for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); ) { if(needsSeparator) { sb.append(Platform.getNewline()); } - final String key = i.next(); - sb.append(key).append(": "); + final String key = keyI.next(); + sb.append("MapGLVersions ").append(key).append(": "); final Integer valI = deviceVersionAvailable.get(key); if(null != valI) { - final int bits32 = valI.intValue(); - final int major = ( bits32 & 0xFF000000 ) >>> 24 ; - final int minor = ( bits32 & 0x00FF0000 ) >>> 16 ; - final int ctp = ( bits32 & 0x0000FFFF ) ; - sb.append(GLContext.getGLVersion(major, minor, ctp, null)); + final int[] ctp = { 0 }; + final VersionNumber version = decomposeBits(valI.intValue(), ctp); + GLContext.getGLVersion(sb, version, ctp[0], null); } else { sb.append("n/a"); } @@ -2032,8 +2026,10 @@ public abstract class GLContext { } return sb; } - protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) { - final StringBuilder sb = new StringBuilder(); + protected static StringBuilder getGLVersion(final StringBuilder sb, final VersionNumber version, final int ctp, final String gl_version) { + return getGLVersion(sb, version.getMajor(), version.getMinor(), ctp, gl_version); + } + protected static StringBuilder getGLVersion(final StringBuilder sb, final int major, final int minor, final int ctp, final String gl_version) { sb.append(major); sb.append("."); sb.append(minor); @@ -2044,7 +2040,10 @@ public abstract class GLContext { sb.append(" - "); sb.append(gl_version); } - return sb.toString(); + return sb; + } + protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) { + return getGLVersion(new StringBuilder(), major, minor, ctp, gl_version).toString(); } // diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index d21befcc5..469718995 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -45,7 +45,10 @@ import java.nio.IntBuffer; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; import java.util.Map; +import java.util.Set; import com.jogamp.common.ExceptionUtils; import com.jogamp.common.os.DynamicLookupHelper; @@ -59,12 +62,12 @@ import com.jogamp.gluegen.runtime.opengl.GLNameResolver; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; import com.jogamp.opengl.GLExtensions; import com.jogamp.opengl.GLRendererQuirks; - import com.jogamp.nativewindow.AbstractGraphicsConfiguration; import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.NativeSurface; import com.jogamp.nativewindow.NativeWindowFactory; import com.jogamp.nativewindow.ProxySurface; +import com.jogamp.nativewindow.egl.EGLGraphicsDevice; import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GL2ES3; @@ -805,28 +808,28 @@ public abstract class GLContextImpl extends GLContext { reqProfile = GLContext.CTX_PROFILE_COMPAT; isCompat = true; } - GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + final MappedGLVersion me = mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion, ctxOptions, glRendererQuirks); // Perform all required profile mappings if( isCompat ) { // COMPAT via non ARB - GLContext.mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks); if( reqMajor >= 4 ) { - GLContext.mapAvailableGLVersion(device, 3, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); - GLContext.mapAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + mapAvailableGLVersion(device, 3, reqProfile, ctxVersion, ctxOptions, glRendererQuirks); + mapAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks); } if( reqMajor >= 3 ) { - GLContext.mapAvailableGLVersion(device, 2, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + mapAvailableGLVersion(device, 2, reqProfile, ctxVersion, ctxOptions, glRendererQuirks); } } else { // CORE via non ARB, unlikely, however .. if( reqMajor >= 4 ) { - GLContext.mapAvailableGLVersion(device, 3, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + mapAvailableGLVersion(device, 3, reqProfile, ctxVersion, ctxOptions, glRendererQuirks); } } GLContext.setAvailableGLVersionsSet(device, true); if (DEBUG) { - System.err.println(getThreadName() + ": createContextOLD-MapVersionsAvailable HAVE: " + device+" -> "+reqMajor+"."+reqProfile+ " -> "+getGLVersion()); + System.err.println(getThreadName() + ": createContextOLD-MapGLVersions HAVE: " + me); } } } @@ -990,6 +993,128 @@ public abstract class GLContextImpl extends GLContext { return _ctx; } + //---------------------------------------------------------------------- + // + + public static class MappedGLVersion { + public final AbstractGraphicsDevice device; + public final int reqMajorVersion; + public final int reqProfile; + public final VersionNumber ctxVersion; + public final int ctxOptions; + public final GLRendererQuirks quirks; + public final VersionNumber preCtxVersion; + public final int preCtxOptions; + public MappedGLVersion(final AbstractGraphicsDevice device, final int reqMajorVersion, final int reqProfile, + final VersionNumber ctxVersion, final int ctxOptions, final GLRendererQuirks quirks, + final VersionNumber preCtxVersion, final int preCtxOptions) { + this.device = device; + this.reqMajorVersion = reqMajorVersion; + this.reqProfile = reqProfile; + this.ctxVersion = ctxVersion; + this.ctxOptions = ctxOptions; + this.quirks = quirks; + this.preCtxVersion = preCtxVersion; + this.preCtxOptions = preCtxOptions; + } + public final String toString() { + return toString(new StringBuilder(), -1, -1, -1, -1).toString(); + } + public final StringBuilder toString(final StringBuilder sb, final int minMajor, final int minMinor, final int maxMajor, final int maxMinor) { + sb.append(device.toString()).append(" ").append(reqMajorVersion).append(" ("); + GLContext.getGLProfile(sb, reqProfile).append(")"); + if( minMajor >=0 && minMinor >=0 && maxMajor >= 0 && maxMinor >= 0) { + sb.append("[").append(minMajor).append(".").append(minMinor).append(" .. ").append(maxMajor).append(".").append(maxMinor).append("]"); + } + sb.append(": ["); + if( null != preCtxVersion ) { + GLContext.getGLVersion(sb, preCtxVersion, preCtxOptions, null); + } else { + sb.append("None"); + } + sb.append("] -> ["); + GLContext.getGLVersion(sb, ctxVersion, ctxOptions, null).append("]"); + return sb; + } + } + public static interface MappedGLVersionListener { + void glVersionMapped(final MappedGLVersion e); + } + private static MappedGLVersionListener mapGLVersionListener = null; + protected static synchronized void setMappedGLVersionListener(final MappedGLVersionListener mvl) { + mapGLVersionListener = mvl; + } + + /** + * Called by {@link jogamp.opengl.GLContextImpl#createContextARBMapVersionsAvailable(int,int)} not intended to be used by + * implementations. However, if {@link jogamp.opengl.GLContextImpl#createContextARB(long, boolean)} is not being used within + * {@link com.jogamp.opengl.GLDrawableFactory#getOrCreateSharedContext(com.jogamp.nativewindow.AbstractGraphicsDevice)}, + * GLProfile has to map the available versions. + * + * @param reqMajor Key Value either 1, 2, 3 or 4 + * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} + * @param resVersion the resulting version number + * @param resCtp the resulting context options + * @return the old mapped value + * + * @see #createContextARBMapVersionsAvailable + */ + protected static MappedGLVersion mapAvailableGLVersion(final AbstractGraphicsDevice device, + final int reqMajor, final int profile, + final VersionNumber resVersion, final int resCtp, final GLRendererQuirks resQuirks) + { + @SuppressWarnings("deprecation") + final Integer preVal = mapAvailableGLVersion(device, reqMajor, profile, resVersion.getMajor(), resVersion.getMinor(), resCtp); + final int[] preCtp = { 0 }; + final VersionNumber preVersion = null != preVal ? decomposeBits(preVal.intValue(), preCtp) : null; + final MappedGLVersion res = new MappedGLVersion(device, reqMajor, profile, resVersion, resCtp, resQuirks, preVersion, preCtp[0]); + if( null != mapGLVersionListener ) { + mapGLVersionListener.glVersionMapped(res); + } + return res; + } + + protected static void remapAvailableGLVersions(final AbstractGraphicsDevice fromDevice, final AbstractGraphicsDevice toDevice) { + if( fromDevice == toDevice || fromDevice.getUniqueID() == toDevice.getUniqueID() ) { + return; // NOP + } + synchronized(deviceVersionAvailable) { + if(DEBUG) { + System.err.println(getThreadName() + ": createContextARB-MapGLVersions REMAP "+fromDevice+" -> "+toDevice); + } + final IdentityHashMap<String, Integer> newDeviceVersionAvailable = new IdentityHashMap<String, Integer>(); + final Set<String> keys = deviceVersionAvailable.keySet(); + for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); ) { + final String origKey = keyI.next(); + final Integer valI = deviceVersionAvailable.get(origKey); + if( null != valI ) { + if(DEBUG) { + final int[] ctp = { 0 }; + final VersionNumber version = decomposeBits(valI.intValue(), ctp); + System.err.println(" MapGLVersions REMAP OLD "+origKey+" -> "+GLContext.getGLVersion(new StringBuilder(), version, ctp[0], null).toString()); + } + newDeviceVersionAvailable.put(origKey, valI); + final int devSepIdx = origKey.lastIndexOf('-'); + if( 0 >= devSepIdx ) { + throw new InternalError("device-separator '-' at "+devSepIdx+" of "+origKey); + } + final String devUniqueID = origKey.substring(0, devSepIdx); + if( fromDevice.getUniqueID().equals(devUniqueID) ) { + final String profileReq = origKey.substring(devSepIdx); + final String newKey = (toDevice.getUniqueID()+profileReq).intern(); + if(DEBUG) { + System.err.println(" MapGLVersions REMAP NEW "+newKey+" -> (ditto)"); + } + newDeviceVersionAvailable.put(newKey, valI); + } + } + } + deviceVersionAvailable.clear(); + deviceVersionAvailable.putAll(newDeviceVersionAvailable); + GLContext.setAvailableGLVersionsSet(toDevice, true); + } + } + private final boolean mapGLVersions(final AbstractGraphicsDevice device) { synchronized (GLContext.deviceVersionAvailable) { if (DEBUG) { @@ -1012,14 +1137,14 @@ public abstract class GLContextImpl extends GLContext { /** * OSX 10.9 GLRendererQuirks.GL4NeedsGL3Request, quirk is added as usual @ setRendererQuirks(..) */ - if( !GLProfile.disableOpenGLCore && !hasGL4 && !hasGL3 ) { - hasGL3 = createContextARBMapVersionsAvailable(3, CTX_PROFILE_CORE); // GL3 + if( !GLProfile.disableOpenGLDesktop && !GLProfile.disableOpenGLCore && !hasGL4 && !hasGL3 ) { + hasGL3 = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_CORE); // GL3 success |= hasGL3; if( hasGL3 ) { final boolean isHWAccel = 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ); if( isHWAccel && ctxVersion.getMajor() >= 4 ) { // Gotcha: Creating a '3.2' ctx delivers a >= 4 ctx. - GLContext.mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks); hasGL4 = true; if(DEBUG) { System.err.println(getThreadName() + ": createContextARB-MapGLVersions: Quirk Triggerd: "+GLRendererQuirks.toString(GLRendererQuirks.GL4NeedsGL3Request)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber()); @@ -1029,14 +1154,14 @@ public abstract class GLContextImpl extends GLContext { } } } - if( !GLProfile.disableOpenGLCore ) { + if( !GLProfile.disableOpenGLDesktop && !GLProfile.disableOpenGLCore ) { if( !hasGL4 ) { - hasGL4 = createContextARBMapVersionsAvailable(4, CTX_PROFILE_CORE); // GL4 + hasGL4 = createContextARBMapVersionsAvailable(device, 4, CTX_PROFILE_CORE); // GL4 success |= hasGL4; if( hasGL4 ) { if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) { // Map hw-accel GL4 to all lower core profiles: GL3 - GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks); if( PROFILE_ALIASING ) { hasGL3 = true; } @@ -1045,60 +1170,62 @@ public abstract class GLContextImpl extends GLContext { } } if( !hasGL3 ) { - hasGL3 = createContextARBMapVersionsAvailable(3, CTX_PROFILE_CORE); // GL3 + hasGL3 = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_CORE); // GL3 success |= hasGL3; if( hasGL3 ) { resetStates(false); // clean this context states, since creation was temporary } } } - if( !hasGL4bc ) { - hasGL4bc = createContextARBMapVersionsAvailable(4, CTX_PROFILE_COMPAT); // GL4bc - success |= hasGL4bc; - if( hasGL4bc ) { - if( !hasGL4 ) { // last chance .. ignore hw-accel - GLContext.mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); - hasGL4 = true; - } - if( !hasGL3 ) { // last chance .. ignore hw-accel - GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); - hasGL3 = true; - } - if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) { - // Map hw-accel GL4bc to all lower compatible profiles: GL3bc, GL2 - GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); - GLContext.mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); - if(PROFILE_ALIASING) { - hasGL3bc = true; - hasGL2 = true; + if( !GLProfile.disableOpenGLDesktop ) { + if( !hasGL4bc ) { + hasGL4bc = createContextARBMapVersionsAvailable(device, 4, CTX_PROFILE_COMPAT); // GL4bc + success |= hasGL4bc; + if( hasGL4bc ) { + if( !hasGL4 ) { // last chance .. ignore hw-accel + mapAvailableGLVersion(device, 4, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks); + hasGL4 = true; } + if( !hasGL3 ) { // last chance .. ignore hw-accel + mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks); + hasGL3 = true; + } + if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) { + // Map hw-accel GL4bc to all lower compatible profiles: GL3bc, GL2 + mapAvailableGLVersion(device, 3, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks); + mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks); + if(PROFILE_ALIASING) { + hasGL3bc = true; + hasGL2 = true; + } + } + resetStates(false); // clean this context states, since creation was temporary } - resetStates(false); // clean this context states, since creation was temporary } - } - if( !hasGL3bc ) { - hasGL3bc = createContextARBMapVersionsAvailable(3, CTX_PROFILE_COMPAT); // GL3bc - success |= hasGL3bc; - if( hasGL3bc ) { - if(!hasGL3) { // last chance .. ignore hw-accel - GLContext.mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); - hasGL3 = true; - } - if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) { - // Map hw-accel GL3bc to all lower compatible profiles: GL2 - GLContext.mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); - if(PROFILE_ALIASING) { - hasGL2 = true; + if( !hasGL3bc ) { + hasGL3bc = createContextARBMapVersionsAvailable(device, 3, CTX_PROFILE_COMPAT); // GL3bc + success |= hasGL3bc; + if( hasGL3bc ) { + if(!hasGL3) { // last chance .. ignore hw-accel + mapAvailableGLVersion(device, 3, CTX_PROFILE_CORE, ctxVersion, ctxOptions, glRendererQuirks); + hasGL3 = true; + } + if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctxOptions ) ) { + // Map hw-accel GL3bc to all lower compatible profiles: GL2 + mapAvailableGLVersion(device, 2, CTX_PROFILE_COMPAT, ctxVersion, ctxOptions, glRendererQuirks); + if(PROFILE_ALIASING) { + hasGL2 = true; + } } + resetStates(false); // clean this context states, since creation was temporary } - resetStates(false); // clean this context states, since creation was temporary } - } - if( !hasGL2 ) { - hasGL2 = createContextARBMapVersionsAvailable(2, CTX_PROFILE_COMPAT); // GL2 - success |= hasGL2; - if( hasGL2 ) { - resetStates(false); // clean this context states, since creation was temporary + if( !hasGL2 ) { + hasGL2 = createContextARBMapVersionsAvailable(device, 2, CTX_PROFILE_COMPAT); // GL2 + success |= hasGL2; + if( hasGL2 ) { + resetStates(false); // clean this context states, since creation was temporary + } } } if(success) { @@ -1120,38 +1247,43 @@ public abstract class GLContextImpl extends GLContext { * Note: Since context creation is temporary, caller need to issue {@link #resetStates(boolean)}, if creation was successful, i.e. returns true. * This method does not reset the states, allowing the caller to utilize the state variables. **/ - private final boolean createContextARBMapVersionsAvailable(final int reqMajor, final int reqProfile) { + private final boolean createContextARBMapVersionsAvailable(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile) { long _context; int ctp = CTX_IS_ARB_CREATED | reqProfile; // To ensure GL profile compatibility within the JOGL application // we always try to map against the highest GL version, // so the user can always cast to the highest available one. - int majorMax, minorMax; - int majorMin, minorMin; + int maxMajor, maxMinor; + int minMajor, minMinor; final int major[] = new int[1]; final int minor[] = new int[1]; if( CTX_PROFILE_ES == reqProfile ) { - majorMax=reqMajor; minorMax=GLContext.getMaxMinor(ctp, majorMax); - majorMin=reqMajor; minorMin=0; + if( 3 == reqMajor ) { // ES3 - ES2 + maxMajor=3; maxMinor=GLContext.getMaxMinor(ctp, maxMajor); + minMajor=2; minMinor=0; + } else { // ES2 or ES1 + maxMajor=reqMajor; maxMinor=GLContext.getMaxMinor(ctp, maxMajor); + minMajor=reqMajor; minMinor=0; + } } else { if( 4 == reqMajor ) { - majorMax=4; minorMax=GLContext.getMaxMinor(ctp, majorMax); - majorMin=4; minorMin=0; + maxMajor=4; maxMinor=GLContext.getMaxMinor(ctp, maxMajor); + minMajor=4; minMinor=0; } else if( 3 == reqMajor ) { - majorMax=3; minorMax=GLContext.getMaxMinor(ctp, majorMax); - majorMin=3; minorMin=1; + maxMajor=3; maxMinor=GLContext.getMaxMinor(ctp, maxMajor); + minMajor=3; minMinor=1; } else /* if( glp.isGL2() ) */ { // our minimum desktop OpenGL runtime requirements are 1.1, // nevertheless we restrict ARB context creation to 2.0 to spare us futile attempts - majorMax=3; minorMax=0; - majorMin=2; minorMin=0; + maxMajor=3; maxMinor=0; + minMajor=2; minMinor=0; } } _context = createContextARBVersions(0, true, ctp, - /* max */ majorMax, minorMax, - /* min */ majorMin, minorMin, + /* max */ maxMajor, maxMinor, + /* min */ minMajor, minMinor, /* res */ major, minor); if( 0 == _context && CTX_PROFILE_CORE == reqProfile && !PROFILE_ALIASING ) { @@ -1159,8 +1291,8 @@ public abstract class GLContextImpl extends GLContext { ctp &= ~CTX_PROFILE_CORE ; ctp |= CTX_OPTION_FORWARD ; _context = createContextARBVersions(0, true, ctp, - /* max */ majorMax, minorMax, - /* min */ majorMin, minorMin, + /* max */ maxMajor, maxMinor, + /* min */ minMajor, minMinor, /* res */ major, minor); if( 0 == _context ) { // Try a compatible one .. even though not requested .. last resort @@ -1168,25 +1300,24 @@ public abstract class GLContextImpl extends GLContext { ctp &= ~CTX_OPTION_FORWARD ; ctp |= CTX_PROFILE_COMPAT ; _context = createContextARBVersions(0, true, ctp, - /* max */ majorMax, minorMax, - /* min */ majorMin, minorMin, + /* max */ maxMajor, maxMinor, + /* min */ minMajor, minMinor, /* res */ major, minor); } } final boolean res; if( 0 != _context ) { - final AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(); // ctxMajorVersion, ctxMinorVersion, ctxOptions is being set by // createContextARBVersions(..) -> setGLFunctionAvailbility(..) -> setContextVersion(..) - GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions); + final MappedGLVersion me = mapAvailableGLVersion(device, reqMajor, reqProfile, ctxVersion, ctxOptions, glRendererQuirks); destroyContextARBImpl(_context); if (DEBUG) { - System.err.println(getThreadName() + ": createContextARB-MapGLVersions "+device+", HAVE: "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), reqProfile).toString()+ ") ["+majorMax+"."+minorMax+" .. "+majorMin+"."+minorMin+"] -> "+getGLVersion()); + System.err.println(getThreadName() + ": createContextARB-MapGLVersions HAVE "+me.toString(new StringBuilder(), minMajor, minMinor, maxMajor, maxMinor).toString()); } res = true; } else { if (DEBUG) { - System.err.println(getThreadName() + ": createContextARB-MapGLVersions "+device+", NOPE: "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), reqProfile).toString()+ ") ["+majorMax+"."+minorMax+" .. "+majorMin+"."+minorMin+"]"); + System.err.println(getThreadName() + ": createContextARB-MapGLVersions NOPE "+device+", "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), reqProfile).toString()+ ") ["+maxMajor+"."+maxMinor+" .. "+minMajor+"."+minMinor+"]"); } res = false; } @@ -1913,7 +2044,7 @@ public abstract class GLContextImpl extends GLContext { final String MesaRendererIntelsp = "Intel(R)"; final boolean hwAccel = 0 == ( ctp & GLContext.CTX_IMPL_ACCEL_SOFT ); final boolean compatCtx = 0 != ( ctp & GLContext.CTX_PROFILE_COMPAT ); - final boolean esCtx = 0 != ( ctp & GLContext.CTX_PROFILE_ES ); + final boolean isES = 0 != ( ctp & GLContext.CTX_PROFILE_ES ); final boolean isX11 = NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true); final boolean isWindows = Platform.getOSType() == Platform.OSType.WINDOWS; final boolean isDriverMesa = glRenderer.contains(MesaSP) || glRenderer.contains("Gallium "); @@ -1936,7 +2067,7 @@ public abstract class GLContextImpl extends GLContext { // // General Quirks // - if( esCtx ) { + if( isES ) { if( 2 == reqMajor && 2 < major ) { final int quirk = GLRendererQuirks.GLES3ViaEGLES2Config; if(DEBUG) { @@ -2219,7 +2350,7 @@ public abstract class GLContextImpl extends GLContext { if( !GLRendererQuirks.areSameStickyDevice(factoryDefaultDevice, adevice) ) { GLRendererQuirks.pushStickyDeviceQuirks(factoryDefaultDevice, quirks); } - if( esCtx ) { + if( isES ) { final AbstractGraphicsDevice eglFactoryDefaultDevice = GLDrawableFactory.getEGLFactory().getDefaultDevice(); if( !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, adevice) && !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, factoryDefaultDevice) ) { diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java index 3c1175420..eba8b1df3 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java @@ -49,6 +49,7 @@ import com.jogamp.opengl.GLProfile; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableImpl; +import jogamp.opengl.GLDynamicLookupHelper; import jogamp.opengl.egl.EGLExtImpl; import jogamp.opengl.egl.EGLExtProcAddressTable; @@ -167,9 +168,8 @@ public class EGLContext extends GLContextImpl { final long eglConfig = config.getNativeConfig(); final EGLDrawableFactory factory = (EGLDrawableFactory) drawable.getFactoryImpl(); - final boolean hasOpenGLAPISupport = factory.hasOpenGLAPISupport(); + final boolean hasFullOpenGLAPISupport = factory.hasFullOpenGLAPISupport(); 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 ) ; @@ -177,9 +177,9 @@ public class EGLContext extends GLContextImpl { if(DEBUG) { System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: Start "+getGLVersion(reqMajor, reqMinor, ctp, "@creation") - + ", hasOpenGLAPISupport "+hasOpenGLAPISupport + + ", OpenGL API Support "+factory.hasOpenGLAPISupport() + ", useKHRCreateContext "+useKHRCreateContext - + ", allowOpenGLAPI "+allowOpenGLAPI + + ", Full OpenGL API Support "+hasFullOpenGLAPISupport + ", device "+device); } if ( 0 == eglDisplay ) { @@ -202,8 +202,7 @@ public class EGLContext extends GLContextImpl { * hence it must be switched before makeCurrent w/ different APIs, see: * eglWaitClient(); */ - if( ctDesktopGL && !allowOpenGLAPI ) { - // if( ctDesktopGL && !hasOpenGLAPISupport ) { + if( ctDesktopGL && !hasFullOpenGLAPISupport ) { if(DEBUG) { System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: DesktopGL not avail "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")); } @@ -211,7 +210,7 @@ public class EGLContext extends GLContextImpl { } try { - if( allowOpenGLAPI && device.getEGLVersion().compareTo(Version1_2) >= 0 ) { + if( hasFullOpenGLAPISupport && device.getEGLVersion().compareTo(Version1_2) >= 0 ) { EGL.eglWaitClient(); // EGL >= 1.2 } if( !EGL.eglBindAPI( ctDesktopGL ? EGL.EGL_OPENGL_API : EGL.EGL_OPENGL_ES_API) ) { diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java index 853599ec2..1bfb26260 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -66,6 +66,7 @@ import com.jogamp.opengl.GLProfile; import jogamp.common.os.PlatformPropsImpl; import jogamp.opengl.Debug; import jogamp.opengl.GLContextImpl; +import jogamp.opengl.GLContextImpl.MappedGLVersion; import jogamp.opengl.GLDrawableFactoryImpl; import jogamp.opengl.GLDrawableImpl; import jogamp.opengl.GLDynamicLookupHelper; @@ -77,7 +78,6 @@ import com.jogamp.common.nio.Buffers; import com.jogamp.common.nio.PointerBuffer; import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.os.Platform; -import com.jogamp.common.util.PropertyAccess; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.common.util.VersionNumber; import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook; @@ -89,17 +89,19 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG; // allow package access private static final boolean DEBUG_SHAREDCTX = DEBUG || GLContext.DEBUG; - /* package */ static final boolean QUERY_EGL_ES_NATIVE_TK; - static { Debug.initSingleton(); - QUERY_EGL_ES_NATIVE_TK = PropertyAccess.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true); } private static boolean eglDynamicLookupHelperInit = false; private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null; private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null; private static GLDynamicLookupHelper eglGLnDynamicLookupHelper = null; + private static boolean isANGLE = false; + private static boolean hasX11 = false; + private static String defaultConnection = null; + private static EGLGraphicsDevice defaultDevice = null; + private static EGLFeatures defaultDeviceEGLFeatures = null; private static final boolean isANGLE(final GLDynamicLookupHelper dl) { if(Platform.OSType.WINDOWS == PlatformPropsImpl.OS_TYPE) { @@ -192,12 +194,16 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { eglDynamicLookupHelperInit = true; // Check for other underlying stuff .. - if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) { + final String nwt = NativeWindowFactory.getNativeWindowType(true); + if(NativeWindowFactory.TYPE_X11 == nwt) { hasX11 = true; try { ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader()); } catch (final Exception jre) { /* n/a .. */ } + } else { + hasX11 = false; } + defaultConnection = NativeWindowFactory.getDefaultDisplayConnection(nwt); /** * FIXME: Probably need to move EGL from a static model @@ -336,8 +342,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { // The act of constructing them causes them to be registered EGLGraphicsConfigurationFactory.registerFactory(); - // FIXME: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE! - defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + // Note: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE! + // Hence opening will happen later, eventually + defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, defaultConnection, AbstractGraphicsDevice.DEFAULT_UNIT); // Init shared resources off thread // Will be released via ShutdownHook @@ -410,10 +417,6 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } } - private boolean isANGLE = false; - private boolean hasX11 = false; - private EGLGraphicsDevice defaultDevice = null; - private EGLFeatures defaultDeviceEGLFeatures; private SharedResourceImplementation sharedResourceImplementation; private SharedResourceRunner sharedResourceRunner; @@ -817,9 +820,27 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { public final boolean hasDefaultDeviceKHRCreateContext() { return defaultDeviceEGLFeatures.hasKHRCreateContext; } + /** + * Method returns {@code true} if {@code EGL_OpenGL_API} is supported, + * otherwise method returns {@code false}. + */ public final boolean hasOpenGLAPISupport() { return defaultDeviceEGLFeatures.hasGLAPI; } + /** + * Method returns {@code true} if {@code EGL_OpenGL_API} and {@code EGL_KHR_create_context} is supported, + * otherwise method returns {@code false}. + */ + public final boolean hasFullOpenGLAPISupport() { + /** + * 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'. + */ + return null != eglGLnDynamicLookupHelper && + defaultDeviceEGLFeatures.hasGLAPI && defaultDeviceEGLFeatures.hasKHRCreateContext; + } @Override public final AbstractGraphicsDevice getDefaultDevice() { @@ -948,7 +969,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected final ProxySurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, + protected final EGLSurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstreamHook) { final boolean[] ownDevice = { false }; @@ -957,14 +978,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - public final ProxySurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, + public final EGLSurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) { chosenCaps = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height)); } @Override - public final ProxySurface createSurfacelessImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, + public final EGLSurface createSurfacelessImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) { chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); final boolean[] ownDevice = { false }; @@ -1007,7 +1028,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected ProxySurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle, + protected EGLSurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle, final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstream) { final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(deviceReq); |