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 <neil@linux.intel.com>

(cherry picked from commit 79252d4e419e2462c5bc89ea4614b40bddc932c5)
This commit is contained in:
Robert Bragg 2013-04-30 14:09:11 +01:00
parent cf002a7989
commit cc4e144dd7
4 changed files with 63 additions and 3 deletions

View File

@ -262,6 +262,8 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
struct wl_buffer *buffer, struct wl_buffer *buffer,
CoglError **error) CoglError **error)
{ {
int format;
if (wl_buffer_is_shm (buffer)) if (wl_buffer_is_shm (buffer))
{ {
int stride = wl_shm_buffer_get_stride (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), wl_shm_buffer_get_data (buffer),
error); error);
} }
else else if (_cogl_egl_query_wayland_buffer (ctx, buffer,
EGL_TEXTURE_FORMAT,
&format))
{ {
EGLImageKHR image; EGLImageKHR image;
CoglTexture2D *tex; CoglTexture2D *tex = NULL;
CoglPixelFormat internal_format;
_COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints &
COGL_RENDERER_CONSTRAINT_USES_EGL, COGL_RENDERER_CONSTRAINT_USES_EGL,
NULL); 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, image = _cogl_egl_create_image (ctx,
EGL_WAYLAND_BUFFER_WL, EGL_WAYLAND_BUFFER_WL,
buffer, buffer,
@ -316,12 +339,19 @@ cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
tex = _cogl_egl_texture_2d_new_from_image (ctx, tex = _cogl_egl_texture_2d_new_from_image (ctx,
buffer->width, buffer->width,
buffer->height, buffer->height,
COGL_PIXEL_FORMAT_ARGB_8888_PRE, internal_format,
image, image,
error); error);
_cogl_egl_destroy_image (ctx, image); _cogl_egl_destroy_image (ctx, image);
return tex; 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 */ #endif /* COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT */

View File

@ -86,6 +86,10 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLImageKHR, eglBindWaylandDisplay,
COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglUnbindWaylandDisplay, COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglUnbindWaylandDisplay,
(EGLDisplay dpy, (EGLDisplay dpy,
struct wl_display *wayland_display)) 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_END ()
COGL_WINSYS_FEATURE_BEGIN (create_context, COGL_WINSYS_FEATURE_BEGIN (create_context,

View File

@ -159,6 +159,14 @@ _cogl_egl_destroy_image (CoglContext *ctx,
EGLImageKHR image); EGLImageKHR image);
#endif #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 CoglBool
_cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, _cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer,
CoglError **error); CoglError **error);

View File

@ -1041,3 +1041,21 @@ _cogl_egl_destroy_image (CoglContext *ctx,
egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image); egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image);
} }
#endif #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