[GTK] When using EGL, request an OpenGL core profile when possible
authormagomez@igalia.com <magomez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Mar 2018 11:51:58 +0000 (11:51 +0000)
committermagomez@igalia.com <magomez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Mar 2018 11:51:58 +0000 (11:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178719

Reviewed by Carlos Garcia Campos.

When using EGL and OpenGL, try to request a context with version >= 3.2 with a core profile
whenever possible. In order to to this, we require EGL version 1.5 or version 1.4 with the
extension EGL_KHR_create_context. If EGL requirements are not met, or we cannot get a
context with version >= 3.2 then use whatever EGL gives us.

Covered by existent tests.

* platform/graphics/egl/GLContextEGL.cpp:
(WebCore::GLContextEGL::createWindowContext):
(WebCore::GLContextEGL::createPbufferContext):
(WebCore::GLContextEGL::createSurfacelessContext):
(WebCore::GLContextEGL::createContextForEGLVersion):
* platform/graphics/egl/GLContextEGL.h:
* platform/graphics/egl/GLContextEGLWPE.cpp:
(WebCore::GLContextEGL::createWPEContext):
* platform/graphics/egl/GLContextEGLWayland.cpp:
(WebCore::GLContextEGL::createWaylandContext):
* platform/graphics/egl/GLContextEGLX11.cpp:
(WebCore::GLContextEGL::createPixmapContext):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229663 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/egl/GLContextEGL.cpp
Source/WebCore/platform/graphics/egl/GLContextEGL.h
Source/WebCore/platform/graphics/egl/GLContextEGLWPE.cpp
Source/WebCore/platform/graphics/egl/GLContextEGLWayland.cpp
Source/WebCore/platform/graphics/egl/GLContextEGLX11.cpp

index 2f760a1..e21182a 100644 (file)
@@ -1,3 +1,30 @@
+2018-03-16  Miguel Gomez  <magomez@igalia.com>
+
+        [GTK] When using EGL, request an OpenGL core profile when possible
+        https://bugs.webkit.org/show_bug.cgi?id=178719
+
+        Reviewed by Carlos Garcia Campos.
+
+        When using EGL and OpenGL, try to request a context with version >= 3.2 with a core profile
+        whenever possible. In order to to this, we require EGL version 1.5 or version 1.4 with the
+        extension EGL_KHR_create_context. If EGL requirements are not met, or we cannot get a
+        context with version >= 3.2 then use whatever EGL gives us.
+
+        Covered by existent tests.
+
+        * platform/graphics/egl/GLContextEGL.cpp:
+        (WebCore::GLContextEGL::createWindowContext):
+        (WebCore::GLContextEGL::createPbufferContext):
+        (WebCore::GLContextEGL::createSurfacelessContext):
+        (WebCore::GLContextEGL::createContextForEGLVersion):
+        * platform/graphics/egl/GLContextEGL.h:
+        * platform/graphics/egl/GLContextEGLWPE.cpp:
+        (WebCore::GLContextEGL::createWPEContext):
+        * platform/graphics/egl/GLContextEGLWayland.cpp:
+        (WebCore::GLContextEGL::createWaylandContext):
+        * platform/graphics/egl/GLContextEGLX11.cpp:
+        (WebCore::GLContextEGL::createPixmapContext):
+
 2018-03-16  Zan Dobersek  <zdobersek@igalia.com>
 
         [TexMap] Don't use the TextureMapperAnimation::Client interface to apply animation
index e50e4bb..24d06ba 100644 (file)
@@ -28,6 +28,7 @@
 #include "EpoxyEGL.h"
 #else
 #include <EGL/egl.h>
+#include <EGL/eglext.h>
 #endif
 
 #if USE(CAIRO)
 
 namespace WebCore {
 
-static const EGLint gContextAttributes[] = {
-#if USE(OPENGL_ES)
-    EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-    EGL_NONE
-};
-
 #if USE(OPENGL_ES)
 static const EGLenum gEGLAPIVersion = EGL_OPENGL_ES_API;
 #else
@@ -141,7 +135,7 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(GLNativeWindowTy
         return nullptr;
     }
 
-    EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
+    EGLContext context = createContextForEGLVersion(platformDisplay, config, sharingContext);
     if (context == EGL_NO_CONTEXT) {
         WTFLogAlways("Cannot create EGL window context: %s\n", lastErrorString());
         return nullptr;
@@ -181,7 +175,7 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createPbufferContext(PlatformDisplay
         return nullptr;
     }
 
-    EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
+    EGLContext context = createContextForEGLVersion(platformDisplay, config, sharingContext);
     if (context == EGL_NO_CONTEXT) {
         WTFLogAlways("Cannot create EGL Pbuffer context: %s\n", lastErrorString());
         return nullptr;
@@ -218,7 +212,7 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createSurfacelessContext(PlatformDis
         return nullptr;
     }
 
-    EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
+    EGLContext context = createContextForEGLVersion(platformDisplay, config, sharingContext);
     if (context == EGL_NO_CONTEXT) {
         WTFLogAlways("Cannot create EGL surfaceless context: %s\n", lastErrorString());
         return nullptr;
@@ -360,6 +354,65 @@ IntSize GLContextEGL::defaultFrameBufferSize()
     return IntSize(width, height);
 }
 
+EGLContext GLContextEGL::createContextForEGLVersion(PlatformDisplay& platformDisplay, EGLConfig config, EGLContext sharingContext)
+{
+    static EGLint contextAttributes[7];
+    static bool contextAttributesInitialized = false;
+
+    if (!contextAttributesInitialized) {
+        contextAttributesInitialized = true;
+
+#if USE(OPENGL_ES)
+        // GLES case. Not much to do here besides requesting a GLES2 version.
+        contextAttributes[0] = EGL_CONTEXT_CLIENT_VERSION;
+        contextAttributes[1] = 2;
+        contextAttributes[2] = EGL_NONE;
+#else
+        // OpenGL case. We want to request an OpenGL version >= 3.2 with a core profile. If that's not possible,
+        // we'll use whatever is available. In order to request a concrete version of OpenGL we need EGL version
+        // 1.5 or EGL version 1.4 with the extension EGL_KHR_create_context.
+        EGLContext context = EGL_NO_CONTEXT;
+
+        if (platformDisplay.eglCheckVersion(1, 5)) {
+            contextAttributes[0] = EGL_CONTEXT_MAJOR_VERSION;
+            contextAttributes[1] = 3;
+            contextAttributes[2] = EGL_CONTEXT_MINOR_VERSION;
+            contextAttributes[3] = 2;
+            contextAttributes[4] = EGL_CONTEXT_OPENGL_PROFILE_MASK;
+            contextAttributes[5] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
+            contextAttributes[6] = EGL_NONE;
+
+            // Try to create a context with this configuration.
+            context = eglCreateContext(platformDisplay.eglDisplay(), config, sharingContext, contextAttributes);
+        } else if (platformDisplay.eglCheckVersion(1, 4)) {
+            const char* extensions = eglQueryString(platformDisplay.eglDisplay(), EGL_EXTENSIONS);
+            if (GLContext::isExtensionSupported(extensions, "EGL_KHR_create_context")) {
+                contextAttributes[0] = EGL_CONTEXT_MAJOR_VERSION_KHR;
+                contextAttributes[1] = 3;
+                contextAttributes[2] = EGL_CONTEXT_MINOR_VERSION_KHR;
+                contextAttributes[3] = 2;
+                contextAttributes[4] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
+                contextAttributes[5] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
+                contextAttributes[6] = EGL_NONE;
+
+                // Try to create a context with this configuration.
+                context = eglCreateContext(platformDisplay.eglDisplay(), config, sharingContext, contextAttributes);
+            }
+        }
+
+        // If the context creation worked, just return it.
+        if (context != EGL_NO_CONTEXT)
+            return context;
+
+        // Legacy case: the required EGL version is not present, or we haven't been able to create a >= 3.2 OpenGL
+        // context, so just request whatever is available.
+        contextAttributes[0] = EGL_NONE;
+#endif
+    }
+
+    return eglCreateContext(platformDisplay.eglDisplay(), config, sharingContext, contextAttributes);
+}
+
 bool GLContextEGL::makeContextCurrent()
 {
     ASSERT(m_context);
index e810ac7..360156e 100644 (file)
@@ -55,6 +55,8 @@ public:
     virtual ~GLContextEGL();
 
 private:
+    static EGLContext createContextForEGLVersion(PlatformDisplay&, EGLConfig, EGLContext);
+
     bool makeContextCurrent() override;
     void swapBuffers() override;
     void waitNative() override;
index cb64237..c049e19 100644 (file)
@@ -53,14 +53,7 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createWPEContext(PlatformDisplay& pl
         return nullptr;
     }
 
-    static const EGLint contextAttributes[] = {
-#if USE(OPENGL_ES)
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-        EGL_NONE
-    };
-
-    EGLContext context = eglCreateContext(display, config, sharingContext, contextAttributes);
+    EGLContext context = createContextForEGLVersion(platformDisplay, config, sharingContext);
     if (context == EGL_NO_CONTEXT) {
         WTFLogAlways("Cannot create EGL WPE context: %s\n", lastErrorString());
         return nullptr;
index cd38680..ceab92d 100644 (file)
@@ -51,14 +51,7 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createWaylandContext(PlatformDisplay
     if (!getEGLConfig(display, &config, WindowSurface))
         return nullptr;
 
-    static const EGLint contextAttributes[] = {
-#if USE(OPENGL_ES)
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-        EGL_NONE
-    };
-
-    EGLContext context = eglCreateContext(display, config, sharingContext, contextAttributes);
+    EGLContext context = createContextForEGLVersion(platformDisplay, config, sharingContext);
     if (context == EGL_NO_CONTEXT)
         return nullptr;
 
index caaf9e2..67a8e0b 100644 (file)
@@ -49,13 +49,7 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createPixmapContext(PlatformDisplay&
     if (!getEGLConfig(display, &config, PixmapSurface))
         return nullptr;
 
-    static const EGLint contextAttributes[] = {
-#if USE(OPENGL_ES)
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-        EGL_NONE
-    };
-    EGLContext context = eglCreateContext(display, config, sharingContext, contextAttributes);
+    EGLContext context = createContextForEGLVersion(platformDisplay, config, sharingContext);
     if (context == EGL_NO_CONTEXT)
         return nullptr;