From e0ed09f8e2df570a9542f606a133c8fde074cbfe Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Thu, 26 Mar 2015 16:33:55 +0100
Subject: Bug 1150 - Fix GLContextImpl.createImpl(..) NoARBCreateContext and
 '!ARB GL >= 3.1' issues

This fix solves the described issues below.

Test cases added for onscreen and offscreen drawables,
the latter includes Window's bitmap special case.

GLContextImpl.createImpl(..): Fix NoARBCreateContext and '!ARB GL >= 3.1' issues:
=================================================================================
GLContextImpl.createImpl(..) implementation of X11GLXContext and WindowsWGLContext
wrongly handles the case of NoARBCreateContext.
Here the !ARB created context shall allow GL >= 3.1,
since ARB context creation is disabled and 'no mix' can occur.

The latter was already intended due to failure criteris 'createContextARBTried'
in:
  if( glCaps.getGLProfile().isGL3() && createContextARBTried ) {
     failure("createImpl ctx !ARB but ARB is used, profile > GL2 requested");
  }

Further, WindowsWGLContext treats glCaps.isBitmap()
within the 'createContextARBTried=true' case, but it shall never
tried using the ARB context creation method.
This even lead to the issue of creating a 1.1 context,
but having the ProcAddressTable being still on the GL > 2 cached table.
This is due to 'setGLFunctionAvailability(..)'.

Ensure 'setGLFunctionAvailability(..)' is functional
====================================================

Caller shall either throws an exception if method returns false
or issues a state reset.

In case 'setGLFunctionAvailability(..)' throws an exception itself,
the states are no issue.
---
 src/jogl/classes/jogamp/opengl/GLContextImpl.java  | 65 +++++++++++++---------
 src/jogl/classes/jogamp/opengl/egl/EGLContext.java | 34 +++++++----
 .../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java | 11 +++-
 .../opengl/windows/wgl/WindowsWGLContext.java      | 43 +++++++-------
 .../opengl/x11/glx/X11ExternalGLXContext.java      |  2 +-
 .../jogamp/opengl/x11/glx/X11GLXContext.java       | 39 +++++++------
 6 files changed, 113 insertions(+), 81 deletions(-)

(limited to 'src/jogl/classes')

diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index c56dc74da..401ea29c6 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -851,18 +851,25 @@ public abstract class GLContextImpl extends GLContext {
   }
 
   /**
-   * Platform dependent entry point for context creation.<br>
-   *
-   * This method is called from {@link #makeCurrentWithinLock()} .. {@link #makeCurrent()} .<br>
-   *
+   * Platform dependent entry point for context creation.
+   * <p>
+   * This method is called from {@link #makeCurrentWithinLock()} .. {@link #makeCurrent()} .
+   * </p>
+   * <p>
    * The implementation shall verify this context with a
-   * <code>MakeContextCurrent</code> call.<br>
-   *
-   * The implementation <b>must</b> leave the context current.<br>
-   *
+   * <code>MakeContextCurrent</code> call.
+   * </p>
+   * <p>
+   * The implementation <b>must</b> leave the context current.
+   * </p>
+   * <p>
+   * Non fatal context creation failure via return {@code false}
+   * is currently implemented for: {@code MacOSXCGLContext}.
+   * </p>
    * @param sharedWithHandle the shared context handle or 0
-   * @return true if successful, or false
-   * @throws GLException
+   * @return {@code true} if successful. Method returns {@code false} if the context creation failed non fatally,
+   * hence it may be created at a later time. Otherwise method throws {@link GLException}.
+   * @throws GLException if method fatally fails creating the context and no attempt shall be made at a later time.
    */
   protected abstract boolean createImpl(long sharedWithHandle) throws GLException ;
 
@@ -908,6 +915,15 @@ public abstract class GLContextImpl extends GLContext {
    */
   protected abstract void destroyContextARBImpl(long context);
 
+  protected final boolean isCreateContextARBAvail(final AbstractGraphicsDevice device) {
+    return !GLProfile.disableOpenGLARBContext &&
+           !GLRendererQuirks.existStickyDeviceQuirk(device, GLRendererQuirks.NoARBCreateContext);
+  }
+  protected final String getCreateContextARBAvailStr(final AbstractGraphicsDevice device) {
+    final boolean noARBCreateContext = GLRendererQuirks.existStickyDeviceQuirk(device, GLRendererQuirks.NoARBCreateContext);
+    return "disabled "+GLProfile.disableOpenGLARBContext+", quirk "+noARBCreateContext;
+  }
+
   /**
    * Platform independent part of using the <code>ARB_create_context</code>
    * mechanism to create a context.<br>
@@ -929,25 +945,12 @@ public abstract class GLContextImpl extends GLContext {
    */
   protected final long createContextARB(final long share, final boolean direct)
   {
-    if( GLProfile.disableOpenGLARBContext ||
-        GLRendererQuirks.existStickyDeviceQuirk(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(),
-                                                GLRendererQuirks.NoARBCreateContext) ) {
-        if( DEBUG ) {
-            System.err.println(getThreadName() + ": createContextARB: Disabled "+
-                    "- property disableOpenGLARBContext "+ GLProfile.disableOpenGLARBContext +
-                    ", quirk NoARBCreateContext "+GLRendererQuirks.existStickyDeviceQuirk(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(),
-                                                                                          GLRendererQuirks.NoARBCreateContext));
-        }
-        return 0;
-    }
     final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
     final AbstractGraphicsDevice device = config.getScreen().getDevice();
-
     if (DEBUG) {
       System.err.println(getThreadName() + ": createContextARB: mappedVersionsAvailableSet("+device.getConnection()+"): "+
                GLContext.getAvailableGLVersionsSet(device));
     }
-
     final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
     final GLProfile glp = glCaps.getGLProfile();
 
@@ -1016,7 +1019,7 @@ public abstract class GLContextImpl extends GLContext {
                             System.err.println("Quirk Triggerd: "+GLRendererQuirks.toString(GLRendererQuirks.GL4NeedsGL3Request)+": cause: OS "+Platform.getOSType()+", OS Version "+Platform.getOSVersionNumber());
                         }
                     }
-                    resetStates(false); // clean this context states, since creation was temporary
+                    resetStates(false); // clean the context states, since creation was temporary
                 }
             }
         }
@@ -1468,9 +1471,14 @@ public abstract class GLContextImpl extends GLContext {
    * the cache of which GL functions are available for calling through this
    * context. See {@link #isFunctionAvailable(String)} for more information on
    * the definition of "available".
-   * <br>
+   * <p>
    * All ProcaddressTables are being determined and cached, the GL version is being set
    * and the extension cache is determined as well.
+   * </p>
+   * <p>
+   * It is the callers responsibility to issue {@link #resetStates(boolean)}
+   * in case this method returns {@code false} or throws a {@link GLException}.
+   * </p>
    *
    * @param force force the setting, even if is already being set.
    *              This might be useful if you change the OpenGL implementation.
@@ -1489,13 +1497,16 @@ public abstract class GLContextImpl extends GLContext {
    * @return returns <code>true</code> if successful, otherwise <code>false</code>.<br>
    *                 If <code>strictMatch</code> is <code>false</code> method shall always return <code>true</code> or throw an exception.
    *                 If <code>false</code> is returned, no data has been cached or mapped, i.e. ProcAddressTable, Extensions, Version, etc.
+   * @throws GLException in case of an unexpected OpenGL related issue, e.g. missing expected GL function pointer.
    * @see #setContextVersion
    * @see com.jogamp.opengl.GLContext#CTX_OPTION_ANY
    * @see com.jogamp.opengl.GLContext#CTX_PROFILE_COMPAT
    * @see com.jogamp.opengl.GLContext#CTX_IMPL_ES2_COMPAT
    */
   protected final boolean setGLFunctionAvailability(final boolean force, int major, int minor, int ctxProfileBits,
-                                                    final boolean strictMatch, final boolean withinGLVersionsMapping) {
+                                                    final boolean strictMatch, final boolean withinGLVersionsMapping)
+                                                    throws GLException
+  {
     if( null != this.gl && null != glProcAddressTable && !force ) {
         return true; // already done and not forced
     }
@@ -1695,7 +1706,7 @@ public abstract class GLContextImpl extends GLContext {
         synchronized(mappedContextTypeObjectLock) {
             table = mappedGLProcAddress.get( contextFQN );
             if(null != table && !verifyInstance(glp, "ProcAddressTable", table)) {
-                throw new InternalError("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
+                throw new GLException("GLContext GL ProcAddressTable mapped key("+contextFQN+" - " + GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
                       ") -> "+ table.getClass().getName()+" not matching "+glp.getGLImplBaseClassName());
             }
         }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 9d7ad64f9..b6a05aeeb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -51,6 +51,7 @@ import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.egl.EGLExtImpl;
 import jogamp.opengl.egl.EGLExtProcAddressTable;
+import jogamp.opengl.windows.wgl.WindowsWGLContext;
 
 import com.jogamp.common.ExceptionUtils;
 import com.jogamp.common.nio.Buffers;
@@ -310,16 +311,25 @@ public class EGLContext extends GLContextImpl {
         final AbstractGraphicsDevice device = config.getScreen().getDevice();
         final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
         final GLProfile glp = glCaps.getGLProfile();
-
-        contextHandle = createContextARB(shareWithHandle, true);
-        if (DEBUG) {
-            if( 0 != contextHandle ) {
-                System.err.println(getThreadName() + ": EGLContext.createImpl: OK (ARB) on eglDevice "+device+
-                        ", eglConfig "+config+", "+glp+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError()));
-            } else {
-                System.err.println(getThreadName() + ": EGLContext.createImpl: NOT OK (ARB) - creation failed on eglDevice "+device+
-                        ", eglConfig "+config+", "+glp+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError()));
+        final boolean createContextARBAvailable = isCreateContextARBAvail(device);
+        if(DEBUG) {
+            System.err.println(getThreadName() + ": EGLContext.createImpl: START "+glCaps+", share "+toHexString(shareWithHandle));
+            System.err.println(getThreadName() + ": Use ARB[avail["+getCreateContextARBAvailStr(device)+
+                    "] -> "+createContextARBAvailable+"]]");
+        }
+        if( createContextARBAvailable ) {
+            contextHandle = createContextARB(shareWithHandle, true);
+            if (DEBUG) {
+                if( 0 != contextHandle ) {
+                    System.err.println(getThreadName() + ": createImpl: OK (ARB) on eglDevice "+device+
+                            ", eglConfig "+config+", "+glp+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError()));
+                } else {
+                    System.err.println(getThreadName() + ": createImpl: NOT OK (ARB) - creation failed on eglDevice "+device+
+                            ", eglConfig "+config+", "+glp+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError()));
+                }
             }
+        } else {
+            contextHandle = 0;
         }
         if( 0 == contextHandle ) {
             if( !glp.isGLES() ) {
@@ -339,18 +349,18 @@ public class EGLContext extends GLContextImpl {
                 EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_NO_SURFACE, EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT);
                 EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle);
                 contextHandle = 0;
-                throw new InternalError("setGLFunctionAvailability !strictMatch failed");
+                throw new GLException("setGLFunctionAvailability !strictMatch failed");
             }
         }
         if (DEBUG) {
-            System.err.println(getThreadName() + ": EGLContext.createImpl: Created OpenGL context 0x" +
+            System.err.println(getThreadName() + ": createImpl: Created OpenGL context 0x" +
                                Long.toHexString(contextHandle) +
                                ",\n\twrite surface 0x" + Long.toHexString(drawable.getHandle()) +
                                ",\n\tread  surface 0x" + Long.toHexString(drawableRead.getHandle())+
                                ",\n\t"+this+
                                ",\n\tsharing with 0x" + Long.toHexString(shareWithHandle));
         }
-        return 0 != contextHandle;
+        return true;
     }
 
     @Override
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 3c22e612f..d4fc0b005 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -289,8 +289,15 @@ public class MacOSXCGLContext extends GLContextImpl
   @Override
   protected boolean createImpl(final long shareWithHandle) throws GLException {
     final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
-    final GLCapabilitiesImmutable capabilitiesChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
-    final GLProfile glp = capabilitiesChosen.getGLProfile();
+    final AbstractGraphicsDevice device = config.getScreen().getDevice();
+    final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+    final GLProfile glp = glCaps.getGLProfile();
+    final boolean createContextARBAvailable = isCreateContextARBAvail(device);
+    if(DEBUG) {
+        System.err.println(getThreadName() + ": MacOSXCGLContext.createImpl: START "+glCaps+", share "+toHexString(shareWithHandle));
+        System.err.println(getThreadName() + ": Use ARB[avail["+getCreateContextARBAvailStr(device)+
+                "] -> "+createContextARBAvailable+"]]");
+    }
     if( glp.isGLES() ||
         ( glp.isGL3() && !isLionOrLater ) || ( glp.isGL4() && !isMavericksOrLater ) ) {
         throw new GLException("OpenGL profile not supported on MacOSX "+Platform.getOSVersionNumber()+": "+glp);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index 966a4dcf5..a8269ad5c 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -50,7 +50,6 @@ import com.jogamp.nativewindow.NativeSurface;
 import com.jogamp.opengl.GLContext;
 import com.jogamp.opengl.GLException;
 import com.jogamp.opengl.GLCapabilitiesImmutable;
-
 import com.jogamp.common.nio.Buffers;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
@@ -278,7 +277,7 @@ public class WindowsWGLContext extends GLContextImpl {
    * called by {@link #makeCurrentImpl()}.
    */
   @Override
-  protected boolean createImpl(long shareWithHandle) {
+  protected boolean createImpl(long shareWithHandle) throws GLException {
     final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
     final AbstractGraphicsDevice device = config.getScreen().getDevice();
     final WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
@@ -287,14 +286,18 @@ public class WindowsWGLContext extends GLContextImpl {
 
     isGLReadDrawableAvailable(); // trigger setup wglGLReadDrawableAvailable
 
-    if (DEBUG) {
-        System.err.println(getThreadName() + ": createImpl: START "+glCaps+", share "+toHexString(shareWithHandle));
+    final boolean createContextARBAvailable = isCreateContextARBAvail(device) && !glCaps.isBitmap();
+    final boolean sharedCreatedWithARB = null != sharedContext && sharedContext.isCreatedWithARBMethod();
+    if(DEBUG) {
+        System.err.println(getThreadName() + ": WindowsWGLContext.createImpl: START "+glCaps+", share "+toHexString(shareWithHandle));
+        System.err.println(getThreadName() + ": Use ARB[avail["+getCreateContextARBAvailStr(device)+
+                "], bitmap "+glCaps.isBitmap()+" -> "+createContextARBAvailable+
+                "], shared "+sharedCreatedWithARB+"]");
     }
-
     boolean createContextARBTried = false;
 
-    // utilize the shared context's GLXExt in case it was using the ARB method and it already exists ; exclude BITMAP
-    if( null != sharedContext && sharedContext.isCreatedWithARBMethod() && !glCaps.isBitmap() ) {
+    // utilize the shared context's GLXExt in case it was using the ARB method and it already exists
+    if( createContextARBAvailable && sharedCreatedWithARB ) {
         if ( sharedContext.getRendererQuirks().exist( GLRendererQuirks.NeedCurrCtx4ARBCreateContext ) ) {
             if(GLContext.CONTEXT_NOT_CURRENT == sharedContext.makeCurrent()) {
                 throw new GLException("Could not make Shared Context current: "+sharedContext);
@@ -327,34 +330,27 @@ public class WindowsWGLContext extends GLContextImpl {
         if( !setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT, false /* strictMatch */, null == sharedContext /* withinGLVersionsMapping */) ) { // use GL_VERSION
             WGL.wglMakeCurrent(0, 0); // release temp context
             WGL.wglDeleteContext(temp_ctx);
-            throw new InternalError("setGLFunctionAvailability !strictMatch failed");
+            throw new GLException("setGLFunctionAvailability !strictMatch failed");
         }
         WGL.wglMakeCurrent(0, 0); // release temp context
 
-        if( !createContextARBTried ) {
+        if( createContextARBAvailable && !createContextARBTried ) {
             // is*Available calls are valid since setGLFunctionAvailability(..) was called
-            final boolean isProcCreateContextAttribsARBAvailable;
-            final boolean isExtARBCreateContextAvailable;
-            if( !glCaps.isBitmap() ) { // exclude ARB if BITMAP
-                isProcCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB");
-                isExtARBCreateContextAvailable = isExtensionAvailable("WGL_ARB_create_context");
-            } else {
-                isProcCreateContextAttribsARBAvailable = false;
-                isExtARBCreateContextAvailable = false;
-            }
+            final boolean isProcCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB");
+            final boolean isExtARBCreateContextAvailable = isExtensionAvailable("WGL_ARB_create_context");
             if ( isProcCreateContextAttribsARBAvailable && isExtARBCreateContextAvailable ) {
                 // initial ARB context creation
                 contextHandle = createContextARB(shareWithHandle, true);
                 createContextARBTried=true;
                 if (DEBUG) {
                     if( 0 != contextHandle ) {
-                        System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+toHexString(shareWithHandle));
+                        System.err.println(getThreadName() + ": createImpl: OK (ARB, initial) share "+toHexString(shareWithHandle));
                     } else {
-                        System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+toHexString(shareWithHandle));
+                        System.err.println(getThreadName() + ": createImpl: NOT OK (ARB, initial) - creation failed - share "+toHexString(shareWithHandle));
                     }
                 }
             } else if (DEBUG) {
-                System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+toHexString(shareWithHandle)+
+                System.err.println(getThreadName() + ": createImpl: NOT OK (ARB, initial) - extension not available - share "+toHexString(shareWithHandle)+
                                    ", isProcCreateContextAttribsARBAvailable "+isProcCreateContextAttribsARBAvailable+
                                    ", isExtGLXARBCreateContextAvailable "+isExtARBCreateContextAvailable);
             }
@@ -378,10 +374,11 @@ public class WindowsWGLContext extends GLContextImpl {
             // otherwise context of similar profile but different creation method may not be share-able.
             WGL.wglMakeCurrent(0, 0);
             WGL.wglDeleteContext(temp_ctx);
-            throw new GLException(getThreadName()+": WindowsWGLContex.createContextImpl ctx !ARB but ARB is used, profile > GL2 requested (OpenGL >= 3.1). Requested: "+glCaps.getGLProfile()+", current: "+getGLVersion());
+            throw new GLException(getThreadName()+": createImpl ctx !ARB but ARB is used, profile > GL2 requested (OpenGL >= 3.1). Requested: "+glCaps.getGLProfile()+", current: "+getGLVersion());
         }
         if(DEBUG) {
-            System.err.println("WindowsWGLContext.createContext ARB not used, fall back to !ARB context "+getGLVersion());
+            System.err.println(getThreadName()+": createImpl ARB not used[avail "+createContextARBAvailable+
+                               ", tried "+createContextARBTried+"], fall back to !ARB context "+getGLVersion());
         }
 
         // continue with temp context
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index fab5895e8..274d16ddd 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -113,7 +113,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
   }
 
   @Override
-  protected boolean createImpl(final long shareWithHandle) {
+  protected boolean createImpl(final long shareWithHandle) throws GLException {
       return true;
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 4665dc17c..63b0b35c0 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -298,7 +298,7 @@ public class X11GLXContext extends GLContextImpl {
   }
 
   @Override
-  protected boolean createImpl(final long shareWithHandle) {
+  protected boolean createImpl(final long shareWithHandle) throws GLException {
     boolean direct = true; // try direct always
     isDirect = false; // fall back
 
@@ -314,6 +314,14 @@ public class X11GLXContext extends GLContextImpl {
 
     final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
     final GLProfile glp = glCaps.getGLProfile();
+    final boolean createContextARBAvailable = isCreateContextARBAvail(device) && config.hasFBConfig();
+    final boolean sharedCreatedWithARB = null != sharedContext && sharedContext.isCreatedWithARBMethod();
+    if(DEBUG) {
+        System.err.println(getThreadName() + ": X11GLXContext.createImpl: START "+glCaps+", share "+toHexString(shareWithHandle));
+        System.err.println(getThreadName() + ": Use ARB[avail["+getCreateContextARBAvailStr(device)+
+                "], fbCfg "+config.hasFBConfig()+" -> "+createContextARBAvailable+
+                "], shared "+sharedCreatedWithARB+"]");
+    }
 
     if( !config.hasFBConfig() ) {
         // not able to use FBConfig -> GLX 1.1
@@ -332,23 +340,22 @@ public class X11GLXContext extends GLContextImpl {
             glXReleaseContext(display); // release temp context
             GLX.glXDestroyContext(display, contextHandle);
             contextHandle = 0;
-            throw new InternalError("setGLFunctionAvailability !strictMatch failed.1");
+            throw new GLException("setGLFunctionAvailability !strictMatch failed.1");
         }
         isDirect = GLX.glXIsDirect(display, contextHandle);
         if (DEBUG) {
-            System.err.println(getThreadName() + ": createContextImpl: OK (old-1) share "+toHexString(shareWithHandle)+", direct "+isDirect+"/"+direct);
+            System.err.println(getThreadName() + ": createImpl: OK (old-1) share "+toHexString(shareWithHandle)+", direct "+isDirect+"/"+direct);
         }
         return true;
     }
-
     boolean createContextARBTried = false;
 
     // utilize the shared context's GLXExt in case it was using the ARB method and it already exists
-    if( null != sharedContext && sharedContext.isCreatedWithARBMethod() ) {
+    if( createContextARBAvailable && sharedCreatedWithARB ) {
         contextHandle = createContextARB(shareWithHandle, direct);
         createContextARBTried = true;
         if ( DEBUG && 0 != contextHandle ) {
-            System.err.println(getThreadName() + ": createContextImpl: OK (ARB, using sharedContext) share "+toHexString(shareWithHandle));
+            System.err.println(getThreadName() + ": createImpl: OK (ARB, using sharedContext) share "+toHexString(shareWithHandle));
         }
     }
 
@@ -366,10 +373,10 @@ public class X11GLXContext extends GLContextImpl {
         if( !setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT, false /* strictMatch */, null == sharedContext /* withinGLVersionsMapping */) ) { // use GL_VERSION
             glXReleaseContext(display); // release temp context
             GLX.glXDestroyContext(display, temp_ctx);
-            throw new InternalError("setGLFunctionAvailability !strictMatch failed.2");
+            throw new GLException("setGLFunctionAvailability !strictMatch failed.2");
         }
         glXReleaseContext(display); // release temp context
-        if( !createContextARBTried ) {
+        if( createContextARBAvailable && !createContextARBTried ) {
             // is*Available calls are valid since setGLFunctionAvailability(..) was called
             final boolean isProcCreateContextAttribsARBAvailable = isFunctionAvailable("glXCreateContextAttribsARB");
             final boolean isExtARBCreateContextAvailable = isExtensionAvailable("GLX_ARB_create_context");
@@ -379,13 +386,13 @@ public class X11GLXContext extends GLContextImpl {
                 createContextARBTried=true;
                 if (DEBUG) {
                     if( 0 != contextHandle ) {
-                        System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+toHexString(shareWithHandle));
+                        System.err.println(getThreadName() + ": createImpl: OK (ARB, initial) share "+toHexString(shareWithHandle));
                     } else {
-                        System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+toHexString(shareWithHandle));
+                        System.err.println(getThreadName() + ": createImpl: NOT OK (ARB, initial) - creation failed - share "+toHexString(shareWithHandle));
                     }
                 }
             } else if( DEBUG ) {
-                System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+toHexString(shareWithHandle)+
+                System.err.println(getThreadName() + ": createImpl: NOT OK (ARB, initial) - extension not available - share "+toHexString(shareWithHandle)+
                                    ", isProcCreateContextAttribsARBAvailable "+isProcCreateContextAttribsARBAvailable+
                                    ", isExtGLXARBCreateContextAvailable "+isExtARBCreateContextAvailable);
             }
@@ -408,11 +415,11 @@ public class X11GLXContext extends GLContextImpl {
             // otherwise context of similar profile but different creation method may not be share-able.
             glXReleaseContext(display);
             GLX.glXDestroyContext(display, temp_ctx);
-            throw new GLException(getThreadName()+": X11GLXContext.createContextImpl ARB n/a but required, profile > GL2 requested (OpenGL >= 3.1). Requested: "+glp+", current: "+getGLVersion());
+            throw new GLException(getThreadName()+": createImpl ARB n/a but required, profile > GL2 requested (OpenGL >= 3.1). Requested: "+glp+", current: "+getGLVersion());
         }
-
         if(DEBUG) {
-            System.err.println(getThreadName()+": X11GLXContext.createContextImpl ARB not used, fall back to !ARB context "+getGLVersion());
+            System.err.println(getThreadName()+": createImpl ARB not used[avail "+createContextARBAvailable+
+                               ", tried "+createContextARBTried+"], fall back to !ARB context "+getGLVersion());
         }
 
         // continue with temp context
@@ -423,12 +430,12 @@ public class X11GLXContext extends GLContextImpl {
             throw new GLException(getThreadName()+": Error making context(1) current: display "+toHexString(display)+", context "+toHexString(contextHandle)+", drawable "+drawable);
         }
         if (DEBUG) {
-            System.err.println(getThreadName() + ": createContextImpl: OK (old-2) share "+toHexString(shareWithHandle));
+            System.err.println(getThreadName() + ": createImpl: OK (old-2) share "+toHexString(shareWithHandle));
         }
     }
     isDirect = GLX.glXIsDirect(display, contextHandle);
     if (DEBUG) {
-        System.err.println(getThreadName() + ": createContextImpl: OK direct "+isDirect+"/"+direct);
+        System.err.println(getThreadName() + ": createImpl: OK direct "+isDirect+"/"+direct);
     }
 
     return true;
-- 
cgit v1.2.3