/*
 * Copyright 2023 Rive
 */

#include "rive/pls/pls_draw.hpp"

#include "gr_inner_fan_triangulator.hpp"
#include "path_utils.hpp"
#include "pls_path.hpp"
#include "pls_paint.hpp"
#include "rive/math/wangs_formula.hpp"
#include "rive/pls/pls_image.hpp"
#include "shaders/constants.glsl"

namespace rive::pls
{
namespace
{
constexpr static int kNumSegmentsInMiterOrBevelJoin = 5;
constexpr static int kStrokeStyleFlag = 8;
constexpr static int kRoundJoinStyleFlag = kStrokeStyleFlag << 1;
RIVE_ALWAYS_INLINE constexpr int style_flags(bool isStroked, bool roundJoinStroked)
{
    int styleFlags = (isStroked << 3) | (roundJoinStroked << 4);
    assert(bool(styleFlags & kStrokeStyleFlag) == isStroked);
    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];
    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]);
    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] = fmaxf(cuspT[i] - math::EPSILON, minT);
        t[i * 2 + 1] = fminf(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(bool closed, StrokeJoin join, StrokeCap cap)
{
    if (closed)
    {
        switch (join)
        {
            case StrokeJoin::round:
                return StrokeCap::round;
            case StrokeJoin::miter:
                return StrokeCap::square;
            case StrokeJoin::bevel:
                return StrokeCap::butt;
        }
    }
    return cap;
}

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

RIVE_ALWAYS_INLINE uint32_t join_type_flags(StrokeJoin join)
{
    switch (join)
    {
        case StrokeJoin::miter:
            return MITER_REVERT_JOIN_CONTOUR_FLAG;
        case StrokeJoin::round:
            return 0;
        case StrokeJoin::bevel:
            return BEVEL_JOIN_CONTOUR_FLAG;
    }
    RIVE_UNREACHABLE();
}
} // namespace

PLSDraw::PLSDraw(IAABB pixelBounds,
                 const Mat2D& matrix,
                 BlendMode blendMode,
                 rcp<const PLSTexture> imageTexture,
                 Type type) :
    m_imageTextureRef(imageTexture.release()),
    m_pixelBounds(pixelBounds),
    m_matrix(matrix),
    m_blendMode(blendMode),
    m_type(type)
{
    if (m_blendMode != BlendMode::srcOver)
    {
        m_drawContents |= pls::DrawContents::advancedBlend;
    }
}

void PLSDraw::setClipID(uint32_t clipID)
{
    m_clipID = clipID;

    // For clipUpdates, m_clipID refers to the ID we are writing to the stencil buffer (NOT the ID
    // we are clipping against). It therefore doesn't affect the activeClip flag in that case.
    if (!(m_drawContents & pls::DrawContents::clipUpdate))
    {
        if (m_clipID != 0)
        {
            m_drawContents |= pls::DrawContents::activeClip;
        }
        else
        {
            m_drawContents &= ~pls::DrawContents::activeClip;
        }
    }
}

bool PLSDraw::allocateGradientIfNeeded(PLSRenderContext::LogicalFlush* flush,
                                       ResourceCounters* counters)
{
    return m_gradientRef == nullptr ||
           flush->allocateGradient(m_gradientRef, counters, &m_simplePaintValue.colorRampLocation);
}

void PLSDraw::releaseRefs()
{
    safe_unref(m_imageTextureRef);
    safe_unref(m_gradientRef);
}

PLSDrawUniquePtr PLSPathDraw::Make(PLSRenderContext* context,
                                   const Mat2D& matrix,
                                   rcp<const PLSPath> path,
                                   FillRule fillRule,
                                   const PLSPaint* paint,
                                   RawPath* scratchPath)
{
    assert(path != nullptr);
    assert(paint != nullptr);
    AABB mappedBounds;
    if (context->frameInterlockMode() == pls::InterlockMode::atomics)
    {
        // In atomic mode, find a tighter bounding box in order to maximize reordering.
        mappedBounds = matrix.mapBoundingBox(path->getRawPath().points().data(),
                                             path->getRawPath().points().count());
    }
    else
    {
        // Otherwise we can get away with just mapping the path's bounding box.
        mappedBounds = matrix.mapBoundingBox(path->getBounds());
    }
    assert(mappedBounds.width() >= 0);
    assert(mappedBounds.height() >= 0);
    if (paint->getIsStroked())
    {
        // Outset the path's bounding box to account for stroking.
        float strokeOutset = paint->getThickness() * .5f;
        if (paint->getJoin() == StrokeJoin::miter)
        {
            strokeOutset *= 4;
        }
        else if (paint->getCap() == StrokeCap::square)
        {
            strokeOutset *= math::SQRT2;
        }
        AABB strokePixelOutset = matrix.mapBoundingBox({0, 0, strokeOutset, strokeOutset});
        mappedBounds = mappedBounds.inset(-strokePixelOutset.width(), -strokePixelOutset.height());
    }
    IAABB pixelBounds = mappedBounds.roundOut();
    if (!paint->getIsStroked())
    {
        // Use interior triangulation to draw filled paths if they're large enough to benefit from
        // it.
        const AABB& localBounds = path->getBounds();
        // FIXME! Implement interior triangulation in depthStencil mode.
        if (context->frameInterlockMode() != pls::InterlockMode::depthStencil &&
            path->getRawPath().verbs().count() < 1000 &&
            pls::FindTransformedArea(localBounds, matrix) > 512 * 512)
        {
            return PLSDrawUniquePtr(context->make<InteriorTriangulationDraw>(
                context,
                pixelBounds,
                matrix,
                std::move(path),
                fillRule,
                paint,
                scratchPath,
                localBounds.width() > localBounds.height()
                    ? InteriorTriangulationDraw::TriangulatorAxis::horizontal
                    : InteriorTriangulationDraw::TriangulatorAxis::vertical));
        }
    }
    return PLSDrawUniquePtr(context->make<MidpointFanPathDraw>(context,
                                                               pixelBounds,
                                                               matrix,
                                                               std::move(path),
                                                               fillRule,
                                                               paint));
}

PLSPathDraw::PLSPathDraw(IAABB pixelBounds,
                         const Mat2D& matrix,
                         rcp<const PLSPath> path,
                         FillRule fillRule,
                         const PLSPaint* paint,
                         Type type,
                         pls::InterlockMode frameInterlockMode) :
    PLSDraw(pixelBounds, matrix, paint->getBlendMode(), ref_rcp(paint->getImageTexture()), type),
    m_pathRef(path.release()),
    m_fillRule(paint->getIsStroked() ? FillRule::nonZero : fillRule),
    m_paintType(paint->getType())
{
    assert(m_pathRef != nullptr);
    assert(!m_pathRef->getRawPath().empty());
    assert(paint != nullptr);
    if (m_blendMode == BlendMode::srcOver && paint->getIsOpaque())
    {
        m_drawContents |= pls::DrawContents::opaquePaint;
    }
    if (paint->getIsStroked())
    {
        m_drawContents |= pls::DrawContents::stroke;
        m_strokeRadius = paint->getThickness() * .5f;
        // Ensure stroke radius is nonzero. (In PLS, zero radius means the path is filled.)
        m_strokeRadius = fmaxf(m_strokeRadius, std::numeric_limits<float>::min());
        assert(!std::isnan(m_strokeRadius)); // These should get culled in PLSRenderer::drawPath().
        assert(m_strokeRadius > 0);
    }
    else if (m_fillRule == FillRule::evenOdd)
    {
        m_drawContents |= pls::DrawContents::evenOddFill;
    }
    if (paint->getType() == pls::PaintType::clipUpdate)
    {
        m_drawContents |= pls::DrawContents::clipUpdate;
        if (paint->getSimpleValue().outerClipID != 0)
        {
            m_drawContents |= pls::DrawContents::activeClip;
        }
    }

    if (isStroked())
    {
        // Stroke triangles are always forward.
        m_contourDirections = pls::ContourDirections::forward;
    }
    else if (frameInterlockMode != pls::InterlockMode::depthStencil)
    {
        // atomic and rasterOrdering fills need reverse AND forward triangles.
        m_contourDirections = pls::ContourDirections::reverseAndForward;
    }
    else if (m_fillRule != FillRule::evenOdd)
    {
        // Emit "nonZero" depthStencil fills in a direction such that the dominant triangle winding
        // area is always clockwise. This maximizes pixel throughput since we will draw
        // counterclockwise triangles twice and clockwise only once.
        float matrixDeterminant = matrix[0] * matrix[3] - matrix[2] * matrix[1];
        m_contourDirections = m_pathRef->getCoarseArea() * matrixDeterminant >= 0
                                  ? pls::ContourDirections::forward
                                  : pls::ContourDirections::reverse;
    }
    else
    {
        // "evenOdd" depthStencil fils just get drawn twice, so any direction is fine.
        m_contourDirections = pls::ContourDirections::forward;
    }

    m_simplePaintValue = paint->getSimpleValue();
    m_gradientRef = safe_ref(paint->getGradient());
    RIVE_DEBUG_CODE(m_pathRef->lockRawPathMutations();)
    RIVE_DEBUG_CODE(m_rawPathMutationID = m_pathRef->getRawPathMutationID();)
    assert(isStroked() == (strokeRadius() > 0));
}

void PLSPathDraw::pushToRenderContext(PLSRenderContext::LogicalFlush* flush)
{
    // Make sure the rawPath in our path reference hasn't changed since we began holding!
    assert(m_rawPathMutationID == m_pathRef->getRawPathMutationID());
    assert(!m_pathRef->getRawPath().empty());

    size_t tessVertexCount = m_type == Type::midpointFanPath
                                 ? m_resourceCounts.midpointFanTessVertexCount
                                 : m_resourceCounts.outerCubicTessVertexCount;
    if (tessVertexCount > 0)
    {
        // Push a path record.
        flush->pushPath(this,
                        m_type == Type::midpointFanPath ? PatchType::midpointFan
                                                        : PatchType::outerCurves,
                        tessVertexCount);

        onPushToRenderContext(flush);
    }
}

void PLSPathDraw::releaseRefs()
{
    PLSDraw::releaseRefs();
    RIVE_DEBUG_CODE(m_pathRef->unlockRawPathMutations();)
    m_pathRef->unref();
}

MidpointFanPathDraw::MidpointFanPathDraw(PLSRenderContext* context,
                                         IAABB pixelBounds,
                                         const Mat2D& matrix,
                                         rcp<const PLSPath> path,
                                         FillRule fillRule,
                                         const PLSPaint* paint) :
    PLSPathDraw(pixelBounds,
                matrix,
                std::move(path),
                fillRule,
                paint,
                Type::midpointFanPath,
                context->frameInterlockMode())
{
    if (isStroked())
    {
        m_strokeMatrixMaxScale = m_matrix.findMaxScale();
        m_strokeJoin = paint->getJoin();
        m_strokeCap = paint->getCap();
    }

    // Count up how much temporary storage this function will need to reserve in CPU buffers.
    const RawPath& rawPath = m_pathRef->getRawPath();
    size_t contourCount = rawPath.countMoveTos();
    assert(contourCount != 0);

    m_contours = reinterpret_cast<ContourInfo*>(
        context->perFrameAllocator().alloc(sizeof(ContourInfo) * contourCount));

    size_t maxStrokedCurvesBeforeChops = 0;
    size_t maxCurves = 0;
    size_t maxRotations = 0;
    // 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 pathMaxLinesOrCurvesBeforeChops = rawPath.verbs().size() - 1;
    // Stroked cubics can be chopped into a maximum of 5 segments.
    size_t pathMaxLinesOrCurvesAfterChops =
        isStroked() ? pathMaxLinesOrCurvesBeforeChops * 5 : pathMaxLinesOrCurvesBeforeChops;
    maxCurves += pathMaxLinesOrCurvesAfterChops;
    if (isStroked())
    {
        maxStrokedCurvesBeforeChops += pathMaxLinesOrCurvesBeforeChops;
        maxRotations += pathMaxLinesOrCurvesAfterChops;
        if (m_strokeJoin == StrokeJoin::round)
        {
            // If the stroke has round joins, we also record the rotations between (pre-chopped)
            // joins in order to calculate how many vertices are in each round join.
            maxRotations += pathMaxLinesOrCurvesBeforeChops;
        }
    }

    // Each stroked curve will record the number of chops it requires (either 0, 1, or 2).
    size_t maxChops = maxStrokedCurvesBeforeChops;
    // 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 5 internal points per chop.
    size_t maxChopVertices = maxStrokedCurvesBeforeChops * 5;
    // +3 for each contour because we align each contour's curves and rotations on multiples of 4.
    size_t maxPaddedRotations = isStroked() ? maxRotations + contourCount * 3 : 0;
    size_t maxPaddedCurves = maxCurves + contourCount * 3;

    // Reserve intermediate space for the polar segment counts of each curve and round join.
    if (isStroked())
    {
        m_numChops.reset(context->numChopsAllocator(), maxChops);
        m_chopVertices.reset(context->chopVerticesAllocator(), maxChopVertices);
        m_tangentPairs = context->tangentPairsAllocator().alloc(maxPaddedRotations);
        m_polarSegmentCounts = context->polarSegmentCountsAllocator().alloc(maxPaddedRotations);
    }
    m_parametricSegmentCounts = context->parametricSegmentCountsAllocator().alloc(maxPaddedCurves);

    size_t lineCount = 0;
    size_t unpaddedCurveCount = 0;
    size_t unpaddedRotationCount = 0;
    size_t emptyStrokeCountForCaps = 0;

    // Iteration pass 1: Collect information on contour and curves counts for every path in the
    // batch, and begin counting tessellated vertices.
    size_t contourIdx = 0;
    size_t curveIdx = 0;
    size_t rotationIdx = 0; // We measure rotations on both curves and round joins.
    bool roundJoinStroked = isStroked() && m_strokeJoin == StrokeJoin::round;
    wangs_formula::VectorXform vectorXform(m_matrix);
    RawPath::Iter startOfContour = rawPath.begin();
    RawPath::Iter end = rawPath.end();
    int preChopVerbCount = 0; // Original number of lines and curves, before chopping.
    Vec2D endpointsSum{};
    bool closed = !isStroked();
    Vec2D lastTangent = {0, 1};
    Vec2D firstTangent = {0, 1};
    size_t roundJoinCount = 0;
    size_t contourFirstCurveIdx = curveIdx;
    assert(contourFirstCurveIdx % 4 == 0);
    size_t contourFirstRotationIdx = rotationIdx;
    assert(contourFirstRotationIdx % 4 == 0);
    auto finishAndAppendContour = [&](RawPath::Iter iter) {
        if (closed)
        {
            Vec2D finalPtInContour = iter.rawPtsPtr()[-1];
            // Bit-cast to uint64_t because we don't want the special equality rules for NaN. If
            // we're empty or otherwise return back to p0, we want to detect this, regardless of
            // whether there are NaN values.
            if (math::bit_cast<uint64_t>(startOfContour.movePt()) !=
                math::bit_cast<uint64_t>(finalPtInContour))
            {
                assert(preChopVerbCount > 0);
                if (roundJoinStroked)
                {
                    // Round join before implicit closing line.
                    Vec2D tangent = startOfContour.movePt() - finalPtInContour;
                    assert(rotationIdx < maxPaddedRotations);
                    m_tangentPairs[rotationIdx++] = {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(rotationIdx < maxPaddedRotations);
                m_tangentPairs[rotationIdx++] = {lastTangent, firstTangent};
                ++roundJoinCount;
            }
        }
        size_t strokeJoinCount = preChopVerbCount;
        if (!closed)
        {
            strokeJoinCount = std::max<size_t>(strokeJoinCount, 1) - 1;
        }
        assert(contourIdx < contourCount);
        m_contours[contourIdx++] = {
            iter,
            lineCount,
            contourFirstCurveIdx,
            curveIdx,
            contourFirstRotationIdx,
            rotationIdx,
            isStroked() ? Vec2D() : endpointsSum * (1.f / preChopVerbCount),
            closed,
            strokeJoinCount,
            0,                 // strokeCapSegmentCount
            0,                 // paddingVertexCount
            RIVE_DEBUG_CODE(0) // tessVertexCount
        };
        unpaddedCurveCount += curveIdx - contourFirstCurveIdx;
        contourFirstCurveIdx = curveIdx = math::round_up_to_multiple_of<4>(curveIdx);
        unpaddedRotationCount += rotationIdx - contourFirstRotationIdx;
        contourFirstRotationIdx = rotationIdx = math::round_up_to_multiple_of<4>(rotationIdx);
    };
    const int styleFlags = style_flags(isStroked(), 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 = !isStroked();
                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(rotationIdx < maxPaddedRotations);
                    m_tangentPairs[rotationIdx++] = {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(rotationIdx < maxPaddedRotations);
                    m_tangentPairs[rotationIdx++] = {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_chopVertices.push_back() = {t[0], t[1]};
                        chop_cubic_around_cusps(p,
                                                localChopBuffer,
                                                t,
                                                numChops,
                                                m_strokeMatrixMaxScale);
                        p = localChopBuffer;
                        numChops *= 2;
                        break;
                    case simple_chop_key(2): // 2 non-cusp chops
                        m_chopVertices.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
                    {
                        pathutils::ChopCubicAt(p, localChopBuffer, t[0]);
                        p = localChopBuffer;
                        memcpy(m_chopVertices.push_back_n(5), p + 1, sizeof(Vec2D) * 5);
                        break;
                    }
                }
                // Calculate segment counts for each chopped section independently.
                for (const Vec2D* end = p + numChops * 3 + 3; p != end;
                     p += 3, ++curveIdx, ++rotationIdx)
                {
                    float n4 = wangs_formula::cubic_pow4(p, kParametricPrecision, vectorXform);
                    // Record n^4 for now. This will get resolved later.
                    assert(curveIdx < maxPaddedCurves);
                    RIVE_INLINE_MEMCPY(m_parametricSegmentCounts + curveIdx, &n4, sizeof(uint32_t));
                    assert(rotationIdx < maxPaddedRotations);
                    find_cubic_tangents(p, m_tangentPairs[rotationIdx].data());
                }
                break;
            }
            case StyledVerb::filledCubic:
            {
                const Vec2D* p = iter.cubicPts();
                ++preChopVerbCount;
                endpointsSum += p[3];
                float n4 = wangs_formula::cubic_pow4(p, kParametricPrecision, vectorXform);
                // Record n^4 for now. This will get resolved later.
                assert(curveIdx < maxPaddedCurves);
                RIVE_INLINE_MEMCPY(m_parametricSegmentCounts + curveIdx++, &n4, sizeof(uint32_t));
                break;
            }
        }
    }
    if (startOfContour != end)
    {
        finishAndAppendContour(end);
    }
    assert(contourIdx == contourCount);
    assert(contourCount > 0);
    assert(curveIdx <= maxPaddedCurves);
    assert(rotationIdx <= maxPaddedRotations);
    assert(curveIdx % 4 == 0);    // Because we write parametric segment counts in batches of 4.
    assert(rotationIdx % 4 == 0); // Because we write polar segment counts in batches of 4.
    assert(isStroked() || maxPaddedRotations == 0);
    assert(isStroked() || rotationIdx == 0);

    // Return any data we conservatively allocated but did not use.
    if (isStroked())
    {
        m_numChops.shrinkToFit(context->numChopsAllocator(), maxChops);
        m_chopVertices.shrinkToFit(context->chopVerticesAllocator(), maxChopVertices);
        context->tangentPairsAllocator().rewindLastAllocation(maxPaddedRotations - rotationIdx);
        context->polarSegmentCountsAllocator().rewindLastAllocation(maxPaddedRotations -
                                                                    rotationIdx);
    }
    context->parametricSegmentCountsAllocator().rewindLastAllocation(maxPaddedCurves - curveIdx);

    // Iteration pass 2: Finish calculating the numbers of tessellation segments in each contour,
    // using SIMD.
    size_t contourFirstLineIdx = 0;
    size_t tessVertexCount = 0;
    for (size_t i = 0; i < contourCount; ++i)
    {
        ContourInfo* contour = &m_contours[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 = contour->firstCurveIdx; j < contour->endCurveIdx; j += 4)
        {
            // Curves recorded their segment counts raised to the 4th power. Now find their
            // roots and convert to integers in batches of 4.
            assert(j + 4 <= curveIdx);
            float4 n = simd::load4f(m_parametricSegmentCounts + 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 <= curveIdx);
            simd::store(m_parametricSegmentCounts + 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 (isStroked())
        {
            // Finish calculating and counting polar segments for each stroked curve and
            // round join.
            const float r_ = m_strokeRadius * m_strokeMatrixMaxScale;
            const float polarSegmentsPerRad =
                pathutils::CalcPolarSegmentsPerRadian<kPolarPrecision>(r_);
            for (j = contour->firstRotationIdx; j < contour->endRotationIdx; j += 4)
            {
                // Measure the rotations of curves in batches of 4.
                assert(j + 4 <= rotationIdx);

                float4 tx0, ty0, tx1, ty1;
                std::tie(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 <= rotationIdx);
                simd::store(m_polarSegmentCounts + 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 (m_strokeJoin == 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 == contour->firstCurveIdx;
            StrokeCap cap;
            bool needsCaps;
            if (!empty)
            {
                cap = m_strokeCap;
                needsCaps = !contour->closed;
            }
            else
            {
                cap = empty_stroke_cap(contour->closed, m_strokeJoin, m_strokeCap);
                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.
                    float 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.
                    strokeCapSegmentCount += 2;
                    // Make sure not to exceed kMaxPolarSegments.
                    strokeCapSegmentCount = fminf(strokeCapSegmentCount, kMaxPolarSegments);
                    contour->strokeCapSegmentCount = static_cast<uint32_t>(strokeCapSegmentCount);
                }
                else
                {
                    contour->strokeCapSegmentCount = kNumSegmentsInMiterOrBevelJoin;
                }
                // PLS expects all patches to have >0 tessellation vertices, so for the case of an
                // empty patch with a stroke cap, contour->strokeCapSegmentCount can't be zero.
                // Also, pushContourToRenderContext() uses "strokeCapSegmentCount != 0" to tell if
                // it needs stroke caps.
                assert(contour->strokeCapSegmentCount >= 2);
                // 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 - contour->firstCurveIdx;
            contourVertexCount += contourCurveCount;
        }
        contourVertexCount += simd::reduce_add(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;)

        tessVertexCount += contourVertexCount;
        contourFirstLineIdx = contour->endLineIdx;
    }

    assert(contourFirstLineIdx == lineCount);
    RIVE_DEBUG_CODE(m_pendingLineCount = lineCount);
    RIVE_DEBUG_CODE(m_pendingCurveCount = unpaddedCurveCount);
    RIVE_DEBUG_CODE(m_pendingRotationCount = unpaddedRotationCount);
    RIVE_DEBUG_CODE(m_pendingEmptyStrokeCountForCaps = emptyStrokeCountForCaps);

    if (tessVertexCount > 0)
    {
        m_resourceCounts.pathCount = 1;
        m_resourceCounts.contourCount = contourCount;
        // maxTessellatedSegmentCount does not get doubled when we emit both forward and mirrored
        // contours because the forward and mirrored pair both get packed into a single
        // pls::TessVertexSpan.
        m_resourceCounts.maxTessellatedSegmentCount =
            lineCount + unpaddedCurveCount + emptyStrokeCountForCaps;
        m_resourceCounts.midpointFanTessVertexCount =
            m_contourDirections == pls::ContourDirections::reverseAndForward ? tessVertexCount * 2
                                                                             : tessVertexCount;
    }
}

void MidpointFanPathDraw::onPushToRenderContext(PLSRenderContext::LogicalFlush* flush)
{
    const RawPath& rawPath = m_pathRef->getRawPath();
    RawPath::Iter startOfContour = rawPath.begin();
    for (size_t i = 0; i < m_resourceCounts.contourCount; ++i)
    {
        // Push a contour and curve records.
        const ContourInfo& contour = m_contours[i];
        assert(startOfContour.verb() == PathVerb::move);
        assert(isStroked() || contour.closed); // Fills are always closed.
        RIVE_DEBUG_CODE(m_pendingStrokeJoinCount = isStroked() ? contour.strokeJoinCount : 0;)
        RIVE_DEBUG_CODE(m_pendingStrokeCapCount = contour.strokeCapSegmentCount != 0 ? 2 : 0;)

        const Vec2D* pts = startOfContour.rawPtsPtr();
        size_t curveIdx = contour.firstCurveIdx;
        size_t rotationIdx = contour.firstRotationIdx;
        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 (isStroked())
        {
            joinTypeFlags = join_type_flags(m_strokeJoin);
            roundJoinStroked = joinTypeFlags == 0;
            if (contour.strokeCapSegmentCount != 0)
            {
                StrokeCap cap = !contour.closed ? m_strokeCap
                                                : empty_stroke_cap(true, m_strokeJoin, m_strokeCap);
                emulatedCapAsJoinFlags = EMULATED_STROKE_CAP_CONTOUR_FLAG;
                if (cap == StrokeCap::square)
                {
                    emulatedCapAsJoinFlags |= MITER_CLIP_JOIN_CONTOUR_FLAG;
                }
                else if (cap == StrokeCap::butt)
                {
                    emulatedCapAsJoinFlags |= BEVEL_JOIN_CONTOUR_FLAG;
                }
                needsFirstEmulatedCapAsJoin = true;
            }
        }

        // Make a data record for this current contour on the GPU.
        flush->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(isStroked(), roundJoinStroked);
        Vec2D joinTangent = {0, 1};
        int joinSegmentCount = 1;
        Vec2D implicitClose[2]; // In case we need an implicit closing line.
        for (auto iter = startOfContour; 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_pendingRotationCount;)
                        RIVE_DEBUG_CODE(--m_pendingStrokeJoinCount;)
                    }
                    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_pendingStrokeCapCount;)
                    }
                    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_pendingStrokeJoinCount;)
                    }
                    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_pendingStrokeCapCount;)
                    }
                    [[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(flush,
                                                               cubic.data(),
                                                               emulatedCapAsJoinFlags,
                                                               contour.strokeCapSegmentCount);
                        needsFirstEmulatedCapAsJoin = false;
                    }
                    flush->pushCubic(cubic.data(),
                                     joinTangent,
                                     joinTypeFlags,
                                     1,
                                     1,
                                     joinSegmentCount);
                    RIVE_DEBUG_CODE(--m_pendingLineCount;)
                    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_chopVertices.pop_front().x,
                                                    chopKey >> 1,
                                                    m_strokeMatrixMaxScale);
                            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_chopVertices.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_chopVertices queue.
                            localChopBuffer[0] = p[0];
                            memcpy(localChopBuffer + 1,
                                   m_chopVertices.pop_front_n(5),
                                   sizeof(Vec2D) * 5);
                            localChopBuffer[6] = p[3];
                            p = localChopBuffer;
                            numChops = 1;
                            break;
                    }
                    if (needsFirstEmulatedCapAsJoin)
                    {
                        // Emulate the start cap as a 180-degree join before the first stroke.
                        pushEmulatedStrokeCapAsJoinBeforeCubic(flush,
                                                               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];
                        flush->pushCubic(p,
                                         joinTangent,
                                         joinTypeFlags,
                                         parametricSegmentCount,
                                         polarSegmentCount,
                                         1);
                        RIVE_DEBUG_CODE(--m_pendingCurveCount;)
                        RIVE_DEBUG_CODE(--m_pendingRotationCount;)
                    }
                    // Push the final chop, with a join.
                    uint32_t parametricSegmentCount = m_parametricSegmentCounts[curveIdx++];
                    uint32_t polarSegmentCount = m_polarSegmentCounts[rotationIdx++];
                    RIVE_DEBUG_CODE(--m_pendingRotationCount;)
                    if (contour.closed || !is_final_verb_of_contour(iter, end))
                    {
                        if (styledVerb == StyledVerb::roundJoinStrokedCubic)
                        {
                            joinTangent = m_tangentPairs[rotationIdx][1];
                            joinSegmentCount = m_polarSegmentCounts[rotationIdx];
                            ++rotationIdx;
                            RIVE_DEBUG_CODE(--m_pendingRotationCount;)
                        }
                        else
                        {
                            joinTangent = find_join_tangent(iter.cubicPts() + 3,
                                                            end.rawPtsPtr(),
                                                            contour.closed,
                                                            pts);
                            joinSegmentCount = kNumSegmentsInMiterOrBevelJoin;
                        }
                        RIVE_DEBUG_CODE(--m_pendingStrokeJoinCount;)
                    }
                    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_pendingStrokeCapCount;)
                    }
                    flush->pushCubic(p,
                                     joinTangent,
                                     joinTypeFlags,
                                     parametricSegmentCount,
                                     polarSegmentCount,
                                     joinSegmentCount);
                    RIVE_DEBUG_CODE(--m_pendingCurveCount;)
                    break;
                }
                case StyledVerb::filledCubic:
                {
                    uint32_t parametricSegmentCount = m_parametricSegmentCounts[curveIdx++];
                    flush->pushCubic(iter.cubicPts(), Vec2D{}, 0, parametricSegmentCount, 1, 1);
                    RIVE_DEBUG_CODE(--m_pendingCurveCount;)
                    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(flush,
                                                   std::array{p0, right, right, right}.data(),
                                                   emulatedCapAsJoinFlags,
                                                   contour.strokeCapSegmentCount);
            pushEmulatedStrokeCapAsJoinBeforeCubic(flush,
                                                   std::array{p0, left, left, left}.data(),
                                                   emulatedCapAsJoinFlags,
                                                   contour.strokeCapSegmentCount);
        }
        else if (contour.closed)
        {
            implicitClose[0] = end.rawPtsPtr()[-1];
            // Bit-cast to uint64_t because we don't want the special equality rules for NaN. If
            // we're empty or otherwise return back to p0, we want to detect this, regardless of
            // whether there are NaN values.
            if (math::bit_cast<uint64_t>(implicitClose[0]) !=
                math::bit_cast<uint64_t>(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_pendingRotationCount;)
                    RIVE_DEBUG_CODE(--m_pendingStrokeJoinCount;)
                }
                else if (isStroked())
                {
                    joinTangent = find_starting_tangent(pts, end.rawPtsPtr());
                    joinSegmentCount = kNumSegmentsInMiterOrBevelJoin;
                    RIVE_DEBUG_CODE(--m_pendingStrokeJoinCount;)
                }
                flush->pushCubic(cubic.data(), joinTangent, joinTypeFlags, 1, 1, joinSegmentCount);
                RIVE_DEBUG_CODE(--m_pendingLineCount;)
            }
        }

        assert(curveIdx == contour.endCurveIdx);
        assert(rotationIdx == contour.endRotationIdx);

        assert(m_pendingStrokeJoinCount == 0);
        assert(m_pendingStrokeCapCount == 0);
        startOfContour = contour.endOfContour;
    }

    // Make sure we only pushed the amount of data we reserved.
    assert(m_pendingLineCount == 0);
    assert(m_pendingCurveCount == 0);
    assert(m_pendingRotationCount == 0);
    assert(m_pendingEmptyStrokeCountForCaps == 0);
}

void MidpointFanPathDraw::pushEmulatedStrokeCapAsJoinBeforeCubic(
    PLSRenderContext::LogicalFlush* flush,
    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.
    assert(strokeCapSegmentCount >= 2);
    flush->pushCubic(std::array{cubic[3], cubic[2], cubic[1], cubic[0]}.data(),
                     find_cubic_tan0(cubic),
                     emulatedCapAsJoinFlags,
                     0,
                     0,
                     strokeCapSegmentCount);
    RIVE_DEBUG_CODE(--m_pendingStrokeCapCount;)
    RIVE_DEBUG_CODE(--m_pendingEmptyStrokeCountForCaps;)
}

InteriorTriangulationDraw::InteriorTriangulationDraw(PLSRenderContext* context,
                                                     IAABB pixelBounds,
                                                     const Mat2D& matrix,
                                                     rcp<const PLSPath> path,
                                                     FillRule fillRule,
                                                     const PLSPaint* paint,
                                                     RawPath* scratchPath,
                                                     TriangulatorAxis triangulatorAxis) :
    PLSPathDraw(pixelBounds,
                matrix,
                std::move(path),
                fillRule,
                paint,
                Type::interiorTriangulationPath,
                context->frameInterlockMode())
{
    assert(!isStroked());
    assert(m_strokeRadius == 0);
    processPath(PathOp::countDataAndTriangulate,
                &context->perFrameAllocator(),
                scratchPath,
                triangulatorAxis,
                nullptr);
}

void InteriorTriangulationDraw::onPushToRenderContext(PLSRenderContext::LogicalFlush* flush)
{
    processPath(PathOp::submitOuterCubics, nullptr, nullptr, TriangulatorAxis::dontCare, flush);
    if (flush->desc().interlockMode == pls::InterlockMode::atomics)
    {
        // We need a barrier between the outer cubics and interior triangles in atomic mode.
        flush->pushBarrier();
    }
    flush->pushInteriorTriangulation(this);
}

void InteriorTriangulationDraw::processPath(PathOp op,
                                            TrivialBlockAllocator* allocator,
                                            RawPath* scratchPath,
                                            TriangulatorAxis triangulatorAxis,
                                            PLSRenderContext::LogicalFlush* flush)
{
    Vec2D chops[kMaxCurveSubdivisions * 3 + 1];
    const RawPath& rawPath = m_pathRef->getRawPath();
    assert(!rawPath.empty());
    wangs_formula::VectorXform vectorXform(m_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)
                    {
                        flush->pushCubic(convert_line_to_cubic(pts[-1], p0).data(),
                                         {0, 0},
                                         CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG,
                                         kPatchSegmentCountExcludingJoin,
                                         1,
                                         kJoinSegmentCount);
                    }
                    ++patchCount;
                }
                if (op == PathOp::countDataAndTriangulate)
                {
                    scratchPath->move(pts[0]);
                }
                else
                {
                    flush->pushContour({0, 0}, true, 0);
                }
                p0 = pts[0];
                ++contourCount;
                break;
            case PathVerb::line:
                if (op == PathOp::countDataAndTriangulate)
                {
                    scratchPath->line(pts[1]);
                }
                else
                {
                    flush->pushCubic(convert_line_to_cubic(pts).data(),
                                     {0, 0},
                                     CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG,
                                     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
                    {
                        flush->pushCubic(pts,
                                         {0, 0},
                                         CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG,
                                         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
                        {
                            flush->pushCubic(chop,
                                             {0, 0},
                                             CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG,
                                             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)
        {
            flush->pushCubic(convert_line_to_cubic(lastPt, p0).data(),
                             {0, 0},
                             CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG,
                             kPatchSegmentCountExcludingJoin,
                             1,
                             kJoinSegmentCount);
        }
        ++patchCount;
    }

    if (op == PathOp::countDataAndTriangulate)
    {
        assert(m_triangulator == nullptr);
        assert(triangulatorAxis != TriangulatorAxis::dontCare);
        m_triangulator = allocator->make<GrInnerFanTriangulator>(
            *scratchPath,
            m_matrix,
            triangulatorAxis == TriangulatorAxis::horizontal
                ? GrTriangulator::Comparator::Direction::kHorizontal
                : GrTriangulator::Comparator::Direction::kVertical,
            m_fillRule,
            allocator);
        // We also draw each "grout" triangle using an outerCubic patch.
        patchCount += m_triangulator->groutList().count();

        if (patchCount > 0)
        {
            m_resourceCounts.pathCount = 1;
            m_resourceCounts.contourCount = contourCount;
            // maxTessellatedSegmentCount does not get doubled when we emit both forward and
            // mirrored contours because the forward and mirrored pair both get packed into a single
            // pls::TessVertexSpan.
            m_resourceCounts.maxTessellatedSegmentCount = patchCount;
            // outerCubic patches emit their tessellated geometry twice: once forward and once
            // mirrored.
            m_resourceCounts.outerCubicTessVertexCount =
                m_contourDirections == pls::ContourDirections::reverseAndForward
                    ? patchCount * kOuterCurvePatchSegmentSpan * 2
                    : patchCount * kOuterCurvePatchSegmentSpan;
            m_resourceCounts.maxTriangleVertexCount = m_triangulator->maxVertexCount();
        }
    }
    else
    {
        assert(m_triangulator != nullptr);
        // Submit grout triangles, retrofitted into outerCubic patches.
        for (auto* node = m_triangulator->groutList().head(); node; node = node->fNext)
        {
            Vec2D triangleAsCubic[4] = {node->fPts[0], node->fPts[1], {0, 0}, node->fPts[2]};
            flush->pushCubic(triangleAsCubic,
                             {0, 0},
                             RETROFITTED_TRIANGLE_CONTOUR_FLAG,
                             kPatchSegmentCountExcludingJoin,
                             1,
                             kJoinSegmentCount);
            ++patchCount;
        }
        assert(contourCount == m_resourceCounts.contourCount);
        assert(patchCount == m_resourceCounts.maxTessellatedSegmentCount);
        assert(patchCount * kOuterCurvePatchSegmentSpan * 2 ==
                   m_resourceCounts.outerCubicTessVertexCount ||
               patchCount * kOuterCurvePatchSegmentSpan ==
                   m_resourceCounts.outerCubicTessVertexCount);
    }
}

ImageRectDraw::ImageRectDraw(PLSRenderContext* context,
                             IAABB pixelBounds,
                             const Mat2D& matrix,
                             BlendMode blendMode,
                             rcp<const PLSTexture> imageTexture,
                             float opacity) :
    PLSDraw(pixelBounds, matrix, blendMode, std::move(imageTexture), Type::imageRect),
    m_opacity(opacity)
{
    // If we support image paints for paths, the client should draw a rectangular path with an
    // image paint instead of using this draw.
    assert(!context->frameSupportsImagePaintForPaths());
    m_resourceCounts.imageDrawCount = 1;
}

void ImageRectDraw::pushToRenderContext(PLSRenderContext::LogicalFlush* flush)
{
    flush->pushImageRect(this);
}

ImageMeshDraw::ImageMeshDraw(IAABB pixelBounds,
                             const Mat2D& matrix,
                             BlendMode blendMode,
                             rcp<const PLSTexture> imageTexture,
                             rcp<const RenderBuffer> vertexBuffer,
                             rcp<const RenderBuffer> uvBuffer,
                             rcp<const RenderBuffer> indexBuffer,
                             uint32_t indexCount,
                             float opacity) :
    PLSDraw(pixelBounds, matrix, blendMode, std::move(imageTexture), Type::imageMesh),
    m_vertexBufferRef(vertexBuffer.release()),
    m_uvBufferRef(uvBuffer.release()),
    m_indexBufferRef(indexBuffer.release()),
    m_indexCount(indexCount),
    m_opacity(opacity)
{
    assert(m_vertexBufferRef != nullptr);
    assert(m_uvBufferRef != nullptr);
    assert(m_indexBufferRef != nullptr);
    m_resourceCounts.imageDrawCount = 1;
}

void ImageMeshDraw::pushToRenderContext(PLSRenderContext::LogicalFlush* flush)
{
    flush->pushImageMesh(this);
}

void ImageMeshDraw::releaseRefs()
{
    PLSDraw::releaseRefs();
    m_vertexBufferRef->unref();
    m_uvBufferRef->unref();
    m_indexBufferRef->unref();
}

StencilClipReset::StencilClipReset(PLSRenderContext* context,
                                   uint32_t previousClipID,
                                   ResetAction resetAction) :
    PLSDraw(context->getClipContentBounds(previousClipID),
            Mat2D(),
            BlendMode::srcOver,
            nullptr,
            Type::stencilClipReset),
    m_previousClipID(previousClipID)
{
    switch (resetAction)
    {
        case ResetAction::intersectPreviousClip:
            m_drawContents |= pls::DrawContents::activeClip;
            [[fallthrough]];
        case ResetAction::clearPreviousClip:
            m_drawContents |= pls::DrawContents::clipUpdate;
            break;
    }
    m_resourceCounts.maxTriangleVertexCount = 6;
}

void StencilClipReset::pushToRenderContext(PLSRenderContext::LogicalFlush* flush)
{
    flush->pushStencilClipReset(this);
}
} // namespace rive::pls
