/*
 * 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 * (GAUSSIAN_INTEGRAL_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::featherAtlas;
        }
    }
    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,
                             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,
            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::featherAtlas)
    {
        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::featherAtlas)
                    ? 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::featherAtlas)
                    ? 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::featherAtlas)
                    ? gpu::ContourDirections::reverse
                    : gpu::ContourDirections::forwardThenReverse;
            m_contourFlags |= NEGATE_PATH_FILL_COVERAGE_FLAG;
        }
        else
        {
            m_contourDirections =
                (m_coverageType == CoverageType::featherAtlas)
                    ? 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::featherAtlas)
    {
        // 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,
                                            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(),
        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 feather atlas region if needed.
    if (m_coverageType == CoverageType::featherAtlas ||
        (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::featherAtlas)
        {
            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->allocateFeatherAtlasDraw(this,
                                                 w,
                                                 h,
                                                 PADDING,
                                                 &x,
                                                 &y,
                                                 &m_featherAtlasScissor))
            {
                return false; // There wasn't room for our path in the atlas.
            }
            m_featherAtlasTransform.scaleFactor = scaleFactor;
            m_featherAtlasTransform.translateX =
                x - visibleBounds.left * scaleFactor;
            m_featherAtlasTransform.translateY =
                y - visibleBounds.top * scaleFactor;
            m_featherAtlasScissorEnabled = 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(const gpu::PlatformFeatures& platformFeatures)
{
    RIVE_PROF_SCOPE_L(2)
    m_subpassCount = 1;
    m_prepassCount = 0;

    switch (m_coverageType)
    {
        case CoverageType::featherAtlas:
            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 (enums::all_flags_set(m_drawContents,
                                          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 if (platformFeatures.supportsPipelineDynamicState)
            {
                // MSAA "fast" path, combined: the three subpasses (borrowed
                // coverage, fans, stencil reset) collapse onto a single
                // msaaDynamicMidpointFans draw that switches between them with
                // dynamic color/depth/stencil/cull state. One batch keeps the
                // reorderer able to instance non-overlapping paths together.
                m_subpassCount = 1;
            }
            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(m_triangulatorFillRule));
                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(m_triangulatorFillRule));
                    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);
            }
            assert(1 <= passCount && passCount <= 3);
            assert(passIdx < passCount);
            gpu::DrawType msaaDrawType;
            if (passCount == 1)
            {
                if (isStroke())
                {
                    msaaDrawType = gpu::DrawType::msaaStrokes;
                }
                else if (enums::all_flags_set(m_drawContents,
                                              gpu::kNestedClipUpdateMask))
                {
                    msaaDrawType = gpu::DrawType::msaaMidpointFanPathsStencil;
                }
                else
                {
                    assert(
                        flush->platformFeatures().supportsPipelineDynamicState);
                    msaaDrawType = gpu::DrawType::msaaDynamicMidpointFans;
                }
            }
            else
            {
                constexpr static gpu::DrawType MSAAFillTypes[][3] = {
                    // 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,
                    },
                };
                msaaDrawType = MSAAFillTypes[passCount - 2][passIdx];
            }
            return &flush->pushMidpointFanDraw(this,
                                               msaaDrawType,
                                               tessVertexCount,
                                               m_msaaTessLocation);
        }

        case CoverageType::featherAtlas:
            // 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->pushFeatherAtlasBlit(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::pushFeatherAtlasTessellation(RenderContext::LogicalFlush* flush,
                                            uint32_t* tessVertexCount,
                                            uint32_t* tessBaseVertex)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_coverageType == CoverageType::featherAtlas);
    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,
            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,
    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};
    // Used with InteriorTriangulationOp::pushOuterCubicTessellationData.
    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::pushOuterCubicTessellationData)
                {
                    contourIDWithFlags =
                        m_contourFlags |
                        tessWriter->pushContour({0, 0},
                                                isStroke(),
                                                /*closed=*/true,
                                                0);
                }
                p0 = pts[0];
                ++contourCount;
                break;
            case PathVerb::line:
                if (op ==
                    InteriorTriangulationOp::pushOuterCubicTessellationData)
                {
                    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)
                    {
                        tessWriter->pushCubic(
                            pts,
                            m_contourDirections,
                            {0, 0},
                            kPatchSegmentCountExcludingJoin,
                            1,
                            kJoinSegmentCount,
                            contourIDWithFlags |
                                CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG);
                    }
                    else
                    {
                        RIVE_DEBUG_CODE(size_t pushedPatchCount = 0;)
                        // 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)
                        {
                            tessWriter->pushCubic(
                                chop,
                                m_contourDirections,
                                {0, 0},
                                kPatchSegmentCountExcludingJoin,
                                1,
                                kJoinSegmentCount,
                                contourIDWithFlags |
                                    CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG);
                            chop += 3;
                            RIVE_DEBUG_CODE(++pushedPatchCount;)
                        }
                        // Fill the inner region between subdivisions.
                        const auto emitMiddleOutGlueTriangles =
                            [&](auto&& self, size_t p0, size_t pLast) -> void {
                            if (pLast - p0 < 2)
                            {
                                return;
                            }
                            size_t pMid = (p0 + pLast) / 2;
                            Vec2D triangleAsCubic[4] = {chops[p0 * 3],
                                                        chops[pMid * 3],
                                                        {0, 0},
                                                        chops[pLast * 3]};
                            tessWriter->pushCubic(
                                triangleAsCubic,
                                m_contourDirections,
                                {0, 0},
                                kPatchSegmentCountExcludingJoin,
                                1,
                                kJoinSegmentCount,
                                contourIDWithFlags |
                                    RETROFITTED_TRIANGLE_CONTOUR_FLAG);
                            RIVE_DEBUG_CODE(++pushedPatchCount;)
                            self(self, p0, pMid);
                            self(self, pMid, pLast);
                        };
                        emitMiddleOutGlueTriangles(emitMiddleOutGlueTriangles,
                                                   0,
                                                   numSubdivisions);
                        assert(pushedPatchCount == numSubdivisions * 2 - 1);
                    }
                }
                patchCount += numSubdivisions * 2 - 1;
                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>(
            rawPath,
            triangulatorAxis == TriangulatorAxis::horizontal
                ? GrTriangulator::Comparator::Direction::kHorizontal
                : GrTriangulator::Comparator::Direction::kVertical,
            allocator);
        // The triangulator's mesh is transform- and fill-rule-independent (so
        // it can be cached); the fill rule and winding are fed per draw.
        // clockwise and nonZero paths both triangulate as nonZero, because
        // clockwise fill still needs the backwards triangles for borrowed
        // coverage.
        m_triangulatorFillRule = m_pathFillRule == FillRule::evenOdd
                                     ? FillRule::evenOdd
                                     : FillRule::nonZero;
        float matrixDeterminant =
            m_matrix[0] * m_matrix[3] - m_matrix[2] * m_matrix[1];
        m_triangulatorReverseTriangles = matrixDeterminant < 0;
        m_triangulatorNegateWinding =
            (matrixDeterminant < 0) !=
            static_cast<bool>(m_contourFlags & NEGATE_PATH_FILL_COVERAGE_FLAG);
        // 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(m_triangulatorFillRule);
        }
    }
    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
