summaryrefslogtreecommitdiff
path: root/src/compositor
diff options
context:
space:
mode:
authorJonas Ã…dahl <jadahl@gmail.com>2022-02-09 12:41:14 +0100
committerMarge Bot <marge-bot@gnome.org>2022-04-07 07:28:44 +0000
commit9d0f612de14ca47d0a0cd89021367a49060c61ee (patch)
tree81e024c2c5e2925f6b55ff62d63468223db67366 /src/compositor
parentd4ffaf291ffb805b2c1d0389b284a57ba3471383 (diff)
downloadmutter-9d0f612de14ca47d0a0cd89021367a49060c61ee.tar.gz
shaped-texture: Paint with the right layer snippet
When we get passed a "snippet" to the shaped texture, it's added as a pipeline layer snippet to change how the source texture is sampled. When we draw from a texture tower however we have allocated regular textures which doesn't need any special layer snippet, so create separate pipelines for those that doesn't use that snippet. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/528 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2278>
Diffstat (limited to 'src/compositor')
-rw-r--r--src/compositor/meta-shaped-texture.c126
1 files changed, 98 insertions, 28 deletions
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index b45b1732c..34fec6852 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -89,8 +89,12 @@ struct _MetaShapedTexture
CoglSnippet *snippet;
CoglPipeline *base_pipeline;
+ CoglPipeline *unmasked_pipeline;
+ CoglPipeline *unmasked_tower_pipeline;
CoglPipeline *masked_pipeline;
+ CoglPipeline *masked_tower_pipeline;
CoglPipeline *unblended_pipeline;
+ CoglPipeline *unblended_tower_pipeline;
gboolean is_y_inverted;
@@ -240,8 +244,12 @@ static void
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
{
g_clear_pointer (&stex->base_pipeline, cogl_object_unref);
+ g_clear_pointer (&stex->unmasked_pipeline, cogl_object_unref);
+ g_clear_pointer (&stex->unmasked_tower_pipeline, cogl_object_unref);
g_clear_pointer (&stex->masked_pipeline, cogl_object_unref);
+ g_clear_pointer (&stex->masked_tower_pipeline, cogl_object_unref);
g_clear_pointer (&stex->unblended_pipeline, cogl_object_unref);
+ g_clear_pointer (&stex->unblended_tower_pipeline, cogl_object_unref);
}
static void
@@ -378,9 +386,6 @@ get_base_pipeline (MetaShapedTexture *stex,
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
- if (stex->snippet)
- cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
-
stex->base_pipeline = pipeline;
return stex->base_pipeline;
@@ -388,47 +393,112 @@ get_base_pipeline (MetaShapedTexture *stex,
static CoglPipeline *
get_unmasked_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
+ CoglContext *ctx,
+ CoglTexture *tex)
{
- return get_base_pipeline (stex, ctx);
+ if (stex->texture == tex)
+ {
+ CoglPipeline *pipeline;
+
+ if (stex->unmasked_pipeline)
+ return stex->unmasked_pipeline;
+
+ pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
+ if (stex->snippet)
+ cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
+
+ stex->unmasked_pipeline = pipeline;
+ return pipeline;
+ }
+ else
+ {
+ CoglPipeline *pipeline;
+
+ if (stex->unmasked_tower_pipeline)
+ return stex->unmasked_tower_pipeline;
+
+ pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
+ stex->unmasked_tower_pipeline = pipeline;
+ return pipeline;
+ }
}
static CoglPipeline *
get_masked_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
+ CoglContext *ctx,
+ CoglTexture *tex)
{
- CoglPipeline *pipeline;
+ if (stex->texture == tex)
+ {
+ CoglPipeline *pipeline;
- if (stex->masked_pipeline)
- return stex->masked_pipeline;
+ if (stex->masked_pipeline)
+ return stex->masked_pipeline;
- pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 1,
- "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
- NULL);
+ pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
+ cogl_pipeline_set_layer_combine (pipeline, 1,
+ "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
+ NULL);
+ if (stex->snippet)
+ cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
- stex->masked_pipeline = pipeline;
+ stex->masked_pipeline = pipeline;
+ return pipeline;
+ }
+ else
+ {
+ CoglPipeline *pipeline;
- return pipeline;
+ if (stex->masked_tower_pipeline)
+ return stex->masked_tower_pipeline;
+
+ pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
+ cogl_pipeline_set_layer_combine (pipeline, 1,
+ "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
+ NULL);
+
+ stex->masked_tower_pipeline = pipeline;
+ return pipeline;
+ }
}
static CoglPipeline *
get_unblended_pipeline (MetaShapedTexture *stex,
- CoglContext *ctx)
+ CoglContext *ctx,
+ CoglTexture *tex)
{
- CoglPipeline *pipeline;
+ if (stex->texture == tex)
+ {
+ CoglPipeline *pipeline;
- if (stex->unblended_pipeline)
- return stex->unblended_pipeline;
+ if (stex->unblended_pipeline)
+ return stex->unblended_pipeline;
- pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 0,
- "RGBA = REPLACE (TEXTURE)",
- NULL);
+ pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
+ cogl_pipeline_set_layer_combine (pipeline, 0,
+ "RGBA = REPLACE (TEXTURE)",
+ NULL);
+ if (stex->snippet)
+ cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
- stex->unblended_pipeline = pipeline;
+ stex->unblended_pipeline = pipeline;
+ return pipeline;
+ }
+ else
+ {
+ CoglPipeline *pipeline;
- return pipeline;
+ if (stex->unblended_tower_pipeline)
+ return stex->unblended_tower_pipeline;
+
+ pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
+ cogl_pipeline_set_layer_combine (pipeline, 0,
+ "RGBA = REPLACE (TEXTURE)",
+ NULL);
+
+ stex->unblended_tower_pipeline = pipeline;
+ return pipeline;
+ }
}
static CoglPipeline *
@@ -705,7 +775,7 @@ do_paint_content (MetaShapedTexture *stex,
{
CoglPipeline *opaque_pipeline;
- opaque_pipeline = get_unblended_pipeline (stex, ctx);
+ opaque_pipeline = get_unblended_pipeline (stex, ctx, paint_tex);
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
@@ -749,11 +819,11 @@ do_paint_content (MetaShapedTexture *stex,
if (stex->mask_texture == NULL)
{
- blended_pipeline = get_unmasked_pipeline (stex, ctx);
+ blended_pipeline = get_unmasked_pipeline (stex, ctx, paint_tex);
}
else
{
- blended_pipeline = get_masked_pipeline (stex, ctx);
+ blended_pipeline = get_masked_pipeline (stex, ctx, paint_tex);
cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
}