/*
 * Copyright 2023 Rive
 */

#include "rive/renderer/draw.hpp"

#include "gr_inner_fan_triangulator.hpp"
#include "rive_render_path.hpp"
#include "rive_render_paint.hpp"
#include "rive/math/bezier_utils.hpp"
#include "rive/math/wangs_formula.hpp"
#include "rive/renderer/texture.hpp"
#include "gradient.hpp"
#include "shaders/constants.glsl"
#include "rive/profiler/profiler_macros.h"

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

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

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

constexpr static int NUM_SEGMENTS_IN_MITER_OR_BEVEL_JOIN = 5;
constexpr static int STROKE_OR_FEATHER_STYLE_FLAG = 8;
constexpr static int ROUND_JOIN_STYLE_FLAG = STROKE_OR_FEATHER_STYLE_FLAG << 1;
RIVE_ALWAYS_INLINE constexpr int style_flags(bool isStrokeOrFeather,
                                             bool roundJoinStroked)
{
    int styleFlags = (isStrokeOrFeather << 3) | (roundJoinStroked << 4);
    assert(bool(styleFlags & STROKE_OR_FEATHER_STYLE_FLAG) ==
           isStrokeOrFeather);
    assert(bool(styleFlags & ROUND_JOIN_STYLE_FLAG) == 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 =
        STROKE_OR_FEATHER_STYLE_FLAG | static_cast<int>(PathVerb::move),
    roundJoinStrokedMove = STROKE_OR_FEATHER_STYLE_FLAG |
                           ROUND_JOIN_STYLE_FLAG |
                           static_cast<int>(PathVerb::move),

    filledLine = static_cast<int>(PathVerb::line),
    strokedLine =
        STROKE_OR_FEATHER_STYLE_FLAG | static_cast<int>(PathVerb::line),
    roundJoinStrokedLine = STROKE_OR_FEATHER_STYLE_FLAG |
                           ROUND_JOIN_STYLE_FLAG |
                           static_cast<int>(PathVerb::line),

    filledQuad = static_cast<int>(PathVerb::quad),
    strokedQuad =
        STROKE_OR_FEATHER_STYLE_FLAG | static_cast<int>(PathVerb::quad),
    roundJoinStrokedQuad = STROKE_OR_FEATHER_STYLE_FLAG |
                           ROUND_JOIN_STYLE_FLAG |
                           static_cast<int>(PathVerb::quad),

    filledCubic = static_cast<int>(PathVerb::cubic),
    strokedCubic =
        STROKE_OR_FEATHER_STYLE_FLAG | static_cast<int>(PathVerb::cubic),
    roundJoinStrokedCubic = STROKE_OR_FEATHER_STYLE_FLAG |
                            ROUND_JOIN_STYLE_FLAG |
                            static_cast<int>(PathVerb::cubic),

    filledClose = static_cast<int>(PathVerb::close),
    strokedClose =
        STROKE_OR_FEATHER_STYLE_FLAG | static_cast<int>(PathVerb::close),
    roundJoinStrokedClose = STROKE_OR_FEATHER_STYLE_FLAG |
                            ROUND_JOIN_STYLE_FLAG |
                            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);
}

// 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);
    }
    math::chop_cubic_at(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 = math::eval_cubic_at(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 ROUND_JOIN_CONTOUR_FLAG;
        case StrokeJoin::bevel:
            return BEVEL_JOIN_CONTOUR_FLAG;
    }
    RIVE_UNREACHABLE();
}

inline float find_feather_radius(float paintFeather)
{
    // Blur magnitudes in design tools are customarily the width of two standard
    // deviations, or, the length of the range -1stddev .. +1stddev.
    return paintFeather * (FEATHER_TEXTURE_STDDEVS / 2);
}

inline float find_atlas_feather_scale_factor(float featherRadius,
                                             float matrixMaxScale)
{
    // In practice, and with "gaussian -> linear -> gaussian" filtering, we
    // never need to render a blur with a radius larger than 16 pixels. After
    // this point, we can just scale it up to whatever resolution it needs to be
    // displayed at.
    return 16.f / fmaxf(featherRadius * matrixMaxScale, 16);
}

static uint32_t feather_join_segment_count(float polarSegmentsPerRadian)
{
    uint32_t n =
        static_cast<uint32_t>(ceilf(polarSegmentsPerRadian * math::PI)) +
        FEATHER_JOIN_HELPER_SEGMENT_COUNT;
    n = std::max(n, FEATHER_JOIN_MIN_SEGMENT_COUNT);
    // FEATHER_POLAR_SEGMENT_MIN_ANGLE should limit n long before we reach
    // kMaxPolarSegments.
    assert(n < gpu::kMaxPolarSegments);
    return n;
}
} // namespace

Draw::Draw(IAABB pixelBounds,
           const Mat2D& matrix,
           BlendMode blendMode,
           rcp<Texture> imageTexture,
           ImageSampler imageSampler,
           Type type) :
    m_imageTextureRef(imageTexture.release()),
    m_imageSampler(imageSampler),
    m_pixelBounds(pixelBounds),
    m_matrix(matrix),
    m_blendMode(blendMode),
    m_type(type),
    m_clippedPixelBounds(pixelBounds)
{
    if (m_blendMode != BlendMode::srcOver)
    {
        m_drawContents |= gpu::DrawContents::advancedBlend;
    }
}

void Draw::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 (!enums::is_flag_set(m_drawContents, gpu::DrawContents::clipUpdate))
    {
        if (m_clipID != 0)
        {
            m_drawContents |= gpu::DrawContents::activeClip;
        }
        else
        {
            m_drawContents &= ~gpu::DrawContents::activeClip;
        }
    }
}

void Draw::releaseRefs() { safe_unref(m_imageTextureRef); }

PathDraw::CoverageType PathDraw::SelectCoverageType(
    const RiveRenderPaint* paint,
    float matrixMaxScale,
    const gpu::PlatformFeatures& platformFeatures,
    gpu::InterlockMode interlockMode)
{
    if (paint->getFeather() != 0)
    {
        if (platformFeatures.alwaysFeatherToAtlas ||
            interlockMode == gpu::InterlockMode::msaa ||
            // Always switch to the atlas once we can render quarter-resultion.
            find_atlas_feather_scale_factor(
                find_feather_radius(paint->getFeather()),
                matrixMaxScale) <= .5f)
        {
            return CoverageType::atlas;
        }
    }
    switch (interlockMode)
    {
        case gpu::InterlockMode::rasterOrdering:
        case gpu::InterlockMode::atomics:
            return CoverageType::pixelLocalStorage;
        case gpu::InterlockMode::clockwise:
            return CoverageType::clockwise;
        case gpu::InterlockMode::clockwiseAtomic:
            return CoverageType::clockwiseAtomic;
        case gpu::InterlockMode::msaa:
            return CoverageType::msaa;
    }
    RIVE_UNREACHABLE();
}

DrawUniquePtr PathDraw::Make(RenderContext* context,
                             const Mat2D& matrix,
                             rcp<const RiveRenderPath> path,
                             FillRule fillRule,
                             const RiveRenderPaint* paint,
                             float modulatedOpacity,
                             RawPath* scratchPath,
                             std::optional<IAABB> precomputedPixelBounds)
{
    RIVE_PROF_SCOPE_L(2);
    assert(path != nullptr);
    assert(paint != nullptr);

    CoverageType coverageType =
        SelectCoverageType(paint,
                           matrix.findMaxScale(),
                           context->platformFeatures(),
                           context->frameInterlockMode());

    IAABB pixelBounds;

    // In debug mode, we want to always calculate the bounds and validate
    // against the pre-calculated ones so skip this
#ifdef NDEBUG
    if (precomputedPixelBounds.has_value())
    {
        // These were already computed so we don't need to do it again.
        pixelBounds = *precomputedPixelBounds;
    }
    else
#endif
    {
        // We weren't given pre-computed bounds, so calculate them.
        AABB mappedBounds = matrix.mapBoundingBox(path->getRawPath().points());

        assert(mappedBounds.width() >= 0);
        assert(mappedBounds.height() >= 0);
        if (paint->getIsStroked() || paint->getFeather() != 0)
        {
            // Outset the path's bounding box to account for stroking &
            // feathering.
            float outset = 0;
            if (paint->getIsStroked())
            {
                outset = paint->getThickness() * .5f;
                if (paint->getJoin() == StrokeJoin::miter)
                {
                    // Miter joins may be longer than the stroke radius.
                    outset *= RIVE_MITER_LIMIT;
                }
                else if (paint->getCap() == StrokeCap::square)
                {
                    // The diagonal of a square cap is longer than the stroke
                    // radius.
                    outset *= math::SQRT2;
                }
            }
            if (paint->getFeather() != 0)
            {
                outset += find_feather_radius(paint->getFeather());
            }
            AABB strokePixelOutset =
                matrix.mapBoundingBox({0, 0, outset, outset});
            // Add an extra pixel to the stroke outset radius to account for:
            //   * Butt caps and bevel joins bleed out 1/2 AA width.
            //   * With Manhattan sytle AA, an AA width can be as large as
            //   sqrt(2).
            //   * The diagonal of that sqrt(2)/2 bleed is 1px in length.
            mappedBounds = mappedBounds.outset(strokePixelOutset.width() + 1,
                                               strokePixelOutset.height() + 1);
        }

        pixelBounds = mappedBounds.roundOut();
    }

    // In debug mode, we always compute the pixel bounds, so validate that the
    // value we got was exactly the same as the precomputed bounds.
    assert(!precomputedPixelBounds.has_value() ||
           pixelBounds == *precomputedPixelBounds);

    bool doTriangulation = false;
    const AABB& localBounds = path->getBounds();
    if (context->isOutsideCurrentFrame(pixelBounds))
    {
        // Anything precomputing the pixel bounds should be checking against the
        // screen bounds rather than letting it bubble down into here.
        assert(!precomputedPixelBounds.has_value());
        return nullptr;
    }

    if (!paint->getIsStroked() && paint->getFeather() == 0)
    {
        // Use interior triangulation to draw filled paths if they're large
        // enough to benefit from it.
        //
        // FIXME! Implement interior triangulation for feathers.
        //
        // FIXME! Implement interior triangulation in msaa mode.
        if (context->frameInterlockMode() != gpu::InterlockMode::msaa &&
            path->getRawPath().verbs().count() < 1000 &&
            gpu::find_transformed_area(localBounds, matrix) > 512.f * 512.f)
        {
            doTriangulation = true;
        }
    }

    auto draw = context->make<PathDraw>(pixelBounds,
                                        matrix,
                                        std::move(path),
                                        fillRule,
                                        paint,
                                        modulatedOpacity,
                                        coverageType,
                                        context->frameDescriptor());
    if (doTriangulation)
    {
        draw->initForInteriorTriangulation(
            context,
            scratchPath,
            localBounds.width() > localBounds.height()
                ? PathDraw::TriangulatorAxis::horizontal
                : PathDraw::TriangulatorAxis::vertical);
    }
    else
    {
        draw->initForMidpointFan(context, paint);
    }

    return DrawUniquePtr(draw);
}

PathDraw::PathDraw(IAABB pixelBounds,
                   const Mat2D& matrix,
                   rcp<const RiveRenderPath> path,
                   FillRule initialFillRule,
                   const RiveRenderPaint* paint,
                   float modulatedOpacity,
                   CoverageType coverageType,
                   const RenderContext::FrameDescriptor& frameDesc) :
    Draw(pixelBounds,
         matrix,
         paint->getBlendMode(),
         ref_rcp(paint->getImageTexture()),
         paint->getImageSampler(),
         Type::path),
    m_pathRef(path.release()),
    m_pathFillRule(frameDesc.clockwiseFillOverride ? FillRule::clockwise
                                                   : initialFillRule),
    m_gradientRef(paint->getGradientWithOpacity(modulatedOpacity).release()),
    m_paintType(paint->getType()),
    m_coverageType(coverageType)
{
    assert(m_pathRef != nullptr);
    assert(!m_pathRef->getRawPath().empty());
    assert(paint != nullptr);

    if (paint->getIsOpaque())
    {
        m_drawContents |= gpu::DrawContents::opaquePaint;
    }

    if (paint->getFeather() != 0)
    {
        m_featherRadius = find_feather_radius(paint->getFeather());
        assert(!std::isnan(m_featherRadius)); // These should get culled in
                                              // RiveRenderer::drawPath().
        assert(m_featherRadius > 0);
    }

    if (paint->getIsStroked())
    {
        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
                                             // RiveRenderer::drawPath().
        assert(m_strokeRadius > 0);
    }

    // For atlased paths, m_drawContents refers to the rectangle being drawn
    // into the main render target, not the step that generates the atlas mask.
    if (m_coverageType != CoverageType::atlas)
    {
        if (isStroke())
        {
            m_drawContents |= gpu::DrawContents::stroke;
        }
        else
        {
            if (m_featherRadius)
            {
                m_drawContents |= gpu::DrawContents::featheredFill;
            }
            if (initialFillRule == FillRule::clockwise ||
                frameDesc.clockwiseFillOverride)
            {
                m_drawContents |= gpu::DrawContents::clockwiseFill;
            }
            else if (initialFillRule == FillRule::nonZero)
            {
                m_drawContents |= gpu::DrawContents::nonZeroFill;
            }
            else if (initialFillRule == FillRule::evenOdd)
            {
                m_drawContents |= gpu::DrawContents::evenOddFill;
            }
        }
    }

    if (paint->getType() == gpu::PaintType::clipUpdate)
    {
        m_drawContents |= gpu::DrawContents::clipUpdate;
        if (paint->getSimpleValue().outerClipID != 0)
        {
            m_drawContents |= gpu::DrawContents::activeClip;
        }
    }

    if (isStroke())
    {
        // Stroke triangles are always forward.
        m_contourDirections = gpu::ContourDirections::forward;
    }
    else if (initialFillRule == FillRule::clockwise)
    {
        // Clockwise paths need to be reversed when the matrix is left-handed,
        // so that the intended forward triangles remain clockwise.
        float det = matrix.xx() * matrix.yy() - matrix.yx() * matrix.xy();
        if (det < 0)
        {
            m_contourDirections =
                (m_coverageType == CoverageType::msaa ||
                 m_coverageType == CoverageType::atlas)
                    ? gpu::ContourDirections::reverse
                    : gpu::ContourDirections::forwardThenReverse;
            m_contourFlags |= NEGATE_PATH_FILL_COVERAGE_FLAG; // ignored by msaa
        }
        else
        {
            m_contourDirections =
                (m_coverageType == CoverageType::msaa ||
                 m_coverageType == CoverageType::atlas)
                    ? gpu::ContourDirections::forward
                    : gpu::ContourDirections::reverseThenForward;
        }
    }
    else if (m_coverageType != CoverageType::msaa)
    {
        // atomic and rasterOrdering fills need reverse AND forward triangles.
        if (frameDesc.clockwiseFillOverride &&
            !m_pathRef->isClockwiseDominant(matrix))
        {
            // For clockwiseFill, this is also our opportunity to logically
            // reverse the winding of the path, if it is predominantly
            // counterclockwise.
            m_contourDirections =
                (m_coverageType == CoverageType::atlas)
                    ? gpu::ContourDirections::reverse
                    : gpu::ContourDirections::forwardThenReverse;
            m_contourFlags |= NEGATE_PATH_FILL_COVERAGE_FLAG;
        }
        else
        {
            m_contourDirections =
                (m_coverageType == CoverageType::atlas)
                    ? gpu::ContourDirections::forward
                    : gpu::ContourDirections::reverseThenForward;
        }
    }
    else
    {
        if (initialFillRule == FillRule::nonZero ||
            frameDesc.clockwiseFillOverride)
        {
            // Emit "nonZero" msaa 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.
            m_contourDirections = m_pathRef->isClockwiseDominant(matrix)
                                      ? gpu::ContourDirections::forward
                                      : gpu::ContourDirections::reverse;
        }
        else
        {
            // "evenOdd" msaa fills just get drawn twice, so any direction is
            // fine.
            m_contourDirections = gpu::ContourDirections::forward;
        }
    }

    m_simplePaintValue = paint->getSimpleValue();

    // Apply modulated opacity to the paint value.
    // Gradient modulation is handled upfront in the gradient initialization.
    if (modulatedOpacity != 1.0f)
    {
        switch (m_paintType)
        {
            case gpu::PaintType::solidColor:
                m_simplePaintValue.color =
                    colorModulateOpacity(m_simplePaintValue.color,
                                         modulatedOpacity);
                break;
            case gpu::PaintType::image:
                m_simplePaintValue.imageOpacity *= modulatedOpacity;
                break;
            case gpu::PaintType::linearGradient:
            case gpu::PaintType::radialGradient:
            case gpu::PaintType::clipUpdate:
                break;
        }
    }

    if (m_coverageType == CoverageType::atlas)
    {
        // Reserve two triangles for our on-screen rectangle that reads coverage
        // from the atlas.
        m_resourceCounts.maxTriangleVertexCount = 6;
    }

    RIVE_DEBUG_CODE(m_pathRef->lockRawPathMutations();)
    RIVE_DEBUG_CODE(m_rawPathMutationID = m_pathRef->getRawPathMutationID();)
    assert(isStroke() == (strokeRadius() > 0));
    assert(isFeatheredFill() == (!isStroke() && featherRadius() > 0));
    assert(!isFeatheredFill() || featherRadius() > 0);
}

void PathDraw::releaseRefs()
{
    RIVE_PROF_SCOPE_L(2)
    Draw::releaseRefs();
    RIVE_DEBUG_CODE(m_pathRef->unlockRawPathMutations();)
    m_pathRef->unref();
    safe_unref(m_gradientRef);
}

void PathDraw::initForMidpointFan(RenderContext* context,
                                  const RiveRenderPaint* paint)
{
    RIVE_PROF_SCOPE_L(2)
    // Only call init() once.
    assert((m_resourceCounts.midpointFanTessVertexCount |
            m_resourceCounts.outerCubicTessVertexCount) == 0);

    if (isStrokeOrFeather())
    {
        m_strokeMatrixMaxScale = m_matrix.findMaxScale();

        float r_ = 0;
        if (m_featherRadius != 0)
        {
            r_ = m_featherRadius * m_strokeMatrixMaxScale;

            // Inverse of 1/calc_polar_segments_per_radian at
            // FEATHER_MIN_POLAR_SEGMENT_ANGLE.
            //
            // i.e., 1 / calc_polar_segments_per_radian<kPolarPrecision>(
            //           FEATHER_MIN_POLAR_SEGMENT_ANGLE) ==
            //       FEATHER_MAX_SCREEN_SPACE_RADIUS
            //
            constexpr static float FEATHER_MAX_SCREEN_SPACE_RADIUS =
                1 / (kPolarPrecision *
                     (1 - COS_FEATHER_POLAR_SEGMENT_MIN_ANGLE_OVER_2));
            assert(math::nearly_equal(
                1 / math::calc_polar_segments_per_radian<kPolarPrecision>(
                        FEATHER_MAX_SCREEN_SPACE_RADIUS),
                gpu::FEATHER_POLAR_SEGMENT_MIN_ANGLE));

            // r_ is used to calculate how many polar segments are needed. Limit
            // r_ for large feathers. (See FEATHER_POLAR_SEGMENT_MIN_ANGLE.)
            r_ = std::min(r_, FEATHER_MAX_SCREEN_SPACE_RADIUS);
        }
        if (isStroke())
        {
            r_ += m_strokeRadius * m_strokeMatrixMaxScale;
        }
        m_polarSegmentsPerRadian =
            math::calc_polar_segments_per_radian<kPolarPrecision>(r_);

        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-cubic) move.
    size_t pathMaxLinesOrCurvesBeforeChops = rawPath.verbs().size() - 1;
    // Stroked cubics can be chopped into a maximum of 5 segments.
    size_t pathMaxLinesOrCurvesAfterChops =
        isStrokeOrFeather() ? pathMaxLinesOrCurvesBeforeChops * 5
                            : pathMaxLinesOrCurvesBeforeChops;
    maxCurves += pathMaxLinesOrCurvesAfterChops;
    if (isStrokeOrFeather())
    {
        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 =
        isStrokeOrFeather() ? 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 (isStrokeOrFeather())
    {
        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);

    float parametricPrecision = gpu::kParametricPrecision;
    if (m_featherRadius > 1)
    {
        // Once the blur radius is above ~50 pixels, we don't have to tessellate
        // within 1/4px of the edge anymore.
        // At this point, tessellate within strokeRadius/200 pixels of the edge.
        // (parametricPrecision == 1/tolerance.)
        parametricPrecision =
            std::min(parametricPrecision * 100.f /
                         (m_featherRadius * m_strokeMatrixMaxScale),
                     parametricPrecision);
    }

    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;
    // We measure rotations on both curves and round joins.
    size_t rotationIdx = 0;
    bool roundJoinStroked = isStroke() && m_strokeJoin == StrokeJoin::round;
    wangs_formula::VectorXform vectorXform(m_matrix);
    RawPath::Iter startOfContour = rawPath.begin();
    RawPath::Iter end = rawPath.end();
    // Original number of lines and curves, before chopping.
    int preChopVerbCount = 0;
    Vec2D endpointsSum{};
    bool closed = !isStroke();
    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,
            isStroke() ? 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(isStrokeOrFeather(), 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 = !isStroke();
                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];
                math::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 = false;
                uint8_t numChops =
                    isStroke()
                        ? math::find_cubic_convex_180_chops(p, t, &areCusps)
                        : 0; // Feathers already got chopped.
                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]};
                        math::chop_cubic_at(p, localChopBuffer, t[0], t[1]);
                        p = localChopBuffer;
                        break;
                    case simple_chop_key(1): // 1 non-cusp chop
                    {
                        math::chop_cubic_at(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,
                                                         parametricPrecision,
                                                         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);
                    if (isStroke())
                    {
                        math::find_cubic_tangents(
                            p,
                            m_tangentPairs[rotationIdx].data());
                    }
                    else
                    {
                        // FIXME: Feathered fills don't have polar segments for
                        // now, but we're leaving space for them in
                        // m_tangentPairs because we will convert them to use a
                        // similar concept of "polar joins" once we move them
                        // onto the GPU.
                        m_tangentPairs[rotationIdx] = {Vec2D{0, 1},
                                                       Vec2D{0, 1}};
                    }
                }
                break;
            }
            case StyledVerb::filledCubic:
            {
                const Vec2D* p = iter.cubicPts();
                ++preChopVerbCount;
                endpointsSum += p[3];
                float n4 = wangs_formula::cubic_pow4(p,
                                                     parametricPrecision,
                                                     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);
    // Because we write parametric segment counts in batches of 4.
    assert(curveIdx % 4 == 0);
    // Because we write polar segment counts in batches of 4.
    assert(rotationIdx % 4 == 0);
    assert(isStrokeOrFeather() || maxPaddedRotations == 0);
    assert(isStrokeOrFeather() || rotationIdx == 0);

    // Return any data we conservatively allocated but did not use.
    if (isStrokeOrFeather())
    {
        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 = math::lossless_numeric_cast<uint32_t>(
            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 (isStrokeOrFeather())
        {
            // Finish calculating and counting polar segments for each stroked
            // curve and round join.
            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 * m_polarSegmentsPerRadian);
                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 (!isStroke())
            {
                assert(isFeatheredFill());
                uint32_t numSegmentsInFeatherJoin =
                    feather_join_segment_count(m_polarSegmentsPerRadian);
                contourVertexCount +=
                    contour->strokeJoinCount * (numSegmentsInFeatherJoin - 1);
            }
            else 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 *
                                      (NUM_SEGMENTS_IN_MITER_OR_BEVEL_JOIN - 1);
            }

            // Count stroke caps, if any.
            bool empty = contour->endLineIdx == contourFirstLineIdx &&
                         contour->endCurveIdx == contour->firstCurveIdx;
            StrokeCap cap;
            bool needsCaps = false;
            if (!empty)
            {
                cap = m_strokeCap;
                needsCaps = !contour->closed;
            }
            else if (isStroke())
            {
                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(m_polarSegmentsPerRadian * 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 =
                        NUM_SEGMENTS_IN_MITER_OR_BEVEL_JOIN;
                }
                // 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 =
            math::padding_to_align_up<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 gpu::TessVertexSpan.
        m_resourceCounts.maxTessellatedSegmentCount =
            lineCount + unpaddedCurveCount + emptyStrokeCountForCaps;
        m_resourceCounts.midpointFanTessVertexCount =
            gpu::ContourDirectionsAreDoubleSided(m_contourDirections)
                ? tessVertexCount * 2
                : tessVertexCount;
    }
}

void PathDraw::initForInteriorTriangulation(RenderContext* context,
                                            RawPath* scratchPath,
                                            TriangulatorAxis triangulatorAxis)
{
    RIVE_PROF_SCOPE_L(2)
    PUSH_DISABLE_CLANG_SIMD_ABI_WARNING()
    assert(simd::all(m_resourceCounts.toVec() == 0)); // Only call init() once.
    POP_DISABLE_CLANG_SIMD_ABI_WARNING()
    assert(!isStrokeOrFeather());
    assert(m_strokeRadius == 0);

    // Every path has at least 1 (non-cubic) move.
    size_t originalNumChopsSize = m_pathRef->getRawPath().verbs().size() - 1;
    m_numChops.reset(context->numChopsAllocator(), originalNumChopsSize);
    iterateInteriorTriangulation(
        InteriorTriangulationOp::countDataAndTriangulate,
        &context->perFrameAllocator(),
        scratchPath,
        triangulatorAxis,
        nullptr);
    m_numChops.shrinkToFit(context->numChopsAllocator(), originalNumChopsSize);
}

bool PathDraw::allocateResources(RenderContext::LogicalFlush* flush)
{
    RIVE_PROF_SCOPE_L(2)
    const RenderContext::FrameDescriptor& frameDesc = flush->frameDescriptor();

    // Allocate a gradient if needed. Do this first since it's more expensive to
    // fail after setting up an atlas draw than a gradient draw.
    if (m_gradientRef != nullptr)
    {
        if (!flush->allocateGradient(m_gradientRef,
                                     &m_simplePaintValue.colorRampLocation))
        {
            return false;
        }
    }

    // Allocate a coverage buffer range or atlas region if needed.
    if (m_coverageType == CoverageType::atlas ||
        (m_coverageType == CoverageType::clockwiseAtomic &&
         // Outermost (i.e., non-nested) clockwiseAtomic clips render directly
         // to the clip buffer without using the coverage buffer.
         !isOutermostClipUpdate()))
    {
        constexpr static int PADDING = 2;

        // We don't need any coverage space for areas outside the viewport.
        // TODO: Account for active clips as well once we have the info.
        IAABB renderTargetBounds = {
            0,
            0,
            static_cast<int32_t>(frameDesc.renderTargetWidth),
            static_cast<int32_t>(frameDesc.renderTargetHeight),
        };
        IAABB visibleBounds = renderTargetBounds.intersect(m_pixelBounds);

        if (m_coverageType == CoverageType::atlas)
        {
            const float scaleFactor =
                find_atlas_feather_scale_factor(m_featherRadius,
                                                m_strokeMatrixMaxScale);
            auto w = static_cast<uint16_t>(
                ceilf(visibleBounds.width() * scaleFactor));
            auto h = static_cast<uint16_t>(
                ceilf(visibleBounds.height() * scaleFactor));
            uint16_t x, y;
            if (!flush->allocateAtlasDraw(this,
                                          w,
                                          h,
                                          PADDING,
                                          &x,
                                          &y,
                                          &m_atlasScissor))
            {
                return false; // There wasn't room for our path in the atlas.
            }
            m_atlasTransform.scaleFactor = scaleFactor;
            m_atlasTransform.translateX = x - visibleBounds.left * scaleFactor;
            m_atlasTransform.translateY = y - visibleBounds.top * scaleFactor;
            m_atlasScissorEnabled = visibleBounds != m_pixelBounds;
        }
        else
        {
            // Round up width and height to multiples of BUFFER_IMAGE_TILE_SIZE
            // for tiling.
            uint32_t coverageWidth =
                math::round_up_to_multiple_of<BUFFER_IMAGE_TILE_SIZE>(
                    visibleBounds.width() + PADDING * 2);
            uint32_t coverageHeight =
                math::round_up_to_multiple_of<BUFFER_IMAGE_TILE_SIZE>(
                    visibleBounds.height() + PADDING * 2);

            // Get our coverage allocation.
            size_t offset = flush->allocateCoverageBufferRange(coverageHeight *
                                                               coverageWidth);
            if (offset == -1)
            {
                return false; // There wasn't room for our coverage buffer.
            }
            m_coverageBufferRange.offset =
                math::lossless_numeric_cast<uint32_t>(offset);
            m_coverageBufferRange.pitch = coverageWidth;
            m_coverageBufferRange.offsetX = -visibleBounds.left + PADDING;
            m_coverageBufferRange.offsetY = -visibleBounds.top + PADDING;
        }
    }
    return true;
}

void PathDraw::countSubpasses()
{
    RIVE_PROF_SCOPE_L(2)
    m_subpassCount = 1;
    m_prepassCount = 0;

    switch (m_coverageType)
    {
        case CoverageType::atlas:
            assert(m_triangulator == nullptr);
            m_subpassCount = 1;
            break;

        case CoverageType::pixelLocalStorage:
            m_subpassCount = (m_triangulator != nullptr)
                                 ? 2 // outer cubics, interior triangles
                                 : 1;
            break;

        case CoverageType::clockwise:
            m_subpassCount =
                (m_triangulator != nullptr)
                    ? 3 // ccw interior tris, outer cubics, cw interior tris
                    : 1;
            break;

        case CoverageType::clockwiseAtomic:
            m_subpassCount = (m_triangulator != nullptr) ? 2 : 1;
            if (needsBorrowedCoveragePrepass())
            {
                // Add prepasses for borrowed coverage.
                m_prepassCount = m_subpassCount;
            }
            break;

        case CoverageType::msaa:
        {
            if (isStroke())
            {
                m_subpassCount = 1; // Strokes can be rendered in a single pass.
            }
            else if ((m_drawContents & gpu::kNestedClipUpdateMask) ==
                     gpu::kNestedClipUpdateMask)
            {
                // Nested clip updates only have a stencil pass. (The reset is
                // handled by a separate ClipReset draw.)
                m_subpassCount = 1;
            }
            else if (enums::is_flag_set(m_drawContents,
                                        gpu::DrawContents::evenOddFill))
            {
                m_subpassCount = 2; // MSAA "slow" path: stencil-then-cover.
            }
            else
            {
                // MSAA "fast" path: (effectively) single pass rendering.
                m_subpassCount = 3;
            }
            if (isOpaque())
            {
                const bool usesClipping =
                    enums::any_flag_set(m_drawContents,
                                        gpu::DrawContents::activeClip |
                                            gpu::DrawContents::clipUpdate);
                if (!usesClipping)
                {
                    // Render this path front-to-back instead of back-to-front.
                    assert(m_prepassCount == 0);
                    m_prepassCount = m_subpassCount;
                    m_subpassCount = 0;
                }
            }
        }
    }
}

gpu::DrawBatch* PathDraw::pushToRenderContext(
    RenderContext::LogicalFlush* flush,
    int subpassIndex)
{
    RIVE_PROF_SCOPE_L(2)
    // 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());

    assert(m_resourceCounts.outerCubicTessVertexCount == 0 ||
           m_resourceCounts.midpointFanTessVertexCount == 0);
    uint32_t tessVertexCount = math::lossless_numeric_cast<uint32_t>(
        m_resourceCounts.outerCubicTessVertexCount |
        m_resourceCounts.midpointFanTessVertexCount);
    if (tessVertexCount == 0)
    {
        return nullptr;
    }

    if (m_pathID == 0)
    {
        // Reserve our pathID and write out a path record.
        m_pathID = flush->pushPath(this);
    }

    switch (m_coverageType)
    {
        case CoverageType::pixelLocalStorage:
        case CoverageType::clockwise:
        {
            const int mainSubpassIdx =
                (m_coverageType == CoverageType::clockwise &&
                 m_triangulator != nullptr)
                    ? 1
                    : 0;
            if (subpassIndex == mainSubpassIdx)
            {
                // Tessellation (midpoint fan or outer cubic).
                uint32_t tessLocation =
                    allocateTessellationVertices(flush, tessVertexCount);
                pushTessellationData(flush, tessVertexCount, tessLocation);
                return &pushTessellationDraw(flush,
                                             tessVertexCount,
                                             tessLocation);
            }
            else
            {
                // Interior triangles.
                assert(m_triangulator != nullptr);
                assert((m_coverageType == CoverageType::pixelLocalStorage &&
                        subpassIndex == 1) ||
                       (m_coverageType == CoverageType::clockwise &&
                        (subpassIndex == 0 || subpassIndex == 2)));
                gpu::DrawBatch* batch = flush->pushInteriorTriangulationDraw(
                    this,
                    m_pathID,
                    (m_coverageType == CoverageType::clockwise)
                        // Clockwise mode renders counterclockwise (borrowed
                        // coverage) interior triangles in a separate pass.
                        ? (subpassIndex == 0) ? gpu::WindingFaces::negative
                                              : gpu::WindingFaces::positive
                        : gpu::WindingFaces::all,
                    (subpassIndex == 0) // => CoverageType::clockwise
                        ? gpu::ShaderMiscFlags::borrowedCoveragePass
                        : gpu::ShaderMiscFlags::none RIVE_DEBUG_CODE(
                              ,
                              &m_numInteriorTriangleVerticesPushed));
                assert(m_numInteriorTriangleVerticesPushed <=
                       m_triangulator->maxVertexCount());
                return batch;
            }
            RIVE_UNREACHABLE();
        }

        case CoverageType::clockwiseAtomic:
        {
            if (m_prepassCount != 0)
            {
                // The subpass and prepass each emit half the vertices.
                assert(m_prepassCount == m_subpassCount);
                assert(tessVertexCount % 2 == 0);
                assert(needsBorrowedCoveragePrepass());
                tessVertexCount /= 2;
            }
            switch (subpassIndex)
            {
                case -1: // Tessellation (borrowed, midpointFan or outerCubic).
                    assert(!isStroke());
                    m_prepassTessLocation =
                        allocateTessellationVertices(flush, tessVertexCount);
                    return &pushTessellationDraw(
                        flush,
                        tessVertexCount,
                        m_prepassTessLocation,
                        gpu::ShaderMiscFlags::borrowedCoveragePass);

                case 0: // Tessellation (midpointFan or outerCubic).
                {
                    uint32_t tessLocation =
                        allocateTessellationVertices(flush, tessVertexCount);
                    pushTessellationData(flush, tessVertexCount, tessLocation);
                    return &pushTessellationDraw(flush,
                                                 tessVertexCount,
                                                 tessLocation);
                }

                case -2: // Interior triangles (borrowed).
                case 1:  // Interior triangles.
                {
                    assert(!isStroke());
                    assert(m_triangulator != nullptr);
                    gpu::DrawBatch* batch =
                        flush->pushInteriorTriangulationDraw(
                            this,
                            m_pathID,
                            m_prepassCount == 0 ? gpu::WindingFaces::all
                            : subpassIndex < 0  ? gpu::WindingFaces::negative
                                                : gpu::WindingFaces::positive,
                            subpassIndex < 0
                                ? gpu::ShaderMiscFlags::borrowedCoveragePass
                                : gpu::ShaderMiscFlags::none RIVE_DEBUG_CODE(
                                      ,
                                      &m_numInteriorTriangleVerticesPushed));
                    assert(m_numInteriorTriangleVerticesPushed <=
                           m_triangulator->maxVertexCount());
                    return batch;
                }
            }
            RIVE_UNREACHABLE();
        }

        case CoverageType::msaa:
        {
            assert(m_prepassCount == 0 || m_subpassCount == 0);
            int passCount = m_prepassCount | m_subpassCount;
            int passIdx = subpassIndex + m_prepassCount;
            if (passIdx == 0)
            {
                m_msaaTessLocation =
                    allocateTessellationVertices(flush, tessVertexCount);
                pushTessellationData(flush,
                                     tessVertexCount,
                                     m_msaaTessLocation);
            }
            constexpr static gpu::DrawType MSAA_FILL_TYPES[][3] = {
                // Nested clip update (passCount == 1; the reset is handled by a
                // separate ClipReset draw.)
                {
                    gpu::DrawType::msaaMidpointFanPathsStencil,
                },

                // Slow path (passCount == 2): stencil-then-cover
                {
                    gpu::DrawType::msaaMidpointFanPathsStencil,
                    gpu::DrawType::msaaMidpointFanPathsCover,
                },

                // Fast path (passCount == 3): (mostly) single pass rendering.
                {
                    gpu::DrawType::msaaMidpointFanBorrowedCoverage,
                    gpu::DrawType::msaaMidpointFans,
                    gpu::DrawType::msaaMidpointFanStencilReset,
                },
            };
            assert(passCount <= 3);
            assert(passIdx < passCount);
            gpu::DrawType msaaDrawType =
                isStroke() ? gpu::DrawType::msaaStrokes
                           : MSAA_FILL_TYPES[passCount - 1][passIdx];
            return &flush->pushMidpointFanDraw(this,
                                               msaaDrawType,
                                               tessVertexCount,
                                               m_msaaTessLocation);
        }

        case CoverageType::atlas:
            // Atlas draws only have one subpass -- the rectangular blit from
            // the atlas to the screen. The step that renders coverage to the
            // offscreen atlas is handled separately, outside the subpass
            // system.
            assert(subpassIndex == 0);
            return &flush->pushAtlasBlit(this, m_pathID);
    }

    RIVE_UNREACHABLE();
}

gpu::DrawBatch& PathDraw::pushTessellationDraw(
    RenderContext::LogicalFlush* flush,
    uint32_t tessVertexCount,
    uint32_t tessLocation,
    gpu::ShaderMiscFlags shaderMiscFlags)
{
    if (m_triangulator != nullptr)
    {
        assert(!isStroke());
        return flush->pushOuterCubicsDraw(this,
                                          gpu::DrawType::outerCurvePatches,
                                          tessVertexCount,
                                          tessLocation,
                                          shaderMiscFlags);
    }
    else
    {
        return flush->pushMidpointFanDraw(
            this,
            isFeatheredFill() ? gpu::DrawType::midpointFanCenterAAPatches
                              : gpu::DrawType::midpointFanPatches,
            tessVertexCount,
            tessLocation,
            shaderMiscFlags);
    }
}

void PathDraw::pushAtlasTessellation(RenderContext::LogicalFlush* flush,
                                     uint32_t* tessVertexCount,
                                     uint32_t* tessBaseVertex)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_coverageType == CoverageType::atlas);
    assert(m_resourceCounts.outerCubicTessVertexCount == 0 ||
           m_resourceCounts.midpointFanTessVertexCount == 0);

    *tessVertexCount = math::lossless_numeric_cast<uint32_t>(
        m_resourceCounts.outerCubicTessVertexCount |
        m_resourceCounts.midpointFanTessVertexCount);

    if (*tessVertexCount == 0)
    {
        assert(m_pathID == 0);
        return;
    }

    *tessBaseVertex = allocateTessellationVertices(flush, *tessVertexCount);
    pushTessellationData(flush, *tessVertexCount, *tessBaseVertex);
}

void PathDraw::pushTessellationData(RenderContext::LogicalFlush* flush,
                                    uint32_t tessVertexCount,
                                    uint32_t tessLocation)
{
    RIVE_PROF_SCOPE_L(2)
    // Determine where to fill in forward and mirrored tessellations.
    uint32_t forwardTessVertexCount, forwardTessLocation,
        mirroredTessVertexCount, mirroredTessLocation;
    switch (m_contourDirections)
    {
        case gpu::ContourDirections::forward:
            forwardTessVertexCount = tessVertexCount;
            forwardTessLocation = tessLocation;
            mirroredTessLocation = mirroredTessVertexCount = 0;
            break;
        case gpu::ContourDirections::reverse:
            forwardTessVertexCount = forwardTessLocation = 0;
            mirroredTessVertexCount = tessVertexCount;
            mirroredTessLocation = tessLocation + tessVertexCount;
            break;
        case gpu::ContourDirections::reverseThenForward:
            if (m_coverageType == CoverageType::clockwiseAtomic &&
                m_prepassTessLocation != 0) // With padding, this will only be
                                            // zero if it's not needed.
            {
                // The tessellation for borrowed coverage was allocated at a
                // different location than the forward tessellation, both with
                // "tessVertexCount" vertices.
                assert(needsBorrowedCoveragePrepass());
                forwardTessVertexCount = mirroredTessVertexCount =
                    tessVertexCount;
                forwardTessLocation = tessLocation;
                mirroredTessLocation = m_prepassTessLocation + tessVertexCount;
            }
            else
            {
                // The reverse and forward tessellations are allocated
                // contiguously, with a combined vertex count of
                // "tessVertexCount". (tessVertexCount/2 vertices each.)
                assert(tessVertexCount % 2 == 0);
                forwardTessVertexCount = mirroredTessVertexCount =
                    tessVertexCount / 2;
                forwardTessLocation = mirroredTessLocation =
                    tessLocation + tessVertexCount / 2;
            }
            break;
        case gpu::ContourDirections::forwardThenReverse:
            if (m_coverageType == CoverageType::clockwiseAtomic &&
                m_prepassTessLocation != 0) // With padding, this will only be
                                            // zero if it's not needed.
            {
                // The tessellation for borrowed coverage was allocated at a
                // different location than the forward tessellation, both with
                // "tessVertexCount" vertices.
                assert(needsBorrowedCoveragePrepass());
                forwardTessVertexCount = mirroredTessVertexCount =
                    tessVertexCount;
                forwardTessLocation = m_prepassTessLocation;
                mirroredTessLocation = tessLocation + tessVertexCount;
            }
            else
            {
                // The reverse and forward tessellations are allocated
                // contiguously, with a combined vertex count of
                // "tessVertexCount". (tessVertexCount/2 vertices each.)
                assert(tessVertexCount % 2 == 0);
                forwardTessVertexCount = mirroredTessVertexCount =
                    tessVertexCount / 2;
                forwardTessLocation = tessLocation;
                mirroredTessLocation = tessLocation + tessVertexCount;
            }
            break;
    }

    // Write out the TessVertexSpans and path contours.
    RenderContext::TessellationWriter tessWriter(flush,
                                                 m_pathID,
                                                 m_contourDirections,
                                                 forwardTessVertexCount,
                                                 forwardTessLocation,
                                                 mirroredTessVertexCount,
                                                 mirroredTessLocation);

    if (m_triangulator != nullptr)
    {
        iterateInteriorTriangulation(
            InteriorTriangulationOp::pushOuterCubicTessellationData,
            nullptr,
            nullptr,
            TriangulatorAxis::dontCare,
            &tessWriter);
    }
    else
    {
        pushMidpointFanTessellationData(&tessWriter);
    }
}

void PathDraw::pushMidpointFanTessellationData(
    RenderContext::TessellationWriter* tessWriter)
{
    RIVE_PROF_SCOPE_L(3)
    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(isStroke() || contour.closed); // Fills are always closed.
        RIVE_DEBUG_CODE(m_pendingStrokeJoinCount =
                            isStrokeOrFeather() ? 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;
        // Emit a starting cap before the next cubic?
        bool needsFirstEmulatedCapAsJoin = false;
        uint32_t emulatedCapAsJoinFlags = 0;
        if (isStrokeOrFeather())
        {
            joinTypeFlags = isStroke() ? join_type_flags(m_strokeJoin)
                                       : FEATHER_JOIN_CONTOUR_FLAG;
            roundJoinStroked = joinTypeFlags == ROUND_JOIN_CONTOUR_FLAG;
            if (contour.strokeCapSegmentCount != 0)
            {
                StrokeCap cap =
                    !contour.closed
                        ? m_strokeCap
                        : empty_stroke_cap(true, m_strokeJoin, m_strokeCap);
                switch (cap)
                {
                    case StrokeCap::butt:
                        emulatedCapAsJoinFlags = BEVEL_JOIN_CONTOUR_FLAG;
                        break;
                    case StrokeCap::square:
                        emulatedCapAsJoinFlags = MITER_CLIP_JOIN_CONTOUR_FLAG;
                        break;
                    case StrokeCap::round:
                        emulatedCapAsJoinFlags = ROUND_JOIN_CONTOUR_FLAG;
                        break;
                }
                emulatedCapAsJoinFlags |= EMULATED_STROKE_CAP_CONTOUR_FLAG;
                needsFirstEmulatedCapAsJoin = true;
            }
        }

        // Make a data record for this current contour on the GPU.
        uint32_t contourIDWithFlags =
            m_contourFlags |
            tessWriter->pushContour(contour.midpoint,
                                    isStroke(),
                                    contour.closed,
                                    contour.paddingVertexCount);

        // When we don't have round joins, the number of segments per join is
        // constant. (Round joins have a variable number of segments per join,
        // depending on the angle.)
        uint32_t numSegmentsInNotRoundJoin;
        if (isFeatheredFill())
        {
            numSegmentsInNotRoundJoin =
                feather_join_segment_count(m_polarSegmentsPerRadian);
        }
        else
        {
            numSegmentsInNotRoundJoin = NUM_SEGMENTS_IN_MITER_OR_BEVEL_JOIN;
        }

        // Convert all curves in the contour to cubics and push them to the GPU.
        const int styleFlags =
            style_flags(isStrokeOrFeather(), 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 = numSegmentsInNotRoundJoin;
                        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(
                            tessWriter,
                            cubic.data(),
                            contour.strokeCapSegmentCount,
                            contourIDWithFlags | emulatedCapAsJoinFlags);
                        needsFirstEmulatedCapAsJoin = false;
                    }
                    tessWriter->pushCubic(cubic.data(),
                                          m_contourDirections,
                                          joinTangent,
                                          1,
                                          1,
                                          joinSegmentCount,
                                          contourIDWithFlags | joinTypeFlags);
                    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();
                            math::chop_cubic_at(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(
                            tessWriter,
                            p,
                            contour.strokeCapSegmentCount,
                            contourIDWithFlags | emulatedCapAsJoinFlags);
                        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];
                        tessWriter->pushCubic(p,
                                              m_contourDirections,
                                              joinTangent,
                                              parametricSegmentCount,
                                              polarSegmentCount,
                                              1,
                                              contourIDWithFlags |
                                                  joinTypeFlags);
                        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 = numSegmentsInNotRoundJoin;
                        }
                        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;)
                    }
                    tessWriter->pushCubic(p,
                                          m_contourDirections,
                                          joinTangent,
                                          parametricSegmentCount,
                                          polarSegmentCount,
                                          joinSegmentCount,
                                          contourIDWithFlags | joinTypeFlags);
                    RIVE_DEBUG_CODE(--m_pendingCurveCount;)
                    break;
                }
                case StyledVerb::filledCubic:
                {
                    uint32_t parametricSegmentCount =
                        m_parametricSegmentCounts[curveIdx++];
                    tessWriter->pushCubic(iter.cubicPts(),
                                          m_contourDirections,
                                          Vec2D{},
                                          parametricSegmentCount,
                                          1,
                                          1,
                                          contourIDWithFlags);
                    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(
                tessWriter,
                std::array{p0, right, right, right}.data(),
                contour.strokeCapSegmentCount,
                contourIDWithFlags | emulatedCapAsJoinFlags);
            pushEmulatedStrokeCapAsJoinBeforeCubic(
                tessWriter,
                std::array{p0, left, left, left}.data(),
                contour.strokeCapSegmentCount,
                contourIDWithFlags | emulatedCapAsJoinFlags);
        }
        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 (isStrokeOrFeather())
                {
                    joinTangent = find_starting_tangent(pts, end.rawPtsPtr());
                    joinSegmentCount = numSegmentsInNotRoundJoin;
                    RIVE_DEBUG_CODE(--m_pendingStrokeJoinCount;)
                }
                tessWriter->pushCubic(cubic.data(),
                                      m_contourDirections,
                                      joinTangent,
                                      1,
                                      1,
                                      joinSegmentCount,
                                      contourIDWithFlags | joinTypeFlags);
                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 PathDraw::pushEmulatedStrokeCapAsJoinBeforeCubic(
    RenderContext::TessellationWriter* tessWriter,
    const Vec2D cubic[],
    uint32_t strokeCapSegmentCount,
    uint32_t contourIDWithFlags)
{
    RIVE_PROF_SCOPE_L(3)
    // 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);
    tessWriter->pushCubic(
        std::array{cubic[3], cubic[2], cubic[1], cubic[0]}.data(),
        m_contourDirections,
        math::find_cubic_tan0(cubic),
        0,
        0,
        strokeCapSegmentCount,
        contourIDWithFlags);
    RIVE_DEBUG_CODE(--m_pendingStrokeCapCount;)
    RIVE_DEBUG_CODE(--m_pendingEmptyStrokeCountForCaps;)
}

void PathDraw::iterateInteriorTriangulation(
    InteriorTriangulationOp op,
    TrivialBlockAllocator* allocator,
    RawPath* scratchPath,
    TriangulatorAxis triangulatorAxis,
    RenderContext::TessellationWriter* tessWriter)
{
    RIVE_PROF_SCOPE_L(2)
    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 == InteriorTriangulationOp::countDataAndTriangulate)
    {
        scratchPath->rewind();
    }
    // Used with InteriorTriangulationOp::pushOuterCubicData.
    uint32_t contourIDWithFlags = 0;
    for (const auto [verb, pts] : rawPath)
    {
        switch (verb)
        {
            case PathVerb::move:
                if (contourCount != 0 && pts[-1] != p0)
                {
                    if (op ==
                        InteriorTriangulationOp::pushOuterCubicTessellationData)
                    {
                        tessWriter->pushCubic(
                            convert_line_to_cubic(pts[-1], p0).data(),
                            m_contourDirections,
                            {0, 0},
                            kPatchSegmentCountExcludingJoin,
                            1,
                            kJoinSegmentCount,
                            contourIDWithFlags |
                                CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG);
                    }
                    ++patchCount;
                }
                if (op == InteriorTriangulationOp::countDataAndTriangulate)
                {
                    scratchPath->move(pts[0]);
                }
                else
                {
                    contourIDWithFlags =
                        m_contourFlags |
                        tessWriter->pushContour({0, 0},
                                                isStroke(),
                                                /*closed=*/true,
                                                0);
                }
                p0 = pts[0];
                ++contourCount;
                break;
            case PathVerb::line:
                if (op == InteriorTriangulationOp::countDataAndTriangulate)
                {
                    scratchPath->line(pts[1]);
                }
                else
                {
                    tessWriter->pushCubic(
                        convert_line_to_cubic(pts).data(),
                        m_contourDirections,
                        {0, 0},
                        kPatchSegmentCountExcludingJoin,
                        1,
                        kJoinSegmentCount,
                        contourIDWithFlags |
                            CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG);
                }
                ++patchCount;
                break;
            case PathVerb::quad:
                RIVE_UNREACHABLE();
            case PathVerb::cubic:
            {
                uint32_t numSubdivisions;
                if (op == InteriorTriangulationOp::countDataAndTriangulate)
                {
                    numSubdivisions =
                        find_outer_cubic_subdivision_count(pts, vectorXform);
                    m_numChops.push_back(numSubdivisions);
                }
                else
                {
                    numSubdivisions = m_numChops.pop_front();
                }
                if (numSubdivisions == 1)
                {
                    if (op == InteriorTriangulationOp::countDataAndTriangulate)
                    {
                        scratchPath->line(pts[3]);
                    }
                    else
                    {
                        tessWriter->pushCubic(
                            pts,
                            m_contourDirections,
                            {0, 0},
                            kPatchSegmentCountExcludingJoin,
                            1,
                            kJoinSegmentCount,
                            contourIDWithFlags |
                                CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG);
                    }
                }
                else
                {
                    // Passing nullptr for the 'tValues' causes it to chop the
                    // cubic uniformly in T.
                    math::chop_cubic_at(pts,
                                        chops,
                                        nullptr,
                                        numSubdivisions - 1);
                    const Vec2D* chop = chops;
                    for (size_t i = 0; i < numSubdivisions; ++i)
                    {
                        if (op ==
                            InteriorTriangulationOp::countDataAndTriangulate)
                        {
                            scratchPath->line(chop[3]);
                        }
                        else
                        {
                            tessWriter->pushCubic(
                                chop,
                                m_contourDirections,
                                {0, 0},
                                kPatchSegmentCountExcludingJoin,
                                1,
                                kJoinSegmentCount,
                                contourIDWithFlags |
                                    CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG);
                        }
                        chop += 3;
                    }
                }
                patchCount += numSubdivisions;
                break;
            }
            case PathVerb::close:
                break;
        }
    }
    Vec2D lastPt = rawPath.points().back();
    if (contourCount != 0 && lastPt != p0)
    {
        if (op == InteriorTriangulationOp::pushOuterCubicTessellationData)
        {
            tessWriter->pushCubic(
                convert_line_to_cubic(lastPt, p0).data(),
                m_contourDirections,
                {0, 0},
                kPatchSegmentCountExcludingJoin,
                1,
                kJoinSegmentCount,
                contourIDWithFlags |
                    CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG);
        }
        ++patchCount;
    }

    if (op == InteriorTriangulationOp::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,
            // clockwise and nonZero paths both get triangulated as nonZero,
            // because clockwise fill still needs the backwards triangles for
            // borrowed coverage.
            m_pathFillRule == FillRule::evenOdd ? FillRule::evenOdd
                                                : FillRule::nonZero,
            allocator);
        float matrixDeterminant =
            m_matrix[0] * m_matrix[3] - m_matrix[2] * m_matrix[1];
        if ((matrixDeterminant < 0) !=
            static_cast<bool>(m_contourFlags & NEGATE_PATH_FILL_COVERAGE_FLAG))
        {
            m_triangulator->negateWinding();
        }
        // 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 gpu::TessVertexSpan.
            m_resourceCounts.maxTessellatedSegmentCount = patchCount;
            // outerCubic patches emit their tessellated geometry twice: once
            // forward and once mirrored.
            m_resourceCounts.outerCubicTessVertexCount =
                gpu::ContourDirectionsAreDoubleSided(m_contourDirections)
                    ? 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]};
            tessWriter->pushCubic(triangleAsCubic,
                                  m_contourDirections,
                                  {0, 0},
                                  kPatchSegmentCountExcludingJoin,
                                  1,
                                  kJoinSegmentCount,
                                  contourIDWithFlags |
                                      RETROFITTED_TRIANGLE_CONTOUR_FLAG);
            ++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(RenderContext* context,
                             IAABB pixelBounds,
                             const Mat2D& matrix,
                             BlendMode blendMode,
                             rcp<Texture> imageTexture,
                             const ImageSampler imageSampler,
                             float opacity) :
    Draw(pixelBounds,
         matrix,
         blendMode,
         std::move(imageTexture),
         imageSampler,
         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;
}

gpu::DrawBatch* ImageRectDraw::pushToRenderContext(
    RenderContext::LogicalFlush* flush,
    int subpassIndex)
{
    assert(subpassIndex == 0);
    return &flush->pushImageRectDraw(this);
}

ImageMeshDraw::ImageMeshDraw(IAABB pixelBounds,
                             const Mat2D& matrix,
                             BlendMode blendMode,
                             rcp<Texture> imageTexture,
                             const ImageSampler imageSampler,
                             rcp<RenderBuffer> vertexBuffer,
                             rcp<RenderBuffer> uvBuffer,
                             rcp<RenderBuffer> indexBuffer,
                             uint32_t indexCount,
                             float opacity) :
    Draw(pixelBounds,
         matrix,
         blendMode,
         std::move(imageTexture),

         imageSampler,
         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;
}

gpu::DrawBatch* ImageMeshDraw::pushToRenderContext(
    RenderContext::LogicalFlush* flush,
    int subpassIndex)
{
    assert(subpassIndex == 0);
    return &flush->pushImageMeshDraw(this);
}

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

ClipReset::ClipReset(RenderContext* context,
                     uint32_t previousClipID,
                     gpu::DrawContents previousClipDrawContents,
                     ResetAction resetAction) :
    Draw(context->getClipContentBounds(previousClipID),
         Mat2D(),
         BlendMode::srcOver,
         nullptr,
         ImageSampler::LinearClamp(),
         Type::stencilClipReset),
    m_previousClipID(previousClipID)
{
    constexpr static gpu::DrawContents FILL_RULE_FLAGS =
        gpu::DrawContents::nonZeroFill | gpu::DrawContents::evenOddFill |
        gpu::DrawContents::clockwiseFill;
    m_drawContents |= previousClipDrawContents & FILL_RULE_FLAGS;
    switch (resetAction)
    {
        case ResetAction::intersectPreviousClip:
            m_drawContents |= gpu::DrawContents::activeClip;
            [[fallthrough]];
        case ResetAction::clearPreviousClip:
            m_drawContents |= gpu::DrawContents::clipUpdate;
            break;
    }
    m_resourceCounts.maxTriangleVertexCount = 6;
}

gpu::DrawBatch* ClipReset::pushToRenderContext(
    RenderContext::LogicalFlush* flush,
    int subpassIndex)
{
    assert(subpassIndex == 0);
    return &flush->pushClipResetDraw(this);
}
} // namespace rive::gpu
