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