summaryrefslogtreecommitdiff
path: root/src/wayland
diff options
context:
space:
mode:
Diffstat (limited to 'src/wayland')
-rw-r--r--src/wayland/meta-wayland-buffer.c334
-rw-r--r--src/wayland/meta-wayland-buffer.h16
-rw-r--r--src/wayland/meta-wayland-cursor-surface.c9
-rw-r--r--src/wayland/meta-wayland-dma-buf.c228
-rw-r--r--src/wayland/meta-wayland-dma-buf.h8
-rw-r--r--src/wayland/meta-wayland-egl-stream.c21
-rw-r--r--src/wayland/meta-wayland-egl-stream.h4
-rw-r--r--src/wayland/meta-wayland-shell-surface.c6
-rw-r--r--src/wayland/meta-wayland-surface.c8
-rw-r--r--src/wayland/meta-wayland-surface.h4
-rw-r--r--src/wayland/meta-wayland.c22
11 files changed, 441 insertions, 219 deletions
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
index f45679d3a..0a7c81f89 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -123,7 +123,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
stream = meta_wayland_egl_stream_new (buffer, NULL);
if (stream)
{
- CoglTexture2D *texture;
+ CoglMultiPlaneTexture *texture;
texture = meta_wayland_egl_stream_create_texture (stream, NULL);
if (!texture)
@@ -131,7 +131,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
buffer->egl_stream.stream = stream;
buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_STREAM;
- buffer->egl_stream.texture = COGL_TEXTURE (texture);
+ buffer->egl_stream.texture = texture;
buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);
return TRUE;
@@ -163,17 +163,18 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
CoglTextureComponents *components_out)
{
CoglPixelFormat format;
- CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA;
+ g_warning ("SHM BUFFER_FORMAT: %d", wl_shm_buffer_get_format (shm_buffer));
switch (wl_shm_buffer_get_format (shm_buffer))
{
#if G_BYTE_ORDER == G_BIG_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888;
- components = COGL_TEXTURE_COMPONENTS_RGB;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGB;
break;
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
@@ -181,25 +182,59 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888;
- components = COGL_TEXTURE_COMPONENTS_RGB;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGB;
break;
#endif
+ case WL_SHM_FORMAT_NV12:
+ format = COGL_PIXEL_FORMAT_NV12;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_RG;
+ break;
+ case WL_SHM_FORMAT_NV21:
+ format = COGL_PIXEL_FORMAT_NV21;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_RG;
+ break;
+ case WL_SHM_FORMAT_YUV422:
+ format = COGL_PIXEL_FORMAT_YUV422;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[2] = COGL_TEXTURE_COMPONENTS_A;
+ break;
+ case WL_SHM_FORMAT_YVU422:
+ format = COGL_PIXEL_FORMAT_YVU422;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[2] = COGL_TEXTURE_COMPONENTS_A;
+ break;
+ case WL_SHM_FORMAT_YUV444:
+ format = COGL_PIXEL_FORMAT_YUV444;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[2] = COGL_TEXTURE_COMPONENTS_A;
+ break;
+ case WL_SHM_FORMAT_YVU444:
+ format = COGL_PIXEL_FORMAT_YVU444;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[2] = COGL_TEXTURE_COMPONENTS_A;
+ break;
+
default:
g_warn_if_reached ();
format = COGL_PIXEL_FORMAT_ARGB_8888;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
}
if (format_out)
*format_out = format;
- if (components_out)
- *components_out = components;
}
static gboolean
-shm_buffer_attach (MetaWaylandBuffer *buffer,
- CoglTexture **texture,
- gboolean *changed_texture,
- GError **error)
+shm_buffer_attach (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture **texture,
+ gboolean *changed_texture,
+ GError **error)
{
MetaBackend *backend = meta_get_backend ();
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
@@ -207,21 +242,27 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
struct wl_shm_buffer *shm_buffer;
int stride, width, height;
CoglPixelFormat format;
- CoglTextureComponents components;
- CoglBitmap *bitmap;
- CoglTexture *new_texture;
-
+ CoglTextureComponents components[3];
+ guint i, n_planes;
+ guint h_factors[3], v_factors[3];
+ gsize offset = 0;
+ guint8 *data;
+ GPtrArray *bitmaps;
+
+ /* Query the necessary parameters */
shm_buffer = wl_shm_buffer_get (buffer->resource);
stride = wl_shm_buffer_get_stride (shm_buffer);
width = wl_shm_buffer_get_width (shm_buffer);
height = wl_shm_buffer_get_height (shm_buffer);
- shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components);
+ shm_buffer_get_cogl_pixel_format (shm_buffer, &format, components);
+ n_planes = cogl_pixel_format_get_n_planes (format);
+ cogl_pixel_format_get_subsampling_factors (format, h_factors, v_factors);
if (*texture &&
- cogl_texture_get_width (*texture) == width &&
- cogl_texture_get_height (*texture) == height &&
- cogl_texture_get_components (*texture) == components &&
- _cogl_texture_get_format (*texture) == format)
+ cogl_multi_plane_texture_get_width (*texture) == width &&
+ cogl_multi_plane_texture_get_height (*texture) == height &&
+ /*XXX cogl_texture_get_components (*texture) == components && */
+ cogl_multi_plane_texture_get_format (*texture) == format)
{
buffer->is_y_inverted = TRUE;
*changed_texture = FALSE;
@@ -230,56 +271,57 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
cogl_clear_object (texture);
+ /* Safely access the data inside the buffer */
wl_shm_buffer_begin_access (shm_buffer);
+ data = wl_shm_buffer_get_data (shm_buffer);
- bitmap = cogl_bitmap_new_for_data (cogl_context,
- width, height,
- format,
- stride,
- wl_shm_buffer_get_data (shm_buffer));
-
- new_texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap));
- cogl_texture_set_components (new_texture, components);
-
- if (!cogl_texture_allocate (new_texture, error))
+ bitmaps = g_ptr_array_new_full (n_planes, cogl_object_unref);
+ for (i = 0; i < n_planes; i++)
{
- g_clear_pointer (&new_texture, cogl_object_unref);
- if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE))
- {
- CoglTexture2DSliced *texture_sliced;
-
- g_clear_error (error);
-
- texture_sliced =
- cogl_texture_2d_sliced_new_from_bitmap (bitmap,
- COGL_TEXTURE_MAX_WASTE);
- new_texture = COGL_TEXTURE (texture_sliced);
- cogl_texture_set_components (new_texture, components);
-
- if (!cogl_texture_allocate (new_texture, error))
- g_clear_pointer (&new_texture, cogl_object_unref);
- }
+ CoglBitmap *bitmap;
+
+ /* Internally, the texture's planes are laid out in memory as one
+ * contiguous block, so we have to consider any subsampling (based on the
+ * pixel format). */
+ if (i == 0)
+ offset = 0;
+ else
+ offset += (stride / h_factors[i-1]) * (height / v_factors[i-1]);
+
+ g_warning ("Creating plane %d, h_factor = %d, v_factor = %d, offset = %lu",
+ i, h_factors[i], v_factors[i], offset);
+
+ bitmap = cogl_bitmap_new_for_data (cogl_context,
+ width / h_factors[i],
+ height / v_factors[i],
+ format, /* XXX this we have to change later */
+ stride, /* XXX Do we need to change this too?*/
+ data + offset);
+ g_assert (bitmap);
+
+ g_ptr_array_add (bitmaps, bitmap);
}
- cogl_object_unref (bitmap);
+ *texture = cogl_multi_plane_texture_new_from_bitmaps (format,
+ (CoglBitmap **) g_ptr_array_free (bitmaps, FALSE),
+ n_planes, error);
wl_shm_buffer_end_access (shm_buffer);
- if (!new_texture)
- return FALSE;
-
- *texture = new_texture;
*changed_texture = TRUE;
buffer->is_y_inverted = TRUE;
+ g_warning ("Got the following multiplane texture:\n%s", cogl_multi_plane_texture_to_string (*texture));
+ /* g_ptr_array_free (bitmaps, TRUE); */
+
return TRUE;
}
static gboolean
-egl_image_buffer_attach (MetaWaylandBuffer *buffer,
- CoglTexture **texture,
- gboolean *changed_texture,
- GError **error)
+egl_image_buffer_attach (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture **texture,
+ gboolean *changed_texture,
+ GError **error)
{
MetaBackend *backend = meta_get_backend ();
MetaEgl *egl = meta_backend_get_egl (backend);
@@ -288,8 +330,8 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
int format, width, height, y_inverted;
CoglPixelFormat cogl_format;
- EGLImageKHR egl_image;
- CoglTexture2D *texture_2d;
+ guint i, n_planes;
+ GPtrArray *planes;
if (buffer->egl_image.texture)
{
@@ -299,6 +341,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
return TRUE;
}
+ /* Query the necessary properties */
if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
EGL_TEXTURE_FORMAT, &format,
error))
@@ -319,6 +362,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
NULL))
y_inverted = EGL_TRUE;
+ /* Map the EGL texture format to CoglPixelFormat, if possible */
switch (format)
{
case EGL_TEXTURE_RGB:
@@ -327,6 +371,14 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
case EGL_TEXTURE_RGBA:
cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
break;
+ case EGL_TEXTURE_Y_UV_WL:
+ g_warning ("Got a NV12 color format texture!!");
+ cogl_format = COGL_PIXEL_FORMAT_NV12;
+ break;
+ case EGL_TEXTURE_Y_U_V_WL:
+ g_warning ("Got a YUV 4:4:4 color format texture!!");
+ cogl_format = COGL_PIXEL_FORMAT_YUV444;
+ break;
default:
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
@@ -334,27 +386,49 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
return FALSE;
}
- /* 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_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
- EGL_WAYLAND_BUFFER_WL, buffer->resource,
- NULL,
- error);
- if (egl_image == EGL_NO_IMAGE_KHR)
- return FALSE;
+ n_planes = cogl_pixel_format_get_n_planes (cogl_format);
+ planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
- texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
- width, height,
- cogl_format,
- egl_image,
- error);
+ /* Each EGLImage is a plane in the final texture */
+ for (i = 0; i < n_planes; i++)
+ {
+ EGLint egl_attribs[3];
+ EGLImageKHR egl_img;
+ CoglTexture2D *texture_2d;
- meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
+ /* 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_attribs,
+ error);
+
+ if (G_UNLIKELY (egl_img == EGL_NO_IMAGE_KHR))
+ goto on_error;
+
+ texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
+ width, height,
+ cogl_format,
+ egl_img,
+ error);
+
+ meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
+
+ if (G_UNLIKELY (!texture_2d))
+ goto on_error;
+
+ g_ptr_array_add (planes, texture_2d);
+ }
- if (!texture_2d)
- return FALSE;
- buffer->egl_image.texture = COGL_TEXTURE (texture_2d);
+ buffer->egl_image.texture = cogl_multi_plane_texture_new (cogl_format,
+ (CoglTexture **) g_ptr_array_free (planes, FALSE),
+ n_planes);
buffer->is_y_inverted = !!y_inverted;
cogl_clear_object (texture);
@@ -362,14 +436,19 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
*changed_texture = TRUE;
return TRUE;
+
+on_error:
+ g_ptr_array_free (planes, TRUE);
+
+ return FALSE;
}
#ifdef HAVE_WAYLAND_EGLSTREAM
static gboolean
-egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
- CoglTexture **texture,
- gboolean *changed_texture,
- GError **error)
+egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture **texture,
+ gboolean *changed_texture,
+ GError **error)
{
MetaWaylandEglStream *stream = buffer->egl_stream.stream;
@@ -406,10 +485,10 @@ egl_stream_buffer_attach (MetaWaylandBuffer *buffer,
* meta_wayland_buffer_attach(), which also might free it, as described above.
*/
gboolean
-meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
- CoglTexture **texture,
- gboolean *changed_texture,
- GError **error)
+meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture **texture,
+ gboolean *changed_texture,
+ GError **error)
{
g_return_val_if_fail (buffer->resource, FALSE);
@@ -425,14 +504,18 @@ meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
switch (buffer->type)
{
case META_WAYLAND_BUFFER_TYPE_SHM:
+ g_warning ("GOT SHM BUFFER");
return shm_buffer_attach (buffer, texture, changed_texture, error);
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
+ g_warning ("GOT EGL IMAGE BUFFER");
return egl_image_buffer_attach (buffer, texture, changed_texture, error);
#ifdef HAVE_WAYLAND_EGLSTREAM
case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
+ g_warning ("GOT EGL STREAM BUFFER");
return egl_stream_buffer_attach (buffer, texture, changed_texture, error);
#endif
case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
+ g_warning ("GOT DMA BUF BUFFER");
return meta_wayland_dma_buf_buffer_attach (buffer,
texture,
changed_texture,
@@ -466,55 +549,84 @@ meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer)
}
static gboolean
-process_shm_buffer_damage (MetaWaylandBuffer *buffer,
- CoglTexture *texture,
- cairo_region_t *region,
- GError **error)
+process_shm_buffer_damage (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture *texture,
+ cairo_region_t *region,
+ GError **error)
{
struct wl_shm_buffer *shm_buffer;
- int i, n_rectangles;
+ gint j, n_rectangles;
gboolean set_texture_failed = FALSE;
+ CoglPixelFormat format;
+ CoglTextureComponents components[3];
+ guint h_factors[3], v_factors[3], bpp[3];
+ guint offset = 0;
+ const uint8_t *data;
+ int32_t stride;
+ guint i, n_planes = cogl_multi_plane_texture_get_n_planes (texture);
n_rectangles = cairo_region_num_rectangles (region);
shm_buffer = wl_shm_buffer_get (buffer->resource);
+
+ /* Get the data */
wl_shm_buffer_begin_access (shm_buffer);
+ data = wl_shm_buffer_get_data (shm_buffer);
- for (i = 0; i < n_rectangles; i++)
+ /* Query the necessary properties */
+ stride = wl_shm_buffer_get_stride (shm_buffer);
+ shm_buffer_get_cogl_pixel_format (shm_buffer, &format, components);
+ cogl_pixel_format_get_subsampling_factors (format, h_factors, v_factors);
+ cogl_pixel_format_get_bits_per_pixel (format, bpp);
+
+ for (i = 0; i < n_planes; i++)
{
- const uint8_t *data = wl_shm_buffer_get_data (shm_buffer);
- int32_t stride = wl_shm_buffer_get_stride (shm_buffer);
- CoglPixelFormat format;
- int bpp;
- cairo_rectangle_int_t rect;
-
- shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
- bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
- cairo_region_get_rectangle (region, i, &rect);
-
- if (!_cogl_texture_set_region (texture,
- rect.width, rect.height,
- format,
- stride,
- data + rect.x * bpp + rect.y * stride,
- rect.x, rect.y,
- 0,
- error))
+ CoglTexture *plane;
+
+ plane = cogl_multi_plane_texture_get_plane (texture, i);
+
+ for (j = 0; j < n_rectangles; j++)
{
- set_texture_failed = TRUE;
- break;
+ cairo_rectangle_int_t rect;
+
+ cairo_region_get_rectangle (region, i, &rect);
+
+ /* It's possible we get a faulty rectangle of size zero: ignore */
+ if (rect.height == 0 || rect.width == 0)
+ continue;
+
+ /* Calculate the offset in the buffer */
+ if (i > 0)
+ offset += (stride / h_factors[i-1]) * (rect.height / v_factors[i-1]);
+
+ /* XXX don't we need the bpp here? */
+ if (!_cogl_texture_set_region (plane,
+ rect.width / h_factors[i],
+ rect.height / v_factors[i],
+ _cogl_texture_get_format (plane),
+ stride,
+ /* data + offset + rect.x * bpp + rect.y * stride, */
+ data + offset,
+ rect.x, rect.y,
+ 0,
+ error))
+ {
+ set_texture_failed = TRUE;
+ goto out;
+ }
}
}
+out:
wl_shm_buffer_end_access (shm_buffer);
return !set_texture_failed;
}
void
-meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
- CoglTexture *texture,
- cairo_region_t *region)
+meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture *texture,
+ cairo_region_t *region)
{
gboolean res = FALSE;
GError *error = NULL;
diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h
index 5d75a3451..07522f27b 100644
--- a/src/wayland/meta-wayland-buffer.h
+++ b/src/wayland/meta-wayland-buffer.h
@@ -56,19 +56,19 @@ struct _MetaWaylandBuffer
MetaWaylandBufferType type;
struct {
- CoglTexture *texture;
+ CoglMultiPlaneTexture *texture;
} egl_image;
#ifdef HAVE_WAYLAND_EGLSTREAM
struct {
MetaWaylandEglStream *stream;
- CoglTexture *texture;
+ CoglMultiPlaneTexture *texture;
} egl_stream;
#endif
struct {
MetaWaylandDmaBufBuffer *dma_buf;
- CoglTexture *texture;
+ CoglMultiPlaneTexture *texture;
} dma_buf;
};
@@ -80,14 +80,14 @@ MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resou
struct wl_resource * meta_wayland_buffer_get_resource (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_realize (MetaWaylandBuffer *buffer);
-gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
- CoglTexture **texture,
- gboolean *changed_texture,
- GError **error);
+gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture **texture,
+ gboolean *changed_texture,
+ GError **error);
CoglSnippet * meta_wayland_buffer_create_snippet (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer);
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
- CoglTexture *texture,
+ CoglMultiPlaneTexture *texture,
cairo_region_t *region);
#endif /* META_WAYLAND_BUFFER_H */
diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c
index d46b3511f..7ee2701e0 100644
--- a/src/wayland/meta-wayland-cursor-surface.c
+++ b/src/wayland/meta-wayland-cursor-surface.c
@@ -58,7 +58,7 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_surface));
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (priv->cursor_sprite);
- CoglTexture *texture;
+ CoglMultiPlaneTexture *texture;
if (!priv->cursor_renderer)
return;
@@ -66,8 +66,13 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
texture = meta_wayland_surface_get_texture (surface);
if (texture)
{
+ CoglTexture *plane;
+
+ /* XXX We assume that we get a simple (single-plane) texture here */
+ plane = cogl_multi_plane_texture_get_plane (texture, 0);
+
meta_cursor_sprite_set_texture (cursor_sprite,
- texture,
+ plane,
priv->hot_x * surface->scale,
priv->hot_y * surface->scale);
}
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
index e49fba9cf..877cab736 100644
--- a/src/wayland/meta-wayland-dma-buf.c
+++ b/src/wayland/meta-wayland-dma-buf.c
@@ -56,8 +56,9 @@ struct _MetaWaylandDmaBufBuffer
int width;
int height;
uint32_t drm_format;
- uint64_t drm_modifier;
bool is_y_inverted;
+
+ uint64_t drm_modifier[META_WAYLAND_DMA_BUF_MAX_FDS];
int fds[META_WAYLAND_DMA_BUF_MAX_FDS];
int offsets[META_WAYLAND_DMA_BUF_MAX_FDS];
unsigned int strides[META_WAYLAND_DMA_BUF_MAX_FDS];
@@ -65,25 +66,10 @@ struct _MetaWaylandDmaBufBuffer
G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJECT);
-static gboolean
-meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
- GError **error)
+static CoglPixelFormat
+drm_buffer_get_cogl_pixel_format (MetaWaylandDmaBufBuffer *dma_buf)
{
- MetaBackend *backend = meta_get_backend ();
- MetaEgl *egl = meta_backend_get_egl (backend);
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
- CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
- EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
- MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf;
- CoglPixelFormat cogl_format;
- EGLImageKHR egl_image;
- CoglTexture2D *texture;
- EGLint attribs[64];
- int attr_idx = 0;
-
- if (buffer->dma_buf.texture)
- return TRUE;
-
+ g_warning ("Got dma format %d", dma_buf->drm_format);
switch (dma_buf->drm_format)
{
/*
@@ -94,30 +80,62 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
* and access the buffer memory at all.
*/
case DRM_FORMAT_XRGB8888:
- cogl_format = COGL_PIXEL_FORMAT_RGB_888;
- break;
+ return COGL_PIXEL_FORMAT_RGB_888;
case DRM_FORMAT_ARGB8888:
- cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
- break;
+ return COGL_PIXEL_FORMAT_ARGB_8888_PRE;
case DRM_FORMAT_ARGB2101010:
- cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
- break;
+ return COGL_PIXEL_FORMAT_ARGB_2101010_PRE;
case DRM_FORMAT_RGB565:
- cogl_format = COGL_PIXEL_FORMAT_RGB_565;
- break;
+ return COGL_PIXEL_FORMAT_RGB_565;
+ case DRM_FORMAT_YUYV:
+ return COGL_PIXEL_FORMAT_YUYV;
+ case DRM_FORMAT_NV12:
+ return COGL_PIXEL_FORMAT_NV12;
+ case DRM_FORMAT_NV21:
+ return COGL_PIXEL_FORMAT_NV21;
+ case DRM_FORMAT_YUV410:
+ return COGL_PIXEL_FORMAT_YUV410;
+ case DRM_FORMAT_YVU410:
+ return COGL_PIXEL_FORMAT_YVU410;
+ case DRM_FORMAT_YUV411:
+ return COGL_PIXEL_FORMAT_YUV411;
+ case DRM_FORMAT_YVU411:
+ return COGL_PIXEL_FORMAT_YVU411;
+ case DRM_FORMAT_YUV420:
+ return COGL_PIXEL_FORMAT_YUV420;
+ case DRM_FORMAT_YVU420:
+ return COGL_PIXEL_FORMAT_YVU420;
+ case DRM_FORMAT_YUV422:
+ return COGL_PIXEL_FORMAT_YUV422;
+ case DRM_FORMAT_YVU422:
+ return COGL_PIXEL_FORMAT_YVU422;
+ case DRM_FORMAT_YUV444:
+ return COGL_PIXEL_FORMAT_YUV444;
+ case DRM_FORMAT_YVU444:
+ return COGL_PIXEL_FORMAT_YVU444;
default:
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Unsupported buffer format %d", dma_buf->drm_format);
- return FALSE;
+ return COGL_PIXEL_FORMAT_ANY;
}
+}
+
+static EGLImageKHR
+create_egl_image_from_dmabuf (MetaEgl *egl,
+ EGLDisplay egl_display,
+ MetaWaylandDmaBufBuffer *dma_buf,
+ int32_t width,
+ int32_t height,
+ uint32_t drm_format,
+ GError **error)
+{
+ EGLint attribs[64];
+ int attr_idx = 0;
attribs[attr_idx++] = EGL_WIDTH;
- attribs[attr_idx++] = dma_buf->width;
+ attribs[attr_idx++] = width;
attribs[attr_idx++] = EGL_HEIGHT;
- attribs[attr_idx++] = dma_buf->height;
+ attribs[attr_idx++] = height;
attribs[attr_idx++] = EGL_LINUX_DRM_FOURCC_EXT;
- attribs[attr_idx++] = dma_buf->drm_format;
+ attribs[attr_idx++] = drm_format;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_FD_EXT;
attribs[attr_idx++] = dma_buf->fds[0];
@@ -126,9 +144,9 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
attribs[attr_idx++] = dma_buf->strides[0];
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
+ attribs[attr_idx++] = dma_buf->drm_modifier[0] & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
+ attribs[attr_idx++] = dma_buf->drm_modifier[0] >> 32;
if (dma_buf->fds[1] >= 0)
{
@@ -139,9 +157,9 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
attribs[attr_idx++] = dma_buf->strides[1];
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
+ attribs[attr_idx++] = dma_buf->drm_modifier[1] & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
+ attribs[attr_idx++] = dma_buf->drm_modifier[1] >> 32;
}
if (dma_buf->fds[2] >= 0)
@@ -153,9 +171,9 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
attribs[attr_idx++] = dma_buf->strides[2];
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
+ attribs[attr_idx++] = dma_buf->drm_modifier[2] & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
+ attribs[attr_idx++] = dma_buf->drm_modifier[2] >> 32;
}
if (dma_buf->fds[3] >= 0)
@@ -167,46 +185,97 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
attribs[attr_idx++] = dma_buf->strides[3];
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff;
+ attribs[attr_idx++] = dma_buf->drm_modifier[3] & 0xffffffff;
attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
- attribs[attr_idx++] = dma_buf->drm_modifier >> 32;
+ attribs[attr_idx++] = dma_buf->drm_modifier[3] >> 32;
}
attribs[attr_idx++] = EGL_NONE;
- attribs[attr_idx++] = EGL_NONE;
- /* The EXT_image_dma_buf_import spec states that EGL_NO_CONTEXT is to be used
- * in conjunction with the EGL_LINUX_DMA_BUF_EXT target. Similarly, the
- * native buffer is named in the attribs. */
- egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
- EGL_LINUX_DMA_BUF_EXT, NULL, attribs,
- error);
- if (egl_image == EGL_NO_IMAGE_KHR)
- return FALSE;
+ /* The EXT_image_dma_buf_import spec states that EGL_NO_CONTEXT is to be
+ * used in conjunction with the EGL_LINUX_DMA_BUF_EXT target. Similarly,
+ * the native buffer is named in the attribs. */
+ return meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
+ EGL_LINUX_DMA_BUF_EXT, NULL, attribs,
+ error);
+}
- texture = cogl_egl_texture_2d_new_from_image (cogl_context,
- dma_buf->width,
- dma_buf->height,
- cogl_format,
- egl_image,
- error);
+static gboolean
+meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer,
+ GError **error)
+{
+ MetaBackend *backend = meta_get_backend ();
+ MetaEgl *egl = meta_backend_get_egl (backend);
+ ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
+ CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
+ EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
+ MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf;
+ CoglPixelFormat cogl_format;
+ GPtrArray *planes;
+ guint i = 0, n_planes = 1;
- meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
+ if (buffer->dma_buf.texture)
+ return TRUE;
- if (!texture)
- return FALSE;
+ cogl_format = drm_buffer_get_cogl_pixel_format (dma_buf);
+ g_warning ("Dmabuf: Got cogl format %s", cogl_pixel_format_to_string (cogl_format));
+ if (G_UNLIKELY (cogl_format == COGL_PIXEL_FORMAT_ANY))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Unsupported buffer format %d", dma_buf->drm_format);
+ return FALSE;
+ }
- buffer->dma_buf.texture = COGL_TEXTURE (texture);
+ n_planes = cogl_pixel_format_get_n_planes (cogl_format);
+ planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
+
+ /* Each EGLImage is a plane in the final CoglMultiPlaneTexture */
+ for (i = 0; i < n_planes; i++)
+ {
+ EGLImageKHR egl_img;
+ CoglTexture2D *plane;
+
+ egl_img = create_egl_image_from_dmabuf (egl,
+ egl_display,
+ dma_buf,
+ dma_buf->width, dma_buf->height,
+ dma_buf->drm_format,
+ error);
+ if (G_UNLIKELY (egl_img == EGL_NO_IMAGE_KHR))
+ goto on_error;
+
+ plane = cogl_egl_texture_2d_new_from_image (cogl_context,
+ dma_buf->width,
+ dma_buf->height,
+ cogl_format,
+ egl_img,
+ error);
+
+ meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
+
+ if (G_UNLIKELY (!plane))
+ goto on_error;
+
+ g_ptr_array_add (planes, plane);
+ }
+
+ buffer->dma_buf.texture = cogl_multi_plane_texture_new (cogl_format,
+ (CoglTexture **) g_ptr_array_free (planes, FALSE),
+ n_planes);
buffer->is_y_inverted = dma_buf->is_y_inverted;
return TRUE;
+
+on_error:
+ g_ptr_array_free (planes, TRUE);
+ return FALSE;
}
gboolean
-meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
- CoglTexture **texture,
- gboolean *changed_texture,
- GError **error)
+meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture **texture,
+ gboolean *changed_texture,
+ GError **error)
{
if (!meta_wayland_dma_buf_realize_texture (buffer, error))
return FALSE;
@@ -234,7 +303,7 @@ buffer_params_add (struct wl_client *client,
drm_modifier |= ((uint64_t) drm_modifier_lo) & 0xffffffff;
dma_buf = wl_resource_get_user_data (resource);
- if (!dma_buf)
+ if (G_UNLIKELY (!dma_buf))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED,
@@ -242,7 +311,7 @@ buffer_params_add (struct wl_client *client,
return;
}
- if (plane_idx >= META_WAYLAND_DMA_BUF_MAX_FDS)
+ if (G_UNLIKELY (plane_idx >= META_WAYLAND_DMA_BUF_MAX_FDS))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX,
@@ -251,7 +320,7 @@ buffer_params_add (struct wl_client *client,
return;
}
- if (dma_buf->fds[plane_idx] != -1)
+ if (G_UNLIKELY (dma_buf->fds[plane_idx] != -1))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
@@ -260,8 +329,8 @@ buffer_params_add (struct wl_client *client,
return;
}
- if (dma_buf->drm_modifier != DRM_FORMAT_MOD_INVALID &&
- dma_buf->drm_modifier != drm_modifier)
+ if (G_UNLIKELY (dma_buf->drm_modifier[plane_idx] != DRM_FORMAT_MOD_INVALID &&
+ dma_buf->drm_modifier[plane_idx] != drm_modifier))
{
wl_resource_post_error (resource,
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER,
@@ -269,8 +338,9 @@ buffer_params_add (struct wl_client *client,
return;
}
- dma_buf->drm_modifier = drm_modifier;
+
dma_buf->fds[plane_idx] = fd;
+ dma_buf->drm_modifier[plane_idx] = drm_modifier;
dma_buf->offsets[plane_idx] = offset;
dma_buf->strides[plane_idx] = stride;
}
@@ -550,6 +620,16 @@ dma_buf_bind (struct wl_client *client,
send_modifiers (resource, DRM_FORMAT_XRGB8888);
send_modifiers (resource, DRM_FORMAT_ARGB2101010);
send_modifiers (resource, DRM_FORMAT_RGB565);
+ send_modifiers (resource, DRM_FORMAT_NV12);
+ send_modifiers (resource, DRM_FORMAT_YUV410);
+ send_modifiers (resource, DRM_FORMAT_YVU410);
+ send_modifiers (resource, DRM_FORMAT_YUV411);
+ send_modifiers (resource, DRM_FORMAT_YVU420);
+ send_modifiers (resource, DRM_FORMAT_YVU420);
+ send_modifiers (resource, DRM_FORMAT_YUV422);
+ send_modifiers (resource, DRM_FORMAT_YVU422);
+ send_modifiers (resource, DRM_FORMAT_YUV444);
+ send_modifiers (resource, DRM_FORMAT_YVU444);
}
gboolean
@@ -598,10 +678,12 @@ meta_wayland_dma_buf_buffer_init (MetaWaylandDmaBufBuffer *dma_buf)
{
int i;
- dma_buf->drm_modifier = DRM_FORMAT_MOD_INVALID;
for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++)
- dma_buf->fds[i] = -1;
+ {
+ dma_buf->drm_modifier[i] = DRM_FORMAT_MOD_INVALID;
+ dma_buf->fds[i] = -1;
+ }
}
static void
diff --git a/src/wayland/meta-wayland-dma-buf.h b/src/wayland/meta-wayland-dma-buf.h
index 580a3e777..a2b4fd937 100644
--- a/src/wayland/meta-wayland-dma-buf.h
+++ b/src/wayland/meta-wayland-dma-buf.h
@@ -42,10 +42,10 @@ typedef struct _MetaWaylandDmaBufBuffer MetaWaylandDmaBufBuffer;
gboolean meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor);
gboolean
-meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
- CoglTexture **texture,
- gboolean *changed_texture,
- GError **error);
+meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer,
+ CoglMultiPlaneTexture **texture,
+ gboolean *changed_texture,
+ GError **error);
MetaWaylandDmaBufBuffer *
meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer);
diff --git a/src/wayland/meta-wayland-egl-stream.c b/src/wayland/meta-wayland-egl-stream.c
index 3f8908e67..a0125894d 100644
--- a/src/wayland/meta-wayland-egl-stream.c
+++ b/src/wayland/meta-wayland-egl-stream.c
@@ -132,7 +132,7 @@ struct _MetaWaylandEglStream
EGLStreamKHR egl_stream;
MetaWaylandBuffer *buffer;
- CoglTexture2D *texture;
+ CoglMultiPlaneTexture *texture;
gboolean is_y_inverted;
};
@@ -183,7 +183,7 @@ stream_texture_destroyed (gpointer data)
}
static gboolean
-alloc_egl_stream_texture (CoglTexture2D *texture,
+alloc_egl_stream_texture (CoglTexture2D *texture_2d,
gpointer user_data,
GError **error)
{
@@ -199,7 +199,7 @@ alloc_egl_stream_texture (CoglTexture2D *texture,
error);
}
-CoglTexture2D *
+CoglMultiPlaneTexture *
meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
GError **error)
{
@@ -208,7 +208,7 @@ meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
- CoglTexture2D *texture;
+ CoglTexture2D *texture_2d;
int width, height;
int y_inverted;
@@ -230,29 +230,30 @@ meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
NULL))
y_inverted = EGL_TRUE;
- texture =
+ texture_2d =
cogl_texture_2d_new_from_egl_image_external (cogl_context,
width, height,
alloc_egl_stream_texture,
g_object_ref (stream),
stream_texture_destroyed,
error);
- if (!texture)
+ if (!texture_2d)
{
g_object_unref (stream);
return NULL;
}
- if (!cogl_texture_allocate (COGL_TEXTURE (texture), error))
+ if (!cogl_texture_allocate (COGL_TEXTURE (texture_2d), error))
{
- cogl_object_unref (texture);
+ cogl_object_unref (texture_2d);
return NULL;
}
- stream->texture = texture;
+ stream->texture = cogl_multi_plane_texture_new_single_plane (COGL_PIXEL_FORMAT_ANY,
+ COGL_TEXTURE (texture_2d));
stream->is_y_inverted = !!y_inverted;
- return texture;
+ return stream->texture;
}
gboolean
diff --git a/src/wayland/meta-wayland-egl-stream.h b/src/wayland/meta-wayland-egl-stream.h
index fe488ed54..d548d9a72 100644
--- a/src/wayland/meta-wayland-egl-stream.h
+++ b/src/wayland/meta-wayland-egl-stream.h
@@ -45,8 +45,8 @@ MetaWaylandEglStream * meta_wayland_egl_stream_new (MetaWaylandBuffer *buffer,
gboolean meta_wayland_egl_stream_attach (MetaWaylandEglStream *stream,
GError **error);
-CoglTexture2D * meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
- GError **error);
+CoglMultiPlaneTexture * meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream,
+ GError **error);
CoglSnippet * meta_wayland_egl_stream_create_snippet (void);
gboolean meta_wayland_egl_stream_is_y_inverted (MetaWaylandEglStream *stream);
diff --git a/src/wayland/meta-wayland-shell-surface.c b/src/wayland/meta-wayland-shell-surface.c
index 04f2aaeea..41c8da710 100644
--- a/src/wayland/meta-wayland-shell-surface.c
+++ b/src/wayland/meta-wayland-shell-surface.c
@@ -153,7 +153,7 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWindow *window;
MetaWaylandBuffer *buffer;
- CoglTexture *texture;
+ CoglMultiPlaneTexture *texture;
double scale;
surface_role_class =
@@ -171,8 +171,8 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
texture = meta_wayland_surface_get_texture (surface);
- window->buffer_rect.width = cogl_texture_get_width (texture) * scale;
- window->buffer_rect.height = cogl_texture_get_height (texture) * scale;
+ window->buffer_rect.width = cogl_multi_plane_texture_get_width (texture) * scale;
+ window->buffer_rect.height = cogl_multi_plane_texture_get_height (texture) * scale;
}
static void
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index da0acfcbb..afd7275b9 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -247,7 +247,7 @@ get_buffer_width (MetaWaylandSurface *surface)
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (buffer)
- return cogl_texture_get_width (surface->texture);
+ return cogl_multi_plane_texture_get_width (surface->texture);
else
return 0;
}
@@ -258,7 +258,7 @@ get_buffer_height (MetaWaylandSurface *surface)
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (buffer)
- return cogl_texture_get_height (surface->texture);
+ return cogl_multi_plane_texture_get_height (surface->texture);
else
return 0;
}
@@ -722,7 +722,7 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
if (changed_texture && meta_wayland_surface_get_actor (surface))
{
MetaShapedTexture *stex;
- CoglTexture *texture;
+ CoglMultiPlaneTexture *texture;
CoglSnippet *snippet;
gboolean is_y_inverted;
@@ -1843,7 +1843,7 @@ meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
}
-CoglTexture *
+CoglMultiPlaneTexture *
meta_wayland_surface_get_texture (MetaWaylandSurface *surface)
{
return surface->texture;
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index e244a3fdf..b82cdc600 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -149,7 +149,7 @@ struct _MetaWaylandSurface
GHashTable *outputs_to_destroy_notify_id;
MetaMonitorTransform buffer_transform;
- CoglTexture *texture;
+ CoglMultiPlaneTexture *texture;
/* Buffer reference state. */
struct {
@@ -319,7 +319,7 @@ void meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *
gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
MetaWaylandSeat *seat);
-CoglTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
+CoglMultiPlaneTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
MetaSurfaceActor * meta_wayland_surface_get_actor (MetaWaylandSurface *surface);
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index a593f0a7b..02825709d 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -307,6 +307,26 @@ meta_wayland_log_func (const char *fmt,
}
static void
+add_supported_shm_formats (struct wl_display *display)
+{
+ guint i;
+
+ /* Note that a Wayland compositor should support WL_SHM_FORMAT_ARGB8888 and
+ * WL_SHM_FORMAT_XRGB8888 by default, so no need to add it here. */
+ static const guint32 SUPPORTED_FORMATS[] = {
+ WL_SHM_FORMAT_NV12,
+ WL_SHM_FORMAT_NV21,
+ WL_SHM_FORMAT_YUV422,
+ WL_SHM_FORMAT_YUV444,
+ };
+
+ for (i = 0; i < G_N_ELEMENTS (SUPPORTED_FORMATS); i++)
+ {
+ wl_display_add_shm_format (display, SUPPORTED_FORMATS[i]);
+ }
+}
+
+static void
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
{
wl_list_init (&compositor->frame_callbacks);
@@ -318,6 +338,8 @@ meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
compositor->wayland_display = wl_display_create ();
if (compositor->wayland_display == NULL)
g_error ("Failed to create the global wl_display");
+
+ add_supported_shm_formats (compositor->wayland_display);
}
static void