From cc4e144dd773691cb2642063021f1653a9ec4e59 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 30 Apr 2013 14:09:11 +0100 Subject: [PATCH] check the wayland buffer format when creating texture The implementation of cogl_wayland_texture_2d_new_from_buffer now uses eglQueryWaylandBuffer to query the format of the buffer before trying to create a texture from the buffer. This makes sure we don't try and create a texture from YUV buffers for instance that may actually require multiple textures. We now also report an error when we don't understand the buffer type or format. Reviewed-by: Neil Roberts (cherry picked from commit 79252d4e419e2462c5bc89ea4614b40bddc932c5) --- cogl/cogl-texture-2d.c | 36 +++++++++++++++++-- .../cogl-winsys-egl-feature-functions.h | 4 +++ cogl/winsys/cogl-winsys-egl-private.h | 8 +++++ cogl/winsys/cogl-winsys-egl.c | 18 ++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c index 7492e128e..e0998e131 100644 --- a/cogl/cogl-texture-2d.c +++ b/cogl/cogl-texture-2d.c @@ -262,6 +262,8 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx, struct wl_buffer *buffer, CoglError **error) { + int format; + if (wl_buffer_is_shm (buffer)) { int stride = wl_shm_buffer_get_stride (buffer); @@ -301,14 +303,35 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx, wl_shm_buffer_get_data (buffer), error); } - else + else if (_cogl_egl_query_wayland_buffer (ctx, buffer, + EGL_TEXTURE_FORMAT, + &format)) { EGLImageKHR image; - CoglTexture2D *tex; + CoglTexture2D *tex = NULL; + CoglPixelFormat internal_format; _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & COGL_RENDERER_CONSTRAINT_USES_EGL, NULL); + + switch (format) + { + case EGL_TEXTURE_RGB: + internal_format = COGL_PIXEL_FORMAT_RGB_888; + break; + case EGL_TEXTURE_RGBA: + internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; + break; + default: + _cogl_set_error (error, + COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_UNSUPPORTED, + "Can't create texture from unknown " + "wayland buffer format %d\n", format); + return NULL; + } + image = _cogl_egl_create_image (ctx, EGL_WAYLAND_BUFFER_WL, buffer, @@ -316,12 +339,19 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx, tex = _cogl_egl_texture_2d_new_from_image (ctx, buffer->width, buffer->height, - COGL_PIXEL_FORMAT_ARGB_8888_PRE, + internal_format, image, error); _cogl_egl_destroy_image (ctx, image); return tex; } + + _cogl_set_error (error, + COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_UNSUPPORTED, + "Can't create texture from unknown " + "wayland buffer type\n"); + return NULL; } #endif /* COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT */ diff --git a/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/winsys/cogl-winsys-egl-feature-functions.h index a26a6c586..275884335 100644 --- a/cogl/winsys/cogl-winsys-egl-feature-functions.h +++ b/cogl/winsys/cogl-winsys-egl-feature-functions.h @@ -86,6 +86,10 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLImageKHR, eglBindWaylandDisplay, COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglUnbindWaylandDisplay, (EGLDisplay dpy, struct wl_display *wayland_display)) +COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglQueryWaylandBuffer, + (EGLDisplay dpy, + struct wl_buffer *buffer, + EGLint attribute, EGLint *value)) COGL_WINSYS_FEATURE_END () COGL_WINSYS_FEATURE_BEGIN (create_context, diff --git a/cogl/winsys/cogl-winsys-egl-private.h b/cogl/winsys/cogl-winsys-egl-private.h index fe186da9a..9a3b4ad5f 100644 --- a/cogl/winsys/cogl-winsys-egl-private.h +++ b/cogl/winsys/cogl-winsys-egl-private.h @@ -159,6 +159,14 @@ _cogl_egl_destroy_image (CoglContext *ctx, EGLImageKHR image); #endif +#ifdef EGL_WL_bind_wayland_display +CoglBool +_cogl_egl_query_wayland_buffer (CoglContext *ctx, + struct wl_buffer *buffer, + int attribute, + int *value); +#endif + CoglBool _cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, CoglError **error); diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c index 1810615e3..63f224f98 100644 --- a/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/winsys/cogl-winsys-egl.c @@ -1041,3 +1041,21 @@ _cogl_egl_destroy_image (CoglContext *ctx, egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image); } #endif + +#ifdef EGL_WL_bind_wayland_display +CoglBool +_cogl_egl_query_wayland_buffer (CoglContext *ctx, + struct wl_buffer *buffer, + int attribute, + int *value) +{ + CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; + + _COGL_RETURN_IF_FAIL (egl_renderer->pf_eglQueryWaylandBuffer); + + return egl_renderer->pf_eglQueryWaylandBuffer (egl_renderer->edpy, + buffer, + attribute, + value); +} +#endif