diff options
author | Jonas Ã…dahl <jadahl@gmail.com> | 2022-02-09 12:41:14 +0100 |
---|---|---|
committer | Marge Bot <marge-bot@gnome.org> | 2022-04-07 07:28:44 +0000 |
commit | 9d0f612de14ca47d0a0cd89021367a49060c61ee (patch) | |
tree | 81e024c2c5e2925f6b55ff62d63468223db67366 /src/compositor | |
parent | d4ffaf291ffb805b2c1d0389b284a57ba3471383 (diff) | |
download | mutter-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.c | 126 |
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); } |