From 50bb42f0f3556e01f4f3ad12c59dd380662eac14 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 29 Jul 2024 15:48:38 +0200 Subject: [PATCH 1/4] gl: Don't crash on box shadows with negative scales Some places didn't fabs() the scale values properly, leading to assertions when offscreens with negative sizes were created. --- gsk/gl/gskglrenderjob.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c index 570d99665e..d1a581f135 100644 --- a/gsk/gl/gskglrenderjob.c +++ b/gsk/gl/gskglrenderjob.c @@ -2445,8 +2445,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job, const GskRenderNode *node) { const GskRoundedRect *outline = gsk_outset_shadow_node_get_outline (node); - float scale_x = job->scale_x; - float scale_y = job->scale_y; + float scale_x = fabsf (job->scale_x); + float scale_y = fabsf (job->scale_y); float blur_radius = gsk_outset_shadow_node_get_blur_radius (node); float blur_extra = blur_radius * 2.0f; /* 2.0 = shader radius_multiplier */ float half_blur_extra = blur_extra / 2.0f; @@ -2577,8 +2577,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job, &offscreen, texture_width, texture_height, - blur_radius * fabsf (scale_x), - blur_radius * fabsf (scale_y)); + blur_radius * scale_x, + blur_radius * scale_y); gsk_gl_shadow_library_insert (job->driver->shadows_library, &scaled_outline, From 5059ae1d7bf9e59df9fb40b5d8f697fbb1e36c32 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 29 Jul 2024 17:33:34 +0200 Subject: [PATCH 2/4] gpu: Simplify box-shadow shader Instead of doing complicated math, normalize the values to a sigma of 1.0, and then use that. This should also be beneficial for shader performance, because 1.0 is a constant and constant-elimination can kick in on the inlined functions. --- gsk/gpu/shaders/gskgpuboxshadow.glsl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gsk/gpu/shaders/gskgpuboxshadow.glsl b/gsk/gpu/shaders/gskgpuboxshadow.glsl index 5294e0b87d..b5b7b99290 100644 --- a/gsk/gpu/shaders/gskgpuboxshadow.glsl +++ b/gsk/gpu/shaders/gskgpuboxshadow.glsl @@ -111,12 +111,14 @@ blur_corner (vec2 p, if (min (r.x, r.y) <= 0.0) return 0.0; + p /= _sigma; + r /= _sigma; float result = 0.0; float step = max (1.0, r.y / 8.0); for (float y = 0.5 * step; y <= r.y; y += step) { float x = r.x - ellipse_x (r, r.y - y); - result -= gauss (p.y - y, _sigma.y) * erf_range (vec2 (- p.x, x - p.x), _sigma.x); + result -= gauss (p.y - y, 1.0) * erf_range (vec2 (- p.x, x - p.x), 1.0); } return result; } From cc3ed89e34f2866abc1649c823e8b32838ffeeee Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 28 Jul 2024 20:10:56 +0200 Subject: [PATCH 3/4] gpu: Draw proper shadows again The fix in commit 5e7f227d broke shadows while trying to make them faster. So use a better way to make them faster. With the normalized blur radius, we can now conclude that all the values too far from p.y will cause the gauss() call to return close to 0, so we can skip any y value that is too far from p.y. And that allows us to put an upper limit on the loop iterations. Tests included Fixes #6888 --- gsk/gpu/shaders/gskgpuboxshadow.glsl | 8 +++++--- ...set-shadow-corner-blur-huge-nocairo-nogl.node | 10 ++++++++++ ...tset-shadow-corner-blur-huge-nocairo-nogl.png | Bin 0 -> 112 bytes .../gsk/compare/outset-shadow-corner-blur.node | 7 +++++++ .../gsk/compare/outset-shadow-corner-blur.png | Bin 0 -> 4192 bytes testsuite/gsk/meson.build | 2 ++ 6 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 testsuite/gsk/compare/outset-shadow-corner-blur-huge-nocairo-nogl.node create mode 100644 testsuite/gsk/compare/outset-shadow-corner-blur-huge-nocairo-nogl.png create mode 100644 testsuite/gsk/compare/outset-shadow-corner-blur.node create mode 100644 testsuite/gsk/compare/outset-shadow-corner-blur.png diff --git a/gsk/gpu/shaders/gskgpuboxshadow.glsl b/gsk/gpu/shaders/gskgpuboxshadow.glsl index b5b7b99290..f74cc78734 100644 --- a/gsk/gpu/shaders/gskgpuboxshadow.glsl +++ b/gsk/gpu/shaders/gskgpuboxshadow.glsl @@ -114,13 +114,15 @@ blur_corner (vec2 p, p /= _sigma; r /= _sigma; float result = 0.0; - float step = max (1.0, r.y / 8.0); - for (float y = 0.5 * step; y <= r.y; y += step) + float start = max (p.y - 3.0, 0.0); + float end = min (p.y + 3.0, r.y); + float step = (end - start) / 7.0; + for (float y = start; y <= end; y += step) { float x = r.x - ellipse_x (r, r.y - y); result -= gauss (p.y - y, 1.0) * erf_range (vec2 (- p.x, x - p.x), 1.0); } - return result; + return step * result; } float diff --git a/testsuite/gsk/compare/outset-shadow-corner-blur-huge-nocairo-nogl.node b/testsuite/gsk/compare/outset-shadow-corner-blur-huge-nocairo-nogl.node new file mode 100644 index 0000000000..054c3d3ce2 --- /dev/null +++ b/testsuite/gsk/compare/outset-shadow-corner-blur-huge-nocairo-nogl.node @@ -0,0 +1,10 @@ +clip { + clip: 1400 1400 20 20; + child: color-matrix { + matrix: matrix3d(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255); + child: outset-shadow { + blur: 1000; + outline: 0 0 1000 1000 / 1000 0 1000 0; + } + } +} diff --git a/testsuite/gsk/compare/outset-shadow-corner-blur-huge-nocairo-nogl.png b/testsuite/gsk/compare/outset-shadow-corner-blur-huge-nocairo-nogl.png new file mode 100644 index 0000000000000000000000000000000000000000..02d28f5626ee0000a6cedb62ea58b80d947feec0 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAj3?#R^_xk}U#^NA%Cx&(BWL^R}EXkhE0gSv1 zjB_%rjevaS0G|+7AiccG_7;%h_H=O!;gC&U0Fnz}V0<5^`X0z)@O1TaS?83{1OR`Q B7Zd;h literal 0 HcmV?d00001 diff --git a/testsuite/gsk/compare/outset-shadow-corner-blur.node b/testsuite/gsk/compare/outset-shadow-corner-blur.node new file mode 100644 index 0000000000..ac1bd33bd7 --- /dev/null +++ b/testsuite/gsk/compare/outset-shadow-corner-blur.node @@ -0,0 +1,7 @@ +clip { + clip: 0 0 15 15; + child: outset-shadow { + blur: 10; + outline: 0 0 100 100 / 100 0 100 0; + } +} diff --git a/testsuite/gsk/compare/outset-shadow-corner-blur.png b/testsuite/gsk/compare/outset-shadow-corner-blur.png new file mode 100644 index 0000000000000000000000000000000000000000..781abc4fd4a28137e8e126be8b4da52937edcdbe GIT binary patch literal 4192 zcmeHKYitx%6rNHkrC2B}sTBmq0b>DY=drup&d{Zl-O?_&rIZa&AF+34?rsNmXO^95 zciW;;6a?c71!D+^D56k{Mq47jp<>i1pduwa6s1ZdYIy}nQ1Q-epMk_Qk$>G}cjlh+ zo$sFW-E(jDt}ZPpN=+G^f?-&yr`TPFo+FHJauWKTdT8A&^w?ADTd0?TC?1ZeemMwn zy(SEC7?b@N7CRCuJ(}7=C;xS6)Y#p5LQ8JR$>QTLoxEj8`rgo-pFdf)Z~AW?tuKyC zOx_UNR@SsOSONF?>!qTpS?u`V54W^zn6n^(Ed2G0O=T}%{i@}T6FbVAjy>9T>xwE% z_G2F{9lCky=!_?0!){N#eFil>+4jJcTh`S+0RE_1`R=O)cbz|+-?6CmXy%p2(xxUr zkvN-BnRVx)OrJQhc_!YR^+xE-uI*#ne%x5HWrWsHzTEX}(Q*t+cu01+Nk8Huf@#@F%Ml9oW;k{?Z zr5$YbC2p}+e2Ri`XY&0G=Ne7~S3t(ve%HjU1;Yo;+F9S6bg1>VjJ72e2WT>}O>XD8sGc4bmbQ# z&V*W!hr(tQ61xvlm;F6r z^~uffnC0|N1ci6=_Ca^mZh{fY>*d|5SY@Q=aXSfPeqK^VS>nxC;DAtqv`Dh7J(sje z0w6hBu#%kJ&q@x47VVs)7nMiRbfAdPphDyp8S!wy;jmeAXp&|{hP3%5niK?~wYf?!f zKU0l_09sBt1Oku>D*@AC2+kLjdYlAnp?fT)L7@9lfRngeR;pq>4xb!?^K@XS$v9Y+ zbyykB&e%C5M-ON|jA*D64Niu(SmP-e%fh2#kg&k$Q$%1!pjvoW1Oi=+_*6CMB#e}B zBeL7=McYXNI&cFWB2t>Q@w9_yIUmFEjFo5XQ)rf_d*M|{_SgIu+SojJUVO=mWev?= zW18YSY93q?AH|13+1yGvZf*)5i189MPz@zBPs9~>iIqSJKy-R^wriJNzD_ITS|MxA zad0Fn3IggT#!hk$YYu4zK!miAnYGcn z5*n+31S4q&d97enXTg+lW^`4YM_r>yo(br6$e_5m4IN(SETp;*!%odmzBlsIxfVBa z3LGDpq+j|D$Tc8WzZB>fc%Zumk!SL&L@88iozaFun=c`VCpgI7Ih&3x~8189Op{#5nlnN@N=8aToZq j_lp%-gI}o_bu)osiO*pPjGTTMIWbRRiF?P4isk Date: Tue, 30 Jul 2024 01:44:05 +0200 Subject: [PATCH 4/4] gpu: Don't blur tiny blur radii We get those wrong, and there's not really a visual effect. And since we do a check anyway, just disallow them and treat them as unblurred. --- gsk/gpu/gskgpunodeprocessor.c | 4 ++-- .../compare/outset-shadow-corner-blur-tiny.node | 11 +++++++++++ .../compare/outset-shadow-corner-blur-tiny.png | Bin 0 -> 133 bytes testsuite/gsk/meson.build | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 testsuite/gsk/compare/outset-shadow-corner-blur-tiny.node create mode 100644 testsuite/gsk/compare/outset-shadow-corner-blur-tiny.png diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index d3bc55cb16..0349abe0bd 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -2104,7 +2104,7 @@ gsk_gpu_node_processor_add_inset_shadow_node (GskGpuNodeProcessor *self, spread = gsk_inset_shadow_node_get_spread (node); blur_radius = gsk_inset_shadow_node_get_blur_radius (node); - if (blur_radius == 0) + if (blur_radius < 0.01) { float color[4]; @@ -2156,7 +2156,7 @@ gsk_gpu_node_processor_add_outset_shadow_node (GskGpuNodeProcessor *self, dx = gsk_outset_shadow_node_get_dx (node); dy = gsk_outset_shadow_node_get_dy (node); - if (blur_radius == 0) + if (blur_radius < 0.01) { GskRoundedRect outline; float color[4]; diff --git a/testsuite/gsk/compare/outset-shadow-corner-blur-tiny.node b/testsuite/gsk/compare/outset-shadow-corner-blur-tiny.node new file mode 100644 index 0000000000..a61362eb6d --- /dev/null +++ b/testsuite/gsk/compare/outset-shadow-corner-blur-tiny.node @@ -0,0 +1,11 @@ +color { + bounds: 0 0 100 100; + color: rgba(0,0,0,0); +} +clip { + clip: 10 10 20 20; + child: outset-shadow { + blur: 0.00001; + outline: 0 0 100 100 / 100 0 100 0; + } +} diff --git a/testsuite/gsk/compare/outset-shadow-corner-blur-tiny.png b/testsuite/gsk/compare/outset-shadow-corner-blur-tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..eea25d772f943500328ab6e6a5881bfeaacf094d GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^DIm