--- 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 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel