/*
 * Copyright 2026 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tests/graphite/sparse_strips/FastValidator.h"

#include "include/core/SkMatrix.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkString.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkVx.h"
#include "src/gpu/graphite/geom/EndCaps.h"
#include "src/gpu/graphite/geom/WideTiles.h"
#include "src/gpu/graphite/sparse_strips/AlphaAtlasManager.h"
#include "src/gpu/graphite/sparse_strips/Flatten.h"
#include "src/gpu/graphite/sparse_strips/MSAA_LUT.h"
#include "src/gpu/graphite/sparse_strips/MakeStrips.h"
#include "src/gpu/graphite/sparse_strips/Polyline.h"
#include "src/gpu/graphite/sparse_strips/SparseStripsTypes.h"
#include "src/gpu/graphite/sparse_strips/Tiler.h"
#include "src/gpu/graphite/sparse_strips/WindingHistogram.h"
#include "tests/Test.h"
#include "tests/graphite/sparse_strips/CoverageTestUtils.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <utility>
#include <vector>

namespace skgpu::graphite {

namespace {

struct LineHit {
    skvx::float8 x;
    skvx::int8 dir;  // +1 downward, -1 upward, 0 inactive
};

template <uint16_t kTileHeight>
std::vector<std::vector<Line>> build_tile_row_line_buckets(const Polyline& polyline,
                                                           int clipBottom) {
    constexpr float kTileHeightF = static_cast<float>(kTileHeight);
    uint16_t numTileRows = (clipBottom + kTileHeight - 1) / kTileHeight;
    std::vector<std::vector<Line>> buckets(numTileRows);

    for (auto it = polyline.begin(); it != polyline.end(); ++it) {
        auto [line, idx] = *it;
        float minY = std::min(line.p0.fY, line.p1.fY);
        float maxY = std::max(line.p0.fY, line.p1.fY);

        if (maxY < 0.0f || minY >= static_cast<float>(clipBottom)) {
            continue;
        }

        int startTileY = std::max(0, static_cast<int>(std::floor(minY / kTileHeightF)));
        int endTileY = std::min(static_cast<int>(numTileRows) - 1,
                                static_cast<int>(std::floor(maxY / kTileHeightF)));

        for (int ty = startTileY; ty <= endTileY; ++ty) {
            buckets[ty].push_back(line);
        }
    }
    return buckets;
}

void collect_row_hits(int py,
                      const std::vector<Line>& candidateLines,
                      std::vector<LineHit>* rowHits) {
    static const skvx::float8 kSubY =
            (skvx::float8{0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f} + 0.5f) / 8.0f;
    skvx::float8 vPy = static_cast<float>(py) + kSubY;

    rowHits->clear();

    for (const Line& line : candidateLines) {
        float dy = line.p1.fY - line.p0.fY;
        if (dy == 0.0f) {
            continue;
        }
        float invDy = 1.0f / dy;
        float dx = line.p1.fX - line.p0.fX;
        int32_t dir = dy > 0.0f ? 1 : -1;

        // Each line covers the sub-scanlines in [minY, maxY) regardless of its direction, so a
        // sub-scanline passing exactly through a vertex where the path turns vertically sees both
        // or neither of its lines, rather than just one, which would leave a nonzero winding
        // extending to the right of the path.
        float minY = std::min(line.p0.fY, line.p1.fY);
        float maxY = std::max(line.p0.fY, line.p1.fY);
        auto valid = (vPy >= minY) & (vPy < maxY);
        if (any(valid)) {
            skvx::float8 t = (vPy - line.p0.fY) * invDy;
            LineHit hit;
            hit.x = line.p0.fX + t * dx;
            hit.dir = if_then_else(valid, skvx::int8(dir), skvx::int8(0));
            rowHits->push_back(hit);
        }
    }
}

enum class TileKind : uint8_t { kEmpty, kEndCap, kWide };

// EndCaps only cover the tiles that edges pass through, so this validates the rest of the clip:
// every tile whose subsamples are all inside the path must be covered by exactly one WideTile, and
// every tile whose subsamples are all outside must be empty. A tile with subsamples on both sides
// of the path must be an EndCap. Rather than evaluating every subsample, this relies on the winding
// of each sub-scanline being constant between the crossings of the lines. Every tile outside of the
// clip must be empty.
template <uint16_t kTileWidth, uint16_t kTileHeight>
bool validate_solid_tiles(skiatest::Reporter* reporter,
                          const std::vector<std::vector<Line>>& lineBuckets,
                          const WideTiles& wides,
                          const EndCaps& ends,
                          const skvx::float8& subX,
                          const SkIRect& clip,
                          bool isEvenOdd,
                          bool isInverse,
                          const char* testName) {
    // The grid spans from the origin to the clip, so that tiles left of or above the clip can be
    // detected. The clip's left and top are tile aligned.
    const int minTileCol = clip.left() / kTileWidth;
    const int minTileRow = clip.top() / kTileHeight;
    const int numTileCols = (clip.right() + kTileWidth - 1) / kTileWidth;
    const int numTileRows = (clip.bottom() + kTileHeight - 1) / kTileHeight;

    // Rasterize the strip output into the tile grid, verifying that each tile is emitted at most
    // once and lies within the clip.
    std::vector<TileKind> tileKinds(numTileCols * numTileRows, TileKind::kEmpty);
    auto markTiles = [&](uint16_t x, uint16_t y, uint16_t width, TileKind kind) {
        const char* type = kind == TileKind::kWide ? "WideTile" : "EndCap";
        const int right = x + width;
        // Note: WideTiles may end at the right edge of the clip rather than a tile boundary.
        if (x % kTileWidth != 0 || y % kTileHeight != 0 || width == 0 ||
            (right % kTileWidth != 0 && right != clip.right())) {
            REPORTER_ASSERT(reporter,
                            false,
                            "[%s] %s (x:%d, y:%d, width:%d) is not tile aligned",
                            testName,
                            type,
                            x,
                            y,
                            width);
            return false;
        }
        const int row = y / kTileHeight;
        const int startCol = x / kTileWidth;
        const int endCol = (right + kTileWidth - 1) / kTileWidth;
        if (row < minTileRow || row >= numTileRows || startCol < minTileCol ||
            endCol > numTileCols) {
            REPORTER_ASSERT(reporter,
                            false,
                            "[%s] %s (x:%d, y:%d, width:%d) lies outside of the clip "
                            "(l:%d, t:%d, r:%d, b:%d)",
                            testName,
                            type,
                            x,
                            y,
                            width,
                            clip.left(),
                            clip.top(),
                            clip.right(),
                            clip.bottom());
            return false;
        }
        for (int col = startCol; col < endCol; ++col) {
            TileKind& tileKind = tileKinds[row * numTileCols + col];
            if (tileKind != TileKind::kEmpty) {
                REPORTER_ASSERT(reporter,
                                false,
                                "[%s] %s (x:%d, y:%d, width:%d) overlaps another tile at "
                                "tile(%d,%d)",
                                testName,
                                type,
                                x,
                                y,
                                width,
                                col,
                                row);
                return false;
            }
            tileKind = kind;
        }
        return true;
    };
    for (const EndCaps::EndCap& cap : ends.caps()) {
        if (!markTiles(cap.fX, cap.fY, cap.fWidth, TileKind::kEndCap)) {
            return false;
        }
    }
    for (const WideTiles::WideTile& wide : wides.tiles()) {
        if (!markTiles(wide.fX, wide.fY, wide.fWidth, TileKind::kWide)) {
            return false;
        }
    }

    // Per-row prefix counts of the WideTiles and EndCaps, so that each span of constant winding can
    // be checked in constant time.
    std::vector<int> widePrefix(numTileCols + 1, 0);
    std::vector<int> endCapPrefix(numTileCols + 1, 0);

    // Verifies that the tiles overlapping pixels [startX, endX) of pixel row `py`, across which the
    // winding of subsample `k` is constant, are consistent with that winding.
    auto checkSpan = [&](int row, int py, int k, int startX, int endX, int winding) {
        if (startX >= endX) {
            return true;
        }
        const int startCol = startX / kTileWidth;
        const int endCol = (endX - 1) / kTileWidth + 1;
        const int numWides = widePrefix[endCol] - widePrefix[startCol];
        const int numEndCaps = endCapPrefix[endCol] - endCapPrefix[startCol];
        bool inside = isEvenOdd ? (winding & 1) != 0 : winding != 0;
        if (isInverse) {
            inside = !inside;
        }
        if (inside ? numWides + numEndCaps == endCol - startCol : numWides == 0) {
            return true;
        }

        const TileKind expectedKind = inside ? TileKind::kWide : TileKind::kEmpty;
        for (int col = startCol; col < endCol; ++col) {
            const TileKind kind = tileKinds[row * numTileCols + col];
            if (kind != TileKind::kEndCap && kind != expectedKind) {
                REPORTER_ASSERT(reporter,
                                false,
                                "[%s] tile(%d,%d) is %s, but subsample %d of pixel(%d,%d) is %s "
                                "the path (winding %d)",
                                testName,
                                col,
                                row,
                                kind == TileKind::kWide ? "a WideTile" : "empty",
                                k,
                                std::max(startX, col * kTileWidth),
                                py,
                                inside ? "inside" : "outside",
                                winding);
                return false;
            }
        }
        SkDEBUGFAIL("Mismatched tile counts without a mismatched tile");
        return false;
    };

    std::vector<LineHit> rowHits;
    std::vector<std::pair<float, int>> crossings;
    for (int row = minTileRow; row < numTileRows; ++row) {
        const TileKind* rowKinds = &tileKinds[row * numTileCols];
        for (int col = 0; col < numTileCols; ++col) {
            widePrefix[col + 1] = widePrefix[col] + (rowKinds[col] == TileKind::kWide ? 1 : 0);
            endCapPrefix[col + 1] =
                    endCapPrefix[col] + (rowKinds[col] == TileKind::kEndCap ? 1 : 0);
        }

        const std::vector<Line>& candidateLines = lineBuckets[row];
        if (candidateLines.empty()) {
            // Nothing crosses this row, so the winding is zero everywhere.
            if (!checkSpan(row,
                           row * kTileHeight,
                           /*k=*/0,
                           clip.left(),
                           clip.right(),
                           /*winding=*/0)) {
                return false;
            }
            continue;
        }

        const int endY = std::min<int>((row + 1) * kTileHeight, clip.bottom());
        for (int py = row * kTileHeight; py < endY; ++py) {
            collect_row_hits(py, candidateLines, &rowHits);
            for (int k = 0; k < 8; ++k) {
                crossings.clear();
                for (const LineHit& hit : rowHits) {
                    if (hit.dir[k] != 0) {
                        crossings.push_back({hit.x[k], hit.dir[k]});
                    }
                }
                std::sort(crossings.begin(), crossings.end());

                // Returns the first pixel whose subsample `k` is affected by a crossing at `x`,
                // which exactly matches the `vPx >= th.x` test of the EndCap validation. Crossings
                // left of the clip affect its leftmost pixel.
                const float sx = subX[k];
                auto firstAffectedPixel = [&](float x) {
                    // Clamp before converting, since crossings may lie far outside of the clip.
                    int px = static_cast<int>(std::clamp(std::ceil(x - sx),
                                                         static_cast<float>(clip.left()),
                                                         static_cast<float>(clip.right())));
                    while (px > clip.left() && static_cast<float>(px - 1) + sx >= x) {
                        --px;
                    }
                    while (px < clip.right() && static_cast<float>(px) + sx < x) {
                        ++px;
                    }
                    return px;
                };

                int winding = 0;
                int spanStart = clip.left();
                for (size_t i = 0; i < crossings.size();) {
                    const int px = firstAffectedPixel(crossings[i].first);
                    if (!checkSpan(row, py, k, spanStart, px, winding)) {
                        return false;
                    }
                    while (i < crossings.size() && firstAffectedPixel(crossings[i].first) <= px) {
                        winding += crossings[i].second;
                        ++i;
                    }
                    spanStart = std::max(spanStart, px);
                }
                if (!checkSpan(row, py, k, spanStart, clip.right(), winding)) {
                    return false;
                }
            }
        }
    }
    return true;
}

}  // namespace

template <uint16_t kTileWidth, uint16_t kTileHeight>
void FastValidator<kTileWidth, kTileHeight>::RunScalarWinding(
        const Tiles<kTileWidth, kTileHeight>& tileContainer,
        WideTiles* wides,
        EndCaps* ends,
        AlphaAtlasManager* atlasManager,
        SkPathFillType fillType,
        const Polyline& polyline,
        const SparseStripConfig::LUTArray& maskLut,
        bool isCulled,
        const WindingHistogram& windingHistogram,
        const SkIRect& clipRect,
        MsaaExactMaskObserver observer) {
    MakeStrips::MsaaScalar<kTileWidth, kTileHeight>(tileContainer,
                                                    wides,
                                                    ends,
                                                    atlasManager,
                                                    fillType,
                                                    polyline,
                                                    maskLut,
                                                    isCulled,
                                                    windingHistogram,
                                                    clipRect,
                                                    observer);
}

template <uint16_t kTileWidth, uint16_t kTileHeight>
void FastValidator<kTileWidth, kTileHeight>::RunSimdWinding(
        const Tiles<kTileWidth, kTileHeight>& tileContainer,
        WideTiles* wides,
        EndCaps* ends,
        AlphaAtlasManager* atlasManager,
        SkPathFillType fillType,
        const Polyline& polyline,
        const SparseStripConfig::LUTArray& maskLut,
        bool isCulled,
        const WindingHistogram& windingHistogram,
        const SkIRect& clipRect,
        MsaaExactMaskObserver observer) {
    MakeStrips::MsaaSimd<kTileWidth, kTileHeight>(tileContainer,
                                                  wides,
                                                  ends,
                                                  atlasManager,
                                                  fillType,
                                                  polyline,
                                                  maskLut,
                                                  isCulled,
                                                  windingHistogram,
                                                  clipRect,
                                                  observer);
}

template <uint16_t kTileWidth, uint16_t kTileHeight>
bool FastValidator<kTileWidth, kTileHeight>::ValidateStripOutput(
        skiatest::Reporter* reporter,
        const SkPath& path,
        const Polyline& polyline,
        const Polyline& unculledPolyline,
        const Tiles<kTileWidth, kTileHeight>& tiler,
        const WideTiles& wides,
        const EndCaps& ends,
        const AlphaAtlasManager& atlasManager,
        const SkTDArray<uint8_t>& exactMasks,
        const SkIRect& clip,
        SkPathFillType fillType,
        const char* testName,
        std::array<uint32_t, 3>* minorErrorCount) {
    if (ends.empty() && !exactMasks.empty()) {
        REPORTER_ASSERT(reporter, false, "[%s] No endcaps but mask observer has data.", testName);
        return false;
    }

    static const skvx::float8 kSubX =
            (skvx::cast<float>(skvx::byte8::Load(kMsaaPattern<uint8_t>.data())) + 0.5f) / 8.0f;

    bool isEvenOdd = SkPathFillType_IsEvenOdd(fillType);
    bool isInverse = SkPathFillType_IsInverse(fillType);

    auto lineBuckets = build_tile_row_line_buckets<kTileHeight>(unculledPolyline, clip.bottom());

    int32_t maskIdx = 0;
    int cachedPy = -1;
    std::vector<LineHit> rowHits;

    for (const auto& cap : ends.caps()) {
        uint16_t spannedTiles = cap.fWidth / kTileWidth;
        uint16_t currX = cap.fX;
        uint16_t currY = cap.fY;
        int tileRowY = currY / kTileHeight;
        const auto& candidateLines = (tileRowY < static_cast<int>(lineBuckets.size()))
                                             ? lineBuckets[tileRowY]
                                             : std::vector<Line>();
        const uint8_t* pageData = atlasManager.getPageData(cap.fTexPage);
        int32_t capAlphaOffset = cap.fAlphaIndex;

        for (int32_t s = 0; s < spannedTiles; ++s) {
            uint16_t tileStartX = currX + s * kTileWidth;
            float tileMinX = static_cast<float>(tileStartX);
            float tileMaxX = static_cast<float>(tileStartX + kTileWidth);
            int32_t tileStartIdx = maskIdx;

            for (int32_t y = 0; y < kTileHeight; ++y) {
                int py = currY + y;
                if (py != cachedPy) {
                    collect_row_hits(py, candidateLines, &rowHits);
                    cachedPy = py;
                }

                // Partition hits for this tile of interest:
                // - hits entirely left of tile contribute to baseWinding
                // - hits crossing inside tile are kept in tileHits
                // - hits entirely right of tile are ignored
                skvx::int8 baseWinding(0);
                std::vector<LineHit> tileHits;
                for (const auto& hit : rowHits) {
                    auto isLeft = (hit.dir != 0) & (hit.x < tileMinX);
                    auto isRight = (hit.dir != 0) & (hit.x >= tileMaxX);
                    baseWinding += if_then_else(isLeft, hit.dir, skvx::int8(0));

                    auto inTile = (hit.dir != 0) & (!isLeft) & (!isRight);
                    if (any(inTile)) {
                        LineHit th;
                        th.x = hit.x;
                        th.dir = if_then_else(inTile, hit.dir, skvx::int8(0));
                        tileHits.push_back(th);
                    }
                }

                for (int32_t x = 0; x < kTileWidth; ++x) {
                    float px = static_cast<float>(tileStartX + x);
                    skvx::float8 vPx = px + kSubX;

                    skvx::int8 pixelWinding = baseWinding;
                    for (const auto& th : tileHits) {
                        pixelWinding += if_then_else(vPx >= th.x, th.dir, skvx::int8(0));
                    }

                    uint8_t expectedMask = 0;
                    int expectedSamples = 0;
                    for (int k = 0; k < 8; ++k) {
                        int w = pixelWinding[k];
                        bool inside = isEvenOdd ? ((w & 1) != 0) : (w != 0);
                        if (isInverse) {
                            inside = !inside;
                        }
                        if (inside) {
                            expectedSamples++;
                            expectedMask |= (1 << k);
                        }
                    }

                    uint8_t actualMask = (maskIdx < exactMasks.size()) ? exactMasks[maskIdx] : 0;
                    int32_t alphaOffset = capAlphaOffset + (s * kTileHeight + y) * kTileWidth + x;
                    uint8_t actualAlpha = pageData ? pageData[alphaOffset] : 0;

                    int sampleDiff = 0;
                    int actualSamples = 0;
                    for (int k = 0; k < 8; ++k) {
                        if (actualMask & (1 << k)) {
                            actualSamples++;
                        }
                        if ((expectedMask & (1 << k)) != (actualMask & (1 << k))) {
                            sampleDiff++;
                        }
                    }

                    uint8_t expectedAlphaFromMask =
                            static_cast<uint8_t>((actualSamples * 255 + 4) / 8);
                    if (actualAlpha != expectedAlphaFromMask) {
                        CoverageTestUtils::PrintCoverageDiagnostics(reporter,
                                                                    polyline,
                                                                    tiler,
                                                                    tileStartX,
                                                                    currY,
                                                                    exactMasks,
                                                                    tileStartIdx);
                        REPORTER_ASSERT(
                                reporter,
                                false,
                                "[%s] Alpha Reduction Mismatch at tile(%d,%d) pixel(%d,%d). "
                                "Observer tracked %d active bits (expected alpha %d), "
                                "but AlphaAtlas output was %d.",
                                testName,
                                tileStartX / kTileWidth,
                                currY / kTileHeight,
                                x,
                                y,
                                actualSamples,
                                expectedAlphaFromMask,
                                actualAlpha);
                        return false;
                    }

                    // Pixels outside of the clip are never drawn, and the geometry that only
                    // affects them may have been culled, so only their alpha reduction is checked.
                    const bool inClip = clip.contains(tileStartX + x, py);
                    if (inClip && sampleDiff > 3) {
                        CoverageTestUtils::PrintCoverageDiagnostics(reporter,
                                                                    polyline,
                                                                    tiler,
                                                                    tileStartX,
                                                                    currY,
                                                                    exactMasks,
                                                                    tileStartIdx);
                        REPORTER_ASSERT(reporter,
                                        false,
                                        "[%s] Fail at tile(%d,%d). Exp %d, Got %d (alpha %d)",
                                        testName,
                                        tileStartX / kTileWidth,
                                        currY / kTileHeight,
                                        expectedSamples,
                                        actualSamples,
                                        actualAlpha);
                        return false;
                    } else if (inClip && sampleDiff > 0) {
                        if (minorErrorCount) {
                            (*minorErrorCount)[sampleDiff - 1]++;
                        }
                    }

                    maskIdx++;
                }
            }
        }
    }

    bool bufferSizeMatch = (maskIdx == exactMasks.size());
    REPORTER_ASSERT(reporter,
                    bufferSizeMatch,
                    "[%s] Checked %d mask/alpha bytes but observer size is %d",
                    testName,
                    maskIdx,
                    exactMasks.size());
    if (!bufferSizeMatch) {
        return false;
    }

    return validate_solid_tiles<kTileWidth, kTileHeight>(
            reporter, lineBuckets, wides, ends, kSubX, clip, isEvenOdd, isInverse, testName);
}

template <uint16_t kTileWidth, uint16_t kTileHeight>
bool FastValidator<kTileWidth, kTileHeight>::ValidatePath(
        skiatest::Reporter* reporter,
        Recorder* recorder,
        const SkPath& path,
        const SkMatrix& ctm,
        uint16_t viewportWidth,
        uint16_t viewportHeight,
        const char* testName,
        const SparseStripConfig::LUTArray& maskLut,
        StripFunc stripFunc,
        std::array<uint32_t, 3>* minorErrorCount) {
    return ValidatePath(reporter,
                        recorder,
                        path,
                        ctm,
                        SkIRect::MakeWH(viewportWidth, viewportHeight),
                        testName,
                        maskLut,
                        stripFunc,
                        minorErrorCount);
}

template <uint16_t kTileWidth, uint16_t kTileHeight>
bool FastValidator<kTileWidth, kTileHeight>::ValidatePath(
        skiatest::Reporter* reporter,
        Recorder* recorder,
        const SkPath& path,
        const SkMatrix& ctm,
        const SkIRect& clipRect,
        const char* testName,
        const SparseStripConfig::LUTArray& maskLut,
        StripFunc stripFunc,
        std::array<uint32_t, 3>* minorErrorCount) {
    if (path.isEmpty() || !path.isFinite()) {
        return true;
    }

    if (clipRect.isEmpty() || clipRect.fLeft < 0 || clipRect.fTop < 0 ||
        clipRect.fLeft % kTileWidth != 0 || clipRect.fTop % kTileHeight != 0) {
        REPORTER_ASSERT(reporter,
                        false,
                        "[%s] Clip (l:%d, t:%d, r:%d, b:%d) must be non-empty, with a tile aligned "
                        "left and top",
                        testName,
                        clipRect.fLeft,
                        clipRect.fTop,
                        clipRect.fRight,
                        clipRect.fBottom);
        return false;
    }

    Flatten flattener;

    // 1. Unculled ground-truth polyline (computes true topology without culling)
    Polyline unculledPolyline;
    flattener.processPathsSimdTest(path, ctm, clipRect, &unculledPolyline);

    // 2. Production culled polyline for the pipeline under test
    Polyline testPolyline;
    flattener.processPaths<FlattenMode::kSimd>(path, ctm, clipRect, &testPolyline);

    // Like StripGenerator's, the histogram is indexed by the tile rows of the device, so it must
    // cover every row down to the bottom of the clip.
    uint16_t numTileRows = (clipRect.bottom() + kTileHeight - 1) / kTileHeight;
    WindingHistogram windingHistogram(numTileRows);
    windingHistogram.resize(numTileRows);
    windingHistogram.clear();

    Tiles<kTileWidth, kTileHeight> tiler;
    bool isCulled = tiler.makeTilesMSAA(testPolyline, clipRect, &windingHistogram);
    tiler.sortTiles();

    WideTiles wides;
    EndCaps ends;
    AlphaAtlasManager atlasManager(recorder);
    SkTDArray<uint8_t> exactMasks;

    auto observer = [&](uint8_t exactMask, skvx::int8) { exactMasks.push_back(exactMask); };

    if (stripFunc) {
        stripFunc(tiler,
                  &wides,
                  &ends,
                  &atlasManager,
                  path.getFillType(),
                  testPolyline,
                  maskLut,
                  isCulled,
                  windingHistogram,
                  clipRect,
                  observer);
    } else {
        RunSimdWinding(tiler,
                       &wides,
                       &ends,
                       &atlasManager,
                       path.getFillType(),
                       testPolyline,
                       maskLut,
                       isCulled,
                       windingHistogram,
                       clipRect,
                       observer);
    }

    return ValidateStripOutput(reporter,
                               path,
                               testPolyline,
                               unculledPolyline,
                               tiler,
                               wides,
                               ends,
                               atlasManager,
                               exactMasks,
                               clipRect,
                               path.getFillType(),
                               testName,
                               minorErrorCount);
}

// Explicit template instantiations
template class FastValidator<4, 4>;
template class FastValidator<8, 8>;

}  // namespace skgpu::graphite
