/*
 * 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] = 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(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 &&
            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(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 = std::max(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());

    size_t tessVertexCount = m_type == Type::midpointFanPath
                                 ? m_resourceCounts.midpointFanTessVertexCount
                                 : m_resourceCounts.outerCubicTessVertexCount;
    if (tessVertexCount == 0)
    {
        return;
    }
    assert(!m_pathRef->getRawPath().empty());

    // 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();
    if (contourCount == 0)
    {
        // The entire batch is empty.
        return;
    }

    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 inside
            // of Vec2D::operator==. 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);
                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 <= 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.
                    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;
                }
                // pushContourToRenderContext() 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 - 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];
            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_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.
    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();

        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
