[PATCH weston 1/4] gl-renderer: use eglGetPlatformDisplayEXT to get an EGLDisplay

Jonny Lamb jonny.lamb at collabora.co.uk
Tue Feb 17 07:48:00 PST 2015


---
 src/compositor-drm.c     | 14 ++++++++-
 src/compositor-fbdev.c   |  2 +-
 src/compositor-wayland.c | 21 +++++++++++--
 src/compositor-x11.c     | 14 ++++++++-
 src/gl-renderer.c        | 79 ++++++++++++++++++++++++++++++++++++++++++++++--
 src/gl-renderer.h        |  6 +++-
 6 files changed, 126 insertions(+), 10 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 209f2ae..bf3dab8 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -52,6 +52,8 @@
 #include "vaapi-recorder.h"
 #include "presentation_timing-server-protocol.h"
 
+#include <EGL/eglext.h>
+
 #ifndef DRM_CAP_TIMESTAMP_MONOTONIC
 #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
 #endif
@@ -68,6 +70,10 @@
 #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
 #endif
 
+#ifndef EGL_PLATFORM_GBM_KHR
+#define EGL_PLATFORM_GBM_KHR 0x31D7
+#endif
+
 static int option_current_mode = 0;
 
 enum output_config {
@@ -1391,8 +1397,14 @@ drm_compositor_create_gl_renderer(struct drm_compositor *ec)
 {
 	EGLint format;
 
+	if (!gl_renderer->supports ||
+	    (gl_renderer->supports(&ec->base, "EGL_KHR_platform_gbm") < 0 &&
+	     gl_renderer->supports(&ec->base, "EGL_MESA_platform_gbm") < 0)) {
+		return -1;
+	}
+
 	format = ec->format;
-	if (gl_renderer->create(&ec->base, ec->gbm,
+	if (gl_renderer->create(&ec->base, EGL_PLATFORM_GBM_KHR, (void *) ec->gbm,
 			       gl_renderer->opaque_attribs, &format) < 0) {
 		return -1;
 	}
diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
index eedf252..41b43f1 100644
--- a/src/compositor-fbdev.c
+++ b/src/compositor-fbdev.c
@@ -925,7 +925,7 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[],
 			goto out_launcher;
 		}
 
-		if (gl_renderer->create(&compositor->base, EGL_DEFAULT_DISPLAY,
+		if (gl_renderer->create(&compositor->base, 0, EGL_DEFAULT_DISPLAY,
 					gl_renderer->opaque_attribs,
 					NULL) < 0) {
 			weston_log("gl_renderer_create failed.\n");
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 04a2331..850cd4c 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -45,8 +45,14 @@
 #include "fullscreen-shell-client-protocol.h"
 #include "presentation_timing-server-protocol.h"
 
+#include <EGL/eglext.h>
+
 #define WINDOW_TITLE "Weston Compositor"
 
+#ifndef EGL_PLATFORM_WAYLAND_KHR
+#define EGL_PLATFORM_WAYLAND_KHR 0x31D8
+#endif
+
 struct wayland_compositor {
 	struct weston_compositor base;
 
@@ -1961,9 +1967,18 @@ wayland_compositor_create(struct wl_display *display, int use_pixman,
 	}
 
 	if (!c->use_pixman) {
-		if (gl_renderer->create(&c->base, c->parent.wl_display,
-				gl_renderer->alpha_attribs,
-				NULL) < 0) {
+		if (!gl_renderer->supports ||
+		    (gl_renderer->supports(&c->base, "EGL_KHR_platform_wayland") < 0 &&
+		     gl_renderer->supports(&c->base, "EGL_EXT_platform_wayland"))) {
+			weston_log("No support for EGL_KHR_platform_wayland; "
+			           "falling back to pixman.\n");
+			c->use_pixman = 1;
+
+		} else if (gl_renderer->create(&c->base,
+					       EGL_PLATFORM_WAYLAND_KHR,
+					       c->parent.wl_display,
+					       gl_renderer->alpha_attribs,
+					       NULL) < 0) {
 			weston_log("Failed to initialize the GL renderer; "
 				   "falling back to pixman.\n");
 			c->use_pixman = 1;
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index aa1e519..ad7f4c3 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -53,8 +53,14 @@
 #include "../shared/image-loader.h"
 #include "presentation_timing-server-protocol.h"
 
+#include <EGL/eglext.h>
+
 #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10)
 
+#ifndef EGL_PLATFORM_X11_KHR
+#define EGL_PLATFORM_X11_KHR 0x31D5
+#endif
+
 static int option_width;
 static int option_height;
 static int option_scale;
@@ -1485,7 +1491,13 @@ init_gl_renderer(struct x11_compositor *c)
 	if (!gl_renderer)
 		return -1;
 
-	ret = gl_renderer->create(&c->base, (EGLNativeDisplayType) c->dpy,
+	if (!gl_renderer->supports ||
+	    (gl_renderer->supports(&c->base, "EGL_KHR_platform_x11") < 0 &&
+	     gl_renderer->supports(&c->base, "EGL_EXT_platform_x11") < 0)) {
+		return -1;
+	}
+
+	ret = gl_renderer->create(&c->base, EGL_PLATFORM_X11_KHR, (void *) c->dpy,
 				  gl_renderer->opaque_attribs, NULL);
 
 	return ret;
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index bb46acd..279028b 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -162,6 +162,10 @@ struct gl_renderer {
 	struct wl_signal destroy_signal;
 };
 
+#ifdef EGL_EXT_platform_base
+static PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
+#endif
+
 static inline struct gl_output_state *
 get_output_state(struct weston_output *output)
 {
@@ -1971,9 +1975,70 @@ static const EGLint gl_renderer_alpha_attribs[] = {
 	EGL_NONE
 };
 
+/* returns negative:
+ *  1. if EGL client extensions aren't supported.
+ * returns positive:
+ *  1. if the EGL version is >= 1.5,
+ *  2. if the supplied EGL client extension is supported,
+ *  3. in the fallback case to using eglGetDisplay after logging a
+ *     warning. */
+static int
+gl_renderer_supports(struct weston_compositor *ec, const char *extension)
+{
+	static int natively_supported = -1;
+	static const char *extensions = NULL;
+
+	/* first check if EGL is >= 1.5, where platform_base is guaranteed to
+	 * be present */
+
+	if (natively_supported < 0) {
+		const char *version = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION);
+
+		/* version will be NULL if the version is < 1.5 */
+		natively_supported = (version != NULL);
+	}
+
+	if (natively_supported > 0) {
+		weston_log("EGL version is >= 1.5 so assuming platform_base support.\n");
+		return 1;
+	}
+
+	/* now get the client extensions and the eglGetPlatformDisplayEXT
+	 * function pointer */
+
+	if (!extensions) {
+		extensions = (const char *) eglQueryString(
+			EGL_NO_DISPLAY, EGL_EXTENSIONS);
+
+		if (!extensions)
+			return -1;
+
+		log_extensions("EGL client extensions",
+			       extensions);
+
+#ifdef EGL_EXT_platform_base
+		get_platform_display =
+			(void *) eglGetProcAddress("eglGetPlatformDisplayEXT");
+#endif
+	}
+
+	/* check the supplied extension name is present in the (present)
+	 * client extensions */
+
+	if (strstr(extensions, extension))
+		return 1;
+
+	/* in the end fall back to eglGetDisplay and friends */
+
+	weston_log("warning: unable to check for %s support; "
+		   "could fall back to eglGetDisplay.\n", extension);
+	return 1;
+}
+
 static int
-gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
-	const EGLint *attribs, const EGLint *visual_id)
+gl_renderer_create(struct weston_compositor *ec, EGLenum platform,
+	void *native_window, const EGLint *attribs,
+	const EGLint *visual_id)
 {
 	struct gl_renderer *gr;
 	EGLint major, minor;
@@ -1989,7 +2054,14 @@ gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
 	gr->base.surface_set_color = gl_renderer_surface_set_color;
 	gr->base.destroy = gl_renderer_destroy;
 
-	gr->egl_display = eglGetDisplay(display);
+	if (get_platform_display && platform) {
+		gr->egl_display =
+			get_platform_display(platform, native_window,
+					     NULL);
+	} else {
+		gr->egl_display = eglGetDisplay(native_window);
+	}
+
 	if (gr->egl_display == EGL_NO_DISPLAY) {
 		weston_log("failed to create display\n");
 		goto err_egl;
@@ -2200,6 +2272,7 @@ WL_EXPORT struct gl_renderer_interface gl_renderer_interface = {
 	.opaque_attribs = gl_renderer_opaque_attribs,
 	.alpha_attribs = gl_renderer_alpha_attribs,
 
+	.supports = gl_renderer_supports,
 	.create = gl_renderer_create,
 	.display = gl_renderer_display,
 	.output_create = gl_renderer_output_create,
diff --git a/src/gl-renderer.h b/src/gl-renderer.h
index 77b1952..96b3cd5 100644
--- a/src/gl-renderer.h
+++ b/src/gl-renderer.h
@@ -50,8 +50,12 @@ struct gl_renderer_interface {
 	const EGLint *opaque_attribs;
 	const EGLint *alpha_attribs;
 
+	int (*supports)(struct weston_compositor *ec,
+			const char *extension);
+
 	int (*create)(struct weston_compositor *ec,
-		      EGLNativeDisplayType display,
+		      EGLenum platform,
+		      void *native_window,
 		      const EGLint *attribs,
 		      const EGLint *visual_id);
 
-- 
2.1.4



More information about the wayland-devel mailing list