summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2020-07-12 09:40:00 +0200
committerTimm Bäder <mail@baedert.org>2020-07-17 05:49:11 +0200
commit37d7ab88dc125ec9ab6ff326f371aa028cfa6df1 (patch)
treea76b60f9247fdd67f652be99f990a99f30f338f4
parent6cde64072d6e2fcdca0fb8da249cb26ad57ba358 (diff)
downloadgtk+-37d7ab88dc125ec9ab6ff326f371aa028cfa6df1.tar.gz
gl renderer: Avoid 9-slicing things that can't be
The outline needs to be large enough so changing the size of the outline does not affect the resulting blurred texture. Fixes #2776
-rw-r--r--gsk/gl/gskglrenderer.c67
1 files changed, 57 insertions, 10 deletions
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index db716794c1..9df466a248 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -1786,7 +1786,6 @@ render_unblurred_outset_shadow_node (GskGLRenderer *self,
}
-
static GdkRGBA COLOR_WHITE = { 1, 1, 1, 1 };
static inline void
render_outset_shadow_node (GskGLRenderer *self,
@@ -1807,19 +1806,32 @@ render_outset_shadow_node (GskGLRenderer *self,
OpShadow *shadow;
int blurred_texture_id;
int cached_tid;
+ bool do_slicing;
/* scaled_outline is the minimal outline we need to draw the given drop shadow,
* enlarged by the spread and offset by the blur radius. */
scaled_outline = *outline;
- /* Shrink our outline to the minimum size that can still hold all the border radii */
- gsk_rounded_rect_shrink_to_minimum (&scaled_outline);
- /* Increase by the spread */
- gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
- /* Grow bounds but don't grow corners */
- graphene_rect_inset (&scaled_outline.bounds, - extra_blur_pixels, - extra_blur_pixels);
- /* For the center part, we add a few pixels */
- scaled_outline.bounds.size.width += SHADOW_EXTRA_SIZE;
- scaled_outline.bounds.size.height += SHADOW_EXTRA_SIZE;
+
+ if (outline->bounds.size.width < blur_extra ||
+ outline->bounds.size.height < blur_extra)
+ {
+ do_slicing = false;
+ gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
+ }
+ else
+ {
+ /* Shrink our outline to the minimum size that can still hold all the border radii */
+ gsk_rounded_rect_shrink_to_minimum (&scaled_outline);
+ /* Increase by the spread */
+ gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
+ /* Grow bounds but don't grow corners */
+ graphene_rect_inset (&scaled_outline.bounds, - blur_extra / 2.0, - blur_extra / 2.0);
+ /* For the center part, we add a few pixels */
+ scaled_outline.bounds.size.width += SHADOW_EXTRA_SIZE;
+ scaled_outline.bounds.size.height += SHADOW_EXTRA_SIZE;
+
+ do_slicing = true;
+ }
texture_width = (int)ceil ((scaled_outline.bounds.size.width + blur_extra) * scale);
texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale);
@@ -1904,6 +1916,41 @@ render_outset_shadow_node (GskGLRenderer *self,
blurred_texture_id = cached_tid;
}
+
+ if (!do_slicing)
+ {
+ const float min_x = floorf (builder->dx + outline->bounds.origin.x - spread - (blur_extra / 2.0) + dx);
+ const float min_y = floorf (builder->dy + outline->bounds.origin.y - spread - (blur_extra / 2.0) + dy);
+ float x1, x2, y1, y2, tx1, tx2, ty1, ty2;
+
+ ops_set_program (builder, &self->programs->outset_shadow_program);
+ ops_set_color (builder, color);
+ ops_set_texture (builder, blurred_texture_id);
+
+ shadow = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
+ shadow->outline = transform_rect (self, builder, outline);
+
+ tx1 = 0; tx2 = 1;
+ ty1 = 0; ty2 = 1;
+
+ x1 = min_x;
+ x2 = min_x + texture_width / scale;
+ y1 = min_y;
+ y2 = min_y + texture_height / scale;
+
+ ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
+ { { x1, y1 }, { tx1, ty2 }, },
+ { { x1, y2 }, { tx1, ty1 }, },
+ { { x2, y1 }, { tx2, ty2 }, },
+
+ { { x2, y2 }, { tx2, ty1 }, },
+ { { x1, y2 }, { tx1, ty1 }, },
+ { { x2, y1 }, { tx2, ty2 }, },
+ });
+ return;
+ }
+
+
ops_set_program (builder, &self->programs->outset_shadow_program);
ops_set_color (builder, color);
ops_set_texture (builder, blurred_texture_id);