background-content: Anti-alias texels that intersect the circle boundary

Previously we chose to only anti-alias texels inside the boundary
(`clip_radius - 1.0`) but zoomed in you could see it was slightly smaller
than the correct curve (#2024).

Similarly if you choose to only anti-alias texels outside that edge
(`clip_radius + 1.0`) then you'd get an overly convex curve that doesn't
match up with the straight line sections.

So now we anti-alias texels that intersect the circle boundary, regardless
of which side they are mostly on. For efficiency we define "intersect" to
mean any texel whose center is within 0.5 of the theoretical edge.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2024
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2102>
This commit is contained in:
Daniel van Vugt 2021-11-22 18:23:08 +08:00 committed by Marge Bot
parent acadf5b3f7
commit 858b5c12b1

View File

@ -169,16 +169,17 @@ typedef enum
" float dist_squared = dot (delta, delta); \n"\ " float dist_squared = dot (delta, delta); \n"\
" \n"\ " \n"\
" // Fully outside the circle \n"\ " // Fully outside the circle \n"\
" if (dist_squared >= (clip_radius * clip_radius)) \n"\ " float outer_radius = clip_radius + 0.5; \n"\
" if (dist_squared >= (outer_radius * outer_radius)) \n"\
" return 0.0; \n"\ " return 0.0; \n"\
" \n"\ " \n"\
" // Fully inside the circle \n"\ " // Fully inside the circle \n"\
" float inner_radius = clip_radius - 1.0; \n"\ " float inner_radius = clip_radius - 0.5; \n"\
" if (dist_squared <= (inner_radius * inner_radius)) \n"\ " if (dist_squared <= (inner_radius * inner_radius)) \n"\
" return 1.0; \n"\ " return 1.0; \n"\
" \n"\ " \n"\
" // Only pixels on the edge of the curve need expensive antialiasing \n"\ " // Only pixels on the edge of the curve need expensive antialiasing \n"\
" return clip_radius - sqrt (dist_squared); \n"\ " return outer_radius - sqrt (dist_squared); \n"\
"} \n" "} \n"
#define ROUNDED_CLIP_FRAGMENT_SHADER_CODE \ #define ROUNDED_CLIP_FRAGMENT_SHADER_CODE \