pub const CLIPPED_SURFACE: &str = r"#version 100
//_DEFINES_
#if defined(EXTERNAL)
#extension GL_OES_EGL_image_external : require
#endif
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#if defined(EXTERNAL)
uniform samplerExternalOES tex;
#else
uniform sampler2D tex;
#endif
uniform float alpha;
uniform mat3 input_to_geo;
uniform vec2 geo_size;
uniform vec4 corner_radius;
uniform float geo_px;
varying vec2 v_coords;
#if defined(DEBUG_FLAGS)
uniform float tint;
#endif
void main() {
vec4 colour = texture2D(tex, v_coords);
#if defined(NO_ALPHA)
colour = vec4(colour.rgb, 1.0) * alpha;
#else
colour = colour * alpha;
#endif
#if defined(DEBUG_FLAGS)
if (tint == 1.0)
colour = vec4(0.0, 0.2, 0.0, 0.2) + colour * 0.8;
#endif
// Into the client's own pixels, then ROUNDED_CORNERS' field, unchanged.
vec2 geo = (input_to_geo * vec3(v_coords, 1.0)).xy;
vec2 half_size = geo_size * 0.5;
float picked = (geo.x < half_size.x)
? ((geo.y < half_size.y) ? corner_radius.x : corner_radius.z)
: ((geo.y < half_size.y) ? corner_radius.y : corner_radius.w);
float r = min(picked, min(half_size.x, half_size.y));
vec2 p = abs(geo - half_size) - (half_size - vec2(r));
float away = min(max(p.x, p.y), 0.0) + length(max(p, 0.0)) - r;
float band = 0.5 / max(geo_px, 0.0001);
gl_FragColor = colour * (1.0 - smoothstep(-band, band, away));
}
";Expand description
Rounded corners for one client surface, drawn where it is: the surface’s
texture coordinate is taken into the client’s rectangle through
input_to_geo, and the distance field is ROUNDED_CORNERS’ own, measured
there. So a subsurface’s corner that coincides with the client’s is cut and
its others are not, and the band is one screen pixel at any zoom
(geo_px), which the old shader’s own comment could not promise.
tests::the_clipped_program_is_shaped_the_way_smithay_requires, and
wirecheck’s case 11h, which draws a root surface and a subsurface through it.