f7d48e
From d3d8ab8eabc3178f3c31ee71dcc926297ff1c1b0 Mon Sep 17 00:00:00 2001
f7d48e
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
f7d48e
Date: Tue, 8 Feb 2022 17:14:06 +0100
f7d48e
Subject: [PATCH 1/2] shaped-texture: Pass along the snippet to the texture
f7d48e
 tower
f7d48e
f7d48e
The snippet is used make sure the right source is sampled in the shader.
f7d48e
This wasn't done in the texture tower, meaning the textures from the
f7d48e
tower were not correct.
f7d48e
f7d48e
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/528
f7d48e
---
f7d48e
 src/compositor/meta-shaped-texture.c |  2 ++
f7d48e
 src/compositor/meta-texture-tower.c  | 27 +++++++++++++++++++++++++++
f7d48e
 src/compositor/meta-texture-tower.h  |  3 +++
f7d48e
 3 files changed, 32 insertions(+)
f7d48e
f7d48e
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
f7d48e
index 095dd246f0c0..68919c5f1c5c 100644
f7d48e
--- a/src/compositor/meta-shaped-texture.c
f7d48e
+++ b/src/compositor/meta-shaped-texture.c
f7d48e
@@ -1242,6 +1242,8 @@ meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
f7d48e
   g_clear_pointer (&stex->snippet, cogl_object_unref);
f7d48e
   if (snippet)
f7d48e
     stex->snippet = cogl_object_ref (snippet);
f7d48e
+
f7d48e
+  meta_texture_tower_set_snippet (stex->paint_tower, snippet);
f7d48e
 }
f7d48e
 
f7d48e
 /**
f7d48e
diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c
f7d48e
index 1fc4623e5e54..0ae717abe4d4 100644
f7d48e
--- a/src/compositor/meta-texture-tower.c
f7d48e
+++ b/src/compositor/meta-texture-tower.c
f7d48e
@@ -62,6 +62,7 @@ struct _MetaTextureTower
f7d48e
   CoglOffscreen *fbos[MAX_TEXTURE_LEVELS];
f7d48e
   Box invalid[MAX_TEXTURE_LEVELS];
f7d48e
   CoglPipeline *pipeline_template;
f7d48e
+  CoglSnippet *snippet;
f7d48e
 };
f7d48e
 
f7d48e
 /**
f7d48e
@@ -97,6 +98,7 @@ meta_texture_tower_free (MetaTextureTower *tower)
f7d48e
     cogl_object_unref (tower->pipeline_template);
f7d48e
 
f7d48e
   meta_texture_tower_set_base_texture (tower, NULL);
f7d48e
+  cogl_clear_object (&tower->snippet);
f7d48e
 
f7d48e
   g_free (tower);
f7d48e
 }
f7d48e
@@ -216,6 +218,28 @@ meta_texture_tower_update_area (MetaTextureTower *tower,
f7d48e
     }
f7d48e
 }
f7d48e
 
f7d48e
+void
f7d48e
+meta_texture_tower_set_snippet (MetaTextureTower *tower,
f7d48e
+                                CoglSnippet      *snippet)
f7d48e
+{
f7d48e
+  int i;
f7d48e
+
f7d48e
+  if (tower->snippet == snippet)
f7d48e
+    return;
f7d48e
+
f7d48e
+  g_clear_pointer (&tower->snippet, cogl_object_unref);
f7d48e
+
f7d48e
+  if (snippet)
f7d48e
+    tower->snippet = cogl_object_ref (snippet);
f7d48e
+
f7d48e
+  for (i = 1; i < tower->n_levels; i++)
f7d48e
+    {
f7d48e
+      cogl_clear_object (&tower->textures[i]);
f7d48e
+      g_clear_object (&tower->fbos[i]);
f7d48e
+    }
f7d48e
+  cogl_clear_object (&tower->pipeline_template);
f7d48e
+}
f7d48e
+
f7d48e
 /* It generally looks worse if we scale up a window texture by even a
f7d48e
  * small amount than if we scale it down using bilinear filtering, so
f7d48e
  * we always pick the *larger* adjacent level. */
f7d48e
@@ -408,6 +432,9 @@ texture_tower_revalidate (MetaTextureTower *tower,
f7d48e
   pipeline = cogl_pipeline_copy (tower->pipeline_template);
f7d48e
   cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]);
f7d48e
 
f7d48e
+  if (tower->snippet && level == 1)
f7d48e
+    cogl_pipeline_add_layer_snippet (pipeline, 0, tower->snippet);
f7d48e
+
f7d48e
   cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
f7d48e
                                             invalid->x1, invalid->y1,
f7d48e
                                             invalid->x2, invalid->y2,
f7d48e
diff --git a/src/compositor/meta-texture-tower.h b/src/compositor/meta-texture-tower.h
f7d48e
index 1f5b371467c9..5522dfbb16ac 100644
f7d48e
--- a/src/compositor/meta-texture-tower.h
f7d48e
+++ b/src/compositor/meta-texture-tower.h
f7d48e
@@ -63,6 +63,9 @@ void              meta_texture_tower_update_area       (MetaTextureTower *tower,
f7d48e
 CoglTexture      *meta_texture_tower_get_paint_texture (MetaTextureTower    *tower,
f7d48e
                                                         ClutterPaintContext *paint_context);
f7d48e
 
f7d48e
+void meta_texture_tower_set_snippet (MetaTextureTower *tower,
f7d48e
+                                     CoglSnippet      *snippet);
f7d48e
+
f7d48e
 G_END_DECLS
f7d48e
 
f7d48e
 #endif /* __META_TEXTURE_TOWER_H__ */
f7d48e
-- 
f7d48e
2.34.1
f7d48e
f7d48e
f7d48e
From b78a24dfebf56b04538058ff731890ee997d0d10 Mon Sep 17 00:00:00 2001
f7d48e
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
f7d48e
Date: Wed, 9 Feb 2022 12:41:14 +0100
f7d48e
Subject: [PATCH 2/2] shaped-texture: Paint with the right layer snippet
f7d48e
f7d48e
When we get passed a "snippet" to the shaped texture, it's added as a
f7d48e
pipeline layer snippet to change how the source texture is sampled. When
f7d48e
we draw from a texture tower however we have allocated regular textures
f7d48e
which doesn't need any special layer snippet, so create separate
f7d48e
pipelines for those that doesn't use that snippet.
f7d48e
f7d48e
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/528
f7d48e
---
f7d48e
 src/compositor/meta-shaped-texture.c | 126 +++++++++++++++++++++------
f7d48e
 1 file changed, 98 insertions(+), 28 deletions(-)
f7d48e
f7d48e
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
f7d48e
index 68919c5f1c5c..0d09f2f4e164 100644
f7d48e
--- a/src/compositor/meta-shaped-texture.c
f7d48e
+++ b/src/compositor/meta-shaped-texture.c
f7d48e
@@ -91,8 +91,12 @@ struct _MetaShapedTexture
f7d48e
   CoglSnippet *snippet;
f7d48e
 
f7d48e
   CoglPipeline *base_pipeline;
f7d48e
+  CoglPipeline *unmasked_pipeline;
f7d48e
+  CoglPipeline *unmasked_tower_pipeline;
f7d48e
   CoglPipeline *masked_pipeline;
f7d48e
+  CoglPipeline *masked_tower_pipeline;
f7d48e
   CoglPipeline *unblended_pipeline;
f7d48e
+  CoglPipeline *unblended_tower_pipeline;
f7d48e
 
f7d48e
   gboolean is_y_inverted;
f7d48e
 
f7d48e
@@ -243,8 +247,12 @@ static void
f7d48e
 meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
f7d48e
 {
f7d48e
   g_clear_pointer (&stex->base_pipeline, cogl_object_unref);
f7d48e
+  g_clear_pointer (&stex->unmasked_pipeline, cogl_object_unref);
f7d48e
+  g_clear_pointer (&stex->unmasked_tower_pipeline, cogl_object_unref);
f7d48e
   g_clear_pointer (&stex->masked_pipeline, cogl_object_unref);
f7d48e
+  g_clear_pointer (&stex->masked_tower_pipeline, cogl_object_unref);
f7d48e
   g_clear_pointer (&stex->unblended_pipeline, cogl_object_unref);
f7d48e
+  g_clear_pointer (&stex->unblended_tower_pipeline, cogl_object_unref);
f7d48e
 }
f7d48e
 
f7d48e
 static void
f7d48e
@@ -381,9 +389,6 @@ get_base_pipeline (MetaShapedTexture *stex,
f7d48e
 
f7d48e
   cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
f7d48e
 
f7d48e
-  if (stex->snippet)
f7d48e
-    cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
f7d48e
-
f7d48e
   stex->base_pipeline = pipeline;
f7d48e
 
f7d48e
   return stex->base_pipeline;
f7d48e
@@ -391,47 +396,112 @@ get_base_pipeline (MetaShapedTexture *stex,
f7d48e
 
f7d48e
 static CoglPipeline *
f7d48e
 get_unmasked_pipeline (MetaShapedTexture *stex,
f7d48e
-                       CoglContext       *ctx)
f7d48e
+                       CoglContext       *ctx,
f7d48e
+                       CoglTexture       *tex)
f7d48e
 {
f7d48e
-  return get_base_pipeline (stex, ctx);
f7d48e
+  if (stex->texture == tex)
f7d48e
+    {
f7d48e
+      CoglPipeline *pipeline;
f7d48e
+
f7d48e
+      if (stex->unmasked_pipeline)
f7d48e
+        return stex->unmasked_pipeline;
f7d48e
+
f7d48e
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
f7d48e
+      if (stex->snippet)
f7d48e
+        cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
f7d48e
+
f7d48e
+      stex->unmasked_pipeline = pipeline;
f7d48e
+      return pipeline;
f7d48e
+    }
f7d48e
+  else
f7d48e
+    {
f7d48e
+      CoglPipeline *pipeline;
f7d48e
+
f7d48e
+      if (stex->unmasked_tower_pipeline)
f7d48e
+        return stex->unmasked_tower_pipeline;
f7d48e
+
f7d48e
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
f7d48e
+      stex->unmasked_tower_pipeline = pipeline;
f7d48e
+      return pipeline;
f7d48e
+    }
f7d48e
 }
f7d48e
 
f7d48e
 static CoglPipeline *
f7d48e
 get_masked_pipeline (MetaShapedTexture *stex,
f7d48e
-                     CoglContext       *ctx)
f7d48e
+                     CoglContext       *ctx,
f7d48e
+                     CoglTexture       *tex)
f7d48e
 {
f7d48e
-  CoglPipeline *pipeline;
f7d48e
+  if (stex->texture == tex)
f7d48e
+    {
f7d48e
+      CoglPipeline *pipeline;
f7d48e
 
f7d48e
-  if (stex->masked_pipeline)
f7d48e
-    return stex->masked_pipeline;
f7d48e
+      if (stex->masked_pipeline)
f7d48e
+        return stex->masked_pipeline;
f7d48e
 
f7d48e
-  pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
f7d48e
-  cogl_pipeline_set_layer_combine (pipeline, 1,
f7d48e
-                                   "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
f7d48e
-                                   NULL);
f7d48e
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
f7d48e
+      cogl_pipeline_set_layer_combine (pipeline, 1,
f7d48e
+                                       "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
f7d48e
+                                       NULL);
f7d48e
+      if (stex->snippet)
f7d48e
+        cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
f7d48e
 
f7d48e
-  stex->masked_pipeline = pipeline;
f7d48e
+      stex->masked_pipeline = pipeline;
f7d48e
+      return pipeline;
f7d48e
+    }
f7d48e
+  else
f7d48e
+    {
f7d48e
+      CoglPipeline *pipeline;
f7d48e
 
f7d48e
-  return pipeline;
f7d48e
+      if (stex->masked_tower_pipeline)
f7d48e
+        return stex->masked_tower_pipeline;
f7d48e
+
f7d48e
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
f7d48e
+      cogl_pipeline_set_layer_combine (pipeline, 1,
f7d48e
+                                       "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
f7d48e
+                                       NULL);
f7d48e
+
f7d48e
+      stex->masked_tower_pipeline = pipeline;
f7d48e
+      return pipeline;
f7d48e
+    }
f7d48e
 }
f7d48e
 
f7d48e
 static CoglPipeline *
f7d48e
 get_unblended_pipeline (MetaShapedTexture *stex,
f7d48e
-                        CoglContext       *ctx)
f7d48e
+                        CoglContext       *ctx,
f7d48e
+                        CoglTexture       *tex)
f7d48e
 {
f7d48e
-  CoglPipeline *pipeline;
f7d48e
+  if (stex->texture == tex)
f7d48e
+    {
f7d48e
+      CoglPipeline *pipeline;
f7d48e
 
f7d48e
-  if (stex->unblended_pipeline)
f7d48e
-    return stex->unblended_pipeline;
f7d48e
+      if (stex->unblended_pipeline)
f7d48e
+        return stex->unblended_pipeline;
f7d48e
 
f7d48e
-  pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
f7d48e
-  cogl_pipeline_set_layer_combine (pipeline, 0,
f7d48e
-                                   "RGBA = REPLACE (TEXTURE)",
f7d48e
-                                   NULL);
f7d48e
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
f7d48e
+      cogl_pipeline_set_layer_combine (pipeline, 0,
f7d48e
+                                       "RGBA = REPLACE (TEXTURE)",
f7d48e
+                                       NULL);
f7d48e
+      if (stex->snippet)
f7d48e
+        cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
f7d48e
 
f7d48e
-  stex->unblended_pipeline = pipeline;
f7d48e
+      stex->unblended_pipeline = pipeline;
f7d48e
+      return pipeline;
f7d48e
+    }
f7d48e
+  else
f7d48e
+    {
f7d48e
+      CoglPipeline *pipeline;
f7d48e
 
f7d48e
-  return pipeline;
f7d48e
+      if (stex->unblended_tower_pipeline)
f7d48e
+        return stex->unblended_tower_pipeline;
f7d48e
+
f7d48e
+      pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
f7d48e
+      cogl_pipeline_set_layer_combine (pipeline, 0,
f7d48e
+                                       "RGBA = REPLACE (TEXTURE)",
f7d48e
+                                       NULL);
f7d48e
+
f7d48e
+      stex->unblended_tower_pipeline = pipeline;
f7d48e
+      return pipeline;
f7d48e
+    }
f7d48e
 }
f7d48e
 
f7d48e
 static CoglPipeline *
f7d48e
@@ -742,7 +812,7 @@ do_paint_content (MetaShapedTexture   *stex,
f7d48e
         {
f7d48e
           CoglPipeline *opaque_pipeline;
f7d48e
 
f7d48e
-          opaque_pipeline = get_unblended_pipeline (stex, ctx);
f7d48e
+          opaque_pipeline = get_unblended_pipeline (stex, ctx, paint_tex);
f7d48e
           cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
f7d48e
           cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
f7d48e
 
f7d48e
@@ -786,11 +856,11 @@ do_paint_content (MetaShapedTexture   *stex,
f7d48e
 
f7d48e
       if (stex->mask_texture == NULL)
f7d48e
         {
f7d48e
-          blended_pipeline = get_unmasked_pipeline (stex, ctx);
f7d48e
+          blended_pipeline = get_unmasked_pipeline (stex, ctx, paint_tex);
f7d48e
         }
f7d48e
       else
f7d48e
         {
f7d48e
-          blended_pipeline = get_masked_pipeline (stex, ctx);
f7d48e
+          blended_pipeline = get_masked_pipeline (stex, ctx, paint_tex);
f7d48e
           cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
f7d48e
           cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
f7d48e
         }
f7d48e
-- 
f7d48e
2.34.1
f7d48e