diff options
author | Timm Bäder <mail@baedert.org> | 2020-07-12 09:40:00 +0200 |
---|---|---|
committer | Timm Bäder <mail@baedert.org> | 2020-07-17 05:49:11 +0200 |
commit | 37d7ab88dc125ec9ab6ff326f371aa028cfa6df1 (patch) | |
tree | a76b60f9247fdd67f652be99f990a99f30f338f4 | |
parent | 6cde64072d6e2fcdca0fb8da249cb26ad57ba358 (diff) | |
download | gtk+-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.c | 67 |
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); |