[waffle] [PATCH 07/13] wegl: untangle dl_can_open() and support_api()

Emil Velikov emil.l.velikov at gmail.com
Tue Apr 5 21:58:20 UTC 2016


Calling dl_can_open() to determine whether the API is supported is
confusing and somewhat incorrect.

Instead, determine the supported APIs based on the string provided by
eglQueryString(EGL_CLIENT_APIS) and cross that with the minimum EGL
requirement (for eglBindAPI) for each one.

Note: we're added a minimum requirement of EGL 1.2 as things will
explode badly with versions prior to it.

v2: Completely reword commit message, finish implementation.

Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
---
 src/waffle/egl/wegl_config.c  | 37 ++++++-------------------
 src/waffle/egl/wegl_display.c | 63 ++++++++++++++++++++++++++-----------------
 src/waffle/egl/wegl_display.h |  2 ++
 3 files changed, 48 insertions(+), 54 deletions(-)

diff --git a/src/waffle/egl/wegl_config.c b/src/waffle/egl/wegl_config.c
index a79bc53..ef35b45 100644
--- a/src/waffle/egl/wegl_config.c
+++ b/src/waffle/egl/wegl_config.c
@@ -41,8 +41,6 @@ static bool
 check_context_attrs(struct wegl_display *dpy,
                     const struct wcore_config_attrs *attrs)
 {
-    struct wcore_platform *plat = dpy->wcore.platform;
-
     if (attrs->context_forward_compatible) {
         assert(attrs->context_api == WAFFLE_CONTEXT_OPENGL);
         assert(wcore_config_attrs_version_ge(attrs, 30));
@@ -57,6 +55,14 @@ check_context_attrs(struct wegl_display *dpy,
 
     switch (attrs->context_api) {
         case WAFFLE_CONTEXT_OPENGL:
+            if (!dpy->supports_opengl) {
+                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
+                             "EGL 1.4 of later and eglQueryString(EGL_CLIENT_APIS) "
+                             "== OpenGL are required in order to request an OpenGL "
+                             "context.");
+                return false;
+            }
+
             if (!wcore_config_attrs_version_eq(attrs, 10) && !dpy->KHR_create_context) {
                 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
                              "KHR_EXT_create_context is required in order to "
@@ -77,32 +83,11 @@ check_context_attrs(struct wegl_display *dpy,
                 return false;
             }
 
-            if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL)) {
-                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
-                             "failed to open the OpenGL library");
-                return false;
-            }
-
             return true;
 
         case WAFFLE_CONTEXT_OPENGL_ES1:
-            if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL_ES1)) {
-                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
-                             "failed to open the OpenGL ES1 library");
-                return false;
-            }
-
-            return true;
-
         case WAFFLE_CONTEXT_OPENGL_ES2:
-            if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL_ES2)) {
-                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
-                             "failed to open the OpenGL ES2 library");
-                return false;
-            }
-
             return true;
-
         case WAFFLE_CONTEXT_OPENGL_ES3:
             if (!dpy->KHR_create_context) {
                 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
@@ -111,12 +96,6 @@ check_context_attrs(struct wegl_display *dpy,
                 return false;
             }
 
-            if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL_ES3)) {
-                wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
-                             "failed to open the OpenGL ES3 library");
-                return false;
-            }
-
             return true;
 
         default:
diff --git a/src/waffle/egl/wegl_display.c b/src/waffle/egl/wegl_display.c
index b3d0d88..c9368fc 100644
--- a/src/waffle/egl/wegl_display.c
+++ b/src/waffle/egl/wegl_display.c
@@ -24,6 +24,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <assert.h>
+#include <string.h>
 
 #include "wcore_error.h"
 #include "wcore_platform.h"
@@ -34,22 +35,46 @@
 #include "wegl_platform.h"
 
 static bool
-get_extensions(struct wegl_display *dpy)
+parse_version_extensions(struct wegl_display *dpy, EGLint major, EGLint minor)
 {
     struct wegl_platform *plat = wegl_platform(dpy->wcore.platform);
-    const char *extensions = plat->eglQueryString(dpy->egl, EGL_EXTENSIONS);
+    const char *apis = plat->eglQueryString(dpy->egl, EGL_CLIENT_APIS);
+    const char *extensions;
 
-    if (!extensions) {
-        wegl_emit_error(plat, "eglQueryString(EGL_EXTENSIONS)");
+    // Our minimum requirement - EGL 1.2 ...
+    if (major != 1 || minor < 2) {
+        wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
+                     "EGL 1.2 or later is required");
         return false;
     }
 
-    // waffle_is_extension_in_string() resets the error state. That's ok,
-    // however, because if we've reached this point then no error should be
-    // pending emission.
-    assert(wcore_error_get_code() == 0);
+    // ... plus working eglQueryString(EGL_CLIENT_APIS) and "OpenGL_ES" in the
+    // APIs string.
+    if (!apis || !strstr(apis, "OpenGL_ES")) {
+        wegl_emit_error(plat, "eglQueryString(EGL_CLIENT_APIS)");
+        return false;
+    }
+
+    // Optional bits, if we're running EGL 1.4 ...
+    if (major == 1 && minor >= 4) {
+        extensions = plat->eglQueryString(dpy->egl, EGL_EXTENSIONS);
+
+        // Should never fail.
+        if (!extensions) {
+            wegl_emit_error(plat, "eglQueryString(EGL_EXTENSIONS)");
+            return false;
+        }
 
-    dpy->KHR_create_context = waffle_is_extension_in_string(extensions, "EGL_KHR_create_context");
+        // waffle_is_extension_in_string() resets the error state. That's ok,
+        // however, because if we've reached this point then no error should be
+        // pending emission.
+        assert(wcore_error_get_code() == 0);
+
+        dpy->KHR_create_context = waffle_is_extension_in_string(extensions, "EGL_KHR_create_context");
+
+        // ... and OpenGL is in the APIs string, then we should be fine.
+        dpy->supports_opengl = waffle_is_extension_in_string(apis, "OpenGL");
+    }
 
     return true;
 }
@@ -81,7 +106,7 @@ wegl_display_init(struct wegl_display *dpy,
         goto fail;
     }
 
-    ok = get_extensions(dpy);
+    ok = parse_version_extensions(dpy, major, minor);
     if (!ok)
         goto fail;
 
@@ -112,30 +137,18 @@ wegl_display_supports_context_api(struct wcore_display *wc_dpy,
                                   int32_t waffle_context_api)
 {
     struct wegl_display *dpy = wegl_display(wc_dpy);
-    struct wcore_platform *wc_plat = dpy->wcore.platform;
-    int32_t waffle_dl;
 
     switch (waffle_context_api) {
         case WAFFLE_CONTEXT_OPENGL:
-            waffle_dl = WAFFLE_DL_OPENGL;
-            break;
+            return dpy->supports_opengl;
         case WAFFLE_CONTEXT_OPENGL_ES1:
-            waffle_dl = WAFFLE_DL_OPENGL_ES1;
-            break;
         case WAFFLE_CONTEXT_OPENGL_ES2:
-            waffle_dl = WAFFLE_DL_OPENGL_ES2;
-            break;
+            return true;
         case WAFFLE_CONTEXT_OPENGL_ES3:
-            if (!dpy->KHR_create_context)
-                return false;
-
-            waffle_dl = WAFFLE_DL_OPENGL_ES3;
-            break;
+            return dpy->KHR_create_context;
         default:
             wcore_error_internal("waffle_context_api has bad value %#x",
                                  waffle_context_api);
             return false;
     }
-
-    return wc_plat->vtbl->dl_can_open(wc_plat, waffle_dl);
 }
diff --git a/src/waffle/egl/wegl_display.h b/src/waffle/egl/wegl_display.h
index 43b83ef..9401334 100644
--- a/src/waffle/egl/wegl_display.h
+++ b/src/waffle/egl/wegl_display.h
@@ -37,6 +37,8 @@ struct wcore_display;
 struct wegl_display {
     struct wcore_display wcore;
     EGLDisplay egl;
+
+    bool supports_opengl;
     bool KHR_create_context;
 };
 
-- 
2.8.0



More information about the waffle mailing list