From 0b813de72a631db8bda81f823bca6b0b62b4f59c Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 17 Sep 2023 06:26:16 +0200 Subject: [PATCH 1/2] gl: gradients should transition in unpremultiplied space So make the gradient shaders do that. --- gsk/gl/resources/conic_gradient.glsl | 6 +++--- gsk/gl/resources/linear_gradient.glsl | 6 +++--- gsk/gl/resources/radial_gradient.glsl | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gsk/gl/resources/conic_gradient.glsl b/gsk/gl/resources/conic_gradient.glsl index f1d33cd6a7..eaa04aa3ad 100644 --- a/gsk/gl/resources/conic_gradient.glsl +++ b/gsk/gl/resources/conic_gradient.glsl @@ -75,10 +75,10 @@ void main() { if (offset < next_offset) { float f = (offset - curr_offset) / (next_offset - curr_offset); - vec4 curr_color = gsk_premultiply(get_color(i)); - vec4 next_color = gsk_premultiply(get_color(i + 1)); + vec4 curr_color = get_color(i); + vec4 next_color = get_color(i + 1); vec4 color = mix(curr_color, next_color, f); - gskSetScaledOutputColor(color, u_alpha); + gskSetScaledOutputColor(gsk_premultiply(color), u_alpha); return; } } diff --git a/gsk/gl/resources/linear_gradient.glsl b/gsk/gl/resources/linear_gradient.glsl index fa130be4cb..8a7a557f8e 100644 --- a/gsk/gl/resources/linear_gradient.glsl +++ b/gsk/gl/resources/linear_gradient.glsl @@ -97,10 +97,10 @@ void main() { if (offset < next_offset) { float f = (offset - curr_offset) / (next_offset - curr_offset); - vec4 curr_color = gsk_premultiply(get_color(i)); - vec4 next_color = gsk_premultiply(get_color(i + 1)); + vec4 curr_color = get_color(i); + vec4 next_color = get_color(i + 1); vec4 color = mix(curr_color, next_color, f); - gskSetScaledOutputColor(color, u_alpha); + gskSetScaledOutputColor(gsk_premultiply (color), u_alpha); return; } } diff --git a/gsk/gl/resources/radial_gradient.glsl b/gsk/gl/resources/radial_gradient.glsl index 59fad00290..d03ca96b8c 100644 --- a/gsk/gl/resources/radial_gradient.glsl +++ b/gsk/gl/resources/radial_gradient.glsl @@ -77,10 +77,10 @@ void main() { if (offset < next_offset) { float f = (offset - curr_offset) / (next_offset - curr_offset); - vec4 curr_color = gsk_premultiply(get_color(i)); - vec4 next_color = gsk_premultiply(get_color(i + 1)); + vec4 curr_color = get_color(i); + vec4 next_color = get_color(i + 1); vec4 color = mix(curr_color, next_color, f); - gskSetScaledOutputColor(color, u_alpha); + gskSetScaledOutputColor(gsk_premultiply(color), u_alpha); return; } } From 95865cb1bf059a20daf617e6f22831f5f6dbdc16 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 18 Sep 2023 07:48:10 +0200 Subject: [PATCH 2/2] gsk: Fix clipping error when drawing shadows When shadows were offset - in particular when offset so the original source was out of bounds of the result - the drawing code would create a pattern for it that didn't include enough of it to compose a shadow. Fix that by not creating those patterns anymore, but instead drawing the source (potentially multiple times) at the required offsets. While that does more drawing, it simplifies the shadow node draw code, and that's the primary goal of the Cairo rendering. Test included. --- gsk/gskrendernodeimpl.c | 24 +++++++----------- .../gsk/compare/shadow-clip-contents.node | 10 ++++++++ .../gsk/compare/shadow-clip-contents.png | Bin 0 -> 116 bytes testsuite/gsk/meson.build | 1 + 4 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 testsuite/gsk/compare/shadow-clip-contents.node create mode 100644 testsuite/gsk/compare/shadow-clip-contents.png diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 9ffaf71ff7..4e848bdb08 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -4852,18 +4852,8 @@ gsk_shadow_node_draw (GskRenderNode *node, cairo_t *cr) { GskShadowNode *self = (GskShadowNode *) node; - cairo_pattern_t *pattern; gsize i; - cairo_save (cr); - /* clip so the push_group() creates a small surface */ - gsk_cairo_rectangle (cr, &self->child->bounds); - cairo_clip (cr); - cairo_push_group (cr); - gsk_render_node_draw (self->child, cr); - pattern = cairo_pop_group (cr); - cairo_restore (cr); - cairo_save (cr); /* clip so the blur area stays small */ gsk_cairo_rectangle (cr, &node->bounds); @@ -4872,27 +4862,31 @@ gsk_shadow_node_draw (GskRenderNode *node, for (i = 0; i < self->n_shadows; i++) { GskShadow *shadow = &self->shadows[i]; + cairo_pattern_t *pattern; /* We don't need to draw invisible shadows */ if (gdk_rgba_is_clear (&shadow->color)) continue; cairo_save (cr); - gdk_cairo_set_source_rgba (cr, &shadow->color); cr = gsk_cairo_blur_start_drawing (cr, shadow->radius, GSK_BLUR_X | GSK_BLUR_Y); + cairo_save (cr); cairo_translate (cr, shadow->dx, shadow->dy); + cairo_push_group (cr); + gsk_render_node_draw (self->child, cr); + pattern = cairo_pop_group (cr); + gdk_cairo_set_source_rgba (cr, &shadow->color); cairo_mask (cr, pattern); + cairo_restore (cr); cr = gsk_cairo_blur_finish_drawing (cr, shadow->radius, &shadow->color, GSK_BLUR_X | GSK_BLUR_Y); cairo_restore (cr); } - cairo_set_source (cr, pattern); - cairo_paint (cr); - cairo_restore (cr); + gsk_render_node_draw (self->child, cr); - cairo_pattern_destroy (pattern); + cairo_restore (cr); } static void diff --git a/testsuite/gsk/compare/shadow-clip-contents.node b/testsuite/gsk/compare/shadow-clip-contents.node new file mode 100644 index 0000000000..8906577319 --- /dev/null +++ b/testsuite/gsk/compare/shadow-clip-contents.node @@ -0,0 +1,10 @@ +clip { + clip: 0 0 50 50; + child: shadow { + shadows: rgb(0,0,0) -20 -20; + child: color { + bounds: 40 40 50 50; + color: rgb(255,0,204); + } + } +} diff --git a/testsuite/gsk/compare/shadow-clip-contents.png b/testsuite/gsk/compare/shadow-clip-contents.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe7bff09ab19b7f8edafca5aee36d7651a0ee4e GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1|+Qw)-3{2o-U3d9-VJ5Y~*Ax;5p);n)3hT zrpcR|xDSg@e07{X&OtCkJs=SR9{QyJN+^up{Xb4uN5|$G^N|P49Pw}bd4R?+c)I$z JtaD0e0st@VB&h%Z literal 0 HcmV?d00001 diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build index b427c2c3cf..c3c15db226 100644 --- a/testsuite/gsk/meson.build +++ b/testsuite/gsk/meson.build @@ -92,6 +92,7 @@ compare_render_tests = [ 'scaled-cairo', 'scaled-texture', 'shadow-behind', + 'shadow-clip-contents', 'shadow-in-opacity', 'shadow-opacity', 'shrink-rounded-border',