From 390ccc3e549e4cc13b7dab91387e72c1f10b77a9 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 29 Aug 2015 04:20:27 +0200 Subject: Bug 1203: GLDrawable-Stateless operations in GLContextImpl, using ctxVersion and ctxOptions - State-less operation during profile probing (mapGLVersions). While probing the GLDrawable/GLProfile and GL instance may not reflect the currently probed OpenGL profile. Hence stateless operation by passing required information is required for: - GLDynamicLookupHelper must be fetched via 'major-version and contextOptions'. - GLContextImpl.resetProcAddress(..) - GLContextImpl.updateGLXProcAddressTable() - GLContextImpl.setGLFunctionAvailability(..) - ExtensionAvailabilityCache TODO: Add replacement for GLProfile validation, which is disabled right now.: drawable.getGLProfile().verifyEquality(gl.getGLProfile()) The GLDrawable.GLProfile maybe less than GL's GLProfile due to current context-version and options. Hence we would need a 'GLProfile.bwCompatibleWith(GLProfile)'. --- src/jogl/classes/jogamp/opengl/GLContextImpl.java | 145 +++++++++++++++------- 1 file changed, 101 insertions(+), 44 deletions(-) (limited to 'src/jogl/classes/jogamp/opengl/GLContextImpl.java') diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 41b815384..d21befcc5 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -688,7 +688,7 @@ public abstract class GLContextImpl extends GLContext { if( CONTEXT_CURRENT_NEW == res ) { // check if the drawable's and the GL's GLProfile are equal // throws an GLException if not - drawable.getGLProfile().verifyEquality(gl.getGLProfile()); + // FIXME: drawable.getGLProfile().verifyEquality(gl.getGLProfile()); glDebugHandler.init( isGL2GL3() && isGLDebugEnabled() ); @@ -1267,11 +1267,19 @@ public abstract class GLContextImpl extends GLContext { // Helpers for various context implementations // - private final Object createInstance(final GLProfile glp, final boolean glObject, final Object[] cstrArgs) { + private final boolean verifyInstance(final GLProfile glp, final String suffix, final Object instance) { + return ReflectionUtil.instanceOf(instance, glp.getGLImplBaseClassName()+suffix); + } + private final Object createInstance(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption, + final boolean glObject, final Object[] cstrArgs) { + final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption); + final GLProfile glp = GLProfile.get(adevice, profileString) ; return ReflectionUtil.createInstance(glp.getGLCtor(glObject), cstrArgs); } - - private final boolean verifyInstance(final GLProfile glp, final String suffix, final Object instance) { + private final boolean verifyInstance(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption, + final String suffix, final Object instance) { + final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption); + final GLProfile glp = GLProfile.get(adevice, profileString) ; return ReflectionUtil.instanceOf(instance, glp.getGLImplBaseClassName()+suffix); } @@ -1279,8 +1287,11 @@ public abstract class GLContextImpl extends GLContext { * Create the GL instance for this context, * requires valid {@link #getGLProcAddressTable()} result! */ - private final GL createGL(final GLProfile glp) { - final GL gl = (GL) createInstance(glp, true, new Object[] { glp, this } ); + private final GL createGL(final AbstractGraphicsDevice adevice, final int majorVersion, final int minorVersion, final int contextOption) { + final String profileString = GLContext.getGLProfile(majorVersion, minorVersion, contextOption); + final GLProfile glp = GLProfile.get(adevice, profileString); + final GL gl = (GL) ReflectionUtil.createInstance(glp.getGLCtor(true), new Object[] { glp, this }); + //nal GL gl = (GL) createInstance(glp, true, new Object[] { glp, this } ); /* FIXME: refactor dependence on Java 2D / JOGL bridge if (tracker != null) { @@ -1354,34 +1365,53 @@ public abstract class GLContextImpl extends GLContext { } protected abstract Map getExtensionNameMap() ; + /** + * Returns the DynamicLookupHelper + */ + public final GLDynamicLookupHelper getGLDynamicLookupHelper() { + return drawable.getFactoryImpl().getGLDynamicLookupHelper( ctxVersion.getMajor(), ctxOptions ); + } + public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) { + return drawable.getFactoryImpl().getGLDynamicLookupHelper( majorVersion, contextOptions ); + } + /** Helper routine which resets a ProcAddressTable generated by the - GLEmitter by looking up anew all of its function pointers. */ - protected final void resetProcAddressTable(final ProcAddressTable table) { + GLEmitter by looking up anew all of its function pointers + using the given {@link GLDynamicLookupHelper}. */ + protected final void resetProcAddressTable(final ProcAddressTable table, final GLDynamicLookupHelper dlh) { AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { - table.reset(getDrawableImpl().getGLDynamicLookupHelper() ); + table.reset( dlh ); return null; } } ); } - private final PrivilegedAction privInitGLGetPtrAction = new PrivilegedAction() { - @Override - public Object run() { - final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper(); - glDynLookupHelper.claimAllLinkPermission(); - try { - glGetStringPtr = glDynLookupHelper.dynamicLookupFunction("glGetString"); - glGetIntegervPtr = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv"); - } finally { - glDynLookupHelper.releaseAllLinkPermission(); - } - return null; - } }; - private final boolean initGLRendererAndGLVersionStrings() { + /** + * Updates the platform's 'GLX' function cache + * @param contextFQN provides a fully qualified key of the context including device and GL profile + * @param dlh {@link GLDynamicLookupHelper} used to {@link #resetProcAddressTable(ProcAddressTable, GLDynamicLookupHelper)} instance. + */ + protected abstract void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh); + + private final boolean initGLRendererAndGLVersionStrings(final int majorVersion, final int contextOptions) { if( !glGetPtrInit ) { - AccessController.doPrivileged(privInitGLGetPtrAction); + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Object run() { + final GLDynamicLookupHelper glDynLookupHelper = getGLDynamicLookupHelper(majorVersion, contextOptions); + if( null != glDynLookupHelper ) { + glDynLookupHelper.claimAllLinkPermission(); + try { + glGetStringPtr = glDynLookupHelper.dynamicLookupFunction("glGetString"); + glGetIntegervPtr = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv"); + } finally { + glDynLookupHelper.releaseAllLinkPermission(); + } + } + return null; + } } ); glGetPtrInit = true; } if( 0 == glGetStringPtr || 0 == glGetIntegervPtr ) { @@ -1527,7 +1557,7 @@ public abstract class GLContextImpl extends GLContext { final VersionNumber reqGLVersion = new VersionNumber(major, minor, 0); final VersionNumber hasGLVersionByString; { - final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings(); + final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings(major, ctxProfileBits); if( !initGLRendererAndGLVersionStringsOK ) { final String errMsg = "Intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null); if( strictMatch ) { @@ -1570,7 +1600,7 @@ public abstract class GLContextImpl extends GLContext { // otherwise cont. w/ version-string method -> 3.0 > Version || Version > MAX! // final VersionNumber hasGLVersionByInt; - if ( ( major >= 3 || hasGLVersionByString.compareTo(Version3_0) >= 0 ) ) { + if ( major >= 3 || hasGLVersionByString.compareTo(Version3_0) >= 0 ) { final int[] glIntMajor = new int[] { 0 }, glIntMinor = new int[] { 0 }; getGLIntVersion(glIntMajor, glIntMinor); hasGLVersionByInt = new VersionNumber(glIntMajor[0], glIntMinor[0], 0); @@ -1699,43 +1729,72 @@ public abstract class GLContextImpl extends GLContext { if (DEBUG) { System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 validated FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion)); } - - updateGLXProcAddressTable(); + final GLDynamicLookupHelper dynamicLookup = getGLDynamicLookupHelper(major, ctxProfileBits); + if( null == dynamicLookup ) { + if(DEBUG) { + System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, No GLDynamicLookupHelper for request: "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)); + } + return false; + } + updateGLXProcAddressTable(contextFQN, dynamicLookup); // // UpdateGLProcAddressTable functionality // _and_ setup GL instance, which ctor requires valid getGLProcAddressTable() result! // { - final GLProfile glp = drawable.getGLProfile(); + final GLProfile glp = drawable.getGLProfile(); // !withinGLVersionsMapping ProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { table = mappedGLProcAddress.get( contextFQN ); - if(null != table && !verifyInstance(glp, "ProcAddressTable", table)) { - throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+ - ") -> "+ table.getClass().getName()+" not matching "+glp.getGLImplBaseClassName()); + if(null != table) { + if( !verifyInstance(adevice, major, minor, ctxProfileBits, "ProcAddressTable", table) ) { + throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+ + ") -> "+ toHexString(table.hashCode()) +" not matching "+table.getClass().getName()); + } + if( !withinGLVersionsMapping && !verifyInstance(glp, "ProcAddressTable", table) ) { + throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+ + ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName()+" not matching "+glp.getGLImplBaseClassName()+"/"+glp); + } } } if(null != table) { glProcAddressTable = table; if(DEBUG) { - System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+") -> "+toHexString(table.hashCode())); + if( withinGLVersionsMapping ) { + System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+ + ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName()); + } else { + System.err.println(getThreadName() + ": GLContext GL ProcAddressTable reusing key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+ + ") -> "+ toHexString(table.hashCode()) +": "+table.getClass().getName()+" -> "+glp.getGLImplBaseClassName()); + } } } else { - glProcAddressTable = (ProcAddressTable) createInstance(glp, false, + glProcAddressTable = (ProcAddressTable) createInstance(adevice, major, minor, ctxProfileBits, false, new Object[] { new GLProcAddressResolver() } ); - resetProcAddressTable( glProcAddressTable ); + resetProcAddressTable(glProcAddressTable, dynamicLookup); + synchronized(mappedContextTypeObjectLock) { mappedGLProcAddress.put(contextFQN, glProcAddressTable); if(DEBUG) { - System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+toHexString(glProcAddressTable.hashCode())); + if( withinGLVersionsMapping ) { + System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+ + ") -> "+toHexString(glProcAddressTable.hashCode()) +": "+glProcAddressTable.getClass().getName()); + } else { + System.err.println(getThreadName() + ": GLContext GL ProcAddressTable mapping key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+ + ") -> "+toHexString(glProcAddressTable.hashCode()) +": "+glProcAddressTable.getClass().getName()+" -> "+glp.getGLImplBaseClassName()); + } } } } - if( null == this.gl || !verifyInstance(glp, "Impl", this.gl) ) { - setGL( createGL( glp ) ); + if( null == this.gl || !verifyInstance(adevice, major, minor, ctxProfileBits, "Impl", this.gl) ) { + setGL( createGL( adevice, major, minor, ctxProfileBits ) ); + } + if( !withinGLVersionsMapping && !verifyInstance(glp, "Impl", this.gl) ) { + throw new GLException("GLContext GL Object mismatch: "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+ + ") -> "+": "+this.gl.getClass().getName()+" not matching "+glp.getGLImplBaseClassName()+"/"+glp); } } @@ -2236,11 +2295,6 @@ public abstract class GLContextImpl extends GLContext { return isHardwareRasterizer; } - /** - * Updates the platform's 'GLX' function cache - */ - protected abstract void updateGLXProcAddressTable(); - protected abstract StringBuilder getPlatformExtensionsStringImpl(); @Override @@ -2265,7 +2319,10 @@ public abstract class GLContextImpl extends GLContext { } // dynamic function lookup at last incl name aliasing (not cached) - final DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper(); + final DynamicLookupHelper dynLookup = getGLDynamicLookupHelper(ctxVersion.getMajor(), ctxOptions); + if( null == dynLookup ) { + throw new GLException("No GLDynamicLookupHelper for "+this); + } final String tmpBase = GLNameResolver.normalizeVEN(GLNameResolver.normalizeARB(glFunctionName, true), true); return AccessController.doPrivileged(new PrivilegedAction() { @Override -- cgit v1.2.3