/*
 * 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"
#include "rive/pls/pls_render_context.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;
    }

    // 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();
}

// Returns the smallest number that can be added to 'value', such that 'value % alignment' == 0.
RIVE_ALWAYS_INLINE uint32_t padding_to_align_up(uint32_t value, uint32_t alignment)
{
    uint32_t maxMultipleOfAlignment = std::numeric_limits<uint32_t>::max() / alignment * alignment;
    uint32_t padding = (maxMultipleOfAlignment - value) % alignment;
    assert((value + padding) % alignment == 0);
    return padding;
}
} // 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 contourCount() const { return m_contourCount; }
    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.)
    void 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->pathBounds,
                                                      path->fillRule,
                                                      context->trivialPerFlushAllocator());
            // We also draw each "breadcrumb" triangle using an outerCubic patch.
            patchCount += path->triangulator->breadcrumbList().count();
            path->tessVertexCount = patchCount * kOuterCurvePatchSegmentSpan;
            m_contourCount += contourCount;
            m_patchCount += patchCount;
        }
        else
        {
            // Submit breadcrumb triangles, emulated by outerCubic patches.
            for (auto* node = path->triangulator->breadcrumbList().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(path->paddingVertexCount + patchCount * kOuterCurvePatchSegmentSpan ==
                   path->tessVertexCount);
            RIVE_DEBUG_CODE(m_writtenContourCount += contourCount;)
            RIVE_DEBUG_CODE(m_writtenPatchCount += patchCount;)
            RIVE_DEBUG_CODE(m_writtenTessVertexCount +=
                            patchCount * (kPatchSegmentCountExcludingJoin + kJoinSegmentCount);)
        }
    }

#ifdef DEBUG
    bool didSubmitAllData()
    {
        return m_writtenContourCount == m_contourCount && 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_contourCount = 0;
    size_t m_patchCount = 0;
    RIVE_DEBUG_CODE(size_t m_writtenContourCount = 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 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;
        }

        // Draw this path using "interior triangulation" if it is a fill, and is sufficiently large.
        assert(path.triangulator == nullptr);
        if (i != strokeIdx) // Never use interior triangulation for strokes.
        {
            float screenSpaceArea = FindTransformedArea(path.pathBounds, *path.matrix);
            if (screenSpaceArea > 512 * 512)
            {
                interiorTriHelper.processPath(
                    InteriorTriangulationHelper::PathOp::countDataAndTriangulate,
                    m_context,
                    &path,
                    &m_scratchPath);
                continue;
            }
        }

        bool stroked = i == strokeIdx; // (Will never be true if finalPathPaint is not stroked.)
        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;
        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),
                                        i,
                                        closed,
                                        strokeJoinCount);
        };
        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);
        }
    }

    if (m_contourBatch.empty() && interiorTriHelper.empty())
    {
        // The entire batch is empty.
        return true;
    }

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

        if (path.triangulator != nullptr)
        {
            // This path will be drawn with interior triangulation. Its tessellation vertex count
            // (not including padding) has already been written to 'path.tessVertexCount'. Pad it up
            // so its first vertex falls on a multiple of kOuterCurvePatchSegmentSpan.
            path.paddingVertexCount =
                padding_to_align_up(baseVertex + tessVertexCount, kOuterCurvePatchSegmentSpan);
            assert((baseVertex + tessVertexCount + path.paddingVertexCount) %
                       kOuterCurvePatchSegmentSpan ==
                   0);
            path.tessVertexCount += path.paddingVertexCount;
            tessVertexCount += path.tessVertexCount;
            continue;
        }

        // Align the beginning of the path on a multiple of kMidpointFanPatchSegmentSpan.
        path.paddingVertexCount =
            padding_to_align_up(baseVertex + tessVertexCount, kMidpointFanPatchSegmentSpan);
        path.tessVertexCount = path.paddingVertexCount;
        tessVertexCount += path.paddingVertexCount;
        assert((baseVertex + tessVertexCount) % kMidpointFanPatchSegmentSpan == 0);

        assert(contour == endContour || contour->pathIdx >= currentPathIdx);
        for (; contour != endContour && contour->pathIdx == currentPathIdx; ++contour)
        {
            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];
            }

            bool stroked = contour->pathIdx == strokeIdx;
            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
            // aligh with contour boundaries.
            constexpr uint32_t maxMultipleOfPatchSpan = std::numeric_limits<uint32_t>::max() /
                                                        kMidpointFanPatchSegmentSpan *
                                                        kMidpointFanPatchSegmentSpan;
            contour->paddingVertexCount =
                (maxMultipleOfPatchSpan - contourVertexCount) % kMidpointFanPatchSegmentSpan;
            contourVertexCount += contour->paddingVertexCount;
            assert(contourVertexCount % kMidpointFanPatchSegmentSpan == 0);
            RIVE_DEBUG_CODE(contour->tessVertexCount = contourVertexCount;)

            path.tessVertexCount += contourVertexCount;
            tessVertexCount += contourVertexCount;
            contourFirstLineIdx = contour->endLineIdx;
            contourFirstCurveIdx = contour->endCurveIdx;
            contourFirstRotationIdx = contour->endRotationIdx;
        }
    }
    assert(contourFirstLineIdx == lineCount);
    assert(contourFirstCurveIdx == curveCount);
    assert(contourFirstRotationIdx == rotationCount);

    // Attempt to reserve space on the GPU for our entire batch of paths.
    if (!m_context->reservePathData(m_pathBatch.size(),
                                    m_contourBatch.size() + interiorTriHelper.contourCount(),
                                    curveCount + lineCount + emptyStrokeCountForCaps +
                                        interiorTriHelper.patchCount(),
                                    tessVertexCount))
    {
        // 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 pushedContourCount = 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;)
    RIVE_DEBUG_CODE(size_t batchStartingTessVertexCount = m_context->currentTessVertexCount());
    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.
    contour = m_contourBatch.begin();
    endContour = m_contourBatch.end();
    for (size_t currentPathIdx = 0; currentPathIdx < m_pathBatch.size(); ++currentPathIdx)
    {
        PathDraw& path = m_pathBatch[currentPathIdx];
        if (path.rawPath->empty())
        {
            continue;
        }

        // 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(uint32_t pathStartingTessVertexCount = m_context->currentTessVertexCount();)

        if (path.triangulator != nullptr)
        {
            // This path is drawn with the interior triangulation algorithm instead.
            interiorTriHelper.processPath(InteriorTriangulationHelper::PathOp::submitOuterCubics,
                                          m_context,
                                          &path);
            m_context->pushInteriorTriangulation(path.triangulator,
                                                 paintType,
                                                 path.clipID,
                                                 blendMode);
            assert(m_context->currentTessVertexCount() ==
                   pathStartingTessVertexCount + path.tessVertexCount);
            continue;
        }

        RIVE_DEBUG_CODE(++pushedPathCount);
        startOfContour = path.rawPath->begin();

        assert(contour == endContour || contour->pathIdx >= currentPathIdx);
        RIVE_DEBUG_CODE(uint32_t contourStartingTessVertexCount =
                            m_context->currentTessVertexCount() + path.paddingVertexCount;)
        for (; contour != endContour && contour->pathIdx == currentPathIdx; ++contour)
        {
            // Push a contour and curve records.
            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));
            assert(m_context->currentTessVertexCount() ==
                   contourStartingTessVertexCount + contour->tessVertexCount);
            curveIdx = contour->endCurveIdx;
            rotationIdx = contour->endRotationIdx;
            startOfContour = contour->endOfContour;
            RIVE_DEBUG_CODE(++pushedContourCount);
            RIVE_DEBUG_CODE(contourStartingTessVertexCount = m_context->currentTessVertexCount();)
        }
        assert(contourStartingTessVertexCount ==
               pathStartingTessVertexCount + path.tessVertexCount);
    }

    // Make sure we only pushed the amount of data we reserved.
    assert(pushedPathCount <=
           m_pathBatch.size()); // Empty paths get skipped, so this won't match exactly.
    assert(pushedContourCount == m_contourBatch.size());
    assert(m_pushedLineCount == lineCount);
    assert(m_pushedCurveCount == curveCount);
    assert(m_pushedRotationCount == rotationCount);
    assert(m_pushedEmptyStrokeCountForCaps == emptyStrokeCountForCaps);
    assert(m_context->currentTessVertexCount() == batchStartingTessVertexCount + tessVertexCount);
    assert(interiorTriHelper.didSubmitAllData());
    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
