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

#include "include/private/SkTDArray.h"
#include "src/core/SkVx.h"
#include "src/gpu/graphite/sparse_strips/Polyline.h"
#include "src/gpu/graphite/sparse_strips/SparseStripsTypes.h"
#include "src/gpu/graphite/sparse_strips/Strip.h"
#include "src/gpu/graphite/sparse_strips/Tiler.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <limits>

namespace skgpu::graphite {

template <uint16_t kTileWidth, uint16_t kTileHeight, bool kIsWinding>
class StripProcessorSimd {
public:
    // Type aliases for convenient handling of the simd registers. In addition to SIMD, we use SWAR
    // to pack subsample winding 4 to 1 u32, each subsample being alloted 1 byte of memory, e.g.
    // -128 / 127 of winding. So a quality of 8 subsamples per pixel (MSAAx8) requires u32x2
    // (SwarPixel) or u8x8 (PixelBytes). Note, currently, this class is hardcoded to MSAAx8.
    // Although it would be fairly straight forward to make this class handle a variable subsample
    // count, we do not anticipate running above MSAAx8 on the CPU, due to a lack of throughput.
    // (Many devices do not 256-wide SIMD, doubling the subsample count doubles memory requirements,
    // etc.)
    static_assert(Strip::kNumSubSamples == 8);
    using SwarPixel = skvx::Vec<2, uint32_t>;
    using PixelBytes = skvx::Vec<8, uint8_t>;

    StripProcessorSimd(SkTDArray<Strip>* stripBuf,
                       SkTDArray<uint8_t>* alphaBuf,
                       bool isInverse,
                       const Polyline& polyline,
                       const SkTDArray<uint8_t>& maskLut,
                       int32_t initialAlphaIdx
#if defined(GPU_TEST_UTILS)
                       , MsaaExactMaskObserver observer
#endif
                       )
            : fCoarseWinding(0)
            , fStripBuf(stripBuf)
            , fAlphaBuf(alphaBuf)
            , fIsInverse(isInverse)
            , fPolyline(polyline)
            , fMaskLut(maskLut)
            , fLocalAlphaIdx(initialAlphaIdx)
#if defined(GPU_TEST_UTILS)
            , fObserver(observer)
#endif
    {
        this->clearWinding(kInitialWinding);
    }

    SK_ALWAYS_INLINE void clearWinding(uint32_t val) {
        SwarPixel* flatSubsampleWinding = &fSubsampleWinding[0][0];

        if constexpr (kTileWidth % 8 == 0) {
            skvx::Vec<16, uint32_t> vec(val);
            for (int i = 0; i < kTilePixelCount; i += 8) {
                vec.store(flatSubsampleWinding + i);
            }
        } else if constexpr (kTileWidth % 4 == 0) {
            skvx::Vec<8, uint32_t> vec(val);
            for (int i = 0; i < kTilePixelCount; i += 4) {
                vec.store(flatSubsampleWinding + i);
            }
        } else {
            SwarPixel p = {val, val};
            for (int i = 0; i < kTilePixelCount; ++i) {
                flatSubsampleWinding[i] = p;
            }
        }
    }

    SK_ALWAYS_INLINE void clearWithCoarseWinding() {
        uint8_t windingByte;
        if constexpr (kIsWinding) {
            // Cast to i8 to sign extend before casting to u8, then apply SWAR bias to map -127/128
            // to 0/255.
            windingByte = 0x80 + static_cast<uint8_t>(static_cast<int8_t>(fCoarseWinding));
        } else {
            windingByte = (fCoarseWinding & 1) ? 1 : 0;
        }
        this->clearWinding(windingByte * 0x01010101u);
    }

    SK_ALWAYS_INLINE void clearWindingForNewRow() { this->clearWinding(kInitialWinding); }

    SK_ALWAYS_INLINE static bool ShouldFill(int32_t w) {
        if constexpr (kIsWinding) {
            return w != 0;
        } else {
            return (w & 1) != 0;
        }
    }

    SK_ALWAYS_INLINE int32_t coarseWinding() const { return fCoarseWinding; }
    SK_ALWAYS_INLINE void setCoarseWinding(int32_t val) { fCoarseWinding = val; }
    SK_ALWAYS_INLINE int32_t localAlphaIdx() const { return fLocalAlphaIdx; }

    // Convert the winding to alpha in row sized chunks. Technically, processChunk could be renamed
    // to processRow, but it is intended to be flexible, so that if the tile width were to exceed
    // the simd width, the row could be proccessed in serial chunks.
    SK_ALWAYS_INLINE void resolveWindingToAlpha() {
        uint8_t* tileAlphaBase = reserveAlphaBuffer();
        for (int32_t row = 0; row < kTileHeight; ++row) {
            if constexpr (kTileWidth % 8 == 0) {
                for (int32_t column = 0; column < kTileWidth; column += 8) {
                    this->processChunk<8>(row, column, tileAlphaBase);
                    tileAlphaBase += 8;
                }
            } else if constexpr (kTileWidth % 4 == 0) {
                for (int32_t column = 0; column < kTileWidth; column += 4) {
                    this->processChunk<4>(row, column, tileAlphaBase);
                    tileAlphaBase += 4;
                }
            }
        }
        fLocalAlphaIdx += kTilePixelCount;
    }

    SK_ALWAYS_INLINE void rasterizeLineToTile(const Tile& tile, std::array<SkPoint, 2> tileBounds) {
        Line line = fPolyline.getLine(tile.lineIdx());
        bool canonicalXDir = line.p1.fX >= line.p0.fX;
        bool canonicalYDir = line.p1.fY >= line.p0.fY;

        uint32_t windingBit = tile.coarseWinding() ? 1 : 0;
        if constexpr (kIsWinding) {
            fCoarseWinding += (canonicalYDir ? 1 : -1) * static_cast<int32_t>(windingBit);
        } else {
            fCoarseWinding ^= static_cast<int32_t>(windingBit);
        }

        // TODO (thomsmit): remove once culling lands
        // Cull lines that exist entirely to the left of the tile.
        float rightEdge = canonicalXDir ? line.p1.fX : line.p0.fX;
        if (rightEdge < 0.0f) {
            return;
        }

        float dx = line.p1.fX - line.p0.fX;
        float dy = line.p1.fY - line.p0.fY;
        float invDx = (std::abs(dx) <= Strip::kStripEpsilon) ? 0.0f : 1.0f / dx;
        float invDy = (std::abs(dy) <= Strip::kStripEpsilon) ? 0.0f : 1.0f / dy;
        float dxdy = dx * invDy;
        std::array<float, 4> derivs = {dx, dy, invDx, invDy};

        auto [clippedLine, topIsOnLeftEdge, botIsOnLeftEdge] =
                Tile::ClipToTile<kTileWidth, kTileHeight>(line,
                                                          tileBounds,
                                                          derivs,
                                                          tile.intersectionMask(),
                                                          canonicalXDir,
                                                          canonicalYDir);
        SkPoint pTop = clippedLine.p0;
        SkPoint pBot = clippedLine.p1;

        if (tile.hasLeftIntersection()) {
            float yEdge = (pTop.fX < pBot.fX) ? pTop.fY : pBot.fY;
            this->fillLeft(yEdge, canonicalXDir);
        }

        if (std::abs(dy) < Strip::kStripEpsilon && pTop.fY == std::floor(pTop.fY)) {
            return;
        }

        int32_t startY = static_cast<int32_t>(std::floor(pTop.fY));
        int32_t endY = static_cast<int32_t>(std::ceil(pBot.fY));
        if (startY < endY) {
            bool isOnlyRow = (startY == endY - 1);
            auto rowInt = FindRowIntersections(pTop, pBot, dxdy, startY, endY);
            LineStepParams stepParams = this->computeLineStepParams(pTop, pBot, dx, dy);

            // First, and possibly only row
            {
                float pTopY = pTop.fY;
                float pBotY = isOnlyRow ? pBot.fY : static_cast<float>(startY + 1);

                bool crossedTop = (pTopY == std::floor(pTopY));
                bool defaultInvert = !crossedTop && stepParams.fSortedXDir;

                uint8_t startMaskVal = 0xff;
                bool startInvert = topIsOnLeftEdge && !crossedTop;
                if (!topIsOnLeftEdge) {
                    startMaskVal = GetTruncationMask</*kIsStart=*/true>(pTopY,
                                                                        static_cast<float>(startY));
                }

                uint8_t endMaskVal = 0xff;
                if (isOnlyRow && !botIsOnLeftEdge) {
                    endMaskVal = GetTruncationMask</*kIsStart=*/false>(pBotY,
                                                                       static_cast<float>(startY));
                }

                bool leftInvert = stepParams.fSortedXDir ? startInvert : defaultInvert;
                bool rightInvert = stepParams.fSortedXDir ? defaultInvert : startInvert;

                uint8_t leftMask = stepParams.fSortedXDir ? startMaskVal : endMaskVal;
                uint8_t rightMask = stepParams.fSortedXDir ? endMaskVal : startMaskVal;

                this->processRowSpan(startY, leftMask, rightMask, leftInvert, defaultInvert,
                                     rightInvert, crossedTop, rowInt, stepParams, canonicalYDir);
            }

            // Middle rows
            for (int32_t row = startY + 1; row < endY - 1; ++row) {
                this->processRowSpan(row, /*leftMask=*/0xff, /*rightMask=*/0xff,
                                     /*leftInvert=*/false, /*midInvert=*/false,
                                     /*rightInvert=*/false, /*crossedTop=*/true, rowInt, stepParams,
                                     canonicalYDir);
            }

            // Bottom row, if it exists
            if (!isOnlyRow) {
                int32_t lastY = endY - 1;
                uint8_t endMaskLast = 0xff;
                if (!botIsOnLeftEdge) {
                    endMaskLast = GetTruncationMask</*kIsStart=*/false>(pBot.fY,
                                                                        static_cast<float>(lastY));
                }

                uint8_t leftMask = stepParams.fSortedXDir ? 0xff : endMaskLast;
                uint8_t rightMask = stepParams.fSortedXDir ? endMaskLast : 0xff;

                this->processRowSpan(lastY, leftMask, rightMask, /*leftInvert=*/false,
                                     /*midInvert=*/false, /*rightInvert=*/false,
                                     /*crossedTop=*/true, rowInt, stepParams, canonicalYDir);
            }
        }
    }

private:
    static constexpr int32_t kTilePixelCount = kTileWidth * kTileHeight;
    static constexpr uint32_t kInitialWinding = kIsWinding ? 0x80808080u : 0u;

    struct LineStepParams {
        const uint8_t* fMaskRowLut;
        int32_t fStepXFixed;
        int32_t fStepYFixed;
        int32_t fTBaseFixed;
        bool fSortedXDir;
    };

    template <int N>
    SK_ALWAYS_INLINE static void ApplyWinding(SwarPixel* target, uint32_t fillVal) {
        auto vSubsampleWinding = skvx::Vec<N, uint32_t>::Load(target);
        skvx::Vec<N, uint32_t> vFill(fillVal);
        if constexpr (kIsWinding) {
            auto windingBytes = sk_bit_cast<skvx::Vec<N * 4, uint8_t>>(vSubsampleWinding);
            auto fillBytes = sk_bit_cast<skvx::Vec<N * 4, uint8_t>>(vFill);
            vSubsampleWinding = sk_bit_cast<skvx::Vec<N, uint32_t>>(windingBytes + fillBytes);
        } else {
            vSubsampleWinding ^= vFill;
        }
        vSubsampleWinding.store(target);
    }

    // Evaluate the subsamples against the winding rule to determine which are "active" (covered).
    // For Even-Odd no processing is required. For the Non-Zero case, we compare subsample winding
    // against the empty SWAR mask. In SkVX, the result of !=, true, is ~0, so we mask away any
    // extraneous bits.
    template <typename VecT> static SK_ALWAYS_INLINE VecT GetActivesWide(VecT v) {
        using Vec8 = skvx::Vec<sizeof(VecT), uint8_t>;
        if constexpr (kIsWinding) {
            const Vec8 emptyBytes(0x80);
            Vec8 vecBytes = sk_bit_cast<skvx::Vec<sizeof(VecT), uint8_t>>(v);
            Vec8 cmp = (vecBytes != emptyBytes);
            return sk_bit_cast<VecT>(cmp) & VecT(0x01010101u);
        } else {
            SkASSERT(all(sk_bit_cast<Vec8>(v) <= 1));
            return v;
        }
    }

    SK_ALWAYS_INLINE uint8_t* reserveAlphaBuffer() {
        if (fAlphaBuf->size() + kTilePixelCount > fAlphaBuf->capacity()) {
            constexpr size_t kChunkSize = 4 * kTilePixelCount;
            fAlphaBuf->reserve(fAlphaBuf->capacity() + kChunkSize);
        }
        return fAlphaBuf->append(kTilePixelCount);
    }

#if defined(GPU_TEST_UTILS)
    SK_ALWAYS_INLINE void observeChunk(int32_t row, int32_t column, int32_t chunkSize) {
        for (int32_t x = column; x < column + chunkSize; ++x) {
            SwarPixel v = fSubsampleWinding[row][x];
            uint8_t exactMask = 0;
            uint32_t lo = v[0];
            uint32_t hi = v[1];
            for (int s = 0; s < 4; ++s) {
                int8_t sLo = static_cast<int8_t>(lo & 0xFF);
                int8_t sHi = static_cast<int8_t>(hi & 0xFF);
                if constexpr (kIsWinding) {
                    sLo = static_cast<int8_t>(static_cast<uint8_t>(sLo) - 0x80);
                    sHi = static_cast<int8_t>(static_cast<uint8_t>(sHi) - 0x80);
                }
                if (ShouldFill(sLo)) exactMask |= (1 << s);
                if (ShouldFill(sHi)) exactMask |= (1 << (s + 4));
                lo >>= 8;
                hi >>= 8;
            }
            if (fIsInverse) {
                exactMask = ~exactMask & ((1 << Strip::kNumSubSamples) - 1);
            }
            fObserver(exactMask);
        }
    }
#endif

    // Resolves the subsample windings of a chunk of pixels to their equivalent 8-bit alpha values:
    //
    //  1) GetActivesWide(): Evaluates the winding rule, returning a skvx::Vec of the same size
    //      where each byte lane contains 1 (active) or 0 (inactive).
    //  2) activeLo / activeHi: Splits the active masks into two separate 32-bit words, each
    //     containing 4 subsamples (one per byte lane).
    //  3) combinedBytes: Sums the two halves together. Each byte lane now holds a value of 0, 1,
    //     or 2.
    //  4) SWAR Horizontal Sum: Multiplying by 0x01010101u (which is 2^24 + 2^16 + 2^8 + 1)
    //     accumulates the sum of all 4 byte lanes into the highest byte. Given a 32-bit word
    //     [ A | B | C | D ], the multiplication expands across the lanes:
    //          Shifted by 0:  [ A | B | C | D ]
    //        + Shifted by 8:  [ B | C | D | 0 ]
    //        + Shifted by 16: [ C | D | 0 | 0 ]
    //        + Shifted by 24: [ D | 0 | 0 | 0 ]
    //     Summed together, the highest byte holds A + B + C + D. This can never overflow into
    //     neighboring lanes, since the maximum value per byte lane is 2.
    //  5) Shifting >> 24: Right-shifting the result isolates the final sum. This discards the lower
    //     accumulation bytes and moves the total subsample count into the lowest byte.
    //  6) Alpha Conversion: The total is multiplied by the maximum alpha value (255), summed by
    //     subsampleCount / 2 for rounding, and right-shifted by log2(subsampleCount). This keeps
    //     the entire conversion in integer math and avoids division.
    template <int kChunkSize>
    SK_ALWAYS_INLINE void processChunk(int32_t row,
                                       int32_t column,
                                       uint8_t* tileAlphaBase) {
        auto vSubsampleWinding =
                skvx::Vec<kChunkSize * 2, uint32_t>::Load(&fSubsampleWinding[row][column]);
        auto actives = GetActivesWide(vSubsampleWinding);

        skvx::Vec<kChunkSize, uint32_t> activeLo;
        skvx::Vec<kChunkSize, uint32_t> activeHi;
        if constexpr (kChunkSize == 8) {
            activeLo = skvx::shuffle<0, 2, 4, 6, 8, 10, 12, 14>(actives);
            activeHi = skvx::shuffle<1, 3, 5, 7, 9, 11, 13, 15>(actives);
        } else {
            activeLo = skvx::shuffle<0, 2, 4, 6>(actives);
            activeHi = skvx::shuffle<1, 3, 5, 7>(actives);
        }

        auto combinedBytes = activeLo + activeHi;
        skvx::Vec<kChunkSize, uint32_t> activeSamples = (combinedBytes * 0x01010101u) >> 24;
        const uint32_t invMask32 = fIsInverse ? 0xffffffff : 0;
        skvx::Vec<kChunkSize, uint32_t> alpha32 = ((activeSamples * 255 + 4) >> 3) ^ invMask32;
        skvx::cast<uint8_t>(alpha32).store(tileAlphaBase);
#if defined(GPU_TEST_UTILS)
        if (fObserver) {
            observeChunk(row, column, kChunkSize);
        }
#endif
    }

    SK_ALWAYS_INLINE static std::array<float, kTileHeight + 1> FindRowIntersections(
            SkPoint pTop, SkPoint pBot, float dxdy, int32_t startY, int32_t endY) {
        std::array<float, kTileHeight + 1> rowInt;
        skvx::float4 vPTopX(pTop.fX);
        skvx::float4 vPTopY(pTop.fY);
        skvx::float4 vDxDy(dxdy);
        skvx::float4 vBase(0.0f, 1.0f, 2.0f, 3.0f);

        int32_t height;
        if constexpr (kTileHeight > 4) {
            height = (endY + 3) / 4 * 4;
        } else {
            height = 4;
        }

        for (int32_t k = 0; k < height; k += 4) {
            skvx::float4 vGridY = skvx::float4(static_cast<float>(k)) + vBase;
            skvx::float4 vGridX = vPTopX + (vGridY - vPTopY) * vDxDy;
            vGridX.store(rowInt.data() + k);
        }

        rowInt[startY] = pTop.fX;
        rowInt[endY] = pBot.fX;
        return rowInt;
    }

    template<bool kIsStart>
    SK_ALWAYS_INLINE static uint8_t GetTruncationMask(float p, float row) {
        uint32_t shift = static_cast<uint32_t>(std::round(8.0f * (p - static_cast<float>(row))));
        if constexpr (kIsStart) {
            return static_cast<uint8_t>(0xff << shift);
        } else {
            return static_cast<uint8_t>(~(0xff << shift));
        }
    }

    SK_ALWAYS_INLINE LineStepParams computeLineStepParams(SkPoint pTop, SkPoint pBot,
                                                          float dx, float dy) const {
        float normalX = dy;
        float normalY = -dx;
        if (normalX < 0.0f) {
            normalX = -normalX;
            normalY = -normalY;
        }
        float D = normalX + std::abs(normalY);
        float invD = (D < Strip::kStripEpsilon) ? 0.0f : 1.0f / D;

        bool hasPositiveSlope = normalY <= 0.0f;
        float C = normalX * pTop.fX + normalY * pTop.fY;
        float s = std::abs(normalY) * invD;
        int lutRowOffset = std::clamp(
                static_cast<int>(std::floor(s * (Strip::kLutMaskHeight / 2))),
                0,
                (Strip::kLutMaskHeight / 2) - 1);
        int lutRow = hasPositiveSlope ? (lutRowOffset + Strip::kLutMaskHeight / 2) : lutRowOffset;

        // Unlike the scalar version, we simply return the raw pointer to the row in the LUT
        const uint8_t* maskRowLut = fMaskLut.data() + (lutRow * Strip::kLutMaskWidth);

        float stepX = normalX * invD;
        float stepY = normalY * invD;
        float tBase = ((hasPositiveSlope ? normalX : D) - C) * invD;

        // We use 16.16 fixed-point arithmetic to avoid floating-point math and conversions inside
        // the inner loops. A 16.16 fixed-point number uses a 32-bit integer where:
        //   - The upper 16 bits represent the integer part.
        //   - The lower 16 bits represent the fractional part.
        //
        // Encoding: value_fixed = round(x * 65536)
        // Decoding (floor): integer_part = value_fixed >> 16
        //
        // In addition to the 16.16 representation (scaled by 65536), we scale by the LUT's width
        // (64.0) so that extracting the LUT column index `u = floor(t * 64)` can be done using a
        // simple bit-shift: `u = clamp(tFixed >> 16, 0, 63)`.
        //
        // Note: We use direct static_cast conversions to int32_t instead of calling SkFloatToFixed
        // because the step and base variables are guaranteed to neither overflow or underflow, so
        // they don't require saturation checks.
        constexpr float kFixedMult = 64.0f * 65536.0f;
        int32_t stepXFixed = static_cast<int32_t>(stepX * kFixedMult);
        int32_t stepYFixed = static_cast<int32_t>(stepY * kFixedMult);
        int32_t tBaseFixed = static_cast<int32_t>(tBase * kFixedMult);

        bool sortedXDir = pTop.fX <= pBot.fX;

        return {
            maskRowLut,
            stepXFixed,
            stepYFixed,
            tBaseFixed,
            sortedXDir
        };
    }

    SK_ALWAYS_INLINE void fillLeft(float yEdge, bool canonicalXDir) {
        uint8_t fillByte;
        if constexpr (kIsWinding) {
            fillByte = canonicalXDir ? 0xFF : 1;
        } else {
            fillByte = 1;
        }

        uint32_t fill32 = fillByte * 0x01010101u;
        int32_t startY = static_cast<int32_t>(std::ceil(yEdge));
        for (int32_t row = startY; row < kTileHeight; ++row) {
            if constexpr (kTileWidth % 8 == 0) {
                for (int32_t column = 0; column < kTileWidth; column += 8) {
                    ApplyWinding<16>(&fSubsampleWinding[row][column], fill32);
                }
            } else if constexpr (kTileWidth % 4 == 0) {
                for (int32_t column = 0; column < kTileWidth; column += 4) {
                    ApplyWinding<8>(&fSubsampleWinding[row][column], fill32);
                }
            }
        }
    }

    template <bool kIsEdgePixel>
    SK_ALWAYS_INLINE void processPixel(SwarPixel* pixel,
                                       uint8_t truncationMask,
                                       const PixelBytes& pInvert,
                                       int32_t tFixed,
                                       const uint8_t* maskRowLut,
                                       bool canonicalYDir) {
        // Shift right by 16 to extract the integer LUT column index `u = floor(t * 64)`.
        int column = std::clamp(tFixed >> 16, 0, Strip::kLutMaskWidthExcl);
        uint8_t maskVal = maskRowLut[column];

        // Apply the truncation mask if we're one of the candidate pixels.
        if constexpr (kIsEdgePixel) {
            maskVal &= truncationMask;
        }

    /*
     * Convert 1 byte of packed coverage bits (maskVal) into 8 separate SIMD byte lanes.
     * E.g., maskVal = 0b10100011:
     *
     * 1) Splat maskVal into all 8 lanes:
     *    [   L0    |    L1    |    L2    |    L3    |    L4    |    L5    |    L6    |   L7    ]
     *    [10100011 | 10100011 | 10100011 | 10100011 | 10100011 | 10100011 | 10100011 | 10100011]
     *
     * 2) Bitwise AND with vBit (2^0, 2^1, ..., 2^7) to isolate bit k in lane k:
     *  & [00000001 | 00000010 | 00000100 | 00001000 | 00010000 | 00100000 | 01000000 | 10000000]
     *    ---------------------------------------------------------------------------------------
     *    [00000001 | 00000010 | 00000000 | 00000000 | 00000000 | 00100000 | 00000000 | 10000000]
     *
     * 3) In SkVX, Vector comparison of != 0 yields ~0 for true (SkVx.h:L316-L318,L357-359); this is
     *    then negated to produce the correct winding across the lanes:
     * != 0:   [  0xFF   |  0xFF   |  0x00   |  0x00   |  0x00   |  0xFF   |  0x00   |  0xFF   ]
     * Unary -:[  0x01   |  0x01   |  0x00   |  0x00   |  0x00   |  0x01   |  0x00   |  0x01   ]
     *         (+1 for covered lanes, 0x00 for uncovered)
     *
     * WARNING: relies on pcmpeqb behavior for 3! If this is not true, this will fail.
     */
        const PixelBytes vBit{1, 2, 4, 8, 16, 32, 64, 128};
        PixelBytes pRes = -((PixelBytes(maskVal) & vBit) != 0);
        PixelBytes pSubsampleWinding = sk_bit_cast<PixelBytes>(*pixel);

        if constexpr (kIsWinding) {
            pRes -= pInvert;
            if (canonicalYDir) {
                pSubsampleWinding += pRes;
            } else {
                pSubsampleWinding -= pRes;
            }
        } else {
            pRes ^= pInvert;
            pSubsampleWinding ^= pRes;
        }

        (*pixel) = sk_bit_cast<SwarPixel>(pSubsampleWinding);
    }

    // The inversion masks could maybe be moved into templating, but for now simply expose them
    // as function arguments and rely on the compiler's DCE to optimize them.
    SK_ALWAYS_INLINE void processRowSpan(int32_t row,
                                         uint8_t leftMask, uint8_t rightMask,
                                         bool leftInvert, bool midInvert, bool rightInvert,
                                         bool crossedTop,
                                         const std::array<float, kTileHeight + 1>& rowInt,
                                         const LineStepParams& params,
                                         bool canonicalYDir) {
        float pTopX = rowInt[row];
        float pBotX = rowInt[row + 1];

        float xMin = std::fmin(pTopX, pBotX);
        float xMax = std::fmax(pTopX, pBotX);
        int32_t xStart = std::clamp(static_cast<int32_t>(std::floor(xMin)), 0, kTileWidth - 1);
        int32_t xEnd = std::clamp(static_cast<int32_t>(std::floor(xMax)), 0, kTileWidth - 1);

        // Compute the initial translation parameter `tFixed` in 16.16 fixed-point format
        // (pre-scaled by 64 * 65536) at the starting pixel (xStart, row) of the span using:
        // tFixed = tBaseFixed + stepYFixed * row + stepXFixed * xStart
        int32_t tFixed =
                params.fTBaseFixed + (params.fStepYFixed * row) + (params.fStepXFixed * xStart);
        SwarPixel* rowSubsampleWindings = fSubsampleWinding[row];

        PixelBytes pMidInvert(midInvert ? 1 : 0);

        if (xStart == xEnd) {
            uint8_t combinedMask = leftMask & rightMask;
            processPixel</*kIsEdgePixel=*/true>(&rowSubsampleWindings[xStart], combinedMask,
                                                PixelBytes(leftInvert ? 1 : 0), tFixed,
                                                params.fMaskRowLut, canonicalYDir);
            tFixed += params.fStepXFixed;
        } else {
            processPixel</*kIsEdgePixel=*/true>(&rowSubsampleWindings[xStart], leftMask,
                                                PixelBytes(leftInvert ? 1 : 0), tFixed,
                                                params.fMaskRowLut, canonicalYDir);
            tFixed += params.fStepXFixed;

            for (int32_t column = xStart + 1; column < xEnd; ++column) {
                processPixel</*kIsEdgePixel=*/false>(&rowSubsampleWindings[column], 0, pMidInvert,
                                                     tFixed, params.fMaskRowLut, canonicalYDir);
                tFixed += params.fStepXFixed;
            }

            processPixel</*kIsEdgePixel=*/true>(&rowSubsampleWindings[xEnd], rightMask,
                                                PixelBytes(rightInvert ? 1 : 0), tFixed,
                                                params.fMaskRowLut, canonicalYDir);
            tFixed += params.fStepXFixed;
        }

        if (crossedTop) {
            uint8_t fillByte;
            if constexpr (kIsWinding) {
                fillByte = canonicalYDir ? 1 : 0xFF;
            } else {
                fillByte = 1;
            }

            int32_t column = xEnd + 1;
            uint32_t fill32 = fillByte * 0x01010101u;
            if constexpr (kTileWidth >= 8) {
                while (column + 8 <= kTileWidth) {
                    ApplyWinding<16>(&fSubsampleWinding[row][column], fill32);
                    column += 8;
                }
            } else if constexpr (kTileWidth >= 4) {
                while (column + 4 <= kTileWidth) {
                    ApplyWinding<8>(&fSubsampleWinding[row][column], fill32);
                    column += 4;
                }
            }

            const PixelBytes pFill(fillByte);
            for (; column < kTileWidth; ++column) {
                PixelBytes pSubsampleWinding =
                        sk_bit_cast<PixelBytes>(fSubsampleWinding[row][column]);
                if constexpr (kIsWinding) {
                    pSubsampleWinding += pFill;
                } else {
                    pSubsampleWinding ^= pFill;
                }
                fSubsampleWinding[row][column] = sk_bit_cast<SwarPixel>(pSubsampleWinding);
            }
        }
    }

    SwarPixel fSubsampleWinding[kTileHeight][kTileWidth];
    int32_t fCoarseWinding;
    SkTDArray<Strip>* fStripBuf;
    SkTDArray<uint8_t>* fAlphaBuf;
    bool fIsInverse;
    const Polyline& fPolyline;
    const SkTDArray<uint8_t>& fMaskLut;
    int32_t fLocalAlphaIdx;
#if defined(GPU_TEST_UTILS)
    MsaaExactMaskObserver fObserver;
#endif
};

}  // namespace skgpu::graphite

#endif  // skgpu_graphite_sparse_strips_StripProcessorSimd_DEFINED
