From 659c98733540b61624d5a1487d5b636000056332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 20 Oct 2016 14:15:28 +0800 Subject: [PATCH] egl: Add helpers for importing Wayland buffers as EGLImage's https://bugzilla.gnome.org/show_bug.cgi?id=773629 --- src/backends/meta-egl-ext.h | 28 ++++++++++++++ src/backends/meta-egl.c | 73 +++++++++++++++++++++++++++++++++++++ src/backends/meta-egl.h | 20 ++++++++++ 3 files changed, 121 insertions(+) diff --git a/src/backends/meta-egl-ext.h b/src/backends/meta-egl-ext.h index eff850866..78fd9a2e7 100644 --- a/src/backends/meta-egl-ext.h +++ b/src/backends/meta-egl-ext.h @@ -30,6 +30,34 @@ #include #include +/* + * This is a little different to the tests shipped with EGL implementations, + * which wrap the entire thing in #ifndef EGL_WL_bind_wayland_display, then go + * on to define both BindWaylandDisplay and QueryWaylandBuffer. + * + * Unfortunately, some implementations (particularly the version of Mesa shipped + * in Ubuntu 12.04) define EGL_WL_bind_wayland_display, but then only provide + * prototypes for (Un)BindWaylandDisplay, completely omitting + * QueryWaylandBuffer. + * + * Detect this, and provide our own definitions if necessary. + */ +#ifndef EGL_WAYLAND_BUFFER_WL +#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */ +#define EGL_WAYLAND_PLANE_WL 0x31D6 /* eglCreateImageKHR target */ + +#define EGL_TEXTURE_Y_U_V_WL 0x31D7 +#define EGL_TEXTURE_Y_UV_WL 0x31D8 +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 +#define EGL_TEXTURE_EXTERNAL_WL 0x31DA + +struct wl_resource; +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif + /* * FIXME: Remove both EGL_EXT_stream_acquire_mode and * EGL_NV_output_drm_flip_event definitions below once both extensions diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c index 569201213..e61790aa4 100644 --- a/src/backends/meta-egl.c +++ b/src/backends/meta-egl.c @@ -41,6 +41,11 @@ struct _MetaEgl PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; + PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; + PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; + + PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL; + PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT; PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT; @@ -327,6 +332,69 @@ meta_egl_get_platform_display (MetaEgl *egl, return display; } +EGLImageKHR +meta_egl_create_image (MetaEgl *egl, + EGLDisplay display, + EGLContext context, + EGLenum target, + EGLClientBuffer buffer, + const EGLint *attrib_list, + GError **error) +{ + EGLImageKHR image; + + if (!is_egl_proc_valid (egl->eglCreateImageKHR, error)) + return EGL_NO_IMAGE_KHR; + + image = egl->eglCreateImageKHR (display, context, + target, buffer, attrib_list); + if (image == EGL_NO_IMAGE_KHR) + { + set_egl_error (error); + return EGL_NO_IMAGE_KHR; + } + + return image; +} + +gboolean +meta_egl_destroy_image (MetaEgl *egl, + EGLDisplay display, + EGLImageKHR image, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglDestroyImageKHR, error)) + return FALSE; + + if (!egl->eglDestroyImageKHR (display, image)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_query_wayland_buffer (MetaEgl *egl, + EGLDisplay display, + struct wl_resource *buffer, + EGLint attribute, + EGLint *value, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglQueryWaylandBufferWL, error)) + return FALSE; + + if (!egl->eglQueryWaylandBufferWL (display, buffer, attribute, value)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + gboolean meta_egl_query_devices (MetaEgl *egl, EGLint max_devices, @@ -604,6 +672,11 @@ meta_egl_constructed (GObject *object) GET_EGL_PROC_ADDR_REQUIRED (eglGetPlatformDisplayEXT); + GET_EGL_PROC_ADDR (eglCreateImageKHR); + GET_EGL_PROC_ADDR (eglDestroyImageKHR); + + GET_EGL_PROC_ADDR (eglQueryWaylandBufferWL); + GET_EGL_PROC_ADDR (eglQueryDevicesEXT); GET_EGL_PROC_ADDR (eglQueryDeviceStringEXT); diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h index aa38a5cad..191955c5f 100644 --- a/src/backends/meta-egl.h +++ b/src/backends/meta-egl.h @@ -48,6 +48,19 @@ gboolean meta_egl_choose_config (MetaEgl *egl, EGLConfig *chosen_config, GError **error); +EGLImageKHR meta_egl_create_image (MetaEgl *egl, + EGLDisplay display, + EGLContext context, + EGLenum target, + EGLClientBuffer buffer, + const EGLint *attrib_list, + GError **error); + +gboolean meta_egl_destroy_image (MetaEgl *egl, + EGLDisplay display, + EGLImageKHR image, + GError **error); + EGLSurface meta_egl_create_pbuffer_surface (MetaEgl *egl, EGLDisplay display, EGLConfig config, @@ -60,6 +73,13 @@ EGLDisplay meta_egl_get_platform_display (MetaEgl *egl, const EGLint *attrib_list, GError **error); +gboolean meta_egl_query_wayland_buffer (MetaEgl *egl, + EGLDisplay display, + struct wl_resource *buffer, + EGLint attribute, + EGLint *value, + GError **error); + gboolean meta_egl_query_devices (MetaEgl *egl, EGLint max_devices, EGLDeviceEXT *devices,