From 19aa3a4fca07ebda54b277e2e355c726c9ecaa4c Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 10 Oct 2016 14:12:40 -0400 Subject: [PATCH] Use eglGetPlatformDisplay{,EXT} if available Calling eglGetDisplay forces libEGL to guess what kind of pointer you passed it. Different EGL libraries will do different things here, and in particular glvnd will do something different than Mesa. Since we do have an API that allows us to explicitly type the display, use it. The explicit call to eglGetProcAddress is working around a bug in libepoxy 1.3, which does not understand the EGL concept of client extensions. Since it does not, the normal epoxy resolver for eglGetPlatformDisplayEXT would not find any provider for that entry point, and crash when you attempted to call it. Signed-off-by: Adam Jackson https://bugzilla.gnome.org/show_bug.cgi?id=772415 --- gdk/wayland/gdkglcontext-wayland.c | 37 +++++++++++++++++++++++++++++- gtk/inspector/general.c | 36 ++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c index ae1354ef70..657368860f 100644 --- a/gdk/wayland/gdkglcontext-wayland.c +++ b/gdk/wayland/gdkglcontext-wayland.c @@ -274,6 +274,40 @@ gdk_wayland_gl_context_init (GdkWaylandGLContext *self) { } +static EGLDisplay +gdk_wayland_get_display (GdkWaylandDisplay *display_wayland) +{ + EGLDisplay dpy = NULL; + + if (epoxy_has_egl_extension (NULL, "EGL_KHR_platform_base")) + { + PFNEGLGETPLATFORMDISPLAYPROC getPlatformDisplay = + (void *) eglGetProcAddress ("eglGetPlatformDisplay"); + + if (getPlatformDisplay) + dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT, + display_wayland->wl_display, + NULL); + if (dpy) + return dpy; + } + + if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base")) + { + PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = + (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT"); + + if (getPlatformDisplay) + dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT, + display_wayland->wl_display, + NULL); + if (dpy) + return dpy; + } + + return eglGetDisplay ((EGLNativeDisplayType) display_wayland->wl_display); +} + gboolean gdk_wayland_display_init_gl (GdkDisplay *display) { @@ -284,7 +318,8 @@ gdk_wayland_display_init_gl (GdkDisplay *display) if (display_wayland->have_egl) return TRUE; - dpy = eglGetDisplay ((EGLNativeDisplayType)display_wayland->wl_display); + dpy = gdk_wayland_get_display (display_wayland); + if (dpy == NULL) return FALSE; diff --git a/gtk/inspector/general.c b/gtk/inspector/general.c index 77d0a767f1..35231b5b39 100644 --- a/gtk/inspector/general.c +++ b/gtk/inspector/general.c @@ -214,6 +214,40 @@ append_egl_extension_row (GtkInspectorGeneral *gen, { add_check_row (gen, GTK_LIST_BOX (gen->priv->gl_box), ext, epoxy_has_egl_extension (dpy, ext), 0); } + +static EGLDisplay +wayland_get_display (struct wl_display *wl_display) +{ + EGLDisplay dpy = NULL; + + if (epoxy_has_egl_extension (NULL, "EGL_KHR_platform_base")) + { + PFNEGLGETPLATFORMDISPLAYPROC getPlatformDisplay = + (void *) eglGetProcAddress ("eglGetPlatformDisplay"); + + if (getPlatformDisplay) + dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT, + wl_display, + NULL); + if (dpy) + return dpy; + } + + if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base")) + { + PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = + (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT"); + + if (getPlatformDisplay) + dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT, + wl_display, + NULL); + if (dpy) + return dpy; + } + + return eglGetDisplay ((EGLNativeDisplayType)wl_display); +} #endif @@ -254,7 +288,7 @@ init_gl (GtkInspectorGeneral *gen) EGLint major, minor; gchar *version; - dpy = eglGetDisplay ((EGLNativeDisplayType)gdk_wayland_display_get_wl_display (display)); + dpy = wayland_get_display (gdk_wayland_display_get_wl_display (display)); if (!eglInitialize (dpy, &major, &minor)) return;