From 390ccc3e549e4cc13b7dab91387e72c1f10b77a9 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
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)'.
---
 make/config/jogl/glu-CustomJavaCode-gl2.java       |   2 +-
 .../jogamp/opengl/ExtensionAvailabilityCache.java  |  11 +-
 src/jogl/classes/jogamp/opengl/GLContextImpl.java  | 145 ++++++++++++++-------
 .../jogamp/opengl/GLDrawableFactoryImpl.java       |   9 +-
 src/jogl/classes/jogamp/opengl/GLDrawableImpl.java |   8 --
 src/jogl/classes/jogamp/opengl/egl/EGLContext.java |   9 +-
 .../jogamp/opengl/egl/EGLDrawableFactory.java      |  16 ++-
 .../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java |  14 +-
 .../macosx/cgl/MacOSXCGLDrawableFactory.java       |   2 +-
 .../opengl/windows/wgl/WindowsWGLContext.java      |  31 ++++-
 .../windows/wgl/WindowsWGLDrawableFactory.java     |   2 +-
 .../jogamp/opengl/x11/glx/X11GLXContext.java       |  31 ++++-
 .../opengl/x11/glx/X11GLXDrawableFactory.java      |   2 +-
 13 files changed, 194 insertions(+), 88 deletions(-)

diff --git a/make/config/jogl/glu-CustomJavaCode-gl2.java b/make/config/jogl/glu-CustomJavaCode-gl2.java
index d7ba58de4..2ade45c0e 100644
--- a/make/config/jogl/glu-CustomJavaCode-gl2.java
+++ b/make/config/jogl/glu-CustomJavaCode-gl2.java
@@ -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);
diff --git a/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java b/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
index 331414869..b28b79418 100644
--- a/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
+++ b/src/jogl/classes/jogamp/opengl/ExtensionAvailabilityCache.java
@@ -45,7 +45,6 @@ import java.util.StringTokenizer;
 
 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;
@@ -138,9 +137,9 @@ final class ExtensionAvailabilityCache {
 
       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");
@@ -156,16 +155,16 @@ final class ExtensionAvailabilityCache {
       }
 
       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 ) {
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<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 ) {
@@ -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<Boolean>() {
         @Override
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index b7f861e13..472172c75 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -245,12 +245,11 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
   }
 
   /**
-   * 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
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index 849a08623..98a0a0948 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -67,14 +67,6 @@ public abstract class GLDrawableImpl implements GLDrawable {
       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();
   }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index b64bb375a..3c1175420 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -363,14 +363,17 @@ public class EGLContext extends GLContextImpl {
     }
 
     @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 );
@@ -385,7 +388,7 @@ public class EGLContext extends GLContextImpl {
             }
         } else {
             eglExtProcAddressTable = new EGLExtProcAddressTable(new GLProcAddressResolver());
-            resetProcAddressTable(eglExtProcAddressTable);
+            resetProcAddressTable(eglExtProcAddressTable, dlh);
             synchronized(mappedContextTypeObjectLock) {
                 mappedGLXProcAddress.put(key, eglExtProcAddressTable);
                 if(DEBUG) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index a45a7efe0..937334513 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -867,17 +867,21 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
     }
 
     @Override
-    public GLDynamicLookupHelper getGLDynamicLookupHelper(final String esProfile) {
+    public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
         final GLDynamicLookupHelper res;
-        if ( GLProfile.GLES2 == esProfile || GLProfile.GLES3 == esProfile ) {
+        if ( EGLContext.isGLES2ES3(majorVersion, contextOptions) ) {
             res = eglES2DynamicLookupHelper;
-        } else if ( GLProfile.GLES1 == esProfile ) {
+        } else if ( EGLContext.isGLES1(majorVersion, contextOptions) ) {
             res = eglES1DynamicLookupHelper;
-        } else {
+        } else if( EGLContext.isGLDesktop(contextOptions) ) {
             res = eglGLnDynamicLookupHelper;
+        } else {
+            throw new IllegalArgumentException("neither GLES1, GLES2, GLES3 nor desktop GL has been specified: "+majorVersion+" ("+EGLContext.getGLProfile(new StringBuilder(), contextOptions).toString());
         }
-        if( null == res ) {
-            throw new GLException("No lookup for esProfile "+esProfile);
+        if( DEBUG_SHAREDCTX ) {
+            if( null == res ) {
+                System.err.println("EGLDrawableFactory.getGLDynamicLookupHelper: NULL for profile "+majorVersion+" ("+EGLContext.getGLProfile(new StringBuilder(), contextOptions).toString());
+            }
         }
         return res;
     }
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 2f88e7619..10a11dd36 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -63,6 +63,7 @@ import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
 import jogamp.nativewindow.macosx.OSXUtil;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
 import jogamp.opengl.GLFBODrawableImpl;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -436,8 +437,17 @@ public class MacOSXCGLContext extends GLContextImpl
       return null;
   }
 
+  /**
+   * {@inheritDoc}
+   * <p>
+   * Ignoring {@code contextFQN}, using {@code MacOSX}-{@link AbstractGraphicsDevice#getUniqueID()}.
+   * </p>
+   */
   @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 = "MacOSX-"+adevice.getUniqueID();
@@ -455,7 +465,7 @@ public class MacOSXCGLContext extends GLContextImpl
         }
     } else {
         cglExtProcAddressTable = new CGLExtProcAddressTable(new GLProcAddressResolver());
-        resetProcAddressTable(getCGLExtProcAddressTable());
+        resetProcAddressTable(getCGLExtProcAddressTable(), dlh);
         synchronized(mappedContextTypeObjectLock) {
             mappedGLXProcAddress.put(key, getCGLExtProcAddressTable());
             if(DEBUG) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index ab1d56e29..120de4a13 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -148,7 +148,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  public GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+  public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
       return macOSXCGLDynamicLookupHelper;
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index 6ff8c57c8..3cf9917e3 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -60,6 +60,7 @@ import com.jogamp.opengl.GLRendererQuirks;
 import jogamp.nativewindow.windows.GDI;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
 import jogamp.opengl.GLXExtensions;
 
 public class WindowsWGLContext extends GLContextImpl {
@@ -201,13 +202,24 @@ public class WindowsWGLContext extends GLContextImpl {
 
   @Override
   protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) {
+    if(DEBUG) {
+        System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
+                ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct);
+    }
     if( null == getWGLExtProcAddressTable()) {
-        updateGLXProcAddressTable();
+        final GLDynamicLookupHelper dlh = getGLDynamicLookupHelper(major, ctp);
+        if( null == dlh ) {
+            if(DEBUG) {
+                System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: Null GLDynamicLookupHelper");
+            }
+            return 0;
+        } else {
+            updateGLXProcAddressTable(null, dlh);
+        }
     }
     final WGLExt _wglExt = getWGLExt();
     if(DEBUG) {
-      System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
-                         ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
+      System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+
                          ", wglCreateContextAttribsARB: "+toHexString(wglExtProcAddressTable._addressof_wglCreateContextAttribsARB));
     }
 
@@ -441,8 +453,17 @@ public class WindowsWGLContext extends GLContextImpl {
     }
   }
 
+  /**
+   * {@inheritDoc}
+   * <p>
+   * Ignoring {@code contextFQN}, using {@code WGL}-{@link AbstractGraphicsDevice#getUniqueID()}.
+   * </p>
+   */
   @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 = "WGL-"+adevice.getUniqueID();
@@ -465,7 +486,7 @@ public class WindowsWGLContext extends GLContextImpl {
         }
     } else {
         wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver());
-        resetProcAddressTable(wglExtProcAddressTable);
+        resetProcAddressTable(wglExtProcAddressTable, dlh);
         synchronized(mappedContextTypeObjectLock) {
             mappedGLXProcAddress.put(key, getWGLExtProcAddressTable());
             if(DEBUG) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index b6a96279c..8fd5454d2 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -228,7 +228,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  public GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+  public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
       return windowsWGLDynamicLookupHelper;
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 3f856e4f8..e4418b431 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -56,6 +56,7 @@ import jogamp.nativewindow.x11.X11Lib;
 import jogamp.nativewindow.x11.X11Util;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
 import jogamp.opengl.GLXExtensions;
 
 import com.jogamp.common.ExceptionUtils;
@@ -224,11 +225,22 @@ public class X11GLXContext extends GLContextImpl {
 
   @Override
   protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) {
-    updateGLXProcAddressTable();
-    final GLXExt _glXExt = getGLXExt();
     if(DEBUG) {
       System.err.println(getThreadName()+": X11GLXContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
-                         ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
+                         ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct);
+    }
+    final GLDynamicLookupHelper dlh = getGLDynamicLookupHelper(major, ctp);
+    if( null == dlh ) {
+        if(DEBUG) {
+            System.err.println(getThreadName()+" - X11GLXContext.createContextARBImpl: Null GLDynamicLookupHelper");
+        }
+        return 0;
+    } else {
+        updateGLXProcAddressTable(null, dlh);
+    }
+    final GLXExt _glXExt = getGLXExt();
+    if(DEBUG) {
+      System.err.println(getThreadName()+": X11GLXContext.createContextARBImpl: "+
                          ", glXCreateContextAttribsARB: "+toHexString(glXExtProcAddressTable._addressof_glXCreateContextAttribsARB));
     }
 
@@ -479,8 +491,17 @@ public class X11GLXContext extends GLContextImpl {
     // Should check for X errors and raise GLException
   }
 
+  /**
+   * {@inheritDoc}
+   * <p>
+   * Ignoring {@code contextFQN}, using {@code GLX}+{@link AbstractGraphicsDevice#getUniqueID()}.
+   * </p>
+   */
   @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 = "GLX-"+adevice.getUniqueID();
@@ -498,7 +519,7 @@ public class X11GLXContext extends GLContextImpl {
         }
     } else {
         glXExtProcAddressTable = new GLXExtProcAddressTable(new GLProcAddressResolver());
-        resetProcAddressTable(getGLXExtProcAddressTable());
+        resetProcAddressTable(getGLXExtProcAddressTable(), dlh);
         synchronized(mappedContextTypeObjectLock) {
             mappedGLXProcAddress.put(key, getGLXExtProcAddressTable());
             if(DEBUG) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index d825309ee..7121776f6 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -160,7 +160,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  public final GLDynamicLookupHelper getGLDynamicLookupHelper(final String profileName) {
+  public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
       return x11GLXDynamicLookupHelper;
   }
 
-- 
cgit v1.2.3