Fix vertically-flipped content in the GLES path-clip composite
Some checks failed
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled

The clip-layer composite shader sampled the offscreen layer at the wrong vertical position, so path-clipped content (e.g. a circular avatar) came out upside down on the GLES backend.
`v_uv.y` runs bottom-to-top in screen space — the layer FBO has GL's lower-left origin, and `ortho_rect` plus the texture shader's flip establish that `v_uv.y == 1` is the top edge. The composite computed the fragment's screen Y as `bbox.y + v_uv.y * bbox.h`, which is the inverted Y, so it read the layer mirrored about the horizontal axis. Compute it as `bbox.y + (1 - v_uv.y) * bbox.h` instead. The mask sampling was already correct (and a symmetric circle hid the flip in the example; a photo reveals it). The software backend is unaffected — it clips through a coverage mask with no layer round-trip.
This commit is contained in:
2026-06-19 00:04:24 +02:00
parent f8c45f0e30
commit 588a3f7e36

View File

@@ -163,7 +163,10 @@ uniform vec2 u_canvas;
uniform vec4 u_bbox; uniform vec4 u_bbox;
void main() void main()
{ {
vec2 sp = u_bbox.xy + v_uv * u_bbox.zw; // `v_uv.y` runs bottom-to-top in screen space (FBO origin is lower-left, as
// `ortho_rect` + the texture shader's flip establish), so the screen Y of
// this fragment is `bbox.y + (1 - v_uv.y) * bbox.h`.
vec2 sp = vec2( u_bbox.x + v_uv.x * u_bbox.z, u_bbox.y + ( 1.0 - v_uv.y ) * u_bbox.w );
vec2 luv = vec2( sp.x / u_canvas.x, 1.0 - sp.y / u_canvas.y ); vec2 luv = vec2( sp.x / u_canvas.x, 1.0 - sp.y / u_canvas.y );
vec4 col = texture2D( u_layer, luv ); vec4 col = texture2D( u_layer, luv );
float cov = texture2D( u_mask, vec2( v_uv.x, 1.0 - v_uv.y ) ).a; float cov = texture2D( u_mask, vec2( v_uv.x, 1.0 - v_uv.y ) ).a;