[gnome-shell/gnome-41] st: Generate shadows from the silhouette of the source texture
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/gnome-41] st: Generate shadows from the silhouette of the source texture
- Date: Sun, 20 Mar 2022 20:21:29 +0000 (UTC)
commit d4f4c8eafec433d5834276d8b13a6478a6f9b452
Author: Daniel van Vugt <daniel van vugt canonical com>
Date: Fri Jul 16 18:34:11 2021 +0800
st: Generate shadows from the silhouette of the source texture
As first mentioned in commit 672171093, the CSS spec defines shadow
colors independently from the colors casting the shadow. It's not
a physical light simulation so a shadow is allowed to be a different
color from texture casting it.
This means we only care about the shape of the source where alpha
values of zero are adjacent to alpha values of non-zero. And all such
non-zero pixels should be treated as fully opaque for the purpose of
shadow generation. While this would be wrong for a physical light
simulation it does allow us to cast shadows around semi-translucent
shapes and better support CSS.
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4477
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1918>
(cherry picked from commit 918c063693450a7333abbd02134ad1eb0a95ef8c)
src/st/st-private.c | 35 +++++++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
---
diff --git a/src/st/st-private.c b/src/st/st-private.c
index 540bad425e..bb981516dc 100644
--- a/src/st/st-private.c
+++ b/src/st/st-private.c
@@ -394,7 +394,10 @@ _st_create_shadow_pipeline (StShadow *shadow_spec,
float sigma;
int src_height, dst_height;
int src_width, dst_width;
+ CoglPipeline *texture_pipeline;
+ static CoglPipelineKey texture_pipeline_key =
+ "st-create-shadow-pipeline-saturate-alpha";
static CoglPipeline *shadow_pipeline_template = NULL;
g_return_val_if_fail (shadow_spec != NULL, NULL);
@@ -433,10 +436,34 @@ _st_create_shadow_pipeline (StShadow *shadow_spec,
});
/* Texture */
- texture_node = clutter_texture_node_new (src_texture,
- 0,
- CLUTTER_SCALING_FILTER_NEAREST,
- CLUTTER_SCALING_FILTER_NEAREST);
+ texture_pipeline = cogl_context_get_named_pipeline (ctx,
+ &texture_pipeline_key);
+
+ if (G_UNLIKELY (texture_pipeline == NULL))
+ {
+ CoglSnippet *snippet;
+
+ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
+ "",
+ "if (cogl_color_out.a > 0.0)\n"
+ " cogl_color_out.a = 1.0;");
+
+ texture_pipeline = cogl_pipeline_new (ctx);
+ cogl_pipeline_add_snippet (texture_pipeline, snippet);
+ cogl_object_unref (snippet);
+
+ cogl_context_set_named_pipeline (ctx,
+ &texture_pipeline_key,
+ texture_pipeline);
+ }
+
+ /* No need to unref texture_pipeline since the named pipeline hash
+ * doesn't change its ref count from 1. Also no need to copy texture_pipeline
+ * since we'll be completely finished with it after clutter_paint_node_paint.
+ */
+
+ cogl_pipeline_set_layer_texture (texture_pipeline, 0, src_texture);
+ texture_node = clutter_pipeline_node_new (texture_pipeline);
clutter_paint_node_add_child (blur_node, texture_node);
clutter_paint_node_add_rectangle (texture_node,
&(ClutterActorBox) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]