Skip to content

Commit

Permalink
Bug 1203: GLDrawable-Stateless operations in GLContextImpl, using ctx…
Browse files Browse the repository at this point in the history
…Version 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)'.
  • Loading branch information
sgothel committed Aug 29, 2015
1 parent c835cdd commit 390ccc3
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 88 deletions.
2 changes: 1 addition & 1 deletion make/config/jogl/glu-CustomJavaCode-gl2.java
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ private static final GLUgl2ProcAddressTable getGLUProcAddressTable() {
if (curContext == null) {
throw new GLException("No OpenGL context current on this thread");
}
GLDynamicLookupHelper glLookupHelper = ((GLDrawableImpl) curContext.getGLDrawable()).getGLDynamicLookupHelper();
GLDynamicLookupHelper glLookupHelper = ((GLContextImpl) curContext).getGLDynamicLookupHelper();
glLookupHelper.loadGLULibrary();
GLUgl2ProcAddressTable tmp = new GLUgl2ProcAddressTable(new GLProcAddressResolver());
tmp.reset(glLookupHelper);
Expand Down
11 changes: 5 additions & 6 deletions src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@

import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES3;
import com.jogamp.opengl.GL2GL3;
import com.jogamp.opengl.GLContext;

import com.jogamp.common.util.VersionNumber;
Expand Down Expand Up @@ -138,9 +137,9 @@ private final void initAvailableExtensions(final GLContextImpl context) {

boolean useGetStringi = false;

// Use 'glGetStringi' only for ARB GL3 context,
// Use 'glGetStringi' only for ARB GL3 and ES3 context,
// on GL2 platforms the function might be available, but not working.
if ( context.isGL3() ) {
if ( context.isGL3() || context.isGLES3() ) {
if ( ! context.isFunctionAvailable("glGetStringi") ) {
if(DEBUG) {
System.err.println("GLContext: GL >= 3.1 usage, but no glGetStringi");
Expand All @@ -156,16 +155,16 @@ private final void initAvailableExtensions(final GLContextImpl context) {
}

if(useGetStringi) {
final GL2GL3 gl2gl3 = gl.getGL2GL3();
final GL2ES3 gl2es3 = (GL2ES3)gl; // validated via context - OK!
final int count;
{
final int[] val = { 0 } ;
gl2gl3.glGetIntegerv(GL2ES3.GL_NUM_EXTENSIONS, val, 0);
gl2es3.glGetIntegerv(GL2ES3.GL_NUM_EXTENSIONS, val, 0);
count = val[0];
}
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
final String ext = gl2gl3.glGetStringi(GL.GL_EXTENSIONS, i);
final String ext = gl2es3.glGetStringi(GL.GL_EXTENSIONS, i);
if( null == availableExtensionCache.put(ext, ext) ) {
// new one
if( 0 < i ) {
Expand Down
145 changes: 101 additions & 44 deletions src/jogl/classes/jogamp/opengl/GLContextImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ protected final int makeCurrent(boolean forceDrawableAssociation) throws GLExcep
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() );

Expand Down Expand Up @@ -1267,20 +1267,31 @@ private final void setContextVersion(final int major, final int minor, final int
// 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);
}

/**
* 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) {
Expand Down Expand Up @@ -1354,34 +1365,53 @@ protected final String mapToRealGLExtensionName(final String glExtensionName) {
}
protected abstract Map<String, String> 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<Object>() {
@Override
public Object run() {
table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
table.reset( dlh );
return null;
}
} );
}

private final PrivilegedAction<Object> privInitGLGetPtrAction = new PrivilegedAction<Object>() {
@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<Object>() {
@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 ) {
Expand Down Expand Up @@ -1527,7 +1557,7 @@ protected final boolean setGLFunctionAvailability(final boolean force, int major
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 ) {
Expand Down Expand Up @@ -1570,7 +1600,7 @@ protected final boolean setGLFunctionAvailability(final boolean force, int major
// 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);
Expand Down Expand Up @@ -1699,43 +1729,72 @@ protected final boolean setGLFunctionAvailability(final boolean force, int major
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);
}
}

Expand Down Expand Up @@ -2236,11 +2295,6 @@ private final boolean isCurrentContextHardwareRasterizer() {
return isHardwareRasterizer;
}

/**
* Updates the platform's 'GLX' function cache
*/
protected abstract void updateGLXProcAddressTable();

protected abstract StringBuilder getPlatformExtensionsStringImpl();

@Override
Expand All @@ -2265,7 +2319,10 @@ public final boolean isFunctionAvailable(final String glFunctionName) {
}

// 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<Boolean>() {
@Override
Expand Down
9 changes: 4 additions & 5 deletions src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,11 @@ protected final AbstractGraphicsDevice getOrCreateSharedDevice(final AbstractGra
}

/**
* Returns the GLDynamicLookupHelper
* @param profileName if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2,
* otherwise the profile is ignored.
* @throws GLException if no DynamicLookupHelper is installed
* Returns the GLDynamicLookupHelper if installed, otherwise {@code null}.
* @param majorVersion the major OpenGL profile version
* @param contextOptions the context profile options
*/
public abstract GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) throws GLException;
public abstract GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions);

//---------------------------------------------------------------------------
// Dispatching GLDrawable construction in respect to the NativeSurface Capabilities
Expand Down
8 changes: 0 additions & 8 deletions src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,6 @@ protected GLDrawableImpl(final GLDrawableFactory factory, final NativeSurface co
this.requestedCapabilities = requestedCapabilities;
}

/**
* Returns the DynamicLookupHelper
* @throws GLException if no DynamicLookupHelper is installed
*/
public final GLDynamicLookupHelper getGLDynamicLookupHelper() throws GLException {
return getFactoryImpl().getGLDynamicLookupHelper( getGLProfile().getImplName() );
}

public final GLDrawableFactoryImpl getFactoryImpl() {
return (GLDrawableFactoryImpl) getFactory();
}
Expand Down
9 changes: 6 additions & 3 deletions src/jogl/classes/jogamp/opengl/egl/EGLContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -363,14 +363,17 @@ protected boolean createImpl(final long shareWithHandle) throws GLException {
}

@Override
protected final void updateGLXProcAddressTable() {
protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
if( null == dlh ) {
throw new GLException("No GLDynamicLookupHelper for "+this);
}
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "EGL-"+adevice.getUniqueID();
// final String key = contextFQN;
if (DEBUG) {
System.err.println(getThreadName() + ": Initializing EGLextension address table: "+key);
}

ProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
table = mappedGLXProcAddress.get( key );
Expand All @@ -385,7 +388,7 @@ protected final void updateGLXProcAddressTable() {
}
} else {
eglExtProcAddressTable = new EGLExtProcAddressTable(new GLProcAddressResolver());
resetProcAddressTable(eglExtProcAddressTable);
resetProcAddressTable(eglExtProcAddressTable, dlh);
synchronized(mappedContextTypeObjectLock) {
mappedGLXProcAddress.put(key, eglExtProcAddressTable);
if(DEBUG) {
Expand Down
Loading

0 comments on commit 390ccc3

Please sign in to comment.