wayland: Add support for YUV-based EGLimages
This commit is contained in:
parent
f11ca9cfaf
commit
ee17ddc18e
@ -319,10 +319,10 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||||
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
||||||
int format, width, height, y_inverted;
|
int format, width, height, y_inverted;
|
||||||
CoglPixelFormat cogl_format;
|
MetaMultiTextureFormat multi_format = META_MULTI_TEXTURE_FORMAT_SIMPLE;
|
||||||
EGLImageKHR egl_image;
|
CoglPixelFormat cogl_format = COGL_PIXEL_FORMAT_ANY;
|
||||||
CoglEglImageFlags flags;
|
guint i, n_planes;
|
||||||
CoglTexture2D *texture_2d;
|
GPtrArray *planes;
|
||||||
|
|
||||||
if (buffer->egl_image.texture)
|
if (buffer->egl_image.texture)
|
||||||
{
|
{
|
||||||
@ -351,6 +351,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
NULL))
|
NULL))
|
||||||
y_inverted = EGL_TRUE;
|
y_inverted = EGL_TRUE;
|
||||||
|
|
||||||
|
/* Query the color format */
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case EGL_TEXTURE_RGB:
|
case EGL_TEXTURE_RGB:
|
||||||
@ -359,6 +360,16 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
case EGL_TEXTURE_RGBA:
|
case EGL_TEXTURE_RGBA:
|
||||||
cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
|
||||||
break;
|
break;
|
||||||
|
case EGL_TEXTURE_Y_UV_WL:
|
||||||
|
/* Technically it can be anything with a separate Y and UV plane
|
||||||
|
* but since this is only used for shaders later, it's ok */
|
||||||
|
multi_format = META_MULTI_TEXTURE_FORMAT_NV12;
|
||||||
|
break;
|
||||||
|
case EGL_TEXTURE_Y_U_V_WL:
|
||||||
|
/* Technically it can be anything with a separate Y and UV plane
|
||||||
|
* but since this is only used for shaders later, it's ok */
|
||||||
|
multi_format = META_MULTI_TEXTURE_FORMAT_YUV444;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_set_error (error, G_IO_ERROR,
|
g_set_error (error, G_IO_ERROR,
|
||||||
G_IO_ERROR_FAILED,
|
G_IO_ERROR_FAILED,
|
||||||
@ -366,35 +377,64 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used
|
/* Each EGLImage is a plane in the final texture */
|
||||||
* in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
|
n_planes = meta_multi_texture_format_get_n_planes (multi_format);
|
||||||
egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
|
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
|
||||||
|
|
||||||
|
g_warning ("Got EGL with format %u", multi_format);
|
||||||
|
|
||||||
|
for (i = 0; i < n_planes; i++)
|
||||||
|
{
|
||||||
|
EGLint egl_attribs[3];
|
||||||
|
EGLImageKHR egl_img;
|
||||||
|
CoglEglImageFlags flags;
|
||||||
|
CoglTexture2D *texture_2d;
|
||||||
|
|
||||||
|
/* Specify that we want the i'th plane */
|
||||||
|
egl_attribs[0] = EGL_WAYLAND_PLANE_WL;
|
||||||
|
egl_attribs[1] = i;
|
||||||
|
egl_attribs[2] = EGL_NONE;
|
||||||
|
|
||||||
|
/* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be
|
||||||
|
* used in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
|
||||||
|
egl_img = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
|
||||||
EGL_WAYLAND_BUFFER_WL, buffer->resource,
|
EGL_WAYLAND_BUFFER_WL, buffer->resource,
|
||||||
NULL,
|
egl_attribs,
|
||||||
error);
|
error);
|
||||||
if (egl_image == EGL_NO_IMAGE_KHR)
|
|
||||||
return FALSE;
|
if (G_UNLIKELY (egl_img == EGL_NO_IMAGE_KHR))
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
flags = COGL_EGL_IMAGE_FLAG_NONE;
|
flags = COGL_EGL_IMAGE_FLAG_NONE;
|
||||||
texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
|
texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
|
||||||
width, height,
|
width, height,
|
||||||
cogl_format,
|
cogl_format,
|
||||||
egl_image,
|
egl_img,
|
||||||
flags,
|
flags,
|
||||||
error);
|
error);
|
||||||
|
|
||||||
meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
|
meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
|
||||||
|
|
||||||
if (!texture_2d)
|
if (G_UNLIKELY (!texture_2d))
|
||||||
return FALSE;
|
goto on_error;
|
||||||
|
|
||||||
buffer->egl_image.texture = meta_multi_texture_new_simple (COGL_TEXTURE (texture_2d));
|
g_ptr_array_add (planes, COGL_TEXTURE (texture_2d));
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->egl_image.texture =
|
||||||
|
meta_multi_texture_new (multi_format,
|
||||||
|
(CoglTexture**) g_ptr_array_free (planes, FALSE),
|
||||||
|
n_planes);
|
||||||
buffer->is_y_inverted = !!y_inverted;
|
buffer->is_y_inverted = !!y_inverted;
|
||||||
|
|
||||||
g_clear_object (texture);
|
g_clear_object (texture);
|
||||||
*texture = g_object_ref (buffer->egl_image.texture);
|
*texture = g_object_ref (buffer->egl_image.texture);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
g_ptr_array_free (planes, TRUE);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND_EGLSTREAM
|
#ifdef HAVE_WAYLAND_EGLSTREAM
|
||||||
|
Loading…
x
Reference in New Issue
Block a user