gl-renderer: use eglGetPlatformDisplayEXT to get an EGLDisplay
authorJonny Lamb <jonny.lamb@collabora.co.uk>
Fri, 20 Mar 2015 14:26:50 +0000 (15:26 +0100)
committerBryce Harrington <bryce@osg.samsung.com>
Fri, 20 Mar 2015 20:55:46 +0000 (13:55 -0700)
Reviewed-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
src/compositor-drm.c
src/compositor-fbdev.c
src/compositor-wayland.c
src/compositor-x11.c
src/gl-renderer.c
src/gl-renderer.h

index 15152b097ee530c0d066edd7d2bb138c4c5956ec..29f0f13bdf42817e93ae995aa89dae97166e48ea 100644 (file)
@@ -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
 #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 {
@@ -1396,8 +1402,13 @@ drm_compositor_create_gl_renderer(struct drm_compositor *ec)
 {
        EGLint format;
 
+       if (!gl_renderer->supports ||
+           gl_renderer->supports(&ec->base, "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;
        }
index c75fe41557b5e6a983cbbe28b96c53c005b5c6b5..6e541e897a957fe9a7ec4d9528e4648a6cec69e5 100644 (file)
@@ -868,7 +868,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");
index 04a2331eb891d48891f432ccb38f022e5c8aef8f..b6fd37d188e46916b884d1d9cb22862a35993931 100644 (file)
 #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,17 @@ 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, "wayland") < 0) {
+                       weston_log("No support for "
+                                  "EGL_{KHR,EXT,MESA}_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;
index e89acb7e458ed3c935b61bd6b51f1a0801cfc152..a435daf9499bb35c75fdf28bcf4b60d3a909a023 100644 (file)
 #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;
@@ -1487,7 +1493,10 @@ 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, "x11") < 0)
+               return -1;
+
+       ret = gl_renderer->create(&c->base, EGL_PLATFORM_X11_KHR, (void *) c->dpy,
                                  gl_renderer->opaque_attribs, NULL);
 
        return ret;
index 10d7d710920644b5cca95a3eb9538c60a8e75ef0..e598d1e940663eea96049db5339137e18534268a 100644 (file)
@@ -166,6 +166,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)
 {
@@ -2148,9 +2152,69 @@ static const EGLint gl_renderer_alpha_attribs[] = {
        EGL_NONE
 };
 
+/** Checks whether a platform EGL client extension is supported
+ *
+ * \param ec The weston compositor
+ * \param extension_suffix The EGL client extension suffix
+ * \return 1 if supported, 0 if using fallbacks, -1 unsupported
+ *
+ * This function checks whether a specific platform_* extension is supported
+ * by EGL.
+ *
+ * The extension suffix should be the suffix of the platform extension (that
+ * specifies a <platform> argument as defined in EGL_EXT_platform_base). For
+ * example, passing "foo" will check whether either "EGL_KHR_platform_foo",
+ * "EGL_EXT_platform_foo", or "EGL_MESA_platform_foo" is supported.
+ *
+ * The return value is 1:
+ *   - if the supplied EGL client extension is supported.
+ * The return value is 0:
+ *   - if the platform_base client extension isn't supported so will
+ *     fallback to eglGetDisplay and friends.
+ * The return value is -1:
+ *   - if the supplied EGL client extension is not supported.
+ */
 static int
-gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
-       const EGLint *attribs, const EGLint *visual_id)
+gl_renderer_supports(struct weston_compositor *ec,
+                    const char *extension_suffix)
+{
+       static const char *extensions = NULL;
+       char s[64];
+
+       if (!extensions) {
+               extensions = (const char *) eglQueryString(
+                       EGL_NO_DISPLAY, EGL_EXTENSIONS);
+
+               if (!extensions)
+                       return 0;
+
+               log_extensions("EGL client extensions",
+                              extensions);
+       }
+
+       snprintf(s, sizeof s, "EGL_KHR_platform_%s", extension_suffix);
+       if (strstr(extensions, s))
+               return 1;
+
+       snprintf(s, sizeof s, "EGL_EXT_platform_%s", extension_suffix);
+       if (strstr(extensions, s))
+               return 1;
+
+       snprintf(s, sizeof s, "EGL_MESA_platform_%s", extension_suffix);
+       if (strstr(extensions, s))
+               return 1;
+
+       /* at this point we definitely have some client extensions but
+        * haven't found the supplied client extension, so chances are it's
+        * not supported. */
+
+       return -1;
+}
+
+static int
+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;
@@ -2169,7 +2233,26 @@ gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
                gl_renderer_surface_get_content_size;
        gr->base.surface_copy_content = gl_renderer_surface_copy_content;
 
-       gr->egl_display = eglGetDisplay(display);
+#ifdef EGL_EXT_platform_base
+       if (!get_platform_display) {
+               get_platform_display =
+                       (void *) eglGetProcAddress("eglGetPlatformDisplayEXT");
+       }
+
+       if (get_platform_display && platform) {
+               gr->egl_display =
+                       get_platform_display(platform, native_window,
+                                            NULL);
+       } else {
+#endif
+               weston_log("warning: either no EGL_EXT_platform_base "
+                          "support or specific platform support; "
+                          "falling back to eglGetDisplay.\n");
+               gr->egl_display = eglGetDisplay(native_window);
+#ifdef EGL_EXT_platform_base
+       }
+#endif
+
        if (gr->egl_display == EGL_NO_DISPLAY) {
                weston_log("failed to create display\n");
                goto err_egl;
@@ -2381,6 +2464,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,
index 77b1952926088ee1c776bf0a0c9514b5d5aa5988..bbf0ac61534620f150a4f4562686708d3aff7474 100644 (file)
@@ -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_suffix);
+
        int (*create)(struct weston_compositor *ec,
-                     EGLNativeDisplayType display,
+                     EGLenum platform,
+                     void *native_window,
                      const EGLint *attribs,
                      const EGLint *visual_id);