d6fcd4
From 529eb8fa3a15e0ae5bf131b1855a117c8a1a026e Mon Sep 17 00:00:00 2001
d6fcd4
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
d6fcd4
Date: Tue, 8 Feb 2022 17:14:06 +0100
d6fcd4
Subject: [PATCH 1/2] shaped-texture: Pass along the snippet to the texture
d6fcd4
 tower
d6fcd4
d6fcd4
The snippet is used make sure the right source is sampled in the shader.
d6fcd4
This wasn't done in the texture tower, meaning the textures from the
d6fcd4
tower were not correct.
d6fcd4
d6fcd4
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/528
d6fcd4
---
d6fcd4
 src/compositor/meta-shaped-texture.c |  2 ++
d6fcd4
 src/compositor/meta-texture-tower.c  | 27 +++++++++++++++++++++++++++
d6fcd4
 src/compositor/meta-texture-tower.h  |  3 +++
d6fcd4
 3 files changed, 32 insertions(+)
d6fcd4
d6fcd4
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
d6fcd4
index 9cae4df07d74..32af6bdc19d7 100644
d6fcd4
--- a/src/compositor/meta-shaped-texture.c
d6fcd4
+++ b/src/compositor/meta-shaped-texture.c
d6fcd4
@@ -1204,6 +1204,8 @@ meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
d6fcd4
   g_clear_pointer (&stex->snippet, cogl_object_unref);
d6fcd4
   if (snippet)
d6fcd4
     stex->snippet = cogl_object_ref (snippet);
d6fcd4
+
d6fcd4
+  meta_texture_tower_set_snippet (stex->paint_tower, snippet);
d6fcd4
 }
d6fcd4
 
d6fcd4
 /**
d6fcd4
diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c
d6fcd4
index a41cdc89dd94..374e1af151ad 100644
d6fcd4
--- a/src/compositor/meta-texture-tower.c
d6fcd4
+++ b/src/compositor/meta-texture-tower.c
d6fcd4
@@ -63,6 +63,7 @@ struct _MetaTextureTower
d6fcd4
   CoglOffscreen *fbos[MAX_TEXTURE_LEVELS];
d6fcd4
   Box invalid[MAX_TEXTURE_LEVELS];
d6fcd4
   CoglPipeline *pipeline_template;
d6fcd4
+  CoglSnippet *snippet;
d6fcd4
 };
d6fcd4
 
d6fcd4
 /**
d6fcd4
@@ -98,6 +99,7 @@ meta_texture_tower_free (MetaTextureTower *tower)
d6fcd4
     cogl_object_unref (tower->pipeline_template);
d6fcd4
 
d6fcd4
   meta_texture_tower_set_base_texture (tower, NULL);
d6fcd4
+  cogl_clear_object (&tower->snippet);
d6fcd4
 
d6fcd4
   g_slice_free (MetaTextureTower, tower);
d6fcd4
 }
d6fcd4
@@ -226,6 +228,28 @@ meta_texture_tower_update_area (MetaTextureTower *tower,
d6fcd4
     }
d6fcd4
 }
d6fcd4
 
d6fcd4
+void
d6fcd4
+meta_texture_tower_set_snippet (MetaTextureTower *tower,
d6fcd4
+                                CoglSnippet      *snippet)
d6fcd4
+{
d6fcd4
+  int i;
d6fcd4
+
d6fcd4
+  if (tower->snippet == snippet)
d6fcd4
+    return;
d6fcd4
+
d6fcd4
+  g_clear_pointer (&tower->snippet, cogl_object_unref);
d6fcd4
+
d6fcd4
+  if (snippet)
d6fcd4
+    tower->snippet = cogl_object_ref (snippet);
d6fcd4
+
d6fcd4
+  for (i = 1; i < tower->n_levels; i++)
d6fcd4
+    {
d6fcd4
+      cogl_clear_object (&tower->textures[i]);
d6fcd4
+      g_clear_object (&tower->fbos[i]);
d6fcd4
+    }
d6fcd4
+  cogl_clear_object (&tower->pipeline_template);
d6fcd4
+}
d6fcd4
+
d6fcd4
 /* It generally looks worse if we scale up a window texture by even a
d6fcd4
  * small amount than if we scale it down using bilinear filtering, so
d6fcd4
  * we always pick the *larger* adjacent level. */
d6fcd4
@@ -420,6 +444,9 @@ texture_tower_revalidate (MetaTextureTower *tower,
d6fcd4
   pipeline = cogl_pipeline_copy (tower->pipeline_template);
d6fcd4
   cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]);
d6fcd4
 
d6fcd4
+  if (tower->snippet && level == 1)
d6fcd4
+    cogl_pipeline_add_layer_snippet (pipeline, 0, tower->snippet);
d6fcd4
+
d6fcd4
   cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
d6fcd4
                                             invalid->x1, invalid->y1,
d6fcd4
                                             invalid->x2, invalid->y2,
d6fcd4
diff --git a/src/compositor/meta-texture-tower.h b/src/compositor/meta-texture-tower.h
d6fcd4
index 6a39e4184200..e3cfe3608b8f 100644
d6fcd4
--- a/src/compositor/meta-texture-tower.h
d6fcd4
+++ b/src/compositor/meta-texture-tower.h
d6fcd4
@@ -62,6 +62,9 @@ void              meta_texture_tower_update_area       (MetaTextureTower *tower,
d6fcd4
                                                         int               height);
d6fcd4
 CoglTexture      *meta_texture_tower_get_paint_texture (MetaTextureTower *tower);
d6fcd4
 
d6fcd4
+void meta_texture_tower_set_snippet (MetaTextureTower *tower,
d6fcd4
+                                     CoglSnippet      *snippet);
d6fcd4
+
d6fcd4
 G_END_DECLS
d6fcd4
 
d6fcd4
 #endif /* __META_TEXTURE_TOWER_H__ */
d6fcd4
-- 
d6fcd4
2.34.1
d6fcd4
d6fcd4
d6fcd4
From 4827e201b341ac4dd0b4ca697df46946b19ae14c Mon Sep 17 00:00:00 2001
d6fcd4
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
d6fcd4
Date: Mon, 21 Feb 2022 18:12:25 +0100
d6fcd4
Subject: [PATCH 2/2] shaped-texture: Paint with the right layer snippet
d6fcd4
d6fcd4
When we get passed a "snippet" to the shaped texture, it's added as a
d6fcd4
pipeline layer snippet to change how the source texture is sampled. When
d6fcd4
we draw from a texture tower however we have allocated regular textures
d6fcd4
which doesn't need any special layer snippet, so create separate
d6fcd4
pipelines for those that doesn't use that snippet.
d6fcd4
d6fcd4
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/528
d6fcd4
---
d6fcd4
 src/compositor/meta-shaped-texture.c | 135 +++++++++++++++++++++------
d6fcd4
 1 file changed, 104 insertions(+), 31 deletions(-)
d6fcd4
d6fcd4
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
d6fcd4
index 32af6bdc19d7..705d27d5b842 100644
d6fcd4
--- a/src/compositor/meta-shaped-texture.c
d6fcd4
+++ b/src/compositor/meta-shaped-texture.c
d6fcd4
@@ -96,8 +96,12 @@ struct _MetaShapedTexture
d6fcd4
   CoglSnippet *snippet;
d6fcd4
 
d6fcd4
   CoglPipeline *base_pipeline;
d6fcd4
+  CoglPipeline *unmasked_pipeline;
d6fcd4
+  CoglPipeline *unmasked_tower_pipeline;
d6fcd4
   CoglPipeline *masked_pipeline;
d6fcd4
+  CoglPipeline *masked_tower_pipeline;
d6fcd4
   CoglPipeline *unblended_pipeline;
d6fcd4
+  CoglPipeline *unblended_tower_pipeline;
d6fcd4
 
d6fcd4
   gboolean is_y_inverted;
d6fcd4
 
d6fcd4
@@ -281,8 +285,12 @@ static void
d6fcd4
 meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
d6fcd4
 {
d6fcd4
   g_clear_pointer (&stex->base_pipeline, cogl_object_unref);
d6fcd4
+  g_clear_pointer (&stex->unmasked_pipeline, cogl_object_unref);
d6fcd4
+  g_clear_pointer (&stex->unmasked_tower_pipeline, cogl_object_unref);
d6fcd4
   g_clear_pointer (&stex->masked_pipeline, cogl_object_unref);
d6fcd4
+  g_clear_pointer (&stex->masked_tower_pipeline, cogl_object_unref);
d6fcd4
   g_clear_pointer (&stex->unblended_pipeline, cogl_object_unref);
d6fcd4
+  g_clear_pointer (&stex->unblended_tower_pipeline, cogl_object_unref);
d6fcd4
 }
d6fcd4
 
d6fcd4
 static void
d6fcd4
@@ -385,9 +393,6 @@ get_base_pipeline (MetaShapedTexture *stex,
d6fcd4
       cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
d6fcd4
     }
d6fcd4
 
d6fcd4
-  if (stex->snippet)
d6fcd4
-    cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
d6fcd4
-
d6fcd4
   stex->base_pipeline = pipeline;
d6fcd4
 
d6fcd4
   return stex->base_pipeline;
d6fcd4
@@ -395,50 +400,118 @@ get_base_pipeline (MetaShapedTexture *stex,
d6fcd4
 
d6fcd4
 static CoglPipeline *
d6fcd4
 get_unmasked_pipeline (MetaShapedTexture *stex,
d6fcd4
-                       CoglContext       *ctx)
d6fcd4
+                       CoglContext       *ctx,
d6fcd4
+                       CoglTexture       *tex)
d6fcd4
 {
d6fcd4
-  return get_base_pipeline (stex, ctx);
d6fcd4
+  if (stex->texture == tex)
d6fcd4
+    {
d6fcd4
+      CoglPipeline *pipeline;
d6fcd4
+
d6fcd4
+      if (stex->unmasked_pipeline)
d6fcd4
+        return stex->unmasked_pipeline;
d6fcd4
+
d6fcd4
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
d6fcd4
+      if (stex->snippet)
d6fcd4
+        cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
d6fcd4
+
d6fcd4
+      stex->unmasked_pipeline = pipeline;
d6fcd4
+      return pipeline;
d6fcd4
+    }
d6fcd4
+  else
d6fcd4
+    {
d6fcd4
+      CoglPipeline *pipeline;
d6fcd4
+
d6fcd4
+      if (stex->unmasked_tower_pipeline)
d6fcd4
+        return stex->unmasked_tower_pipeline;
d6fcd4
+
d6fcd4
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
d6fcd4
+      stex->unmasked_tower_pipeline = pipeline;
d6fcd4
+      return pipeline;
d6fcd4
+    }
d6fcd4
 }
d6fcd4
 
d6fcd4
 static CoglPipeline *
d6fcd4
 get_masked_pipeline (MetaShapedTexture *stex,
d6fcd4
-                     CoglContext       *ctx)
d6fcd4
+                     CoglContext       *ctx,
d6fcd4
+                     CoglTexture       *tex)
d6fcd4
 {
d6fcd4
-  CoglPipeline *pipeline;
d6fcd4
+  if (stex->texture == tex)
d6fcd4
+    {
d6fcd4
+      CoglPipeline *pipeline;
d6fcd4
 
d6fcd4
-  if (stex->masked_pipeline)
d6fcd4
-    return stex->masked_pipeline;
d6fcd4
+      if (stex->masked_pipeline)
d6fcd4
+        return stex->masked_pipeline;
d6fcd4
 
d6fcd4
-  pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
d6fcd4
-  cogl_pipeline_set_layer_combine (pipeline, 1,
d6fcd4
-                                   "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
d6fcd4
-                                   NULL);
d6fcd4
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
d6fcd4
+      cogl_pipeline_set_layer_combine (pipeline, 1,
d6fcd4
+                                       "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
d6fcd4
+                                       NULL);
d6fcd4
+      if (stex->snippet)
d6fcd4
+        cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
d6fcd4
 
d6fcd4
-  stex->masked_pipeline = pipeline;
d6fcd4
+      stex->masked_pipeline = pipeline;
d6fcd4
+      return pipeline;
d6fcd4
+    }
d6fcd4
+  else
d6fcd4
+    {
d6fcd4
+      CoglPipeline *pipeline;
d6fcd4
+
d6fcd4
+      if (stex->masked_tower_pipeline)
d6fcd4
+        return stex->masked_tower_pipeline;
d6fcd4
 
d6fcd4
-  return pipeline;
d6fcd4
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
d6fcd4
+      cogl_pipeline_set_layer_combine (pipeline, 1,
d6fcd4
+                                       "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
d6fcd4
+                                       NULL);
d6fcd4
+
d6fcd4
+      stex->masked_tower_pipeline = pipeline;
d6fcd4
+      return pipeline;
d6fcd4
+    }
d6fcd4
 }
d6fcd4
 
d6fcd4
 static CoglPipeline *
d6fcd4
 get_unblended_pipeline (MetaShapedTexture *stex,
d6fcd4
-                        CoglContext       *ctx)
d6fcd4
+                        CoglContext       *ctx,
d6fcd4
+                        CoglTexture       *tex)
d6fcd4
 {
d6fcd4
-  CoglPipeline *pipeline;
d6fcd4
-  CoglColor color;
d6fcd4
+  if (stex->texture == tex)
d6fcd4
+    {
d6fcd4
+      CoglPipeline *pipeline;
d6fcd4
+      CoglColor color;
d6fcd4
 
d6fcd4
-  if (stex->unblended_pipeline)
d6fcd4
-    return stex->unblended_pipeline;
d6fcd4
+      if (stex->unblended_pipeline)
d6fcd4
+        return stex->unblended_pipeline;
d6fcd4
 
d6fcd4
-  pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
d6fcd4
-  cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
d6fcd4
-  cogl_pipeline_set_blend (pipeline,
d6fcd4
-                           "RGBA = ADD (SRC_COLOR, 0)",
d6fcd4
-                           NULL);
d6fcd4
-  cogl_pipeline_set_color (pipeline, &color;;
d6fcd4
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
d6fcd4
+      cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
d6fcd4
+      cogl_pipeline_set_blend (pipeline,
d6fcd4
+                               "RGBA = ADD (SRC_COLOR, 0)",
d6fcd4
+                               NULL);
d6fcd4
+      cogl_pipeline_set_color (pipeline, &color;;
d6fcd4
+      if (stex->snippet)
d6fcd4
+        cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
d6fcd4
 
d6fcd4
-  stex->unblended_pipeline = pipeline;
d6fcd4
+      stex->unblended_pipeline = pipeline;
d6fcd4
+      return pipeline;
d6fcd4
+    }
d6fcd4
+  else
d6fcd4
+    {
d6fcd4
+      CoglPipeline *pipeline;
d6fcd4
+      CoglColor color;
d6fcd4
 
d6fcd4
-  return pipeline;
d6fcd4
+      if (stex->unblended_tower_pipeline)
d6fcd4
+        return stex->unblended_tower_pipeline;
d6fcd4
+
d6fcd4
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
d6fcd4
+      cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
d6fcd4
+      cogl_pipeline_set_blend (pipeline,
d6fcd4
+                               "RGBA = ADD (SRC_COLOR, 0)",
d6fcd4
+                               NULL);
d6fcd4
+      cogl_pipeline_set_color (pipeline, &color;;
d6fcd4
+
d6fcd4
+      stex->unblended_tower_pipeline = pipeline;
d6fcd4
+      return pipeline;
d6fcd4
+    }
d6fcd4
 }
d6fcd4
 
d6fcd4
 static void
d6fcd4
@@ -714,7 +787,7 @@ do_paint (MetaShapedTexture *stex,
d6fcd4
 
d6fcd4
       if (!cairo_region_is_empty (region))
d6fcd4
         {
d6fcd4
-          opaque_pipeline = get_unblended_pipeline (stex, ctx);
d6fcd4
+          opaque_pipeline = get_unblended_pipeline (stex, ctx, paint_tex);
d6fcd4
           cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
d6fcd4
           cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
d6fcd4
 
d6fcd4
@@ -750,11 +823,11 @@ do_paint (MetaShapedTexture *stex,
d6fcd4
 
d6fcd4
       if (stex->mask_texture == NULL)
d6fcd4
         {
d6fcd4
-          blended_pipeline = get_unmasked_pipeline (stex, ctx);
d6fcd4
+          blended_pipeline = get_unmasked_pipeline (stex, ctx, paint_tex);
d6fcd4
         }
d6fcd4
       else
d6fcd4
         {
d6fcd4
-          blended_pipeline = get_masked_pipeline (stex, ctx);
d6fcd4
+          blended_pipeline = get_masked_pipeline (stex, ctx, paint_tex);
d6fcd4
           cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
d6fcd4
           cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
d6fcd4
         }
d6fcd4
-- 
d6fcd4
2.34.1
d6fcd4