From 2dce639c479f820d1a1e701f5eddffc4b02f5e0f Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Thu, 7 Nov 2013 08:36:46 +0100
Subject: Bug 890 - Fix GLES3 Profile Mapping, i.e. GL2ES2 queries and
 mappings; Validate isGLES*() usage and definition ; Add and use
 ShaderCode.createExtensionDirective(..)

- Fix GLES3 Profile Mapping, i.e. GL2ES2 queries and mappings
  - GLProfile: Add GL2ES2 -> ES3 mapping
  - EGLContext: Reuqest major '3' for ES3
  - EGLGLCapabilities/EGLGraphicsConfiguration: Consider EGLExt.EGL_OPENGL_ES3_BIT_KHR

- Validate isGLES*() usage and definition
  - Fix BuildComposablePipeline's isGLES() code

  - For GLSL related queries use isGLES() instead of isGLES2(),
    which would exclude ES3

- Add and use ShaderCode.createExtensionDirective(..)
  - Supporting creating GLSL extension directives while reusing strings from GLExtensions

- Minor cleanup of GLContextImpl.setGLFuncAvail(..)
---
 make/scripts/tests.sh                              |  4 +-
 .../gluegen/opengl/BuildComposablePipeline.java    |  2 +-
 .../com/jogamp/graph/curve/opengl/Renderer.java    |  2 +-
 .../classes/com/jogamp/opengl/GLExtensions.java    |  1 +
 .../com/jogamp/opengl/util/glsl/ShaderCode.java    | 28 +++++++++++--
 .../opengl/util/texture/TextureSequence.java       |  1 -
 src/jogl/classes/javax/media/opengl/GLBase.java    |  2 +-
 src/jogl/classes/javax/media/opengl/GLProfile.java | 49 ++++++++++++----------
 .../graph/curve/opengl/RegionRendererImpl01.java   |  5 ++-
 .../graph/curve/opengl/TextRendererImpl01.java     |  5 ++-
 src/jogl/classes/jogamp/opengl/GLContextImpl.java  | 34 ++++++++-------
 src/jogl/classes/jogamp/opengl/egl/EGLContext.java | 21 ++++++----
 .../classes/jogamp/opengl/egl/EGLDrawable.java     |  4 +-
 .../jogamp/opengl/egl/EGLDrawableFactory.java      |  9 +---
 .../jogamp/opengl/egl/EGLGLCapabilities.java       |  7 +++-
 .../opengl/egl/EGLGraphicsConfiguration.java       |  2 +
 .../jogamp/opengl/util/av/GLMediaPlayerImpl.java   |  4 +-
 .../jogl/demos/es2/TextureSequenceCubeES2.java     |  5 ++-
 .../test/junit/jogl/demos/es2/av/MovieSimple.java  |  5 ++-
 19 files changed, 117 insertions(+), 73 deletions(-)

diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 53e4e22cd..029866d4e 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -308,7 +308,7 @@ function testawtswt() {
 #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NEWT $*
 #testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $*
@@ -337,7 +337,7 @@ function testawtswt() {
 #
 #testnoawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001RawInit00NEWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001GLJPanelInit01AWT $*
-testawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001GLJPanelInit02AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001GLJPanelInit02AWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001GLWindowInit03NEWT $*
 
 #
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
index b7a9c270e..df60d2f73 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildComposablePipeline.java
@@ -667,7 +667,7 @@ public class BuildComposablePipeline {
             if( 0 != (GEN_GL_IDENTITY_BY_ASSIGNABLE_CLASS & getMode() ) ) {
                 output.println("  @Override");
                 output.println("  public final boolean isGLES() {");
-                output.println("    return isGLES2() || isGLES1();");
+                output.println("    return isGLES3() || isGLES2() || isGLES1();");
                 output.println("  }");
             } else {
                 emitGLIsMethod(output, "GLES");
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
index c642fb652..8783906c2 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
@@ -279,7 +279,7 @@ public abstract class Renderer {
     public static final String es2_precision_fp = "\nprecision mediump float;\nprecision mediump int;\nprecision mediump sampler2D;\n";
 
     protected String getFragmentShaderPrecision(GL2ES2 gl) {
-        if( gl.isGLES2() ) {
+        if( gl.isGLES() ) {
             return es2_precision_fp;
         }
         if( ShaderCode.requiresGL3DefaultPrecision(gl) ) {
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
index c7aadcd14..da9e08a32 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -72,6 +72,7 @@ public class GLExtensions {
   public static final String OES_read_format                 = "GL_OES_read_format";
   public static final String OES_single_precision            = "GL_OES_single_precision";
   public static final String OES_EGL_image_external          = "GL_OES_EGL_image_external";
+  public static final String OES_standard_derivatives        = "GL_OES_standard_derivatives";
 
   public static final String ARB_gpu_shader_fp64             = "GL_ARB_gpu_shader_fp64";
   public static final String ARB_shader_objects              = "GL_ARB_shader_objects";
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
index 206aa0fd7..6a64edeb5 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -843,8 +843,28 @@ public class ShaderCode {
     /** Default precision of GLSL &ge; 1.30 as required until &lt; 1.50 for {@link GL2ES2#GL_FRAGMENT_SHADER fragment-shader}: {@value #gl3_default_precision_fp}. See GLSL Spec 1.30-1.50 Section 4.5.3. */
     public static final String gl3_default_precision_fp = "\nprecision highp float;\nprecision mediump int;\n/*precision mediump sampler2D;*/\n";
 
-    /** Prefer <code>enable</code> over <code>require</code>, since it won't force a failure. */
-    public static final String extOESDerivativesEnable = "#extension GL_OES_standard_derivatives : enable\n";
+    /** <i>Behavior</i> for GLSL extension directive, see {@link #createExtensionDirective(String, String)}, value {@value}. */
+    public static final String REQUIRE = "require";
+    /** <i>Behavior</i> for GLSL extension directive, see {@link #createExtensionDirective(String, String)}, value {@value}. */
+    public static final String ENABLE = "enable";
+    /** <i>Behavior</i> for GLSL extension directive, see {@link #createExtensionDirective(String, String)}, value {@value}. */
+    public static final String DISABLE = "disable";
+    /** <i>Behavior</i> for GLSL extension directive, see {@link #createExtensionDirective(String, String)}, value {@value}. */
+    public static final String WARN = "warn";
+
+    /**
+     * Creates a GLSL extension directive.
+     * <p>
+     * Prefer {@link #ENABLE} over {@link #REQUIRE}, since the latter will force a failure if not supported.
+     * </p>
+     *
+     * @param extensionName
+     * @param behavior shall be either {@link #REQUIRE}, {@link #ENABLE}, {@link #DISABLE} or {@link #WARN}
+     * @return the complete extension directive
+     */
+    public static String createExtensionDirective(String extensionName, String behavior) {
+        return "#extension " + extensionName + " : " + behavior;
+    }
 
     /**
      * Add GLSL version at the head of this shader source code.
@@ -915,7 +935,7 @@ public class ShaderCode {
 
     /** Returns true, if GLSL version requires default precision, i.e. ES2 or GLSL [1.30 .. 1.50[. */
     public static final boolean requiresDefaultPrecision(GL2ES2 gl) {
-        if( gl.isGLES2() || gl.isGLES3() ) {
+        if( gl.isGLES() ) {
             return true;
         }
         return requiresGL3DefaultPrecision(gl);
@@ -979,7 +999,7 @@ public class ShaderCode {
         } else {
             pos = 0;
         }
-        if( gl.isGLES2() && null != esDefaultPrecision ) {
+        if( gl.isGLES() && null != esDefaultPrecision ) {
             pos = insertShaderSource(0, pos, esDefaultPrecision);
         } else {
             pos = addDefaultShaderPrecision(gl, pos);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
index c34e019c2..6f1dd4c64 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
@@ -105,7 +105,6 @@ import com.jogamp.opengl.util.TimeFrameI;
  *
  */
 public interface TextureSequence {
-    public static final String GL_OES_EGL_image_external_Required_Prelude = "#extension GL_OES_EGL_image_external : enable\n";
     public static final String samplerExternalOES = "samplerExternalOES";
     public static final String sampler2D = "sampler2D";
 
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index e84dd7be9..a19a99196 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -150,7 +150,7 @@ public interface GLBase {
 
   /**
    * Indicates whether this GL object conforms to one of the OpenGL ES profiles,
-   * see {@link #isGLES1()} and {@link #isGLES2()}.
+   * see {@link #isGLES1()}, {@link #isGLES2()} and {@link #isGLES3()}.
    * @see GLContext#isGLES()
    */
   public boolean isGLES();
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index c04971176..64c8a6243 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -278,7 +278,7 @@ public class GLProfile {
         if(useIndent) {
             doIndent(sb, indent, indentCount).append("Natives");
             indentCount++;
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4bc).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4bc+" ").append(indent);
         } else {
             sb.append("Natives["+GL4bc+" ");
         }
@@ -291,7 +291,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4+" ").append(indent);
         } else {
             sb.append(", "+GL4+" ");
         }
@@ -304,7 +304,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES3).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES3+" ").append(indent);
         } else {
             sb.append(", "+GLES3+" ");
         }
@@ -317,7 +317,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL3bc).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL3bc+" ").append(indent);
         } else {
             sb.append(", "+GL3bc+" ");
         }
@@ -330,7 +330,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL3).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL3+" ").append(indent);
         } else {
             sb.append(", "+GL3+" ");
         }
@@ -343,7 +343,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2+" ").append(indent);
         } else {
             sb.append(", "+GL2+" ");
         }
@@ -356,7 +356,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES2).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES2+" ").append(indent);
         } else {
             sb.append(", "+GLES2+" ");
         }
@@ -369,7 +369,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES1).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES1+" ").append(indent);
         } else {
             sb.append(", "+GLES1+" ");
         }
@@ -391,7 +391,7 @@ public class GLProfile {
         }
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4ES3).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4ES3+" ").append(indent);
         } else {
             sb.append(", "+GL4ES3+" ");
         }
@@ -399,7 +399,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2GL3).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2GL3+" ").append(indent);
         } else {
             sb.append(", "+GL2GL3+" ");
         }
@@ -407,7 +407,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2ES2).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2ES2+" ").append(indent);
         } else {
             sb.append(", "+GL2ES2+" ");
         }
@@ -415,7 +415,7 @@ public class GLProfile {
         allCount++;
 
         if(useIndent) {
-            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2ES1).append(indent);
+            doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2ES1+" ").append(indent);
         } else {
             sb.append(", "+GL2ES1+" ");
         }
@@ -438,7 +438,7 @@ public class GLProfile {
                     if(useIndent) {
                         doIndent(sb.append(Platform.getNewline()), indent, indentCount);
                     }
-                    sb.append(entry.getKey()+(useIndent?"\t":" ")+entry.getValue());
+                    sb.append(entry.getKey()+(useIndent?" \t":" ")+entry.getValue());
                     if(!useIndent) {
                         sb.append(", ");
                     }
@@ -1208,17 +1208,17 @@ public class GLProfile {
 
     /** Indicates whether this profile uses the native OpenGL ES2 implementations. */
     public final boolean usesNativeGLES2() {
-        return GLES3 == getImplName() || GLES2 == getImplName();
+        return GLES2 == getImplName();
     }
 
-    /** Indicates whether this profile uses the native OpenGL ES2 implementations. */
+    /** Indicates whether this profile uses the native OpenGL ES3 implementations. */
     public final boolean usesNativeGLES3() {
         return GLES3 == getImplName();
     }
 
     /** Indicates whether this profile uses either of the native OpenGL ES implementations. */
     public final boolean usesNativeGLES() {
-        return usesNativeGLES2() || usesNativeGLES1();
+        return usesNativeGLES3() || usesNativeGLES2() || usesNativeGLES1();
     }
 
     /**
@@ -1945,33 +1945,40 @@ public class GLProfile {
             final boolean es2HardwareRasterizer[] = new boolean[1];
             final boolean gles2Available = hasGLES3Impl && ( esCtxUndef || GLContext.isGLES2Available(device, es2HardwareRasterizer) );
             final boolean gles2HWAvailable = gles2Available && es2HardwareRasterizer[0] ;
+            final boolean es3HardwareRasterizer[] = new boolean[1];
+            final boolean gles3Available = hasGLES3Impl && ( esCtxUndef || GLContext.isGLES3Available(device, es3HardwareRasterizer) );
+            final boolean gles3HWAvailable = gles3Available && es3HardwareRasterizer[0] ;
             if(hasGL234Impl) {
                 if(GLContext.isGL4Available(device, isHardwareRasterizer)) {
-                    if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+                    if( (!gles3HWAvailable && !gles2HWAvailable ) || isHardwareRasterizer[0] ) {
                         return GL4;
                     }
                 }
                 if(GLContext.isGL4bcAvailable(device, isHardwareRasterizer)) {
-                    if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+                    if( (!gles3HWAvailable && !gles2HWAvailable ) || isHardwareRasterizer[0] ) {
                         return GL4bc;
                     }
                 }
                 if(GLContext.isGL3Available(device, isHardwareRasterizer)) {
-                    if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+                    if( (!gles3HWAvailable && !gles2HWAvailable ) || isHardwareRasterizer[0] ) {
                         return GL3;
                     }
                 }
                 if(GLContext.isGL3bcAvailable(device, isHardwareRasterizer)) {
-                    if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+                    if( (!gles3HWAvailable && !gles2HWAvailable ) || isHardwareRasterizer[0] ) {
                         return GL3bc;
                     }
                 }
                 if(desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer)) {
-                    if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+                    if( (!gles3HWAvailable && !gles2HWAvailable ) || isHardwareRasterizer[0] ) {
                         return GL2;
                     }
                 }
             }
+            if(gles3Available && ( !gles2HWAvailable || gles3HWAvailable ) ) {
+                isHardwareRasterizer[0] = es3HardwareRasterizer[0];
+                return GLES3;
+            }
             if(gles2Available) {
                 isHardwareRasterizer[0] = es2HardwareRasterizer[0];
                 return GLES2;
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
index 012b1d1dd..31ad974d0 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java
@@ -36,6 +36,7 @@ import com.jogamp.graph.curve.Region;
 import com.jogamp.graph.curve.opengl.GLRegion;
 import com.jogamp.graph.curve.opengl.RegionRenderer;
 import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.util.glsl.ShaderCode;
 import com.jogamp.opengl.util.glsl.ShaderProgram;
 import com.jogamp.opengl.util.glsl.ShaderState;
@@ -57,8 +58,8 @@ public class RegionRendererImpl01 extends RegionRenderer {
         rsVp.defaultShaderCustomization(gl, true, true);
         // rsFp.defaultShaderCustomization(gl, true, true);
         int pos = rsFp.addGLSLVersion(gl);
-        if( gl.isGLES2() ) {
-            pos = rsFp.insertShaderSource(0, pos, ShaderCode.extOESDerivativesEnable);
+        if( gl.isGLES() ) {
+            pos = rsFp.insertShaderSource(0, pos, ShaderCode.createExtensionDirective(GLExtensions.OES_standard_derivatives, ShaderCode.ENABLE));
         }
         final String rsFpDefPrecision =  getFragmentShaderPrecision(gl);
         if( null != rsFpDefPrecision ) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
index 60758b90b..4ec4d1d98 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java
@@ -36,6 +36,7 @@ import jogamp.graph.curve.text.GlyphString;
 import com.jogamp.graph.curve.opengl.RenderState;
 import com.jogamp.graph.curve.opengl.TextRenderer;
 import com.jogamp.graph.font.Font;
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.util.glsl.ShaderCode;
 import com.jogamp.opengl.util.glsl.ShaderProgram;
 import com.jogamp.opengl.util.glsl.ShaderState;
@@ -56,8 +57,8 @@ public class TextRendererImpl01 extends TextRenderer {
         rsVp.defaultShaderCustomization(gl, true, true);
         // rsFp.defaultShaderCustomization(gl, true, true);
         int pos = rsFp.addGLSLVersion(gl);
-        if( gl.isGLES2() ) {
-            pos = rsFp.insertShaderSource(0, pos, ShaderCode.extOESDerivativesEnable);
+        if( gl.isGLES() ) {
+            pos = rsFp.insertShaderSource(0, pos, ShaderCode.createExtensionDirective(GLExtensions.OES_standard_derivatives, ShaderCode.ENABLE));
         }
         final String rsFpDefPrecision =  getFragmentShaderPrecision(gl);
         if( null != rsFpDefPrecision ) {
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index d43da2c3e..42c877ad5 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -1305,11 +1305,8 @@ public abstract class GLContextImpl extends GLContext {
    * <p>
    * If the GL query fails, major will be zero.
    * </p>
-   * <p>
-   * Note: Non ARB ctx is limited to GL 3.0.
-   * </p>
    */
-  private final boolean getGLIntVersion(int[] glIntMajor, int[] glIntMinor, int ctp)  {
+  private final boolean getGLIntVersion(int[] glIntMajor, int[] glIntMinor)  {
     glIntMajor[0] = 0; // clear
     final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
     final long _glGetIntegerv = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv");
@@ -1408,14 +1405,15 @@ public abstract class GLContextImpl extends GLContext {
     if (DEBUG) {
         System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Pre version verification - expected "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+", strictMatch "+strictMatch+", glVersionsMapping " +withinGLVersionsMapping);
     }
-    boolean versionValidated = false;
-    boolean versionGL3IntFailed = false;
+
+    final boolean versionGL3IntOK;
     {
-        // Validate the requested version w/ the GL-version from an integer query.
+        // Validate the requested version w/ the GL-version from an integer query,
+        // as supported by GL [ES] >= 3.0 implementation.
         final VersionNumber hasGLVersionByInt;
         {
             final int[] glIntMajor = new int[] { 0 }, glIntMinor = new int[] { 0 };
-            final boolean getGLIntVersionOK = getGLIntVersion(glIntMajor, glIntMinor, ctxProfileBits);
+            final boolean getGLIntVersionOK = getGLIntVersion(glIntMajor, glIntMinor);
             if( !getGLIntVersionOK ) {
                 final String errMsg = "Fetching GL Integer Version failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null);
                 if( strictMatch ) {
@@ -1432,7 +1430,7 @@ public abstract class GLContextImpl extends GLContext {
             hasGLVersionByInt = new VersionNumber(glIntMajor[0], glIntMinor[0], 0);
         }
         if (DEBUG) {
-            System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Version verification (Int): "+glVersion+", "+hasGLVersionByInt);
+            System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Version verification (Int): String "+glVersion+", Number "+hasGLVersionByInt);
         }
 
         // Only validate if a valid int version was fetched, otherwise cont. w/ version-string method -> 3.0 > Version || Version > MAX!
@@ -1455,16 +1453,20 @@ public abstract class GLContextImpl extends GLContext {
             // Use returned GL version!
             major = hasGLVersionByInt.getMajor();
             minor = hasGLVersionByInt.getMinor();
-            versionValidated = true;
+            versionGL3IntOK = true;
         } else {
-            versionGL3IntFailed = true;
+            versionGL3IntOK = false;
         }
     }
-    if( !versionValidated ) {
+    final boolean versionValidated;
+
+    if( versionGL3IntOK ) {
+        versionValidated = true;
+    } else {
         // Validate the requested version w/ the GL-version from the version string.
         final VersionNumber hasGLVersionByString = getGLVersionNumber(ctxProfileBits, glVersion);
         if (DEBUG) {
-            System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Version verification (String): "+glVersion+", "+hasGLVersionByString);
+            System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Version verification (String): String "+glVersion+", Number "+hasGLVersionByString);
         }
 
         // Only validate if a valid string version was fetched -> MIN > Version || Version > MAX!
@@ -1484,7 +1486,7 @@ public abstract class GLContextImpl extends GLContext {
                 }
                 return false;
             }
-            if( strictMatch && versionGL3IntFailed && major >= 3 ) {
+            if( strictMatch && !versionGL3IntOK && major >= 3 ) {
                 if(DEBUG) {
                     System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: FAIL, GL3/ES3 version Int failed, String: "+GLContext.getGLVersion(major, minor, ctxProfileBits, null)+" -> "+glVersion+", "+hasGLVersionByString);
                 }
@@ -1494,6 +1496,8 @@ public abstract class GLContextImpl extends GLContext {
             major = hasGLVersionByString.getMajor();
             minor = hasGLVersionByString.getMinor();
             versionValidated = true;
+        } else {
+            versionValidated = false;
         }
     }
     if( strictMatch && !versionValidated ) {
@@ -1506,7 +1510,7 @@ public abstract class GLContextImpl extends GLContext {
         System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Post version verification req "+
                 GLContext.getGLVersion(reqGLVersion.getMajor(), reqGLVersion.getMinor(), reqCtxProfileBits, null)+" -> has "+
                 GLContext.getGLVersion(major, minor, ctxProfileBits, null)+
-                ", strictMatch "+strictMatch+", versionValidated "+versionValidated+", versionGL3IntFailed "+versionGL3IntFailed);
+                ", strictMatch "+strictMatch+", versionValidated "+versionValidated+", versionGL3IntOK "+versionGL3IntOK);
     }
 
     if( major < 2 ) { // there is no ES2/3-compat for a profile w/ major < 2
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 903a4c461..b2f06dce6 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -135,13 +135,7 @@ public class EGLContext extends GLContextImpl {
 
     @Override
     protected void destroyImpl() throws GLException {
-      if (!EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle)) {
-          final int eglError = EGL.eglGetError();
-          if(EGL.EGL_SUCCESS != eglError) { /* oops, Mesa EGL impl. may return false, but has no EGL error */
-              throw new GLException("Error destroying OpenGL context " + toHexString(contextHandle) +
-                                    ": error code " + toHexString(eglError));
-          }
-      }
+        destroyContextARBImpl(contextHandle);
     }
 
     @Override
@@ -151,7 +145,13 @@ public class EGLContext extends GLContextImpl {
 
     @Override
     protected void destroyContextARBImpl(long _context) {
-        // FIXME
+        if (!EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), _context)) {
+            final int eglError = EGL.eglGetError();
+            if(EGL.EGL_SUCCESS != eglError) { /* oops, Mesa EGL impl. may return false, but has no EGL error */
+                throw new GLException("Error destroying OpenGL context " + toHexString(_context) +
+                        ": error code " + toHexString(eglError));
+            }
+        }
     }
 
     @Override
@@ -180,12 +180,14 @@ public class EGLContext extends GLContextImpl {
             }
         }
 
+        // Cannot check extension 'EGL_KHR_create_context' before having one current!
+
         final IntBuffer contextAttrsNIO;
         final int contextVersionReq, contextVersionAttr;
         {
             if ( glProfile.usesNativeGLES3() ) {
                 contextVersionReq = 3;
-                contextVersionAttr = 2;
+                contextVersionAttr = 3;
             } else if ( glProfile.usesNativeGLES2() ) {
                 contextVersionReq = 2;
                 contextVersionAttr = 2;
@@ -195,6 +197,7 @@ public class EGLContext extends GLContextImpl {
             } else {
                 throw new GLException("Error creating OpenGL context - invalid GLProfile: "+glProfile);
             }
+            // EGLExt.EGL_CONTEXT_MAJOR_VERSION_KHR == EGL.EGL_CONTEXT_CLIENT_VERSION
             final int[] contextAttrs = new int[] { EGL.EGL_CONTEXT_CLIENT_VERSION, contextVersionAttr, EGL.EGL_NONE };
             contextAttrsNIO = Buffers.newDirectIntBuffer(contextAttrs);
         }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index ab28fb3fb..f184edae3 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -166,7 +166,9 @@ public abstract class EGLDrawable extends GLDrawableImpl {
 
     @Override
     public GLDynamicLookupHelper getGLDynamicLookupHelper() {
-        if (getGLProfile().usesNativeGLES2()) {
+        if (getGLProfile().usesNativeGLES3()) {
+            return getFactoryImpl().getGLDynamicLookupHelper(3);
+        } else if (getGLProfile().usesNativeGLES2()) {
             return getFactoryImpl().getGLDynamicLookupHelper(2);
         } else if (getGLProfile().usesNativeGLES1()) {
             return getFactoryImpl().getGLDynamicLookupHelper(1);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 4202c7454..1438107fe 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -615,12 +615,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         }
         if( null != eglES2DynamicLookupHelper ) {
             madeCurrentES3 = mapAvailableEGLESConfig(adevice, 3, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2);
-            if( madeCurrentES3 ) {
-                // Only support highest - FIXME: Proper ES2/ES3 profile selection
-                madeCurrentES2 = false;
-            } else {
-                madeCurrentES2 = mapAvailableEGLESConfig(adevice, 2, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2);
-            }
+            madeCurrentES2 = mapAvailableEGLESConfig(adevice, 2, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2);
         } else {
             madeCurrentES2 = false;
             madeCurrentES3 = false;
@@ -668,7 +663,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
 
     @Override
     public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) {
-        if (2==esProfile) {
+        if ( 2==esProfile || 3==esProfile ) {
             return eglES2DynamicLookupHelper;
         } else if (1==esProfile) {
             return eglES1DynamicLookupHelper;
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
index b61624d79..e28b53235 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
@@ -101,7 +101,6 @@ public class EGLGLCapabilities extends GLCapabilities {
     if(null == glp) {
         return true;
     }
-    /** FIXME: EGLExt.EGL_OPENGL_ES3_BIT_KHR OK ? */
     if(0 != (renderableType & EGLExt.EGL_OPENGL_ES3_BIT_KHR) && glp.usesNativeGLES3()) {
         return true;
     }
@@ -118,6 +117,9 @@ public class EGLGLCapabilities extends GLCapabilities {
   }
 
   public static GLProfile getCompatible(EGLGraphicsDevice device, int renderableType) {
+    if(0 != (renderableType & EGLExt.EGL_OPENGL_ES3_BIT_KHR) && GLProfile.isAvailable(device, GLProfile.GLES3)) {
+        return GLProfile.get(device, GLProfile.GLES3);
+    }
     if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(device, GLProfile.GLES2)) {
         return GLProfile.get(device, GLProfile.GLES2);
     }
@@ -145,6 +147,9 @@ public class EGLGLCapabilities extends GLCapabilities {
     if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT)) {
         if(!first) sink.append(", "); sink.append("GLES2");  first=false;
     }
+    if(0 != (renderableType & EGLExt.EGL_OPENGL_ES3_BIT_KHR)) {
+        if(!first) sink.append(", "); sink.append("GLES3");  first=false;
+    }
     if(0 != (renderableType & EGL.EGL_OPENVG_API)) {
         if(!first) sink.append(", "); sink.append("VG");  first=false;
     }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index dd7bf99cb..789168b68 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -415,6 +415,8 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
             attrs.put(idx++, EGL.EGL_OPENGL_ES_BIT);
         } else if(caps.getGLProfile().usesNativeGLES2()) {
             attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
+        } else if(caps.getGLProfile().usesNativeGLES3()) {
+            attrs.put(idx++, EGLExt.EGL_OPENGL_ES3_BIT_KHR);
         } else {
             attrs.put(idx++, EGL.EGL_OPENGL_BIT);
         }
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index 91647394d..86e19c920 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -49,9 +49,11 @@ import com.jogamp.common.net.URIQueryProps;
 import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.LFRingbuffer;
 import com.jogamp.common.util.Ringbuffer;
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.util.TimeFrameI;
 import com.jogamp.opengl.util.av.AudioSink;
 import com.jogamp.opengl.util.av.GLMediaPlayer;
+import com.jogamp.opengl.util.glsl.ShaderCode;
 import com.jogamp.opengl.util.texture.Texture;
 import com.jogamp.opengl.util.texture.TextureSequence;
 import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
@@ -221,7 +223,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
     public String getRequiredExtensionsShaderStub() throws IllegalStateException {
         checkGLInit();
         if(GLES2.GL_TEXTURE_EXTERNAL_OES == textureTarget) {
-            return TextureSequence.GL_OES_EGL_image_external_Required_Prelude;
+            return ShaderCode.createExtensionDirective(GLExtensions.OES_EGL_image_external, ShaderCode.ENABLE);
         }
         return "";
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
index e38b9c6e3..a2d3eb6bf 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
@@ -43,6 +43,7 @@ import com.jogamp.newt.Window;
 import com.jogamp.newt.event.MouseAdapter;
 import com.jogamp.newt.event.MouseEvent;
 import com.jogamp.newt.event.MouseListener;
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.JoglVersion;
 import com.jogamp.opengl.util.GLArrayDataServer;
 import com.jogamp.opengl.util.PMVMatrix;
@@ -196,8 +197,8 @@ public class TextureSequenceCubeES2 implements GLEventListener {
         final Texture tex= frame.getTexture();
         
         final boolean useExternalTexture = GLES2.GL_TEXTURE_EXTERNAL_OES == tex.getTarget();
-        if(useExternalTexture && !gl.isExtensionAvailable("GL_OES_EGL_image_external")) {
-            throw new GLException("GL_OES_EGL_image_external requested but not available");
+        if(useExternalTexture && !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external)) {
+            throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
         }
         
         initShader(gl);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
index d29381f35..a087e7e46 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
@@ -54,6 +54,7 @@ import com.jogamp.newt.event.MouseListener;
 import com.jogamp.newt.event.WindowAdapter;
 import com.jogamp.newt.event.WindowEvent;
 import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.JoglVersion;
 import com.jogamp.opengl.test.junit.util.MiscUtils;
 import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -386,8 +387,8 @@ public class MovieSimple implements GLEventListener {
             }
             tex = mPlayer.getLastTexture().getTexture();
             useExternalTexture = GLES2.GL_TEXTURE_EXTERNAL_OES == tex.getTarget();
-            if(useExternalTexture && !gl.isExtensionAvailable("GL_OES_EGL_image_external")) {
-                throw new GLException("GL_OES_EGL_image_external requested but not available");
+            if(useExternalTexture && !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external)) {
+                throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
             }
             if(!mPlayerShared) {
                 mPlayer.setTextureMinMagFilter( new int[] { GL.GL_NEAREST, GL.GL_LINEAR } );
-- 
cgit v1.2.3