#version 330 core
// FX V2 `split` kernel -- ported from Android EditorImageFxSplitFilter.
// Tiles a centre-cropped window of the source into a horizontal x vertical
// grid. The crop keeps the grid cells' aspect equal to the canvas's, which
// is why newSize shrinks along whichever axis has more cells.
in  vec2 TexCoord;
out vec4 FragColor;

uniform sampler2D u_src;
uniform vec2      u_texScale;     // filled region / allocated scratch size
uniform float     u_horizontal;
uniform float     u_vertical;
// CAWP-21496 / CAWP-21655: the clip's own visible footprint as a fraction of
// the plate (x0, y0, w, h), bottom-up origin to match the flipped uv below.
// The grid is laid out inside THIS rect, not the whole plate: the plate is
// canvas-sized, so tiling in plate space folded the transparent letterbox
// margin into every cell (the picture stopped filling its cell) and, for a
// PiP box, spread the cells across the whole canvas instead of inside the
// box. (0,0,1,1) -- a clip that fills the plate -- is the identity.
uniform vec4      u_contentRect;

void main() {
    float horizontalCount = max(u_horizontal, 1.0);
    float verticalCount   = max(u_vertical, 1.0);
    float ratio = verticalCount / horizontalCount;

    vec2 originSize = vec2(1.0, 1.0);
    vec2 newSize = originSize;
    if (ratio > 1.0) {
        newSize.y = 1.0 / ratio;
    } else {
        newSize.x = ratio;
    }
    vec2 offset = (originSize - newSize) / 2.0;

    // Scratch textures are GPU-native (row 0 = bottom) while TexCoord is
    // Y-down. The tiling itself is symmetric under the flip -- every cell
    // shows the same crop -- but the flip has to happen before the sample
    // so u_texScale maps into the filled region.
    vec2 uv = vec2(TexCoord.x, 1.0 - TexCoord.y);

    // Plate uv -> content-local uv, so the grid spans the clip's own edges
    // and each cell crops the clip's picture rather than the whole plate.
    // Outside the clip's footprint there is nothing to tile: stay
    // transparent instead of letting mod() wrap a negative into a
    // plausible-looking but wrong sample (the margin also feeds any later
    // kernel in this layer's chain).
    vec2 local = (uv - u_contentRect.xy) / max(u_contentRect.zw, vec2(1e-4));
    if (any(lessThan(local, vec2(0.0))) || any(greaterThan(local, vec2(1.0)))) {
        FragColor = vec4(0.0);
        return;
    }

    vec2 position = offset + mod(local * min(horizontalCount, verticalCount), newSize);
    FragColor = texture(u_src,
                        (u_contentRect.xy + position * u_contentRect.zw) * u_texScale);
}
