[waffle] [PATCH 8/8] egl: Use eglGetPlatformDisplayEXT as a fallback

2016-10-27 Thread Chad Versace
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 
---
 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 p

Re: [waffle] [PATCH 0/7] Use eglGetPlatformDisplay when possible (v2)

2016-10-27 Thread Chad Versace
On Tue 25 Oct 2016, Emil Velikov wrote:
> On 24 October 2016 at 22:57, Chad Versace  wrote:
> > Before EGL_EXT_platform_base and EGL 1.5, when using Mesa the best way
> > to select the EGL platform was to set the EGL_PLATFORM environment
> > variable. Now that a standard way exists, eglGetPlatformDisplay, let's
> > use it when available.
> >
> > After this series, I have a series to add support for
> > EGL_MESA_platform_surfaceless.
> >
> > This branch lives at
> > 
> > https://github.com/chadversary/waffle/commits/review/eglGetPlatformDisplay-v02
> >
> > v2:
> > - Fix bugs found by Emil.
> > - Don't set EGL_PLATFORM=android.
> > - Last patch, add fallback to use eglGetPlatformDisplayEXT.
> >
> > Chad Versace (8):
> >   egl: Define EGL_PLATFORM_* enums
> >   egl: Update wegl_platform_init signature
> >   egl: Move each platform's setenv("EGL_PLATFORM") into core EGL code (v2)
> >   egl: Query client extensions string
> >   egl: Optionally query for eglGetPlatformDisplay (v2)
> >   egl: Update wegl_display_init signature
> >   egl: Use eglGetPlatformDisplay when possible (v2)
> >   egl: Use eglGetPlatformDisplayEXT as a fallback
> >
> Cannot see 8/8 in the list, so I've check it via the repo.
> The lot looks great imho.
> 
> Reviewed-by: Emil Velikov 

Thanks and pushed.
___
waffle mailing list
waffle@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/waffle