If the EGL platform does not support eglGetPlatformDisplay, but does
support eglGetPlatformDisplayEXT, then use it as a fallback. Of course,
if neither is supported, we fall back all the way to eglGetDisplay.

This is useful for exercising the codepaths on Mesa, which does support
the extensions for eglGetPlatformDisplayEXT but not yet
eglGetPlatformDisplay.

Tested against Mesa master@8c78fdb with `ninja check-func` on Linux for
x11_egl, wayland, and gbm.

Reported-by: Emil Velikov <emil.l.veli...@gmail.com>
---
 src/waffle/egl/wegl_display.c  |  7 +++++++
 src/waffle/egl/wegl_platform.c | 41 ++++++++++++++++++++++++++++++++++++++---
 src/waffle/egl/wegl_platform.h | 11 +++++++++++
 3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/src/waffle/egl/wegl_display.c b/src/waffle/egl/wegl_display.c
index 5403cd1..dae7493 100644
--- a/src/waffle/egl/wegl_display.c
+++ b/src/waffle/egl/wegl_display.c
@@ -111,6 +111,13 @@ wegl_display_init(struct wegl_display *dpy,
             wegl_emit_error(plat, "eglGetPlatformDisplay");
             goto fail;
         }
+    } else if (wegl_platform_can_use_eglGetPlatformDisplayEXT(plat)) {
+        dpy->egl = plat->eglGetPlatformDisplayEXT(plat->egl_platform,
+                                                  native_display, NULL);
+        if (!dpy->egl) {
+            wegl_emit_error(plat, "eglGetPlatformDisplayEXT");
+            goto fail;
+        }
     } else {
         dpy->egl = plat->eglGetDisplay((EGLNativeDisplayType) native_display);
         if (!dpy->egl) {
diff --git a/src/waffle/egl/wegl_platform.c b/src/waffle/egl/wegl_platform.c
index 5887cf5..0d40301 100644
--- a/src/waffle/egl/wegl_platform.c
+++ b/src/waffle/egl/wegl_platform.c
@@ -66,8 +66,9 @@ wegl_platform_teardown(struct wegl_platform *self)
     bool ok = true;
     int error = 0;
 
-    if (!wegl_platform_can_use_eglGetPlatformDisplay(self)
-        && self->egl_platform != EGL_PLATFORM_ANDROID_KHR) {
+    if (!wegl_platform_can_use_eglGetPlatformDisplay(self) &&
+        !wegl_platform_can_use_eglGetPlatformDisplayEXT(self) &&
+        self->egl_platform != EGL_PLATFORM_ANDROID_KHR) {
         unsetenv("EGL_PLATFORM");
     }
 
@@ -164,14 +165,19 @@ wegl_platform_init(struct wegl_platform *self, EGLenum 
egl_platform)
     // EGL 1.5
     RETRIEVE_EGL_SYMBOL_OPTIONAL(eglGetPlatformDisplay);
 
+    // EGL_EXT_platform_display
+    RETRIEVE_EGL_SYMBOL_OPTIONAL(eglGetPlatformDisplayEXT);
+
 #undef RETRIEVE_EGL_SYMBOL
 #undef RETRIEVE_EGL_SYMBOL_OPTIONAL
 
     self->client_extensions =
         self->eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
 
-    if (!wegl_platform_can_use_eglGetPlatformDisplay(self))
+    if (!wegl_platform_can_use_eglGetPlatformDisplay(self) &&
+        !wegl_platform_can_use_eglGetPlatformDisplayEXT(self)) {
         setup_env(self);
+    }
 
 error:
     // On failure the caller of wegl_platform_init will trigger it's own
@@ -207,3 +213,32 @@ wegl_platform_can_use_eglGetPlatformDisplay(const struct 
wegl_platform *plat)
 
     return waffle_is_extension_in_string(plat->client_extensions, ext);
 }
+
+bool
+wegl_platform_can_use_eglGetPlatformDisplayEXT(const struct wegl_platform 
*plat)
+{
+    const char *ext;
+
+    if (!plat->eglGetPlatformDisplayEXT)
+        return false;
+
+    switch (plat->egl_platform) {
+        case EGL_PLATFORM_ANDROID_KHR:
+            // There exist no Android extension for eglGetPlatformDisplayEXT.
+            return false;
+        case EGL_PLATFORM_GBM_KHR:
+            ext = "EGL_MESA_platform_gbm";
+            break;
+        case EGL_PLATFORM_WAYLAND_KHR:
+            ext = "EGL_EXT_platform_wayland";
+            break;
+        case EGL_PLATFORM_X11_KHR:
+            ext = "EGL_EXT_platform_x11";
+            break;
+        default:
+            assert(!"bad egl_platform enum");
+            return false;
+    }
+
+    return waffle_is_extension_in_string(plat->client_extensions, ext);
+}
diff --git a/src/waffle/egl/wegl_platform.h b/src/waffle/egl/wegl_platform.h
index d6788eb..c3c16b7 100644
--- a/src/waffle/egl/wegl_platform.h
+++ b/src/waffle/egl/wegl_platform.h
@@ -91,6 +91,10 @@ struct wegl_platform {
                                          const EGLint *attrib_list);
     EGLBoolean (*eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
     EGLBoolean (*eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
+
+    // EGL_EXT_platform_display
+    EGLDisplay (*eglGetPlatformDisplayEXT)(EGLenum platform, void 
*native_display,
+                                           const EGLint *attrib_list);
 };
 
 DEFINE_CONTAINER_CAST_FUNC(wegl_platform,
@@ -111,3 +115,10 @@ wegl_platform_init(struct wegl_platform *self, EGLenum 
egl_platform);
 // supports the needed platform extension.
 bool
 wegl_platform_can_use_eglGetPlatformDisplay(const struct wegl_platform *plat);
+
+// Can eglGetPlatformDisplayEXT can be used for this platform?
+//
+// True if libEGL exposes the eglGetPlatformDisplayEXT function; and if EGL
+// supports the needed platform extension.
+bool
+wegl_platform_can_use_eglGetPlatformDisplayEXT(const struct wegl_platform 
*plat);
-- 
2.10.1

_______________________________________________
waffle mailing list
waffle@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/waffle

Reply via email to