[mutter/wip/nielsdg/meta-multi-texture-wip: 2/7] shaped-texture: Start using MetaMultiTexture




commit 28b7813eb8ffce543800fec6690c71adea4991d1
Author: Niels De Graef <niels degraef barco com>
Date:   Tue Oct 22 12:25:37 2019 +0200

    shaped-texture: Start using MetaMultiTexture
    
    To be able to later support more complex YUV formats, we need to make
    sure that MetaShapedTexture (the one who will actually render the
    texture) can use the MetaMultiTexture class.

 src/compositor/meta-shaped-texture-private.h |   2 +-
 src/compositor/meta-shaped-texture.c         | 109 ++++++++++++--------
 src/compositor/meta-surface-actor-x11.c      |  23 +++--
 src/compositor/meta-texture-tower.c          | 142 +++++++++++++++++----------
 src/compositor/meta-texture-tower.h          |   5 +-
 src/meta/meta-shaped-texture.h               |   3 +-
 src/wayland/meta-wayland-buffer.c            | 136 ++++++++++++++-----------
 src/wayland/meta-wayland-buffer.h            |  11 ++-
 src/wayland/meta-wayland-dma-buf.c           |  26 ++---
 src/wayland/meta-wayland-dma-buf.h           |   3 +-
 src/wayland/meta-wayland-surface.c           |  10 +-
 src/wayland/meta-wayland-surface.h           |   4 +-
 12 files changed, 283 insertions(+), 191 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index 672f24eb7c..03e27b919f 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -32,7 +32,7 @@
 
 MetaShapedTexture *meta_shaped_texture_new (void);
 void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
-                                      CoglTexture       *texture);
+                                      MetaMultiTexture  *multi_texture);
 void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
                                             gboolean           is_y_inverted);
 void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 547ff4d35c..360e913d5b 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -84,7 +84,7 @@ struct _MetaShapedTexture
 
   MetaTextureTower *paint_tower;
 
-  CoglTexture *texture;
+  MetaMultiTexture *texture;
   CoglTexture *mask_texture;
   CoglSnippet *snippet;
 
@@ -521,18 +521,18 @@ paint_clipped_rectangle_node (MetaShapedTexture     *stex,
 }
 
 static void
-set_cogl_texture (MetaShapedTexture *stex,
-                  CoglTexture       *cogl_tex)
+set_multi_texture (MetaShapedTexture *stex,
+                   MetaMultiTexture  *multi_tex)
 {
   int width, height;
 
-  cogl_clear_object (&stex->texture);
+  g_clear_object (&stex->texture);
 
-  if (cogl_tex != NULL)
+  if (multi_tex != NULL)
     {
-      stex->texture = cogl_object_ref (cogl_tex);
-      width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
-      height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
+      stex->texture = g_object_ref (multi_tex);
+      width = meta_multi_texture_get_width (multi_tex);
+      height = meta_multi_texture_get_height (multi_tex);
     }
   else
     {
@@ -554,7 +554,7 @@ set_cogl_texture (MetaShapedTexture *stex,
    * damage. */
 
   if (stex->create_mipmaps)
-    meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex);
+    meta_texture_tower_set_base_texture (stex->paint_tower, multi_tex);
 }
 
 static gboolean
@@ -586,7 +586,7 @@ static void
 do_paint_content (MetaShapedTexture   *stex,
                   ClutterPaintNode    *root_node,
                   ClutterPaintContext *paint_context,
-                  CoglTexture         *paint_tex,
+                  MetaMultiTexture    *paint_tex,
                   ClutterActorBox     *alloc,
                   uint8_t              opacity)
 {
@@ -599,6 +599,7 @@ do_paint_content (MetaShapedTexture   *stex,
   CoglFramebuffer *framebuffer;
   int sample_width, sample_height;
   gboolean debug_paint_opaque_region;
+  guint n_planes;
 
   ensure_size_valid (stex);
 
@@ -684,6 +685,8 @@ do_paint_content (MetaShapedTexture   *stex,
         }
     }
 
+  n_planes = meta_multi_texture_get_n_planes (paint_tex);
+
   /* First, paint the unblended parts, which are part of the opaque region. */
   if (use_opaque_region)
     {
@@ -706,8 +709,14 @@ do_paint_content (MetaShapedTexture   *stex,
           CoglPipeline *opaque_pipeline;
 
           opaque_pipeline = get_unblended_pipeline (stex, ctx);
-          cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
-          cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
+
+          for (i = 0; i < n_planes; i++)
+            {
+              CoglTexture *plane = meta_multi_texture_get_plane (paint_tex, i);
+
+              cogl_pipeline_set_layer_texture (opaque_pipeline, i, plane);
+              cogl_pipeline_set_layer_filters (opaque_pipeline, i, filter, filter);
+            }
 
           n_rects = cairo_region_num_rectangles (region);
           for (i = 0; i < n_rects; i++)
@@ -746,6 +755,7 @@ do_paint_content (MetaShapedTexture   *stex,
   if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region))
     {
       CoglPipeline *blended_pipeline;
+      guint i;
 
       if (stex->mask_texture == NULL)
         {
@@ -754,16 +764,20 @@ do_paint_content (MetaShapedTexture   *stex,
       else
         {
           blended_pipeline = get_masked_pipeline (stex, ctx);
-          cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
-          cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
+          cogl_pipeline_set_layer_texture (blended_pipeline, n_planes, stex->mask_texture);
+          cogl_pipeline_set_layer_filters (blended_pipeline, n_planes, filter, filter);
         }
 
-      cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
-      cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
+      for (i = 0; i < n_planes; i++)
+        {
+          CoglTexture *plane = meta_multi_texture_get_plane (paint_tex, i);
+
+          cogl_pipeline_set_layer_texture (blended_pipeline, i, plane);
+          cogl_pipeline_set_layer_filters (blended_pipeline, i, filter, filter);
+        }
 
-      CoglColor color;
-      cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
-      cogl_pipeline_set_color (blended_pipeline, &color);
+      cogl_pipeline_set_color4ub (blended_pipeline,
+                                  opacity, opacity, opacity, opacity);
 
       if (blended_tex_region)
         {
@@ -824,11 +838,11 @@ do_paint_content (MetaShapedTexture   *stex,
   g_clear_pointer (&blended_tex_region, cairo_region_destroy);
 }
 
-static CoglTexture *
-select_texture_for_paint (MetaShapedTexture   *stex,
+static MetaMultiTexture *
+select_texture_for_paint (MetaShapedTexture *stex,
                           ClutterPaintContext *paint_context)
 {
-  CoglTexture *texture = NULL;
+  MetaMultiTexture *texture = NULL;
   int64_t now;
 
   if (!stex->texture)
@@ -876,7 +890,7 @@ meta_shaped_texture_paint_content (ClutterContent      *content,
 {
   MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
   ClutterActorBox alloc;
-  CoglTexture *paint_tex = NULL;
+  MetaMultiTexture *paint_tex = NULL;
   uint8_t opacity;
 
   if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
@@ -942,7 +956,7 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
 
   if (create_mipmaps != stex->create_mipmaps)
     {
-      CoglTexture *base_texture;
+      MetaMultiTexture *base_texture;
       stex->create_mipmaps = create_mipmaps;
       base_texture = create_mipmaps ? stex->texture : NULL;
       meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
@@ -1089,18 +1103,18 @@ meta_shaped_texture_update_area (MetaShapedTexture     *stex,
 /**
  * meta_shaped_texture_set_texture:
  * @stex: The #MetaShapedTexture
- * @pixmap: The #CoglTexture to display
+ * @pixmap: The #MetaMultiTexture to display
  */
 void
 meta_shaped_texture_set_texture (MetaShapedTexture *stex,
-                                 CoglTexture       *texture)
+                                 MetaMultiTexture  *texture)
 {
   g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
 
   if (stex->texture == texture)
     return;
 
-  set_cogl_texture (stex, texture);
+  set_multi_texture (stex, texture);
 }
 
 /**
@@ -1141,11 +1155,11 @@ meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
  *
  * Returns: (transfer none): the unshaped texture
  */
-CoglTexture *
+MetaMultiTexture *
 meta_shaped_texture_get_texture (MetaShapedTexture *stex)
 {
   g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
-  return COGL_TEXTURE (stex->texture);
+  return stex->texture;
 }
 
 /**
@@ -1177,13 +1191,19 @@ meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex)
 gboolean
 meta_shaped_texture_has_alpha (MetaShapedTexture *stex)
 {
-  CoglTexture *texture;
+  MetaMultiTexture *multi_texture;
+  CoglTexture *cogl_texture;
 
-  texture = stex->texture;
-  if (!texture)
+  multi_texture = stex->texture;
+  if (!multi_texture)
     return TRUE;
 
-  switch (cogl_texture_get_components (texture))
+  /* FIXME: for now we don't support alpha (except simple textures) */
+  if (meta_multi_texture_get_n_planes (multi_texture) > 1)
+    return FALSE;
+
+  cogl_texture = meta_multi_texture_get_plane (multi_texture, 0);
+  switch (cogl_texture_get_components (cogl_texture))
     {
     case COGL_TEXTURE_COMPONENTS_A:
     case COGL_TEXTURE_COMPONENTS_RGBA:
@@ -1201,12 +1221,12 @@ meta_shaped_texture_has_alpha (MetaShapedTexture *stex)
 gboolean
 meta_shaped_texture_is_opaque (MetaShapedTexture *stex)
 {
-  CoglTexture *texture;
+  MetaMultiTexture *multi_texture;
   cairo_rectangle_int_t opaque_rect;
 
-  texture = stex->texture;
-  if (!texture)
-    return FALSE;
+  multi_texture = stex->texture;
+  if (!multi_texture)
+    return TRUE;
 
   if (!meta_shaped_texture_has_alpha (stex))
     return TRUE;
@@ -1331,7 +1351,13 @@ meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex)
 static gboolean
 should_get_via_offscreen (MetaShapedTexture *stex)
 {
-  if (!cogl_texture_is_get_data_supported (stex->texture))
+  CoglTexture *cogl_texture;
+
+  if (meta_multi_texture_get_n_planes (stex->texture) > 1)
+    return FALSE;
+
+  cogl_texture = meta_multi_texture_get_plane (stex->texture, 0);
+  if (!cogl_texture_is_get_data_supported (cogl_texture))
     return TRUE;
 
   if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
@@ -1476,9 +1502,7 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 
   g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
 
-  texture = COGL_TEXTURE (stex->texture);
-
-  if (texture == NULL)
+  if (stex->texture == NULL)
     return NULL;
 
   ensure_size_valid (stex);
@@ -1521,6 +1545,9 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
                                       image_height);
     }
 
+  /* We know that we only have 1 plane at this point */
+  texture = meta_multi_texture_get_plane (stex->texture, 0);
+
   if (image_clip)
     texture = cogl_texture_new_from_sub_texture (texture,
                                                  image_clip->x,
diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c
index 41ae2dffbc..8024572a8f 100644
--- a/src/compositor/meta-surface-actor-x11.c
+++ b/src/compositor/meta-surface-actor-x11.c
@@ -46,7 +46,7 @@ struct _MetaSurfaceActorX11
 
   MetaDisplay *display;
 
-  CoglTexture *texture;
+  MetaMultiTexture *texture;
   Pixmap pixmap;
   Damage damage;
 
@@ -109,7 +109,7 @@ detach_pixmap (MetaSurfaceActorX11 *self)
   self->pixmap = None;
   meta_x11_error_trap_pop (display->x11_display);
 
-  g_clear_pointer (&self->texture, cogl_object_unref);
+  g_clear_object (&self->texture);
 }
 
 static void
@@ -119,23 +119,23 @@ set_pixmap (MetaSurfaceActorX11 *self,
   CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
   MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
   GError *error = NULL;
-  CoglTexture *texture;
+  CoglTexture *cogl_texture;
 
   g_assert (self->pixmap == None);
   self->pixmap = pixmap;
 
-  texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, self->pixmap, FALSE, &error));
+  cogl_texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, self->pixmap, FALSE, &error));
 
   if (error != NULL)
     {
       g_warning ("Failed to allocate stex texture: %s", error->message);
       g_error_free (error);
     }
-  else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
+  else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 
(cogl_texture))))
     g_warning ("NOTE: Not using GLX TFP!");
 
-  self->texture = texture;
-  meta_shaped_texture_set_texture (stex, texture);
+  self->texture = meta_multi_texture_new_simple (cogl_texture);
+  meta_shaped_texture_set_texture (stex, self->texture);
 }
 
 static void
@@ -192,6 +192,7 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
                                        int x, int y, int width, int height)
 {
   MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
+  CoglTexturePixmapX11 *pixmap;
 
   self->received_damage = TRUE;
 
@@ -215,8 +216,12 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
   if (!meta_surface_actor_x11_is_visible (self))
     return;
 
-  cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (self->texture),
-                                       x, y, width, height);
+  /* We don't support multi-plane or YUV based formats in X */
+  if (!meta_multi_texture_is_simple (self->texture))
+    return;
+
+  pixmap = COGL_TEXTURE_PIXMAP_X11 (meta_multi_texture_get_plane (self->texture, 0));
+  cogl_texture_pixmap_x11_update_area (pixmap, x, y, width, height);
   meta_surface_actor_update_area (actor, x, y, width, height);
 }
 
diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c
index 2571c7e3c0..f3e0fbd98e 100644
--- a/src/compositor/meta-texture-tower.c
+++ b/src/compositor/meta-texture-tower.c
@@ -58,8 +58,8 @@ typedef struct
 struct _MetaTextureTower
 {
   int n_levels;
-  CoglTexture *textures[MAX_TEXTURE_LEVELS];
-  CoglOffscreen *fbos[MAX_TEXTURE_LEVELS];
+  MetaMultiTexture *textures[MAX_TEXTURE_LEVELS];
+  GList *fbos[MAX_TEXTURE_LEVELS];
   Box invalid[MAX_TEXTURE_LEVELS];
   CoglPipeline *pipeline_template;
 };
@@ -113,7 +113,7 @@ meta_texture_tower_free (MetaTextureTower *tower)
  */
 void
 meta_texture_tower_set_base_texture (MetaTextureTower *tower,
-                                     CoglTexture      *texture)
+                                     MetaMultiTexture *texture)
 {
   int i;
 
@@ -126,11 +126,12 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
     {
       for (i = 1; i < tower->n_levels; i++)
         {
-          cogl_clear_object (&tower->textures[i]);
-          g_clear_object (&tower->fbos[i]);
+          g_clear_object (&tower->textures[i]);
+          g_list_free_full (tower->fbos[i], g_object_unref);
+          tower->fbos[i] = NULL;
         }
 
-      cogl_object_unref (tower->textures[0]);
+      g_object_unref (tower->textures[0]);
     }
 
   tower->textures[0] = texture;
@@ -139,10 +140,10 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
     {
       int width, height;
 
-      cogl_object_ref (tower->textures[0]);
+      g_object_ref (tower->textures[0]);
 
-      width = cogl_texture_get_width (tower->textures[0]);
-      height = cogl_texture_get_height (tower->textures[0]);
+      width = meta_multi_texture_get_width (tower->textures[0]);
+      height = meta_multi_texture_get_height (tower->textures[0]);
 
       tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
       tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
@@ -183,8 +184,8 @@ meta_texture_tower_update_area (MetaTextureTower *tower,
   if (tower->textures[0] == NULL)
     return;
 
-  texture_width = cogl_texture_get_width (tower->textures[0]);
-  texture_height = cogl_texture_get_height (tower->textures[0]);
+  texture_width = meta_multi_texture_get_width (tower->textures[0]);
+  texture_height = meta_multi_texture_get_height (tower->textures[0]);
 
   invalid.x1 = x;
   invalid.y1 = y;
@@ -359,9 +360,26 @@ texture_tower_create_texture (MetaTextureTower *tower,
                               int               width,
                               int               height)
 {
-  tower->textures[level] = cogl_texture_new_with_size (width, height,
-                                                       COGL_TEXTURE_NO_AUTO_MIPMAP,
-                                                       TEXTURE_FORMAT);
+  MetaMultiTextureFormat format;
+  guint i, n_planes;
+  GPtrArray *planes;
+  CoglTexture **textures;
+
+  format = meta_multi_texture_get_format (tower->textures[0]);
+  n_planes = meta_multi_texture_format_get_n_planes (format);
+  planes = g_ptr_array_new_full (n_planes, g_object_unref);
+  for (i = 0; i < n_planes; i++)
+    {
+      CoglTexture *texture;
+
+       texture = cogl_texture_new_with_size (width, height,
+                                             COGL_TEXTURE_NO_AUTO_MIPMAP,
+                                             TEXTURE_FORMAT);
+       g_ptr_array_add (planes, texture);
+    }
+
+  textures = (CoglTexture **) g_ptr_array_free (planes, FALSE);
+  tower->textures[level] = meta_multi_texture_new (format, textures, n_planes);
 
   tower->invalid[level].x1 = 0;
   tower->invalid[level].y1 = 0;
@@ -373,50 +391,68 @@ static void
 texture_tower_revalidate (MetaTextureTower *tower,
                           int               level)
 {
-  CoglTexture *source_texture = tower->textures[level - 1];
-  int source_texture_width = cogl_texture_get_width (source_texture);
-  int source_texture_height = cogl_texture_get_height (source_texture);
-  CoglTexture *dest_texture = tower->textures[level];
-  int dest_texture_width = cogl_texture_get_width (dest_texture);
-  int dest_texture_height = cogl_texture_get_height (dest_texture);
+  MetaMultiTexture *src_tex = tower->textures[level - 1];
+  int src_width = meta_multi_texture_get_width (src_tex);
+  int src_height = meta_multi_texture_get_height (src_tex);
+  guint src_n_planes = meta_multi_texture_get_n_planes (src_tex);
+  MetaMultiTexture *dest_tex = tower->textures[level];
+  int dest_width = meta_multi_texture_get_width (dest_tex);
+  int dest_height = meta_multi_texture_get_height (dest_tex);
   Box *invalid = &tower->invalid[level];
-  CoglFramebuffer *fb;
-  GError *catch_error = NULL;
-  CoglPipeline *pipeline;
+  guint i;
 
-  if (tower->fbos[level] == NULL)
-    tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture);
+  /* FIXME: cogl_offscreen_texture_new_with_texture doesn't work for
+   * multi-plane textures, so we have to make an FBO for each layer */
+    for (i = 0; i < src_n_planes; i++)
+    {
+      Box *invalid = &tower->invalid[level];
+      CoglTexture *src_plane, *dest_plane;
+      CoglFramebuffer *fb;
+      GError *catch_error = NULL;
+      CoglPipeline *pipeline;
 
-  fb = COGL_FRAMEBUFFER (tower->fbos[level]);
+      src_plane = meta_multi_texture_get_plane (src_tex, i);
+      dest_plane = meta_multi_texture_get_plane (dest_tex, i);
 
-  if (!cogl_framebuffer_allocate (fb, &catch_error))
-    {
-      g_error_free (catch_error);
-      return;
-    }
+      if (g_list_nth (tower->fbos[level], i) != NULL)
+        {
+          fb = COGL_FRAMEBUFFER (g_list_nth (tower->fbos[level], i)->data);
+        }
+      else
+        {
+          fb = COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (dest_plane));
+          tower->fbos[level] = g_list_append (tower->fbos[level], fb);
+        }
 
-  cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.);
+      if (!cogl_framebuffer_allocate (fb, &catch_error))
+        {
+          g_error_free (catch_error);
+          return;
+        }
 
-  if (!tower->pipeline_template)
-    {
-      CoglContext *ctx =
-        clutter_backend_get_cogl_context (clutter_get_default_backend ());
-      tower->pipeline_template = cogl_pipeline_new (ctx);
-      cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL);
-    }
+      cogl_framebuffer_orthographic (fb, 0, 0, dest_width, dest_height, -1., 1.);
 
-  pipeline = cogl_pipeline_copy (tower->pipeline_template);
-  cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]);
+      if (!tower->pipeline_template)
+        {
+          CoglContext *ctx =
+            clutter_backend_get_cogl_context (clutter_get_default_backend ());
+          tower->pipeline_template = cogl_pipeline_new (ctx);
+          cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL);
+        }
 
-  cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
-                                            invalid->x1, invalid->y1,
-                                            invalid->x2, invalid->y2,
-                                            (2. * invalid->x1) / source_texture_width,
-                                            (2. * invalid->y1) / source_texture_height,
-                                            (2. * invalid->x2) / source_texture_width,
-                                            (2. * invalid->y2) / source_texture_height);
+      pipeline = cogl_pipeline_copy (tower->pipeline_template);
+      cogl_pipeline_set_layer_texture (pipeline, 0, src_plane);
 
-  cogl_object_unref (pipeline);
+      cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
+                                                invalid->x1, invalid->y1,
+                                                invalid->x2, invalid->y2,
+                                                (2. * invalid->x1) / src_width,
+                                                (2. * invalid->y1) / src_height,
+                                                (2. * invalid->x2) / src_width,
+                                                (2. * invalid->y2) / src_height);
+
+      cogl_object_unref (pipeline);
+    }
 
   tower->invalid[level].x1 = tower->invalid[level].x2 = 0;
   tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
@@ -436,8 +472,8 @@ texture_tower_revalidate (MetaTextureTower *tower,
  * Return value: the COGL texture handle to use for painting, or
  *  %NULL if no base texture has yet been set.
  */
-CoglTexture *
-meta_texture_tower_get_paint_texture (MetaTextureTower    *tower,
+MetaMultiTexture *
+meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
                                       ClutterPaintContext *paint_context)
 {
   int texture_width, texture_height;
@@ -448,8 +484,8 @@ meta_texture_tower_get_paint_texture (MetaTextureTower    *tower,
   if (tower->textures[0] == NULL)
     return NULL;
 
-  texture_width = cogl_texture_get_width (tower->textures[0]);
-  texture_height = cogl_texture_get_height (tower->textures[0]);
+  texture_width = meta_multi_texture_get_width (tower->textures[0]);
+  texture_height = meta_multi_texture_get_height (tower->textures[0]);
 
   level = get_paint_level (paint_context, texture_width, texture_height);
   if (level < 0) /* singular paint matrix, scaled to nothing */
diff --git a/src/compositor/meta-texture-tower.h b/src/compositor/meta-texture-tower.h
index 1f5b371467..fece15f763 100644
--- a/src/compositor/meta-texture-tower.h
+++ b/src/compositor/meta-texture-tower.h
@@ -24,6 +24,7 @@
 #define __META_TEXTURE_TOWER_H__
 
 #include "clutter/clutter.h"
+#include <meta/meta-multi-texture.h>
 
 G_BEGIN_DECLS
 
@@ -54,13 +55,13 @@ typedef struct _MetaTextureTower MetaTextureTower;
 MetaTextureTower *meta_texture_tower_new               (void);
 void              meta_texture_tower_free              (MetaTextureTower *tower);
 void              meta_texture_tower_set_base_texture  (MetaTextureTower *tower,
-                                                        CoglTexture      *texture);
+                                                        MetaMultiTexture *texture);
 void              meta_texture_tower_update_area       (MetaTextureTower *tower,
                                                         int               x,
                                                         int               y,
                                                         int               width,
                                                         int               height);
-CoglTexture      *meta_texture_tower_get_paint_texture (MetaTextureTower    *tower,
+MetaMultiTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower,
                                                         ClutterPaintContext *paint_context);
 
 G_END_DECLS
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
index 2ca0e6e61d..1714addf62 100644
--- a/src/meta/meta-shaped-texture.h
+++ b/src/meta/meta-shaped-texture.h
@@ -28,6 +28,7 @@
 
 #include "clutter/clutter.h"
 #include <meta/common.h>
+#include <meta/meta-multi-texture.h>
 
 G_BEGIN_DECLS
 
@@ -45,7 +46,7 @@ void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
                                             gboolean           create_mipmaps);
 
 META_EXPORT
-CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
+MetaMultiTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
 
 META_EXPORT
 void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
index 5fd76cbfc4..d11a350f9e 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -162,7 +162,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 = meta_multi_texture_new_simple (COGL_TEXTURE (texture));
       buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream);
 
       return TRUE;
@@ -190,20 +190,22 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
 
 static gboolean
 shm_format_to_cogl_pixel_format (enum wl_shm_format     shm_format,
-                                 CoglPixelFormat       *format_out,
-                                 CoglTextureComponents *components_out)
+                                 MetaMultiTextureFormat *multi_format_out,
+                                 CoglPixelFormat        *format_out,
+                                 CoglTextureComponents  *components_out)
 {
-  CoglPixelFormat format;
+  MetaMultiTextureFormat multi_format = META_MULTI_TEXTURE_FORMAT_SIMPLE;
+  CoglPixelFormat cogl_format = COGL_PIXEL_FORMAT_ANY;
   CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA;
 
   switch (shm_format)
     {
 #if G_BYTE_ORDER == G_BIG_ENDIAN
     case WL_SHM_FORMAT_ARGB8888:
-      format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
+      cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
       break;
     case WL_SHM_FORMAT_XRGB8888:
-      format = COGL_PIXEL_FORMAT_ARGB_8888;
+      cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
       components = COGL_TEXTURE_COMPONENTS_RGB;
       break;
 #elif G_BYTE_ORDER == G_LITTLE_ENDIAN
@@ -212,10 +214,10 @@ shm_format_to_cogl_pixel_format (enum wl_shm_format     shm_format,
       components = COGL_TEXTURE_COMPONENTS_RGB;
       break;
     case WL_SHM_FORMAT_ARGB8888:
-      format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
+      cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
       break;
     case WL_SHM_FORMAT_XRGB8888:
-      format = COGL_PIXEL_FORMAT_BGRA_8888;
+      cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
       components = COGL_TEXTURE_COMPONENTS_RGB;
       break;
     case WL_SHM_FORMAT_XRGB2101010:
@@ -247,8 +249,10 @@ shm_format_to_cogl_pixel_format (enum wl_shm_format     shm_format,
       return FALSE;
     }
 
-  if (format_out)
-    *format_out = format;
+  if (multi_format_out)
+    *multi_format_out = multi_format;
+  if (cogl_format_out)
+    *cogl_format_out = cogl_format;
   if (components_out)
     *components_out = components;
 
@@ -256,18 +260,21 @@ shm_format_to_cogl_pixel_format (enum wl_shm_format     shm_format,
 }
 
 static gboolean
-shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer  *shm_buffer,
-                                  CoglPixelFormat       *format_out,
-                                  CoglTextureComponents *components_out)
+shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer   *shm_buffer,
+                                  MetaMultiTextureFormat *multi_format_out,
+                                  CoglPixelFormat        *format_out,
+                                  CoglTextureComponents  *components_out)
 {
   MetaBackend *backend = meta_get_backend ();
   ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
   CoglContext *cogl_context =
     clutter_backend_get_cogl_context (clutter_backend);
   CoglPixelFormat cogl_format;
+  MetaMultiTextureFormat multi_format;
   CoglTextureComponents cogl_components;
 
   if (!shm_format_to_cogl_pixel_format (wl_shm_buffer_get_format (shm_buffer),
+                                        &multi_format,
                                         &cogl_format,
                                         &cogl_components))
     return FALSE;
@@ -275,6 +282,8 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer  *shm_buffer,
   if (!cogl_context_format_supports_upload (cogl_context, cogl_format))
     return FALSE;
 
+  if (multi_format_out)
+    *format_out = cogl_format;
   if (format_out)
     *format_out = cogl_format;
   if (components_out)
@@ -307,7 +316,7 @@ shm_format_to_string (MetaDrmFormatBuf *format_buf,
 
 static gboolean
 shm_buffer_attach (MetaWaylandBuffer  *buffer,
-                   CoglTexture       **texture,
+                   MetaMultiTexture  **texture,
                    GError            **error)
 {
   MetaBackend *backend = meta_get_backend ();
@@ -315,23 +324,27 @@ shm_buffer_attach (MetaWaylandBuffer  *buffer,
   CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
   struct wl_shm_buffer *shm_buffer;
   int stride, width, height;
-  CoglPixelFormat format;
+  MetaMultiTextureFormat multi_format;
+  CoglPixelFormat cogl_format;
   CoglTextureComponents components;
   CoglBitmap *bitmap;
+  CoglTexture *new_cogl_tex;
   CoglTexture *new_texture;
-  MetaDrmFormatBuf format_buf;
 
   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);
-  if (!shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components))
+  if (!shm_buffer_get_cogl_pixel_format (shm_buffer, &multi_format, &format, &components))
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                    "Invalid shm pixel format");
       return FALSE;
     }
 
+  /* We only support "simple" textures for now */
+  /* FIXME: should also probably the same error */
+  g_return_val_if_fail (multi_format == META_MULTI_TEXTURE_FORMAT_SIMPLE, FALSE);
   meta_topic (META_DEBUG_WAYLAND,
               "[wl-shm] wl_buffer@%u wl_shm_format %s -> CoglPixelFormat %s",
               wl_resource_get_id (meta_wayland_buffer_get_resource (buffer)),
@@ -340,31 +353,35 @@ shm_buffer_attach (MetaWaylandBuffer  *buffer,
               cogl_pixel_format_to_string (format));
 
   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)
+      meta_multi_texture_get_width (*texture) == width &&
+      meta_multi_texture_get_height (*texture) == height &&
+      meta_multi_texture_get_format (*texture) == multi_format)
     {
-      buffer->is_y_inverted = TRUE;
-      return TRUE;
+      CoglTexture *cogl_texture = meta_multi_texture_get_plane (*texture, 0);
+      if (cogl_texture_get_components (cogl_texture) == components &&
+          _cogl_texture_get_format (cogl_texture) == cogl_format)
+        {
+          buffer->is_y_inverted = TRUE;
+          return TRUE;
+        }
     }
 
-  cogl_clear_object (texture);
+  g_clear_object (texture);
 
   wl_shm_buffer_begin_access (shm_buffer);
 
   bitmap = cogl_bitmap_new_for_data (cogl_context,
                                      width, height,
-                                     format,
+                                     cogl_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);
+  new_cogl_tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap));
+  cogl_texture_set_components (new_cogl_tex, components);
 
-  if (!cogl_texture_allocate (new_texture, error))
+  if (!cogl_texture_allocate (new_cogl_tex, error))
     {
-      g_clear_pointer (&new_texture, cogl_object_unref);
+      g_clear_pointer (&new_cogl_tex, cogl_object_unref);
       if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE))
         {
           CoglTexture2DSliced *texture_sliced;
@@ -374,11 +391,11 @@ shm_buffer_attach (MetaWaylandBuffer  *buffer,
           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);
+          new_cogl_tex = COGL_TEXTURE (texture_sliced);
+          cogl_texture_set_components (new_cogl_tex, components);
 
-          if (!cogl_texture_allocate (new_texture, error))
-            g_clear_pointer (&new_texture, cogl_object_unref);
+          if (!cogl_texture_allocate (new_cogl_tex, error))
+            g_clear_pointer (&new_cogl_tex, cogl_object_unref);
         }
     }
 
@@ -386,10 +403,10 @@ shm_buffer_attach (MetaWaylandBuffer  *buffer,
 
   wl_shm_buffer_end_access (shm_buffer);
 
-  if (!new_texture)
+  if (!new_cogl_tex)
     return FALSE;
 
-  *texture = new_texture;
+  *texture = meta_multi_texture_new_simple (new_cogl_tex);
   buffer->is_y_inverted = TRUE;
 
   return TRUE;
@@ -397,7 +414,7 @@ shm_buffer_attach (MetaWaylandBuffer  *buffer,
 
 static gboolean
 egl_image_buffer_attach (MetaWaylandBuffer  *buffer,
-                         CoglTexture       **texture,
+                         MetaMultiTexture  **texture,
                          GError            **error)
 {
   MetaBackend *backend = meta_get_backend ();
@@ -413,8 +430,8 @@ egl_image_buffer_attach (MetaWaylandBuffer  *buffer,
 
   if (buffer->egl_image.texture)
     {
-      cogl_clear_object (texture);
-      *texture = cogl_object_ref (buffer->egl_image.texture);
+      g_clear_object (texture);
+      *texture = g_object_ref (buffer->egl_image.texture);
       return TRUE;
     }
 
@@ -475,11 +492,11 @@ egl_image_buffer_attach (MetaWaylandBuffer  *buffer,
   if (!texture_2d)
     return FALSE;
 
-  buffer->egl_image.texture = COGL_TEXTURE (texture_2d);
+  buffer->egl_image.texture = meta_multi_texture_new_simple (COGL_TEXTURE (texture_2d));
   buffer->is_y_inverted = !!y_inverted;
 
-  cogl_clear_object (texture);
-  *texture = cogl_object_ref (buffer->egl_image.texture);
+  g_clear_object (texture);
+  *texture = g_object_ref (buffer->egl_image.texture);
 
   return TRUE;
 }
@@ -487,7 +504,7 @@ egl_image_buffer_attach (MetaWaylandBuffer  *buffer,
 #ifdef HAVE_WAYLAND_EGLSTREAM
 static gboolean
 egl_stream_buffer_attach (MetaWaylandBuffer  *buffer,
-                          CoglTexture       **texture,
+                          MetaMultiTexture  **texture,
                           GError            **error)
 {
   MetaWaylandEglStream *stream = buffer->egl_stream.stream;
@@ -497,8 +514,8 @@ egl_stream_buffer_attach (MetaWaylandBuffer  *buffer,
   if (!meta_wayland_egl_stream_attach (stream, error))
     return FALSE;
 
-  cogl_clear_object (texture);
-  *texture = cogl_object_ref (buffer->egl_stream.texture);
+  g_clear_object (texture);
+  *texture = g_object_ref (buffer->egl_stream.texture);
 
   return TRUE;
 }
@@ -507,8 +524,8 @@ egl_stream_buffer_attach (MetaWaylandBuffer  *buffer,
 /**
  * meta_wayland_buffer_attach:
  * @buffer: a pointer to a #MetaWaylandBuffer
- * @texture: (inout) (transfer full): a #CoglTexture representing the surface
- *                                    content
+ * @texture: (inout) (transfer full): a #MetaMultiTexture representing the
+ *                                    surface content
  * @error: return location for error or %NULL
  *
  * This function should be passed a pointer to the texture used to draw the
@@ -525,7 +542,7 @@ egl_stream_buffer_attach (MetaWaylandBuffer  *buffer,
  */
 gboolean
 meta_wayland_buffer_attach (MetaWaylandBuffer  *buffer,
-                            CoglTexture       **texture,
+                            MetaMultiTexture  **texture,
                             GError            **error)
 {
   g_return_val_if_fail (buffer->resource, FALSE);
@@ -594,21 +611,24 @@ meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer)
 
 static gboolean
 process_shm_buffer_damage (MetaWaylandBuffer *buffer,
-                           CoglTexture       *texture,
+                           MetaMultiTexture  *texture,
                            cairo_region_t    *region,
                            GError           **error)
 {
   struct wl_shm_buffer *shm_buffer;
   int i, n_rectangles;
   gboolean set_texture_failed = FALSE;
-  CoglPixelFormat format;
+  MetaMultiTextureFormat multi_format;
+  CoglPixelFormat cogl_format;
+  CoglTexture *cogl_texture;
 
   n_rectangles = cairo_region_num_rectangles (region);
 
   shm_buffer = wl_shm_buffer_get (buffer->resource);
 
-  shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
-  g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
+  shm_buffer_get_cogl_pixel_format (shm_buffer, &multi_format, &cogl_format, NULL);
+  g_return_val_if_fail (multi_format == META_MULTI_TEXTURE_FORMAT_SIMPLE, FALSE);
+  cogl_texture = meta_multi_texture_get_plane (texture, 0);
 
   wl_shm_buffer_begin_access (shm_buffer);
 
@@ -619,12 +639,12 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
       cairo_rectangle_int_t rect;
       int bpp;
 
-      bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
+      bpp = cogl_pixel_format_get_bytes_per_pixel (cogl_format, 0);
       cairo_region_get_rectangle (region, i, &rect);
 
-      if (!_cogl_texture_set_region (texture,
+      if (!_cogl_texture_set_region (cogl_texture,
                                      rect.width, rect.height,
-                                     format,
+                                     cogl_format,
                                      stride,
                                      data + rect.x * bpp + rect.y * stride,
                                      rect.x, rect.y,
@@ -643,7 +663,7 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
 
 void
 meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
-                                    CoglTexture       *texture,
+                                    MetaMultiTexture  *texture,
                                     cairo_region_t    *region)
 {
   gboolean res = FALSE;
@@ -772,12 +792,12 @@ meta_wayland_buffer_finalize (GObject *object)
 {
   MetaWaylandBuffer *buffer = META_WAYLAND_BUFFER (object);
 
-  g_clear_pointer (&buffer->egl_image.texture, cogl_object_unref);
+  g_clear_object (&buffer->egl_image.texture);
 #ifdef HAVE_WAYLAND_EGLSTREAM
-  g_clear_pointer (&buffer->egl_stream.texture, cogl_object_unref);
+  g_clear_object (&buffer->egl_stream.texture);
   g_clear_object (&buffer->egl_stream.stream);
 #endif
-  g_clear_pointer (&buffer->dma_buf.texture, cogl_object_unref);
+  g_clear_object (&buffer->dma_buf.texture);
   g_clear_object (&buffer->dma_buf.dma_buf);
 
   G_OBJECT_CLASS (meta_wayland_buffer_parent_class)->finalize (object);
diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h
index e00406ba26..b8ee06ed29 100644
--- a/src/wayland/meta-wayland-buffer.h
+++ b/src/wayland/meta-wayland-buffer.h
@@ -29,6 +29,7 @@
 #include <wayland-server.h>
 
 #include "cogl/cogl.h"
+#include "meta/meta-multi-texture.h"
 #include "wayland/meta-wayland-types.h"
 #include "wayland/meta-wayland-egl-stream.h"
 #include "wayland/meta-wayland-dma-buf.h"
@@ -56,19 +57,19 @@ struct _MetaWaylandBuffer
   MetaWaylandBufferType type;
 
   struct {
-    CoglTexture *texture;
+    MetaMultiTexture *texture;
   } egl_image;
 
 #ifdef HAVE_WAYLAND_EGLSTREAM
   struct {
     MetaWaylandEglStream *stream;
-    CoglTexture *texture;
+    MetaMultiTexture *texture;
   } egl_stream;
 #endif
 
   struct {
     MetaWaylandDmaBufBuffer *dma_buf;
-    CoglTexture *texture;
+    MetaMultiTexture *texture;
   } dma_buf;
 };
 
@@ -81,12 +82,12 @@ struct wl_resource *    meta_wayland_buffer_get_resource        (MetaWaylandBuff
 gboolean                meta_wayland_buffer_is_realized         (MetaWaylandBuffer     *buffer);
 gboolean                meta_wayland_buffer_realize             (MetaWaylandBuffer     *buffer);
 gboolean                meta_wayland_buffer_attach              (MetaWaylandBuffer     *buffer,
-                                                                 CoglTexture          **texture,
+                                                                 MetaMultiTexture     **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,
+                                                                 MetaMultiTexture      *texture,
                                                                  cairo_region_t        *region);
 CoglScanout *           meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer     *buffer,
                                                                  CoglOnscreen          *onscreen);
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
index 7996958484..943a338e25 100644
--- a/src/wayland/meta-wayland-dma-buf.c
+++ b/src/wayland/meta-wayland-dma-buf.c
@@ -96,7 +96,7 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer  *buffer,
   CoglPixelFormat cogl_format;
   EGLImageKHR egl_image;
   CoglEglImageFlags flags;
-  CoglTexture2D *texture;
+  CoglTexture2D *cogl_texture;
   MetaDrmFormatBuf format_buf;
 
   if (buffer->dma_buf.texture)
@@ -170,20 +170,20 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer  *buffer,
     return FALSE;
 
   flags = COGL_EGL_IMAGE_FLAG_NO_GET_DATA;
-  texture = cogl_egl_texture_2d_new_from_image (cogl_context,
-                                                dma_buf->width,
-                                                dma_buf->height,
-                                                cogl_format,
-                                                egl_image,
-                                                flags,
-                                                error);
+  cogl_texture = cogl_egl_texture_2d_new_from_image (cogl_context,
+                                                     dma_buf->width,
+                                                     dma_buf->height,
+                                                     cogl_format,
+                                                     egl_image,
+                                                     flags,
+                                                     error);
 
   meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
 
-  if (!texture)
+  if (!cogl_texture)
     return FALSE;
 
-  buffer->dma_buf.texture = COGL_TEXTURE (texture);
+  buffer->dma_buf.texture = meta_multi_texture_new_simple (COGL_TEXTURE (cogl_texture));
   buffer->is_y_inverted = dma_buf->is_y_inverted;
 
   return TRUE;
@@ -191,14 +191,14 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer  *buffer,
 
 gboolean
 meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer  *buffer,
-                                    CoglTexture       **texture,
+                                    MetaMultiTexture  **texture,
                                     GError            **error)
 {
   if (!meta_wayland_dma_buf_realize_texture (buffer, error))
     return FALSE;
 
-  cogl_clear_object (texture);
-  *texture = cogl_object_ref (buffer->dma_buf.texture);
+  g_clear_object (texture);
+  *texture = g_object_ref (buffer->dma_buf.texture);
   return TRUE;
 }
 
diff --git a/src/wayland/meta-wayland-dma-buf.h b/src/wayland/meta-wayland-dma-buf.h
index cdc65aeb5b..d0a278f64c 100644
--- a/src/wayland/meta-wayland-dma-buf.h
+++ b/src/wayland/meta-wayland-dma-buf.h
@@ -31,6 +31,7 @@
 #include <glib-object.h>
 
 #include "cogl/cogl.h"
+#include "meta/meta-multi-texture.h"
 #include "wayland/meta-wayland-types.h"
 
 #define META_TYPE_WAYLAND_DMA_BUF_BUFFER (meta_wayland_dma_buf_buffer_get_type ())
@@ -43,7 +44,7 @@ gboolean meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor);
 
 gboolean
 meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer  *buffer,
-                                    CoglTexture       **texture,
+                                    MetaMultiTexture  **texture,
                                     GError            **error);
 
 MetaWaylandDmaBufBuffer *
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 0f0c55b1c7..54b2253f94 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -302,7 +302,7 @@ get_buffer_width (MetaWaylandSurface *surface)
   MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
 
   if (buffer)
-    return cogl_texture_get_width (surface->texture);
+    return meta_multi_texture_get_width (surface->texture);
   else
     return 0;
 }
@@ -313,7 +313,7 @@ get_buffer_height (MetaWaylandSurface *surface)
   MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
 
   if (buffer)
-    return cogl_texture_get_height (surface->texture);
+    return meta_multi_texture_get_height (surface->texture);
   else
     return 0;
 }
@@ -689,7 +689,7 @@ meta_wayland_surface_apply_state (MetaWaylandSurface      *surface,
         }
       else
         {
-          cogl_clear_object (&surface->texture);
+          g_clear_object (&surface->texture);
         }
 
       /* If the newly attached buffer is going to be accessed directly without
@@ -1327,7 +1327,7 @@ wl_surface_destructor (struct wl_resource *resource)
 
   if (surface->buffer_held)
     meta_wayland_surface_unref_buffer_use_count (surface);
-  g_clear_pointer (&surface->texture, cogl_object_unref);
+  g_clear_object (&surface->texture);
   g_clear_pointer (&surface->buffer_ref, meta_wayland_buffer_ref_unref);
 
   g_clear_object (&surface->cached_state);
@@ -1906,7 +1906,7 @@ meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
   return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
 }
 
-CoglTexture *
+MetaMultiTexture *
 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 0c7298886d..71b6c63718 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -162,7 +162,7 @@ struct _MetaWaylandSurface
   GHashTable *outputs;
   MetaMonitorTransform buffer_transform;
 
-  CoglTexture *texture;
+  MetaMultiTexture *texture;
 
   /* Buffer reference state. */
   MetaWaylandBufferRef *buffer_ref;
@@ -326,7 +326,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);
+MetaMultiTexture *  meta_wayland_surface_get_texture (MetaWaylandSurface *surface);
 
 MetaSurfaceActor *  meta_wayland_surface_get_actor (MetaWaylandSurface *surface);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]