/*
 * Copyright 2022 Rive
 */

#include "rive/pls/pls_renderer.hpp"

#include "gr_inner_fan_triangulator.hpp"
#include "path_utils.hpp"
#include "pls_paint.hpp"
#include "pls_path.hpp"
#include "rive/math/math_types.hpp"
#include "rive/math/simd.hpp"
#include "rive/math/wangs_formula.hpp"

namespace rive::pls
{
constexpr static int kNumSegmentsInMiterOrBevelJoin = 5;

PLSRenderer::PLSRenderer(PLSRenderContext* context) : m_context(context) {}

PLSRenderer::~PLSRenderer() {}

void PLSRenderer::save()
{
    // Copy the matrix before pushing, in case the vector grows and invalidates the reference.
    Mat2D matrixCopy = m_stack.back().matrix;
    m_stack.emplace_back(matrixCopy, m_clipStack.size());
}

void PLSRenderer::restore()
{
    assert(!m_stack.empty());
    assert(m_clipStack.size() >= m_stack.back().clipStackHeight);
    m_clipStack.resize(m_stack.back().clipStackHeight);
    if (m_clipStack.empty())
    {
        m_hasArtboardClipCandidate = false;
    }
    m_stack.pop_back();
}

void PLSRenderer::transform(const Mat2D& matrix)
{
    m_stack.back().matrix = m_stack.back().matrix * matrix;
}

bool PLSRenderer::applyClip(uint32_t* clipID)
{
    if (m_clipStack.empty())
    {
        *clipID = 0;
        return true;
    }

    // For now, only apply the final element of the clip stack.
    ClipElement& clip = m_clipStack.back();
    // Ignore the first clip for now if it looks like an artboard clip.
    if (m_clipStack.size() == 1 && m_hasArtboardClipCandidate)
    {
        *clipID = 0;
        return true;
    }

    if (clip.clipID == 0)
    {
        // This clip element doesn't have an ID yet. Assign one.
        clip.clipID = m_context->generateClipID();
        if (clip.clipID == 0)
        {
            return false; // The context is out of clip IDs. We will flush and try again.
        }
    }

    if (m_context->getClipContentID() != clip.clipID)
    {
        // The clip buffer does not contain the current clip stack. Update it.
        m_pathBatch.emplace_back(&clip.matrix,
                                 &clip.path,
                                 clip.pathBounds,
                                 clip.fillRule,
                                 clip.clipID);
        m_context->setClipContentID(clip.clipID);
    }
    assert(clip.clipID != 0);
    *clipID = clip.clipID;
    return true;
}

void PLSRenderer::drawPath(RenderPath* renderPath, RenderPaint* renderPaint)
{
    PLSPath* path = static_cast<PLSPath*>(renderPath);
    PLSPaint* paint = static_cast<PLSPaint*>(renderPaint);

    bool stroked = paint->getIsStroked();
    if (stroked && m_context->frameDescriptor().strokesDisabled)
    {
        return;
    }
    if (!stroked && m_context->frameDescriptor().fillsDisabled)
    {
        return;
    }

    // A stroke width of zero means a path is filled in PLS.
    if (stroked && paint->getThickness() <= 0)
    {
        return;
    }

    // Make (up to) two attempts to draw the path plus any necessary clip updates in a single batch.
    // If the first attempt fails, flush to make room and try again.
    for (size_t i = 0; i < 2; ++i)
    {
        m_pathBatch.clear();
        uint32_t clipID;
        if (!applyClip(&clipID))
        {
            intermediateFlush();
            continue;
        }
        m_pathBatch.emplace_back(&m_stack.back().matrix,
                                 &path->getRawPath(),
                                 path->getBounds(),
                                 path->getFillRule(),
                                 clipID);
        if (!pushInternalPathBatch(paint))
        {
            intermediateFlush();
            continue;
        }
        return;
    }

    fprintf(
        stderr,
        "PLSRenderer::drawPath failed. The path and/or clip stack and/or paint are too complex.\n");
}

void PLSRenderer::clipPath(RenderPath* renderPath)
{
    PLSPath* path = static_cast<PLSPath*>(renderPath);
    // If the first clip in the stack is an axis-aligned rectangle, assume it's the artboard clip.
    if (m_clipStack.empty())
    {
        m_hasArtboardClipCandidate = IsAABB(path->getRawPath());
    }
    m_clipStack.push_back(
        {m_stack.back().matrix, path->getRawPath(), path->getBounds(), path->getFillRule(), 0});
}

void PLSRenderer::drawImage(const RenderImage*, BlendMode, float opacity) {}

void PLSRenderer::drawImageMesh(const RenderImage*,
                                rcp<RenderBuffer> vertices_f32,
                                rcp<RenderBuffer> uvCoords_f32,
                                rcp<RenderBuffer> indices_u16,
                                BlendMode,
                                float opacity)
{}

namespace
{
constexpr static int kStrokeStyleFlag = 8;
constexpr static int kRoundJoinStyleFlag = kStrokeStyleFlag << 1;
RIVE_ALWAYS_INLINE constexpr int style_flags(bool stroked, bool roundJoinStroked)
{
    int styleFlags = (stroked << 3) | (roundJoinStroked << 4);
    assert(bool(styleFlags & kStrokeStyleFlag) == stroked);
    assert(bool(styleFlags & kRoundJoinStyleFlag) == roundJoinStroked);
    return styleFlags;
}

// Switching on a StyledVerb reduces "if (stroked)" branching and makes the code cleaner.
enum class StyledVerb
{
    filledMove = static_cast<int>(PathVerb::move),
    strokedMove = kStrokeStyleFlag | static_cast<int>(PathVerb::move),
    roundJoinStrokedMove =
        kStrokeStyleFlag | kRoundJoinStyleFlag | static_cast<int>(PathVerb::move),

    filledLine = static_cast<int>(PathVerb::line),
    strokedLine = kStrokeStyleFlag | static_cast<int>(PathVerb::line),
    roundJoinStrokedLine =
        kStrokeStyleFlag | kRoundJoinStyleFlag | static_cast<int>(PathVerb::line),

    filledQuad = static_cast<int>(PathVerb::quad),
    strokedQuad = kStrokeStyleFlag | static_cast<int>(PathVerb::quad),
    roundJoinStrokedQuad =
        kStrokeStyleFlag | kRoundJoinStyleFlag | static_cast<int>(PathVerb::quad),

    filledCubic = static_cast<int>(PathVerb::cubic),
    strokedCubic = kStrokeStyleFlag | static_cast<int>(PathVerb::cubic),
    roundJoinStrokedCubic =
        kStrokeStyleFlag | kRoundJoinStyleFlag | static_cast<int>(PathVerb::cubic),

    filledClose = static_cast<int>(PathVerb::close),
    strokedClose = kStrokeStyleFlag | static_cast<int>(PathVerb::close),
    roundJoinStrokedClose =
        kStrokeStyleFlag | kRoundJoinStyleFlag | static_cast<int>(PathVerb::close),
};
RIVE_ALWAYS_INLINE constexpr StyledVerb styled_verb(PathVerb verb, int styleFlags)
{
    return static_cast<StyledVerb>(styleFlags | static_cast<int>(verb));
}

// When chopping strokes, switching on a "chop_key" reduces "if (areCusps)" branching and makes the
// code cleaner.
RIVE_ALWAYS_INLINE constexpr uint8_t chop_key(bool areCusps, uint8_t numChops)
{
    return (numChops << 1) | static_cast<uint8_t>(areCusps);
}
RIVE_ALWAYS_INLINE constexpr uint8_t cusp_chop_key(uint8_t n) { return chop_key(true, n); }
RIVE_ALWAYS_INLINE constexpr uint8_t simple_chop_key(uint8_t n) { return chop_key(false, n); }

// Produces a cubic equivalent to the given line, for which Wang's formula also returns 1.
RIVE_ALWAYS_INLINE std::array<Vec2D, 4> convert_line_to_cubic(const Vec2D line[2])
{
    float4 endPts = simd::load4f(line);
    float4 controlPts = simd::mix(endPts, endPts.zwxy, float4(1 / 3.f));
    std::array<Vec2D, 4> cubic;
    cubic[0] = line[0];
    simd::store(&cubic[1], controlPts);
    cubic[3] = line[1];
    return cubic;
}
RIVE_ALWAYS_INLINE std::array<Vec2D, 4> convert_line_to_cubic(Vec2D p0, Vec2D p1)
{
    Vec2D line[2] = {p0, p1};
    return convert_line_to_cubic(line);
}

// Finds the tangents of the curve at T=0 and T=1 respectively.
RIVE_ALWAYS_INLINE Vec2D find_cubic_tan0(const Vec2D p[4])
{
    Vec2D tan0 = (p[0] != p[1] ? p[1] : p[1] != p[2] ? p[2] : p[3]) - p[0];
    // RawPath should have discarded empty cubics, and FindCubicConvex180Chops should have enough
    // slop to not produce empty chops.
    assert((tan0 != Vec2D{0, 0}));
    return tan0;
}
RIVE_ALWAYS_INLINE Vec2D find_cubic_tan1(const Vec2D p[4])
{
    Vec2D tan1 = p[3] - (p[3] != p[2] ? p[2] : p[2] != p[1] ? p[1] : p[0]);
    // RawPath should have discarded empty cubics, and FindCubicConvex180Chops should have enough
    // slop to not produce empty chops.
    assert((tan1 != Vec2D{0, 0}));
    return tan1;
}
RIVE_ALWAYS_INLINE void find_cubic_tangents(const Vec2D p[4], Vec2D tangents[2])
{
    tangents[0] = find_cubic_tan0(p);
    tangents[1] = find_cubic_tan1(p);
}

// Chops a cubic into 2 * n + 1 segments, surrounding each cusp. The resulting cubics will be
// visually equivalent to the original when stroked, but the cusp won't have artifacts when rendered
// using the parametric/polar sorting algorithm.
//
// The size of dst[] must be 6 * n + 4 Vec2Ds.
static void chop_cubic_around_cusps(const Vec2D p[4],
                                    Vec2D dst[/*6 * n + 4*/],
                                    const float cuspT[],
                                    int n,
                                    float matrixMaxScale)
{
    float t[4];
    assert(n * 2 <= std::size(t));
    // Generate chop points straddling each cusp with padding. This creates buffer space around the
    // cusp that protects against fp32 precision issues.
    for (int i = 0; i < n; ++i)
    {
        // If the cusps are extremely close together, don't allow the straddle points to cross.
        float minT = i == 0 ? 0.f : (cuspT[i - 1] + cuspT[i]) * .5f;
        float maxT = i + 1 == n ? 1.f : (cuspT[i + 1] + cuspT[i]) * .5f;
        t[i * 2 + 0] = std::max(cuspT[i] - math::EPSILON, minT);
        t[i * 2 + 1] = std::min(cuspT[i] + math::EPSILON, maxT);
    }
    pathutils::ChopCubicAt(p, dst, t, n * 2);
    for (int i = 0; i < n; ++i)
    {
        // Find the three chops at this cusp.
        Vec2D* chops = dst + i * 6;
        // Correct the chops to fall on the actual cusp point.
        Vec2D cusp = pathutils::EvalCubicAt(p, cuspT[i]);
        chops[3] = chops[6] = cusp;
        // The only purpose of the middle cubic is to capture the cusp's 180-degree rotation.
        // Implement it as a sub-pixel 180-degree pivot.
        Vec2D pivot = (chops[2] + chops[7]) * .5f;
        pivot = (cusp - pivot).normalized() / (matrixMaxScale * kPolarPrecision * 2) + cusp;
        chops[4] = chops[5] = pivot;
    }
}

// Finds the starting tangent in a contour composed of the points [pts, end). If all points are
// equal, generates a tangent pointing horizontally to the right.
static Vec2D find_starting_tangent(const Vec2D pts[], const Vec2D* end)
{
    assert(end > pts);
    const Vec2D p0 = pts[0];
    while (++pts < end)
    {
        Vec2D p = *pts;
        if (p != p0)
        {
            return p - p0;
        }
    }
    return {1, 0};
}

// Finds the ending tangent in a contour composed of the points [pts, end). If all points are equal,
// generates a tangent pointing horizontally to the left.
static Vec2D find_ending_tangent(const Vec2D pts[], const Vec2D* end)
{
    assert(end > pts);
    const Vec2D endpoint = end[-1];
    while (--end > pts)
    {
        Vec2D p = end[-1];
        if (p != endpoint)
        {
            return endpoint - p;
        }
    }
    return {-1, 0};
}

static Vec2D find_join_tangent_full_impl(const Vec2D* joinPoint,
                                         const Vec2D* end,
                                         bool closed,
                                         const Vec2D* p0)
{
    // Find the first point in the contour not equal to *joinPoint and return the difference.
    // RawPath should have discarded empty verbs, so this should be a fast operation.
    for (const Vec2D* p = joinPoint + 1; p != end; ++p)
    {
        if (*p != *joinPoint)
        {
            return *p - *joinPoint;
        }
    }
    if (closed)
    {
        for (const Vec2D* p = p0; p != joinPoint; ++p)
        {
            if (*p != *joinPoint)
            {
                return *p - *joinPoint;
            }
        }
    }
    // This should never be reached because RawPath discards empty verbs.
    RIVE_UNREACHABLE();
}

RIVE_ALWAYS_INLINE Vec2D find_join_tangent(const Vec2D* joinPoint,
                                           const Vec2D* end,
                                           bool closed,
                                           const Vec2D* p0)
{
    // Quick early out for inlining and branch prediction: The next point in the contour is almost
    // always the point that determines the join tangent.
    const Vec2D* nextPoint = joinPoint + 1;
    nextPoint = nextPoint != end ? nextPoint : p0;
    Vec2D tangent = *nextPoint - *joinPoint;
    return tangent != Vec2D{0, 0} ? tangent
                                  : find_join_tangent_full_impl(joinPoint, end, closed, p0);
}

// Should an empty stroke emit round caps, square caps, or none?
//
// Just pick the cap type that makes the most sense for a contour that animates from non-empty to
// empty:
//
//   * A non-closed contour with round caps and a CLOSED contour with round JOINS both converge to a
//     circle when animated to empty.
//         => round caps on the empty contour.
//
//   * A non-closed contour with square caps converges to a square (albeit with potential rotation
//     that is lost when the contour becomes empty).
//         => square caps on the empty contour.
//
//   * A closed contour with miter JOINS converges to... some sort of polygon with pointy corners.
//         ~=> square caps on the empty contour.
//
//   * All other contours converge to nothing.
//         => butt caps on the empty contour, which are ignored.
//
static StrokeCap empty_stroke_cap(const PLSPaint* paint, bool closed)
{
    if (closed)
    {
        switch (paint->getJoin())
        {
            case StrokeJoin::round:
                return StrokeCap::round;
            case StrokeJoin::miter:
                return StrokeCap::square;
            case StrokeJoin::bevel:
                return StrokeCap::butt;
        }
    }
    return paint->getCap();
}

RIVE_ALWAYS_INLINE bool is_final_verb_of_contour(const RawPath::Iter& iter,
                                                 const RawPath::Iter& end)
{
    return iter.rawVerbsPtr() + 1 == end.rawVerbsPtr();
}
} // namespace

// Helps count required resources for, and submit data to the render context that will be used to
// render paths with the "interior triangulation" algorithm.
class PLSRenderer::InteriorTriangulationHelper
{
public:
    size_t patchCount() const { return m_patchCount; }
    bool empty() const { return m_patchCount == 0; }

    enum class PathOp : bool
    {
        countDataAndTriangulate,
        submitOuterCubics
    };

    // For now, we just iterate and subdivide the path twice (once for each enum in PathOp). Since
    // we only do this for large paths, and since we're triangulating the path interior anyway,
    // adding complexity to only run Wang's formula and chop once would save about ~5% of the total
    // CPU time. (And large paths are GPU-bound anyway.)
    //
    // Returns the number of contours processed.
    size_t processPath(PathOp op,
                       PLSRenderContext* context,
                       PathDraw* path,
                       RawPath* scratchPath = nullptr)
    {
        Vec2D chops[kMaxCurveSubdivisions * 3 + 1];
        const RawPath& rawPath = *path->rawPath;
        assert(!rawPath.empty());
        wangs_formula::VectorXform vectorXform(*path->matrix);
        size_t patchCount = 0;
        size_t contourCount = 0;
        Vec2D p0 = {0, 0};
        if (op == PathOp::countDataAndTriangulate)
        {
            scratchPath->rewind();
        }
        for (const auto [verb, pts] : rawPath)
        {
            switch (verb)
            {
                case PathVerb::move:
                    if (contourCount != 0 && pts[-1] != p0)
                    {
                        if (op == PathOp::submitOuterCubics)
                        {
                            context->pushCubic(convert_line_to_cubic(pts[-1], p0).data(),
                                               {0, 0},
                                               flags::kCullExcessTessellationSegments,
                                               kPatchSegmentCountExcludingJoin,
                                               1,
                                               kJoinSegmentCount);
                        }
                        ++patchCount;
                    }
                    if (op == PathOp::countDataAndTriangulate)
                    {
                        scratchPath->move(pts[0]);
                    }
                    else
                    {
                        context->pushContour({0, 0}, true, 0);
                    }
                    p0 = pts[0];
                    ++contourCount;
                    break;
                case PathVerb::line:
                    if (op == PathOp::countDataAndTriangulate)
                    {
                        scratchPath->line(pts[1]);
                    }
                    else
                    {
                        context->pushCubic(convert_line_to_cubic(pts).data(),
                                           {0, 0},
                                           flags::kCullExcessTessellationSegments,
                                           kPatchSegmentCountExcludingJoin,
                                           1,
                                           kJoinSegmentCount);
                    }
                    ++patchCount;
                    break;
                case PathVerb::quad:
                    RIVE_UNREACHABLE();
                case PathVerb::cubic:
                {
                    size_t numSubdivisions = FindSubdivisionCount(pts, vectorXform);
                    if (numSubdivisions == 1)
                    {
                        if (op == PathOp::countDataAndTriangulate)
                        {
                            scratchPath->line(pts[3]);
                        }
                        else
                        {
                            context->pushCubic(pts,
                                               {0, 0},
                                               flags::kCullExcessTessellationSegments,
                                               kPatchSegmentCountExcludingJoin,
                                               1,
                                               kJoinSegmentCount);
                        }
                    }
                    else
                    {
                        // Passing nullptr for the 'tValues' causes it to chop the cubic uniformly
                        // in T.
                        pathutils::ChopCubicAt(pts, chops, nullptr, numSubdivisions - 1);
                        const Vec2D* chop = chops;
                        for (size_t i = 0; i < numSubdivisions; ++i)
                        {
                            if (op == PathOp::countDataAndTriangulate)
                            {
                                scratchPath->line(chop[3]);
                            }
                            else
                            {
                                context->pushCubic(chop,
                                                   {0, 0},
                                                   flags::kCullExcessTessellationSegments,
                                                   kPatchSegmentCountExcludingJoin,
                                                   1,
                                                   kJoinSegmentCount);
                            }
                            chop += 3;
                        }
                    }
                    patchCount += numSubdivisions;
                    break;
                }
                case PathVerb::close:
                    break;
            }
        }
        Vec2D lastPt = rawPath.points().back();
        if (contourCount != 0 && lastPt != p0)
        {
            if (op == PathOp::submitOuterCubics)
            {
                context->pushCubic(convert_line_to_cubic(lastPt, p0).data(),
                                   {0, 0},
                                   flags::kCullExcessTessellationSegments,
                                   kPatchSegmentCountExcludingJoin,
                                   1,
                                   kJoinSegmentCount);
            }
            ++patchCount;
        }

        if (op == PathOp::countDataAndTriangulate)
        {
            assert(!path->triangulator);
            path->triangulator =
                context->make<GrInnerFanTriangulator>(*scratchPath,
                                                      *path->matrix,
                                                      path->pathBounds,
                                                      path->fillRule,
                                                      context->trivialPerFlushAllocator());
            // We also draw each "grout" triangle using an outerCubic patch.
            patchCount += path->triangulator->groutList().count();
            path->tessVertexCount = patchCount * kOuterCurvePatchSegmentSpan;
            m_patchCount += patchCount;
        }
        else
        {
            // Submit grout triangles, retrofitted into outerCubic patches.
            for (auto* node = path->triangulator->groutList().head(); node; node = node->fNext)
            {
                Vec2D triangleAsCubic[4] = {node->fPts[0], node->fPts[1], {0, 0}, node->fPts[2]};
                context->pushCubic(triangleAsCubic,
                                   {0, 0},
                                   flags::kRetrofittedTriangle,
                                   kPatchSegmentCountExcludingJoin,
                                   1,
                                   kJoinSegmentCount);
                ++patchCount;
            }
            assert(contourCount == path->contourCount);
            assert(path->paddingVertexCount + patchCount * kOuterCurvePatchSegmentSpan ==
                   path->tessVertexCount);
            RIVE_DEBUG_CODE(m_writtenPatchCount += patchCount;)
            RIVE_DEBUG_CODE(m_writtenTessVertexCount += patchCount * kOuterCurvePatchSegmentSpan;)
        }

        return contourCount;
    }

#ifdef DEBUG
    bool didSubmitAllData()
    {
        return m_writtenPatchCount == m_patchCount &&
               m_writtenTessVertexCount == m_patchCount * kOuterCurvePatchSegmentSpan;
    }
#endif

private:
    // The final segment in an outerCurve patch is a bowtie join.
    constexpr static size_t kJoinSegmentCount = 1;
    constexpr static size_t kPatchSegmentCountExcludingJoin =
        kOuterCurvePatchSegmentSpan - kJoinSegmentCount;

    // Maximum # of outerCurve patches a curve on the path can be subdivided into.
    constexpr static size_t kMaxCurveSubdivisions =
        (kMaxParametricSegments + kPatchSegmentCountExcludingJoin - 1) /
        kPatchSegmentCountExcludingJoin;

    static size_t FindSubdivisionCount(const Vec2D pts[],
                                       const wangs_formula::VectorXform& vectorXform)
    {
        size_t numSubdivisions =
            ceilf(wangs_formula::cubic(pts, kParametricPrecision, vectorXform) *
                  (1.f / kPatchSegmentCountExcludingJoin));
        return std::clamp<size_t>(numSubdivisions, 1, kMaxCurveSubdivisions);
    }

    size_t m_patchCount = 0;
    RIVE_DEBUG_CODE(size_t m_writtenPatchCount = 0;)
    RIVE_DEBUG_CODE(size_t m_writtenTessVertexCount = 0;)
};

bool PLSRenderer::pushInternalPathBatch(PLSPaint* finalPathPaint)
{
    // Only the final path in the batch uses 'finalPathPaint', which may or may not be stroked.
    size_t strokeIdx = finalPathPaint->getIsStroked() ? m_pathBatch.size() - 1
                                                      : std::numeric_limits<size_t>::max();
    float strokeMatrixMaxScale =
        finalPathPaint->getIsStroked() ? m_pathBatch.back().matrix->findMaxScale() : 0;
    float strokeRadius = finalPathPaint->getIsStroked() ? finalPathPaint->getThickness() * .5f : 0;

    // Count up how much temporary storage this function will need to reserve in CPU buffers.
    size_t maxStrokedCurvesBeforeChops = 0;
    size_t maxStrokedCurvesAfterChops = 0;
    size_t maxTotalCurvesAfterChops = 0;
    PLSPaint clipPaint;
    for (size_t i = 0; i < m_pathBatch.size(); ++i)
    {
        const RawPath* rawPath = m_pathBatch[i].rawPath;
        if (rawPath->empty())
        {
            continue;
        }
        bool stroked = i == strokeIdx; // (Will never be true if finalPathPaint is not stroked.)
        // Reserve enough space to record all the info we might need for this path.
        assert(rawPath->verbs()[0] == PathVerb::move);
        // Every path has at least 1 (non-curve) move.
        size_t maxCurves = rawPath->verbs().size() - 1;
        // Stroked cubics can be chopped into a maximum of 5 segments.
        size_t maxCurvesAfterChops = stroked ? maxCurves * 5 : maxCurves;
        if (stroked)
        {
            maxStrokedCurvesBeforeChops += maxCurves;
            maxStrokedCurvesAfterChops += maxCurvesAfterChops;
        }
        maxTotalCurvesAfterChops += maxCurvesAfterChops;
    }

    // Reserve temporary CPU storage for the loops that follow.
    // (+3 because we process these values in SIMD batches of 4, an may begin at n - 1.)
    m_parametricSegmentCounts_pow4.resize(
        std::max(maxTotalCurvesAfterChops + 3, m_parametricSegmentCounts_pow4.capacity()));
    m_parametricSegmentCounts.resize(
        std::max(maxTotalCurvesAfterChops + 3, m_parametricSegmentCounts.capacity()));
    size_t maxTangentPairs = 0;
    if (maxStrokedCurvesAfterChops != 0)
    {
        assert(finalPathPaint->getIsStroked());
        // Each stroked curve will record the number of chops it requires (either 0, 1, or 2).
        m_numChops.resizeAndRewind(std::max(maxStrokedCurvesBeforeChops, m_numChops.capacity()));
        // We only chop into this queue if a cubic has one chop. More chops in a single cubic
        // are rare and require a lot of memory, so if a cubic needs more chops we just re-chop
        // the second time around. The maximum size this queue would need is therefore enough to
        // chop each cubic once, or 7 points per.
        m_chops.resizeAndRewind(std::max(maxStrokedCurvesBeforeChops * 7, m_chops.capacity()));
        // After chopping, each stroked curve will also record its beginning and ending tangents
        // (4 floats) so we can measure its rotation.
        maxTangentPairs += maxStrokedCurvesAfterChops;
    }
    if (finalPathPaint->getIsStroked())
    {
        // If the stroke has round joins, we also record the tangents between (pre-chopped) joins in
        // order to calculate how many vertices are in each round join.
        if (finalPathPaint->getJoin() == StrokeJoin::round)
        {
            maxTangentPairs += maxStrokedCurvesBeforeChops;
        }
        // Reserve temporary CPU storage for the loops that follow.
        // (+3 because we process these values in SIMD batches of 4, an may begin at n - 1.)
        m_tangentPairs.resize(std::max(maxTangentPairs + 3, m_tangentPairs.capacity()));
        m_polarSegmentCounts.resize(
            std::max(maxStrokedCurvesAfterChops + 3, m_polarSegmentCounts.capacity()));
    }

    InteriorTriangulationHelper interiorTriHelper;

    // Iteration pass 1: Collect information on contour and curves counts for every path in the
    // batch, and begin counting tessellated vertices.
    m_contourBatch.clear();
    size_t contourCount = 0;
    size_t lineCount = 0;
    size_t curveCount = 0;
    size_t rotationCount = 0; // We measure rotations on both curves and round joins.
    for (size_t i = 0; i < m_pathBatch.size(); ++i)
    {
        PathDraw& path = m_pathBatch[i];
        if (path.rawPath->empty())
        {
            continue;
        }

        size_t pathContourCount = 0;
        bool stroked = i == strokeIdx; // (Will never be true if finalPathPaint is not stroked.)
        assert(path.triangulator == nullptr);
        if (!stroked && FindTransformedArea(path.pathBounds, *path.matrix) > 512 * 512)
        {
            // This path is a sufficiently-large fill. Use interior triangulation!
            pathContourCount = interiorTriHelper.processPath(
                InteriorTriangulationHelper::PathOp::countDataAndTriangulate,
                m_context,
                &path,
                &m_scratchPath);
        }
        else
        {
            bool roundJoinStroked = stroked && finalPathPaint->getJoin() == StrokeJoin::round;
            wangs_formula::VectorXform vectorXform(*path.matrix);
            RawPath::Iter startOfContour = path.rawPath->begin();
            RawPath::Iter end = path.rawPath->end();
            int preChopVerbCount = 0; // Original number of lines and curves, before chopping.
            Vec2D endpointsSum{};
            bool closed = !stroked;
            Vec2D lastTangent = {0, 1};
            Vec2D firstTangent = {0, 1};
            size_t roundJoinCount = 0;
            path.firstContourIdx = m_contourBatch.size();
            auto finishAndAppendContour = [&](RawPath::Iter iter) {
                if (closed)
                {
                    Vec2D finalPtInContour = iter.rawPtsPtr()[-1];
                    if (startOfContour.movePt() != finalPtInContour)
                    {
                        assert(preChopVerbCount > 0);
                        if (roundJoinStroked)
                        {
                            // Round join before implicit closing line.
                            Vec2D tangent = startOfContour.movePt() - finalPtInContour;
                            assert(rotationCount < m_tangentPairs.capacity());
                            m_tangentPairs[rotationCount++] = {lastTangent, tangent};
                            lastTangent = tangent;
                            ++roundJoinCount;
                        }
                        ++lineCount; // Implicit closing line.
                        // The first point in the contour hasn't gotten counted yet.
                        ++preChopVerbCount;
                        endpointsSum += startOfContour.movePt();
                    }
                    if (roundJoinStroked && preChopVerbCount != 0)
                    {
                        // Round join back to the beginning of the contour.
                        assert(rotationCount < m_tangentPairs.capacity());
                        m_tangentPairs[rotationCount++] = {lastTangent, firstTangent};
                        ++roundJoinCount;
                    }
                }
                size_t strokeJoinCount = preChopVerbCount;
                if (!closed)
                {
                    strokeJoinCount = std::max<size_t>(strokeJoinCount, 1) - 1;
                }
                m_contourBatch.emplace_back(iter,
                                            lineCount,
                                            curveCount,
                                            rotationCount,
                                            stroked ? Vec2D()
                                                    : endpointsSum * (1.f / preChopVerbCount),
                                            closed,
                                            strokeJoinCount);
                ++pathContourCount;
            };
            const int styleFlags = style_flags(stroked, roundJoinStroked);
            for (RawPath::Iter iter = startOfContour; iter != end; ++iter)
            {
                switch (styled_verb(iter.verb(), styleFlags))
                {
                    case StyledVerb::roundJoinStrokedMove:
                    case StyledVerb::strokedMove:
                    case StyledVerb::filledMove:
                        if (iter != startOfContour)
                        {
                            finishAndAppendContour(iter);
                            startOfContour = iter;
                        }
                        preChopVerbCount = 0;
                        endpointsSum = {0, 0};
                        closed = !stroked;
                        lastTangent = {0, 1};
                        firstTangent = {0, 1};
                        roundJoinCount = 0;
                        break;
                    case StyledVerb::roundJoinStrokedClose:
                    case StyledVerb::strokedClose:
                    case StyledVerb::filledClose:
                        assert(iter != startOfContour);
                        closed = true;
                        break;
                    case StyledVerb::roundJoinStrokedLine:
                    {
                        const Vec2D* p = iter.linePts();
                        Vec2D tangent = p[1] - p[0];
                        if (preChopVerbCount == 0)
                        {
                            firstTangent = tangent;
                        }
                        else
                        {
                            assert(rotationCount < m_tangentPairs.capacity());
                            m_tangentPairs[rotationCount++] = {lastTangent, tangent};
                            ++roundJoinCount;
                        }
                        lastTangent = tangent;
                        [[fallthrough]];
                    }
                    case StyledVerb::strokedLine:
                    case StyledVerb::filledLine:
                    {
                        const Vec2D* p = iter.linePts();
                        ++preChopVerbCount;
                        endpointsSum += p[1];
                        ++lineCount;
                        break;
                    }
                    case StyledVerb::roundJoinStrokedQuad:
                    case StyledVerb::strokedQuad:
                    case StyledVerb::filledQuad:
                        RIVE_UNREACHABLE();
                        break;
                    case StyledVerb::roundJoinStrokedCubic:
                    {
                        const Vec2D* p = iter.cubicPts();
                        Vec2D unchoppedTangents[2];
                        find_cubic_tangents(p, unchoppedTangents);
                        if (preChopVerbCount == 0)
                        {
                            firstTangent = unchoppedTangents[0];
                        }
                        else
                        {
                            assert(rotationCount < m_tangentPairs.capacity());
                            m_tangentPairs[rotationCount++] = {lastTangent, unchoppedTangents[0]};
                            ++roundJoinCount;
                        }
                        lastTangent = unchoppedTangents[1];
                        [[fallthrough]];
                    }
                    case StyledVerb::strokedCubic:
                    {
                        const Vec2D* p = iter.cubicPts();
                        ++preChopVerbCount;
                        endpointsSum += p[3];
                        // Chop strokes into sections that do not inflect (i.e, are convex), and do
                        // not rotate more than 180 degrees. This is required by the GPU
                        // parametric/polar sorter.
                        float t[2];
                        bool areCusps;
                        uint8_t numChops = pathutils::FindCubicConvex180Chops(p, t, &areCusps);
                        uint8_t chopKey = chop_key(areCusps, numChops);
                        m_numChops.push_back(chopKey);
                        Vec2D localChopBuffer[16];
                        switch (chopKey)
                        {
                            case cusp_chop_key(2): // 2 cusps
                            case cusp_chop_key(1): // 1 cusp
                                // We have to chop carefully around stroked cusps in order to avoid
                                // rendering artifacts. Luckily, cusps are extremely rare in
                                // real-world content.
                                m_chops.push_back() = {t[0], t[1]};
                                chop_cubic_around_cusps(p,
                                                        localChopBuffer,
                                                        t,
                                                        numChops,
                                                        strokeMatrixMaxScale);
                                p = localChopBuffer;
                                numChops *= 2;
                                break;
                            case simple_chop_key(2): // 2 non-cusp chops
                                m_chops.push_back() = {t[0], t[1]};
                                pathutils::ChopCubicAt(p, localChopBuffer, t[0], t[1]);
                                p = localChopBuffer;
                                break;
                            case simple_chop_key(1): // 1 non-cusp chop
                            {
                                Vec2D* buff = m_chops.push_back_n(7);
                                pathutils::ChopCubicAt(p, buff, t[0]);
                                p = buff;
                                break;
                            }
                        }
                        // Calculate segment counts for each chopped section independently.
                        for (const Vec2D* end = p + numChops * 3 + 3; p != end;
                             p += 3, ++curveCount, ++rotationCount)
                        {
                            float n4 =
                                wangs_formula::cubic_pow4(p, kParametricPrecision, vectorXform);
                            m_parametricSegmentCounts_pow4[curveCount] = n4;
                            assert(rotationCount < m_tangentPairs.capacity());
                            find_cubic_tangents(p, m_tangentPairs[rotationCount].data());
                        }
                        break;
                    }
                    case StyledVerb::filledCubic:
                    {
                        const Vec2D* p = iter.cubicPts();
                        ++preChopVerbCount;
                        endpointsSum += p[3];
                        float n4 = wangs_formula::cubic_pow4(p, kParametricPrecision, vectorXform);
                        m_parametricSegmentCounts_pow4[curveCount++] = n4;
                        break;
                    }
                }
            }
            if (startOfContour != end)
            {
                finishAndAppendContour(end);
            }
        }
        path.contourCount = pathContourCount;
        contourCount += pathContourCount;
    }

    if (contourCount == 0)
    {
        // The entire batch is empty.
        return true;
    }

    // Iteration pass 2: Finish calculating the numbers of tessellation segments in each contour,
    // using SIMD.
    size_t contourFirstLineIdx = 0;
    size_t contourFirstCurveIdx = 0;
    size_t contourFirstRotationIdx = 0;
    size_t emptyStrokeCountForCaps = 0;
    PLSRenderContext::TessVertexCounter tessVertexCounter(m_context);
    for (size_t currentPathIdx = 0; currentPathIdx < m_pathBatch.size(); ++currentPathIdx)
    {
        PathDraw& path = m_pathBatch[currentPathIdx];
        if (path.rawPath->empty())
        {
            continue;
        }

        bool stroked = currentPathIdx == strokeIdx;

        // (If we used interior triangulation, interiorTriHelper already counted the path's vertices
        // for us.)
        if (path.triangulator != nullptr)
        {
            assert(path.paddingVertexCount == 0);
            // If the path has a nonzero number of tessellation vertices, pad them so they align on
            // a multiple of the patch size.
            if (path.tessVertexCount > 0)
            {
                assert(!stroked);
                path.paddingVertexCount =
                    tessVertexCounter.countPath<kOuterCurvePatchSegmentSpan>(path.tessVertexCount,
                                                                             false);
                path.tessVertexCount += path.paddingVertexCount;
            }
        }
        else
        {
            assert(path.tessVertexCount == 0);
            for (size_t i = 0; i < path.contourCount; ++i)
            {
                ContourData* contour = &m_contourBatch[path.firstContourIdx + i];
                size_t contourLineCount = contour->endLineIdx - contourFirstLineIdx;
                uint32_t contourVertexCount =
                    contourLineCount * 2; // Each line tessellates to 2 vertices.
                uint4 mergedTessVertexSums4 = 0;

                // Finish calculating and counting parametric segments for each curve.
                size_t j;
                for (j = contourFirstCurveIdx; j < contour->endCurveIdx; j += 4)
                {
                    assert(j + 4 <= m_parametricSegmentCounts_pow4.capacity());
                    // Curves recorded their segment counts raised to the 4th power. Now find their
                    // roots and convert to integers in batches of 4.
                    float4 n = simd::load4f(m_parametricSegmentCounts_pow4.get() + j);
                    n = simd::ceil(simd::sqrt(simd::sqrt(n)));
                    n = simd::clamp(n, float4(1), float4(kMaxParametricSegments));
                    uint4 n_ = simd::cast<uint32_t>(n);
                    assert(j + 4 <= m_parametricSegmentCounts.capacity());
                    simd::store(m_parametricSegmentCounts.get() + j, n_);
                    mergedTessVertexSums4 += n_;
                }
                // We counted in batches of 4. Undo the values we counted from beyond the end of the
                // path.
                while (j-- > contour->endCurveIdx)
                {
                    contourVertexCount -= m_parametricSegmentCounts[j];
                }

                if (stroked)
                {
                    // Finish calculating and counting polar segments for each stroked curve and
                    // round join.
                    const float r_ = strokeRadius * strokeMatrixMaxScale;
                    const float polarSegmentsPerRad =
                        pathutils::CalcPolarSegmentsPerRadian<kPolarPrecision>(r_);
                    for (j = contourFirstRotationIdx; j < contour->endRotationIdx; j += 4)
                    {
                        // Measure the rotations of curves in batches of 4.
                        assert(j + 4 <= m_tangentPairs.capacity());
                        auto [tx0, ty0, tx1, ty1] = simd::load4x4f(&m_tangentPairs[j][0].x);
                        float4 numer = tx0 * tx1 + ty0 * ty1;
                        float4 denom_pow2 = (tx0 * tx0 + ty0 * ty0) * (tx1 * tx1 + ty1 * ty1);
                        float4 cosTheta = numer / simd::sqrt(denom_pow2);
                        cosTheta = simd::clamp(cosTheta, float4(-1), float4(1));
                        float4 theta = simd::fast_acos(cosTheta);
                        // Find polar segment counts from the rotation angles.
                        float4 n = simd::ceil(theta * polarSegmentsPerRad);
                        n = simd::clamp(n, float4(1), float4(kMaxPolarSegments));
                        uint4 n_ = simd::cast<uint32_t>(n);
                        assert(j + 4 <= m_polarSegmentCounts.capacity());
                        simd::store(m_polarSegmentCounts.get() + j, n_);
                        // Polar and parametric segments share the first and final vertices.
                        // Therefore:
                        //
                        //   parametricVertexCount = parametricSegmentCount + 1
                        //
                        //   polarVertexCount = polarVertexCount + 1
                        //
                        //   mergedVertexCount = parametricVertexCount + polarVertexCount - 2
                        //                     = parametricSegmentCount + 1 + polarSegmentCount + 1
                        //                     - 2 = parametricSegmentCount + polarSegmentCount
                        //
                        mergedTessVertexSums4 += n_;
                    }

                    // We counted in batches of 4. Undo the values we counted from beyond the end of
                    // the path.
                    while (j-- > contour->endRotationIdx)
                    {
                        contourVertexCount -= m_polarSegmentCounts[j];
                    }

                    // Count joins.
                    if (finalPathPaint->getJoin() == StrokeJoin::round)
                    {
                        // Round joins share their beginning and ending vertices with the curve on
                        // either side. Therefore, the number of vertices we need to allocate for a
                        // round join is "joinSegmentCount - 1". Do all the -1's here.
                        contourVertexCount -= contour->strokeJoinCount;
                    }
                    else
                    {
                        // The shader needs 3 segments for each miter and bevel join (which
                        // translates to two interior vertices, since joins share their beginning
                        // and ending vertices with the curve on either side).
                        contourVertexCount +=
                            contour->strokeJoinCount * (kNumSegmentsInMiterOrBevelJoin - 1);
                    }

                    // Count stroke caps, if any.
                    bool empty = contour->endLineIdx == contourFirstLineIdx &&
                                 contour->endCurveIdx == contourFirstCurveIdx;
                    StrokeCap cap;
                    bool needsCaps;
                    if (!empty)
                    {
                        cap = finalPathPaint->getCap();
                        needsCaps = !contour->closed;
                    }
                    else
                    {
                        cap = empty_stroke_cap(finalPathPaint, contour->closed);
                        needsCaps =
                            cap != StrokeCap::butt; // Ignore butt caps when the contour is empty.
                    }
                    if (needsCaps)
                    {
                        // We emulate stroke caps as 180-degree joins.
                        if (cap == StrokeCap::round)
                        {
                            // Round caps rotate 180 degrees.
                            contour->strokeCapSegmentCount = ceilf(polarSegmentsPerRad * math::PI);
                            // +2 because round caps emulated as joins need to emit vertices at T=0
                            // and T=1, unlike normal round joins.
                            contour->strokeCapSegmentCount += 2;
                            // Make sure not to exceed kMaxPolarSegments.
                            contour->strokeCapSegmentCount =
                                std::min(contour->strokeCapSegmentCount, kMaxPolarSegments);
                        }
                        else
                        {
                            contour->strokeCapSegmentCount = kNumSegmentsInMiterOrBevelJoin;
                        }
                        // pushContour() uses "strokeCapSegmentCount != 0" to tell if it needs
                        // stroke caps.
                        assert(contour->strokeCapSegmentCount != 0);
                        // As long as a contour isn't empty, we can tack the end cap onto the join
                        // section of the final curve in the stroke. Otherwise, we need to introduce
                        // 0-tessellation-segment curves with non-empty joins to carry the caps.
                        emptyStrokeCountForCaps += empty ? 2 : 1;
                        contourVertexCount += (contour->strokeCapSegmentCount - 1) * 2;
                    }
                }
                else
                {
                    // Fills don't have polar segments:
                    //
                    //   mergedVertexCount = parametricVertexCount = parametricSegmentCount + 1
                    //
                    // Just collect the +1 for each non-stroked curve.
                    size_t contourCurveCount = contour->endCurveIdx - contourFirstCurveIdx;
                    contourVertexCount += contourCurveCount;
                }
                contourVertexCount += simd::sum(mergedTessVertexSums4);

                // Add padding vertices until the number of tessellation vertices in the contour is
                // an exact multiple of kMidpointFanPatchSegmentSpan. This ensures that patch
                // boundaries align with contour boundaries.
                contour->paddingVertexCount =
                    PaddingToAlignUp<kMidpointFanPatchSegmentSpan>(contourVertexCount);
                contourVertexCount += contour->paddingVertexCount;
                assert(contourVertexCount % kMidpointFanPatchSegmentSpan == 0);
                RIVE_DEBUG_CODE(contour->tessVertexCount = contourVertexCount;)

                path.tessVertexCount += contourVertexCount;
                contourFirstLineIdx = contour->endLineIdx;
                contourFirstCurveIdx = contour->endCurveIdx;
                contourFirstRotationIdx = contour->endRotationIdx;
            }
            assert(path.paddingVertexCount == 0);
            // If the path has a nonzero number of tessellation vertices, pad them so they align on
            // a multiple of the patch size.
            if (path.tessVertexCount > 0)
            {
                path.paddingVertexCount =
                    tessVertexCounter.countPath<kMidpointFanPatchSegmentSpan>(path.tessVertexCount,
                                                                              stroked);
                path.tessVertexCount += path.paddingVertexCount;
            }
        }
    }
    assert(contourFirstLineIdx == lineCount);
    assert(contourFirstCurveIdx == curveCount);
    assert(contourFirstRotationIdx == rotationCount);

    // Attempt to reserve space on the GPU for our entire batch of paths.
    size_t curveReserveCount =
        curveCount + lineCount + emptyStrokeCountForCaps + interiorTriHelper.patchCount();
    if (!m_context->reservePathData(m_pathBatch.size(),
                                    contourCount,
                                    curveReserveCount,
                                    tessVertexCounter))
    {
        // The paths don't fit. Give up and let the caller flush and try again.
        return false;
    }

    // Attempt to push 'finalPathPaint' to the GPU buffers.
    PaintData paintData;
    if (!m_context->pushPaint(finalPathPaint, &paintData))
    {
        // The paint doesn't fit. Give up and let the caller flush and try again.
        return false;
    }

    // Iteration pass 3: Now that we have space reserved, push the whole batch of paths to the GPU.
    RIVE_DEBUG_CODE(size_t pushedPathCount = 0;)
    RIVE_DEBUG_CODE(size_t skippedPathCount = 0;)
    RIVE_DEBUG_CODE(size_t pushedContourCount = 0;)
    RIVE_DEBUG_CODE(size_t skippedContourCount = 0;)
    RIVE_DEBUG_CODE(m_pushedLineCount = 0;)
    RIVE_DEBUG_CODE(m_pushedCurveCount = 0;)
    RIVE_DEBUG_CODE(m_pushedRotationCount = 0;)
    RIVE_DEBUG_CODE(m_pushedEmptyStrokeCountForCaps = 0;)
    size_t curveIdx = 0;
    size_t rotationIdx = 0;
    RawPath::Iter startOfContour;
    size_t finalPathIdx = m_pathBatch.size() - 1; // All paths are clips except the final one.
    for (size_t currentPathIdx = 0; currentPathIdx < m_pathBatch.size(); ++currentPathIdx)
    {
        PathDraw& path = m_pathBatch[currentPathIdx];
        if (path.tessVertexCount == 0)
        {
            RIVE_DEBUG_CODE(skippedContourCount += path.contourCount;)
            RIVE_DEBUG_CODE(++skippedPathCount;)
            continue;
        }
        assert(!path.rawPath->empty());

        // Push a path record.
        bool isClipPath = currentPathIdx != finalPathIdx;
        PaintType paintType = isClipPath ? PaintType::clipReplace : finalPathPaint->getType();
        PLSBlendMode blendMode =
            isClipPath ? PLSBlendMode::srcOver : finalPathPaint->getBlendMode();

        m_context->pushPath(path.triangulator ? PatchType::outerCurves : PatchType::midpointFan,
                            *path.matrix,
                            isClipPath ? 0 : strokeRadius,
                            path.fillRule,
                            paintType,
                            path.clipID,
                            blendMode,
                            isClipPath ? PaintData{} : paintData,
                            path.tessVertexCount,
                            path.paddingVertexCount);
        RIVE_DEBUG_CODE(++pushedPathCount;)

        if (path.triangulator != nullptr)
        {
            // This path is drawn with the interior triangulation algorithm instead.
            size_t processedContourCount RIVE_MAYBE_UNUSED = interiorTriHelper.processPath(
                InteriorTriangulationHelper::PathOp::submitOuterCubics,
                m_context,
                &path);
            RIVE_DEBUG_CODE(pushedContourCount += processedContourCount;)
            m_context->pushInteriorTriangulation(path.triangulator,
                                                 paintType,
                                                 path.clipID,
                                                 blendMode);
        }
        else
        {
            startOfContour = path.rawPath->begin();
            for (size_t i = 0; i < path.contourCount; ++i)
            {
                // Push a contour and curve records.
                const ContourData& contour = m_contourBatch[path.firstContourIdx + i];
                RIVE_DEBUG_CODE(m_pushedStrokeJoinCount = 0;)
                RIVE_DEBUG_CODE(m_pushedStrokeCapCount = 0;)
                pushContour(startOfContour,
                            contour,
                            curveIdx,
                            rotationIdx,
                            strokeMatrixMaxScale,
                            currentPathIdx == strokeIdx ? finalPathPaint : nullptr);
                assert(m_pushedCurveCount == contour.endCurveIdx);
                assert(m_pushedRotationCount == contour.endRotationIdx);
                assert(m_pushedStrokeJoinCount ==
                       (currentPathIdx == strokeIdx ? contour.strokeJoinCount : 0));
                assert(m_pushedStrokeCapCount == (contour.strokeCapSegmentCount != 0 ? 2 : 0));
                curveIdx = contour.endCurveIdx;
                rotationIdx = contour.endRotationIdx;
                startOfContour = contour.endOfContour;
                RIVE_DEBUG_CODE(++pushedContourCount);
            }
        }
    }

    // Make sure we only pushed the amount of data we reserved.
    assert(pushedPathCount + skippedPathCount == m_pathBatch.size());
    assert(pushedContourCount + skippedContourCount == contourCount);
    assert(m_pushedLineCount == lineCount);
    assert(m_pushedCurveCount == curveCount);
    assert(m_pushedRotationCount == rotationCount);
    assert(m_pushedEmptyStrokeCountForCaps == emptyStrokeCountForCaps);
    assert(interiorTriHelper.didSubmitAllData());
    assert(m_pushedLineCount + m_pushedCurveCount + m_pushedEmptyStrokeCountForCaps +
               interiorTriHelper.patchCount() ==
           curveReserveCount);
    return true;
}

void PLSRenderer::pushContour(RawPath::Iter iter,
                              const ContourData& contour,
                              size_t curveIdx,
                              size_t rotationIdx,
                              float matrixMaxScale,
                              const PLSPaint* strokePaint)
{
    assert(iter.verb() == PathVerb::move);
    assert(strokePaint != nullptr || contour.closed); // Fills are always closed.
    RIVE_DEBUG_CODE(const size_t startingCurveIdx = curveIdx;)
    RIVE_DEBUG_CODE(const size_t startingRotationIdx = rotationIdx;)

    const Vec2D* pts = iter.rawPtsPtr();
    const RawPath::Iter end = contour.endOfContour;
    uint32_t joinTypeFlags = 0;
    bool roundJoinStroked = false;
    bool needsFirstEmulatedCapAsJoin = false; // Emit a starting cap before the next cubic?
    uint32_t emulatedCapAsJoinFlags = 0;
    if (strokePaint != nullptr)
    {
        joinTypeFlags = flags::JoinTypeFlags(strokePaint->getJoin());
        roundJoinStroked = joinTypeFlags == 0;
        if (contour.strokeCapSegmentCount != 0)
        {
            StrokeCap cap = !contour.closed ? strokePaint->getCap()
                                            : empty_stroke_cap(strokePaint, contour.closed);
            emulatedCapAsJoinFlags = flags::kEmulatedStrokeCap;
            if (cap == StrokeCap::square)
            {
                emulatedCapAsJoinFlags |= flags::kMiterClipJoin;
            }
            else if (cap == StrokeCap::butt)
            {
                emulatedCapAsJoinFlags |= flags::kBevelJoin;
            }
            needsFirstEmulatedCapAsJoin = true;
        }
    }

    // Make a data record for this current contour on the GPU.
    m_context->pushContour(contour.midpoint, contour.closed, contour.paddingVertexCount);

    // Convert all curves in the contour to cubics and push them to the GPU.
    const int styleFlags = style_flags(strokePaint != nullptr, roundJoinStroked);
    Vec2D joinTangent = {0, 1};
    int joinSegmentCount = 1;
    Vec2D implicitClose[2]; // In case we need an implicit closing line.
    for (; iter != end; ++iter)
    {
        StyledVerb styledVerb = styled_verb(iter.verb(), styleFlags);
        switch (styledVerb)
        {
            case StyledVerb::filledMove:
            case StyledVerb::strokedMove:
            case StyledVerb::roundJoinStrokedMove:
                implicitClose[1] = iter.movePt(); // In case we need an implicit closing line.
                break;
            case StyledVerb::filledClose:
            case StyledVerb::strokedClose:
            case StyledVerb::roundJoinStrokedClose:
                assert(contour.closed);
                break;
            case StyledVerb::roundJoinStrokedLine:
            {
                if (contour.closed || !is_final_verb_of_contour(iter, end))
                {
                    joinTangent = m_tangentPairs[rotationIdx][1];
                    joinSegmentCount = m_polarSegmentCounts[rotationIdx];
                    ++rotationIdx;
                    RIVE_DEBUG_CODE(++m_pushedStrokeJoinCount;)
                }
                else
                {
                    // End with a 180-degree join that looks like the stroke cap.
                    joinTangent = -find_ending_tangent(pts, end.rawPtsPtr());
                    joinTypeFlags = emulatedCapAsJoinFlags;
                    joinSegmentCount = contour.strokeCapSegmentCount;
                    RIVE_DEBUG_CODE(++m_pushedStrokeCapCount;)
                }
                goto line_common;
            }
            case StyledVerb::strokedLine:
                if (contour.closed || !is_final_verb_of_contour(iter, end))
                {
                    joinTangent =
                        find_join_tangent(iter.linePts() + 1, end.rawPtsPtr(), contour.closed, pts);
                    joinSegmentCount = kNumSegmentsInMiterOrBevelJoin;
                    RIVE_DEBUG_CODE(++m_pushedStrokeJoinCount;)
                }
                else
                {
                    // End with a 180-degree join that looks like the stroke cap.
                    joinTangent = -find_ending_tangent(pts, end.rawPtsPtr());
                    joinTypeFlags = emulatedCapAsJoinFlags;
                    joinSegmentCount = contour.strokeCapSegmentCount;
                    RIVE_DEBUG_CODE(++m_pushedStrokeCapCount;)
                }
                [[fallthrough]];
            case StyledVerb::filledLine:
            line_common:
            {
                std::array<Vec2D, 4> cubic = convert_line_to_cubic(iter.linePts());
                if (needsFirstEmulatedCapAsJoin)
                {
                    // Emulate the start cap as a 180-degree join before the first stroke.
                    pushEmulatedStrokeCapAsJoinBeforeCubic(cubic.data(),
                                                           emulatedCapAsJoinFlags,
                                                           contour.strokeCapSegmentCount);
                    needsFirstEmulatedCapAsJoin = false;
                }
                m_context
                    ->pushCubic(cubic.data(), joinTangent, joinTypeFlags, 1, 1, joinSegmentCount);
                RIVE_DEBUG_CODE(++m_pushedLineCount;)
                break;
            }
            case StyledVerb::roundJoinStrokedQuad:
            case StyledVerb::strokedQuad:
            case StyledVerb::filledQuad:
                RIVE_UNREACHABLE();
                break;
            case StyledVerb::roundJoinStrokedCubic:
            case StyledVerb::strokedCubic:
            {
                const Vec2D* p = iter.cubicPts();
                uint8_t chopKey = m_numChops.pop_front();
                uint8_t numChops = 0;
                Vec2D localChopBuffer[16];
                switch (chopKey)
                {
                    case cusp_chop_key(2): // 2 cusps
                    case cusp_chop_key(1): // 1 cusp
                        // We have to chop carefully around stroked cusps in order to avoid
                        // rendering artifacts. Luckily, cusps are extremely rare in real-world
                        // content.
                        chop_cubic_around_cusps(p,
                                                localChopBuffer,
                                                &m_chops.pop_front().x,
                                                chopKey >> 1,
                                                matrixMaxScale);
                        p = localChopBuffer;
                        // The bottom bit of chopKey is 1, meaning "areCusps". Clearing the bottom
                        // bit leaves "numChops * 2", which is the number of chops a cusp needs!
                        numChops = chopKey ^ 1;
                        break;

                    case simple_chop_key(2): // 2 non-cusp chops
                    {
                        // Curves that need 2 chops are rare in real-world content. Just re-chop the
                        // curve this time around as well.
                        auto [t0, t1] = m_chops.pop_front();
                        pathutils::ChopCubicAt(p, localChopBuffer, t0, t1);
                        p = localChopBuffer;
                        numChops = 2;
                        break;
                    }
                    case simple_chop_key(1): // 1 non-cusp chop
                        // Single-chop curves were saved in the m_chops queue.
                        p = m_chops.pop_front_n(7);
                        numChops = 1;
                        break;
                }
                if (needsFirstEmulatedCapAsJoin)
                {
                    // Emulate the start cap as a 180-degree join before the first stroke.
                    pushEmulatedStrokeCapAsJoinBeforeCubic(p,
                                                           emulatedCapAsJoinFlags,
                                                           contour.strokeCapSegmentCount);
                    needsFirstEmulatedCapAsJoin = false;
                }
                // Push chops before the final one.
                for (size_t end = curveIdx + numChops; curveIdx != end;
                     ++curveIdx, ++rotationIdx, p += 3)
                {
                    uint32_t parametricSegmentCount = m_parametricSegmentCounts[curveIdx];
                    uint32_t polarSegmentCount = m_polarSegmentCounts[rotationIdx];
                    m_context->pushCubic(p,
                                         joinTangent,
                                         joinTypeFlags,
                                         parametricSegmentCount,
                                         polarSegmentCount,
                                         1);
                }
                // Push the final chop, with a join.
                uint32_t parametricSegmentCount = m_parametricSegmentCounts[curveIdx++];
                uint32_t polarSegmentCount = m_polarSegmentCounts[rotationIdx++];
                if (contour.closed || !is_final_verb_of_contour(iter, end))
                {
                    if (styledVerb == StyledVerb::roundJoinStrokedCubic)
                    {
                        joinTangent = m_tangentPairs[rotationIdx][1];
                        joinSegmentCount = m_polarSegmentCounts[rotationIdx];
                        ++rotationIdx;
                    }
                    else
                    {
                        joinTangent = find_join_tangent(iter.cubicPts() + 3,
                                                        end.rawPtsPtr(),
                                                        contour.closed,
                                                        pts);
                        joinSegmentCount = kNumSegmentsInMiterOrBevelJoin;
                    }
                    RIVE_DEBUG_CODE(++m_pushedStrokeJoinCount;)
                }
                else
                {
                    // End with a 180-degree join that looks like the stroke cap.
                    joinTangent = -find_ending_tangent(pts, end.rawPtsPtr());
                    joinTypeFlags = emulatedCapAsJoinFlags;
                    joinSegmentCount = contour.strokeCapSegmentCount;
                    RIVE_DEBUG_CODE(++m_pushedStrokeCapCount;)
                }
                m_context->pushCubic(p,
                                     joinTangent,
                                     joinTypeFlags,
                                     parametricSegmentCount,
                                     polarSegmentCount,
                                     joinSegmentCount);
                break;
            }
            case StyledVerb::filledCubic:
            {
                uint32_t parametricSegmentCount = m_parametricSegmentCounts[curveIdx++];
                m_context->pushCubic(iter.cubicPts(), Vec2D{}, 0, parametricSegmentCount, 1, 1);
                break;
            }
        }
    }

    if (needsFirstEmulatedCapAsJoin)
    {
        // The contour was empty. Emit both caps on p0.
        Vec2D p0 = pts[0], left = {p0.x - 1, p0.y}, right = {p0.x + 1, p0.y};
        pushEmulatedStrokeCapAsJoinBeforeCubic(std::array{p0, right, right, right}.data(),
                                               emulatedCapAsJoinFlags,
                                               contour.strokeCapSegmentCount);
        pushEmulatedStrokeCapAsJoinBeforeCubic(std::array{p0, left, left, left}.data(),
                                               emulatedCapAsJoinFlags,
                                               contour.strokeCapSegmentCount);
    }
    else if (contour.closed)
    {
        implicitClose[0] = iter.rawPtsPtr()[-1];
        if (implicitClose[0] != implicitClose[1])
        {
            // Draw a line back to the beginning of the contour.
            std::array<Vec2D, 4> cubic = convert_line_to_cubic(implicitClose);
            // Closing join back to the beginning of the contour.
            if (roundJoinStroked)
            {
                joinTangent = m_tangentPairs[rotationIdx][1];
                joinSegmentCount = m_polarSegmentCounts[rotationIdx];
                ++rotationIdx;
                RIVE_DEBUG_CODE(++m_pushedStrokeJoinCount;)
            }
            else if (strokePaint != nullptr)
            {
                joinTangent = find_starting_tangent(pts, end.rawPtsPtr());
                joinSegmentCount = kNumSegmentsInMiterOrBevelJoin;
                RIVE_DEBUG_CODE(++m_pushedStrokeJoinCount;)
            }
            m_context->pushCubic(cubic.data(), joinTangent, joinTypeFlags, 1, 1, joinSegmentCount);
            RIVE_DEBUG_CODE(++m_pushedLineCount;)
        }
    }

    RIVE_DEBUG_CODE(m_pushedCurveCount += curveIdx - startingCurveIdx;)
    RIVE_DEBUG_CODE(m_pushedRotationCount += rotationIdx - startingRotationIdx;)
}

void PLSRenderer::pushEmulatedStrokeCapAsJoinBeforeCubic(const Vec2D cubic[],
                                                         uint32_t emulatedCapAsJoinFlags,
                                                         uint32_t strokeCapSegmentCount)
{
    // Reverse the cubic and push it with zero parametric and polar segments, and a 180-degree join
    // tangent. This results in a solitary join, positioned immediately before the provided cubic,
    // that looks like the desired stroke cap.
    m_context->pushCubic(std::array{cubic[3], cubic[2], cubic[1], cubic[0]}.data(),
                         find_cubic_tan0(cubic),
                         emulatedCapAsJoinFlags,
                         0,
                         0,
                         strokeCapSegmentCount);
    RIVE_DEBUG_CODE(++m_pushedStrokeCapCount;)
    RIVE_DEBUG_CODE(++m_pushedEmptyStrokeCountForCaps;)
}

void PLSRenderer::intermediateFlush()
{
    m_context->flush(PLSRenderContext::FlushType::intermediate);

    // Reset clip IDs, since these get reset by the context on flush.
    for (ClipElement& clip : m_clipStack)
    {
        clip.clipID = 0;
    }
}

bool PLSRenderer::IsAABB(const RawPath& path)
{
    constexpr static size_t kAABBVerbCount = 5;
    constexpr static PathVerb aabbVerbs[kAABBVerbCount] = {PathVerb::move,
                                                           PathVerb::line,
                                                           PathVerb::line,
                                                           PathVerb::line,
                                                           PathVerb::close};
    Span<const PathVerb> verbs = path.verbs();
    if (verbs.count() != kAABBVerbCount || memcmp(verbs.data(), aabbVerbs, sizeof(aabbVerbs)) != 0)
    {
        return false;
    }
    Span<const Vec2D> pts = path.points();
    assert(pts.count() == 4);
    float4 corners = {pts[0].x, pts[0].y, pts[2].x, pts[2].y};
    float4 oppositeCorners = {pts[1].x, pts[1].y, pts[3].x, pts[3].y};
    return simd::all(corners == oppositeCorners.zyxw) || simd::all(corners == oppositeCorners.xwzy);
}
} // namespace rive::pls
