/*
 * Copyright 2022 Rive
 */

#include "rive/renderer/render_context.hpp"

#include "gr_inner_fan_triangulator.hpp"
#include "intersection_board.hpp"
#include "gradient.hpp"
#include "rive_render_paint.hpp"
#include "rive/renderer/draw.hpp"
#ifdef RIVE_CANVAS
#include "rive/renderer/render_canvas.hpp"
#endif
#include "rive/renderer/rive_render_image.hpp"
#include "rive/renderer/render_context_impl.hpp"
#include "rive/gpu_texture_format.hpp"
#include "rive/renderer/stack_vector.hpp"
#include "rive/profiler/profiler_macros.h"

#include "shaders/constants.glsl"

#include <string_view>

#ifdef RIVE_DECODERS
#include "rive/decoders/bitmap_decoder.hpp"
#endif

#ifdef RIVE_KTX2
#include "rive/decoders/decode_ktx2.hpp"
#endif

#include "sort_key_builder.hpp"

namespace rive::gpu
{
constexpr size_t kDefaultSimpleGradientCapacity = 512;
constexpr size_t kDefaultComplexGradientCapacity = 1024;
constexpr size_t kDefaultDrawCapacity = 2048;

// TODO: Move this variable to PlatformFeatures.
constexpr uint32_t kMaxTextureHeight = 2048;
constexpr size_t kMaxTessellationVertexCount =
    kMaxTextureHeight * kTessTextureWidth;
constexpr size_t kMaxTessellationPaddingVertexCount =
    gpu::kMidpointFanPatchSegmentSpan + // Padding at the beginning of the tess
                                        // texture
    (gpu::kOuterCurvePatchSegmentSpan -
     1) + // Max padding between patch types in the tess texture
    1;    // Padding at the end of the tessellation texture
constexpr size_t kMaxTessellationVertexCountBeforePadding =
    kMaxTessellationVertexCount - kMaxTessellationPaddingVertexCount;

// Metal requires vertex buffers to be 256-byte aligned.
constexpr size_t kMaxTessellationAlignmentVertices =
    gpu::kTessVertexBufferAlignmentInElements - 1;

// We can only reorder 32767 draws at a time since the one-based groupIndex
// returned by IntersectionBoard is a signed 16-bit integer.
constexpr size_t kMaxReorderedDrawPassCount =
    std::numeric_limits<int16_t>::max();

// How tall to make a resource texture in order to support the given number of
// items.
template <size_t WidthInItems>
constexpr static size_t resource_texture_height(size_t itemCount)
{
    return (itemCount + WidthInItems - 1) / WidthInItems;
}

constexpr static size_t gradient_data_height(size_t simpleRampCount,
                                             size_t complexRampCount)
{
    return resource_texture_height<gpu::kGradTextureWidthInSimpleRamps>(
               simpleRampCount) +
           complexRampCount;
}

// Returns true if the current bounds poke outside of the containing bounds (and
// thus would need to be clipped against them)
inline bool needsScissor(IAABB currentBounds,
                         IAABB containingBounds,
                         uint32_t renderTargetWidth,
                         uint32_t renderTargetHeight)
{
    // intersect the current bounds with the screen dimensions before testing so
    // that if we end up outside the containing bounds on a side that is also a
    // screen edge it doesn't matter.
    return !containingBounds.contains(currentBounds.intersect(
        IAABB::MakeWH(renderTargetWidth, renderTargetHeight)));
}

inline GradientContentKey::GradientContentKey(rcp<const Gradient> gradient) :
    m_gradient(std::move(gradient))
{}

inline GradientContentKey::GradientContentKey(GradientContentKey&& other) :
    m_gradient(std::move(other.m_gradient))
{}

bool GradientContentKey::operator==(const GradientContentKey& other) const
{
    if (m_gradient.get() == other.m_gradient.get())
    {
        return true;
    }
    else
    {
        return m_gradient->count() == other.m_gradient->count() &&
               !memcmp(m_gradient->stops(),
                       other.m_gradient->stops(),
                       m_gradient->count() * sizeof(float)) &&
               !memcmp(m_gradient->colors(),
                       other.m_gradient->colors(),
                       m_gradient->count() * sizeof(ColorInt));
    }
}

size_t DeepHashGradient::operator()(const GradientContentKey& key) const
{
    const Gradient* grad = key.gradient();
    std::hash<std::string_view> hash;
    size_t x =
        hash(std::string_view(reinterpret_cast<const char*>(grad->stops()),
                              grad->count() * sizeof(float)));
    size_t y =
        hash(std::string_view(reinterpret_cast<const char*>(grad->colors()),
                              grad->count() * sizeof(ColorInt)));
    return x ^ y;
}

RenderContext::RenderContext(std::unique_ptr<RenderContextImpl> impl) :
    m_impl(std::move(impl)),
    // -1 from m_maxPathID so we reserve a path record for the clearColor paint
    // (for atomic mode). This also allows us to index the storage buffers
    // directly by pathID.
    m_maxPathID(MaxPathID(m_impl->platformFeatures().pathIDGranularity) - 1)
{
    // Validate platformFeatures: if supportsBlendAdvancedCoherentKHR is set,
    // supportsBlendAdvancedKHR must also be.
    assert(!m_impl->platformFeatures().supportsBlendAdvancedCoherentKHR ||
           m_impl->platformFeatures().supportsBlendAdvancedKHR);

#ifdef RIVE_GENERATE_FEATHER_LUT
    float table[GAUSSIAN_TABLE_SIZE];
    generate_gausian_integral_table(table);
    generate_inverse_gausian_integral_table(table);
#endif

    setResourceSizes(ResourceAllocationCounts(), /*forceRealloc =*/true);
    releaseResources();
}

RenderContext::~RenderContext()
{
    // Always call flush() to avoid deadlock.
    assert(!m_didBeginFrame);
    // Delete the logical flushes before the block allocators let go of their
    // allocations.
    m_logicalFlushes.clear();
#ifdef RIVE_CANVAS
    m_oreContext.reset();
#endif
}

const gpu::PlatformFeatures& RenderContext::platformFeatures() const
{
    return m_impl->platformFeatures();
}

rcp<RenderBuffer> RenderContext::makeRenderBuffer(RenderBufferType type,
                                                  RenderBufferFlags flags,
                                                  size_t sizeInBytes)
{
    return m_impl->makeRenderBuffer(type, flags, sizeInBytes);
}

#ifdef RIVE_CANVAS
rcp<RenderCanvas> RenderContext::makeRenderCanvas(uint32_t width,
                                                  uint32_t height)
{
    return m_impl->makeRenderCanvas(width, height);
}
rive::ore::Context* RenderContext::ore()
{
    if (m_oreContext == nullptr)
        m_oreContext = m_impl->makeOreContext();
    return m_oreContext.get();
}
#endif

rcp<RenderImage> RenderContext::decodeImage(Span<const uint8_t> encodedBytes)
{
    RIVE_PROF_SCOPE_L(1)
    rcp<Texture> texture = m_impl->platformDecodeImageTexture(encodedBytes);

#ifdef RIVE_KTX2
    // KTX2 magic = «KTX 20»\r\n\x1A\n. Match the first 4 bytes for the cheap
    // dispatch; full magic is re-checked inside DecodeKtx2.
    if (texture == nullptr && encodedBytes.size() >= 12 &&
        encodedBytes[0] == 0xAB && encodedBytes[1] == 0x4B &&
        encodedBytes[2] == 0x54 && encodedBytes[3] == 0x58)
    {
        const Ktx2HwSupport hwSupport = {
            platformFeatures().supportsTextureCompressionBC,
            platformFeatures().supportsTextureCompressionASTC,
            platformFeatures().supportsTextureCompressionETC2,
        };
        Ktx2DecodeResult ktx2;
        if (DecodeKtx2(encodedBytes.data(),
                       encodedBytes.size(),
                       ktx2,
                       hwSupport))
        {
            // KTX2 provides the full level chain (or just level 0). The
            // backends never auto-generate; whatever the file ships with is
            // exactly what gets uploaded.
            texture = m_impl->makeImageTexture(ktx2.pixelWidth,
                                               ktx2.pixelHeight,
                                               ktx2.levelCount,
                                               ktx2.format,
                                               ktx2.blocks.data(),
                                               ktx2.blockWidth,
                                               ktx2.blockHeight,
                                               ktx2.srgb);
        }
    }
#endif

#ifdef RIVE_DECODERS
    if (texture == nullptr)
    {
        auto bitmap = Bitmap::decode(encodedBytes.data(), encodedBytes.size());
        if (bitmap)
        {
            // Bitmap::decode always produces RGBA — convert if needed.
            if (bitmap->pixelFormat() != Bitmap::PixelFormat::RGBAPremul)
            {
                bitmap->pixelFormat(Bitmap::PixelFormat::RGBAPremul);
            }
            uint32_t width = bitmap->width();
            uint32_t height = bitmap->height();
            uint32_t mipLevelCount = math::msb(height | width);
            texture = m_impl->makeImageTexture(width,
                                               height,
                                               mipLevelCount,
                                               GPUTextureFormat::rgba32,
                                               bitmap->bytes(),
                                               /*blockWidth=*/1,
                                               /*blockHeight=*/1,
                                               /*srgb=*/false,
                                               /*generateRemainingMips=*/true);
        }
    }
#endif
    return texture != nullptr ? make_rcp<RiveRenderImage>(std::move(texture))
                              : nullptr;
}

void RenderContext::releaseResources()
{
    assert(!m_didBeginFrame);
    resetContainers();
    setResourceSizes(ResourceAllocationCounts());
    m_maxRecentResourceRequirements = ResourceAllocationCounts();
    m_lastResourceTrimTimeInSeconds = m_impl->secondsNow();
}

void RenderContext::resetContainers()
{
    assert(!m_didBeginFrame);

    if (!m_logicalFlushes.empty())
    {
        // Should get reset to 1 after flush().
        assert(m_logicalFlushes.size() == 1);
        m_logicalFlushes.resize(1);
        m_logicalFlushes.front()->resetContainers();
    }

    m_indirectDrawList.clear();
    m_indirectDrawList.shrink_to_fit();

    m_intersectionBoard = nullptr;
}

RenderContext::LogicalFlush::LogicalFlush(RenderContext* parent) : m_ctx(parent)
{
    rewind();
}

void RenderContext::LogicalFlush::rewind()
{
    RIVE_PROF_SCOPE_L(1)
    m_resourceCounts = Draw::ResourceCounters();
    m_drawPassCount = 0;
    m_simpleGradients.clear();
    m_pendingSimpleGradDraws.clear();
    m_complexGradients.clear();
    m_pendingComplexGradDraws.clear();
    m_pendingGradSpanCount = 0;
    m_clips.clear();
    m_draws.clear();
    m_combinedDrawBounds = IAABB::makeMaximallyNegative();
    m_combinedDrawContents = gpu::DrawContents::none;

    m_pathPaddingCount = 0;
    m_paintPaddingCount = 0;
    m_paintAuxPaddingCount = 0;
    m_contourPaddingCount = 0;
    m_gradSpanPaddingCount = 0;
    m_midpointFanTessEndLocation = 0;
    m_outerCubicTessEndLocation = 0;
    m_outerCubicTessVertexIdx = 0;
    m_midpointFanTessVertexIdx = 0;
    m_baselineShaderMiscFlags = gpu::ShaderMiscFlags::none;

    m_flushDesc = FlushDescriptor();

    m_drawList.reset();
    m_firstDstBlendBarrier = nullptr;
    m_dstBlendBarrierListTail = &m_firstDstBlendBarrier;
    m_combinedShaderFeatures = gpu::ShaderFeatures::NONE;

    m_currentPathID = 0;
    m_currentContourID = 0;

    if (m_atlasRectanizer != nullptr)
    {
        m_atlasRectanizer->reset();
    }
    m_atlasMaxX = 0;
    m_atlasMaxY = 0;
    m_pendingAtlasDraws.clear();

    m_coverageBufferLength = 0;

    m_pendingBarriers = BarrierFlags::none;

    m_currentZIndex = 0;

    RIVE_DEBUG_CODE(m_hasDoneLayout = false;)
}

void RenderContext::LogicalFlush::resetContainers()
{
    m_clips.clear();
    m_clips.shrink_to_fit();
    m_draws.clear();
    m_draws.shrink_to_fit();
    m_draws.reserve(kDefaultDrawCapacity);

    m_simpleGradients.rehash(0);
    m_simpleGradients.reserve(kDefaultSimpleGradientCapacity);

    m_pendingSimpleGradDraws.clear();
    m_pendingSimpleGradDraws.shrink_to_fit();
    m_pendingSimpleGradDraws.reserve(kDefaultSimpleGradientCapacity);

    m_complexGradients.rehash(0);
    m_complexGradients.reserve(kDefaultComplexGradientCapacity);

    m_pendingComplexGradDraws.clear();
    m_pendingComplexGradDraws.shrink_to_fit();
    m_pendingComplexGradDraws.reserve(kDefaultComplexGradientCapacity);

    m_pendingAtlasDraws.clear();
    m_pendingAtlasDraws.shrink_to_fit();
    // Don't reserve any space in m_pendingAtlasDraws since there are many
    // usecases where it isn't used at all.
}

static gpu::InterlockMode select_interlock_mode(
    const RenderContext::FrameDescriptor& frameDescriptor,
    const gpu::PlatformFeatures& platformFeatures)
{
    if (frameDescriptor.msaaSampleCount != 0)
    {
        return gpu::InterlockMode::msaa;
    }
    if (frameDescriptor.clockwiseFillOverride)
    {
        if (platformFeatures.supportsClockwiseMode &&
            !frameDescriptor.disableRasterOrdering)
        {
            return gpu::InterlockMode::clockwise;
        }
        if (platformFeatures.supportsClockwiseAtomicMode)
        {
            return gpu::InterlockMode::clockwiseAtomic;
        }
    }
    if (platformFeatures.supportsRasterOrderingMode &&
        (!frameDescriptor.disableRasterOrdering ||
         // Only respect "disableRasterOrdering" if we have atomic mode to fall
         // back on.
         // FIXME: This API can be improved.
         !platformFeatures.supportsAtomicMode))
    {
        return gpu::InterlockMode::rasterOrdering;
    }
    if (platformFeatures.supportsAtomicMode)
    {
        return gpu::InterlockMode::atomics;
    }
    return gpu::InterlockMode::msaa;
}

void RenderContext::beginFrame(const FrameDescriptor& frameDescriptor)
{
    RIVE_PROF_SCOPE_L(0)

    m_impl->preBeginFrame(this);
    assert(!m_didBeginFrame);
    assert(frameDescriptor.renderTargetWidth > 0);
    assert(frameDescriptor.renderTargetHeight > 0);
    m_frameDescriptor = frameDescriptor;
    m_frameInterlockMode =
        select_interlock_mode(m_frameDescriptor, platformFeatures());
    if (m_frameInterlockMode == gpu::InterlockMode::msaa &&
        m_frameDescriptor.msaaSampleCount == 0)
    {
        // Use 4x MSAA if msaaSampleCount wasn't already specified.
        m_frameDescriptor.msaaSampleCount = 4;
    }
    m_frameShaderFeaturesMask =
        gpu::ShaderFeaturesMaskFor(m_frameInterlockMode);
    if (m_logicalFlushes.empty())
    {
        m_logicalFlushes.emplace_back(new LogicalFlush(this));
    }
    RIVE_DEBUG_CODE(m_didBeginFrame = true);
}

bool RenderContext::isOutsideCurrentFrame(const IAABB& pixelBounds)
{
    assert(m_didBeginFrame);
    int4 bounds = simd::load4i(&pixelBounds);
    auto renderTargetSize =
        simd::cast<int32_t>(uint2{m_frameDescriptor.renderTargetWidth,
                                  m_frameDescriptor.renderTargetHeight});
    return simd::any(bounds.xy >= renderTargetSize || bounds.zw <= 0 ||
                     bounds.xy >= bounds.zw);
}

bool RenderContext::frameSupportsClipRects() const
{
    assert(m_didBeginFrame);
    return m_frameInterlockMode != gpu::InterlockMode::msaa ||
           platformFeatures().supportsClipPlanes;
}

bool RenderContext::frameSupportsImagePaintForPaths() const
{
    assert(m_didBeginFrame);
    return m_frameInterlockMode != gpu::InterlockMode::atomics;
}

uint32_t RenderContext::generateClipID(IAABB contentBounds,
                                       uint32_t parentClipID,
                                       AABBu16 tightenedBounds)
{
    assert(m_didBeginFrame);
    assert(!m_logicalFlushes.empty());
    return m_logicalFlushes.back()->generateClipID(contentBounds,
                                                   parentClipID,
                                                   tightenedBounds);
}

uint32_t RenderContext::LogicalFlush::generateClipID(IAABB contentBounds,
                                                     uint32_t parentClipID,
                                                     AABBu16 tightenedBounds)
{
    if (m_clips.size() < m_ctx->m_maxPathID) // maxClipID == maxPathID.
    {
        m_clips.emplace_back(contentBounds, parentClipID, tightenedBounds);
        assert(m_ctx->m_clipContentID != m_clips.size());
        return math::lossless_numeric_cast<uint32_t>(m_clips.size());
    }
    return 0; // There are no available clip IDs. The caller should flush and
              // try again.
}

RenderContext::LogicalFlush::ClipInfo& RenderContext::LogicalFlush::
    getWritableClipInfo(uint32_t clipID)
{
    assert(clipID > 0);
    assert(clipID <= m_clips.size());
    return m_clips[clipID - 1];
}

bool RenderContext::pushDraws(DrawUniquePtr draws[], size_t drawCount)
{
    assert(m_didBeginFrame);
    assert(!m_logicalFlushes.empty());
    return m_logicalFlushes.back()->pushDraws(draws, drawCount);
}

bool RenderContext::LogicalFlush::pushDraws(DrawUniquePtr draws[],
                                            size_t drawCount)
{
    RIVE_PROF_SCOPE_L(1)
    assert(!m_hasDoneLayout);

    PUSH_DISABLE_CLANG_SIMD_ABI_WARNING()
    auto countsVector = m_resourceCounts.toVec();
    for (size_t i = 0; i < drawCount; ++i)
    {
        assert(!draws[i]->pixelBounds().empty());
        assert(m_ctx->frameSupportsClipRects() ||
               draws[i]->clipRectInverseMatrix() == nullptr);
        countsVector += draws[i]->resourceCounts().toVec();
    }
    POP_DISABLE_CLANG_SIMD_ABI_WARNING()
    Draw::ResourceCounters countsWithNewBatch = countsVector;

    // Textures and buffers have hard size limits. If the new batch doesn't fit
    // within our constraints, the caller needs to flush and try again.
    if (countsWithNewBatch.pathCount > m_ctx->m_maxPathID ||
        countsWithNewBatch.contourCount > kMaxContourID ||
        countsWithNewBatch.midpointFanTessVertexCount +
                countsWithNewBatch.outerCubicTessVertexCount >
            kMaxTessellationVertexCountBeforePadding)
    {
        return false;
    }

    // Allocate subpasses.
    int passCountInBatch = 0;
    for (size_t i = 0; i < drawCount; ++i)
    {
        draws[i]->countSubpasses();
        assert(draws[i]->prepassCount() >= 0);
        assert(draws[i]->subpassCount() >= 0);
        assert(draws[i]->prepassCount() + draws[i]->subpassCount() >= 1);
        passCountInBatch += draws[i]->prepassCount() + draws[i]->subpassCount();
    }

    // We can only reorder 32k draws at a time in atomic and msaa modes since
    // the sort key addresses them with a signed 16-bit index. Make sure we
    // don't exceed that limit.
    if (m_ctx->frameInterlockMode() != gpu::InterlockMode::rasterOrdering &&
        m_drawPassCount + passCountInBatch > kMaxReorderedDrawPassCount)
    {
        return false;
    }

    // Allocate final resources.
    for (size_t i = 0; i < drawCount; ++i)
    {
        if (!draws[i]->allocateResources(this))
        {
            // The draw failed to allocate resources. Give up and let the caller
            // flush and try again.
            //
            // FIXME: This works today, but the surrounding code could be
            // modified to inadvertently leave a stale dangling reference to one
            // of these draws in m_pendingAtlasDraws. This needs to be
            // revisited.
            return false;
        }
    }

    for (size_t i = 0; i < drawCount; ++i)
    {
        m_draws.push_back(std::move(draws[i]));
        // Note: not updating m_combinedDrawBounds here because it will get done
        // in tightenClipBounds later, after we've determined the minimal write
        // sizes for any clips.
        m_combinedDrawContents |= m_draws.back()->drawContents();
    }

    m_resourceCounts = countsWithNewBatch;
    m_drawPassCount += passCountInBatch;
    return true;
}

bool RenderContext::LogicalFlush::allocateGradient(
    const Gradient* gradient,
    gpu::ColorRampLocation* colorRampLocation)
{
    RIVE_PROF_SCOPE_L(2)
    assert(!m_hasDoneLayout);

    const float* stops = gradient->stops();
    size_t stopCount = gradient->count();
    assert(stopCount > 0); // RiveRenderFactory guarantees this.

    if (stopCount == 1 || (stopCount == 2 && stops[0] == 0 && stops[1] == 1))
    {
        // This is a simple gradient that can be implemented by a two-texel
        // color ramp.
        const ColorInt* colors = gradient->colors();
        TwoTexelRamp colorRamp = {colors[0],
                                  // Handle ramps with a single stop.
                                  colors[std::min<size_t>(1, stopCount - 1)]};
        uint64_t simpleKey;
        static_assert(sizeof(simpleKey) == sizeof(ColorInt) * 2);
        RIVE_INLINE_MEMCPY(&simpleKey, &colorRamp, sizeof(ColorInt) * 2);
        uint32_t rampTexelsIdx;
        auto iter = m_simpleGradients.find(simpleKey);
        if (iter != m_simpleGradients.end())
        {
            // This gradient is already in the texture.
            rampTexelsIdx = iter->second;
        }
        else
        {
            if (gradient_data_height(m_simpleGradients.size() + 1,
                                     m_complexGradients.size()) >
                kMaxTextureHeight)
            {
                // We ran out of rows in the gradient texture. Caller has to
                // flush and try again.
                return false;
            }
            rampTexelsIdx = math::lossless_numeric_cast<uint32_t>(
                m_simpleGradients.size() * 2);
            m_simpleGradients.insert({simpleKey, rampTexelsIdx});
            m_pendingSimpleGradDraws.push_back(colorRamp);
            // Simple gradients get uploaded to the GPU as a single GradientSpan
            // instance.
            ++m_pendingGradSpanCount;
        }
        colorRampLocation->row = rampTexelsIdx / kGradTextureWidth;
        colorRampLocation->col = rampTexelsIdx % kGradTextureWidth;
    }
    else
    {
        // This is a complex gradient. Render it to an entire row of the
        // gradient texture.
        GradientContentKey key(ref_rcp(gradient));
        auto iter = m_complexGradients.find(key);
        uint16_t row;
        if (iter != m_complexGradients.end())
        {
            row = iter->second; // This gradient is already in the texture.
        }
        else
        {
            if (gradient_data_height(m_simpleGradients.size(),
                                     m_complexGradients.size() + 1) >
                kMaxTextureHeight)
            {
                // We ran out of rows in the gradient texture. Caller has to
                // flush and try again.
                return false;
            }

            row = static_cast<uint32_t>(m_complexGradients.size());
            m_complexGradients.emplace(std::move(key), row);
            m_pendingComplexGradDraws.push_back(gradient);

            size_t spanCount = stopCount - 1;
            m_pendingGradSpanCount += spanCount;
        }
        // Store the row relative to the first complex gradient for now.
        // PaintData::set() will offset this value by the number of simple
        // gradient rows once its final value is known.
        colorRampLocation->row = row;
        colorRampLocation->col = ColorRampLocation::kComplexGradientMarker;
    }
    return true;
}

bool RenderContext::LogicalFlush::allocateAtlasDraw(PathDraw* pathDraw,
                                                    uint16_t drawWidth,
                                                    uint16_t drawHeight,
                                                    uint16_t desiredPadding,
                                                    uint16_t* x,
                                                    uint16_t* y,
                                                    AABBu16* paddedRegion)
{
    RIVE_PROF_SCOPE_L(2)

    if (m_atlasRectanizer == nullptr)
    {
        uint16_t atlasMaxSize = m_ctx->atlasMaxSize();
        // Use an atlas larger than atlasMaxSize if it's too small for the
        // request (meaning the render target is larger than atlasMaxSize).
        m_atlasRectanizer = std::make_unique<rive::RectanizerSkyline>(
            std::max(atlasMaxSize, drawWidth),
            std::max(atlasMaxSize, drawHeight));
    }

    const uint16_t atlasMaxWidth = m_atlasRectanizer->width();
    const uint16_t atlasMaxHeight = m_atlasRectanizer->height();
    uint16_t paddedWidth =
        std::min<uint16_t>(drawWidth + desiredPadding * 2, atlasMaxWidth);
    uint16_t paddedHeight =
        std::min<uint16_t>(drawHeight + desiredPadding * 2, atlasMaxHeight);
    int16_t ix, iy;
    if (!m_atlasRectanizer->addRect(paddedWidth, paddedHeight, &ix, &iy))
    {
        // Delete the rectanizer of it wasn't big enough for this path. It will
        // be reallocated to a large enough size on the next call.
        if (drawWidth > atlasMaxWidth || drawHeight > atlasMaxHeight)
        {
            m_atlasRectanizer = nullptr;
        }
        m_atlasRectanizer = nullptr;
        return false;
    }

    assert(ix >= 0);
    assert(iy >= 0);
    assert(ix + paddedWidth <= atlasMaxWidth);
    assert(iy + paddedHeight <= atlasMaxHeight);

    *x = ix + (paddedWidth - drawWidth) / 2;
    *y = iy + (paddedHeight - drawHeight) / 2;
    *paddedRegion = {math::lossless_numeric_cast<uint16_t>(ix),
                     math::lossless_numeric_cast<uint16_t>(iy),
                     math::lossless_numeric_cast<uint16_t>(ix + paddedWidth),
                     math::lossless_numeric_cast<uint16_t>(iy + paddedHeight)};
    assert(
        (AABBu16{0, 0, atlasMaxWidth, atlasMaxHeight}).contains(*paddedRegion));

    m_atlasMaxX = std::max<uint32_t>(m_atlasMaxX, paddedRegion->right);
    m_atlasMaxY = std::max<uint32_t>(m_atlasMaxY, paddedRegion->bottom);
    assert(m_atlasMaxX <= atlasMaxWidth);
    assert(m_atlasMaxY <= atlasMaxHeight);

    m_pendingAtlasDraws.push_back(pathDraw);
    return true;
}

size_t RenderContext::LogicalFlush::allocateCoverageBufferRange(size_t length)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_ctx->frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic);
    // Allocations must be aligned to the tile size.
    assert(length % (BUFFER_IMAGE_TILE_SIZE * BUFFER_IMAGE_TILE_SIZE) == 0u);
    uint32_t offset = m_coverageBufferLength;
    if (offset + length > m_ctx->platformFeatures().maxCoverageBufferLength)
    {
        return -1;
    }
    m_coverageBufferLength += length;
    return offset;
}

void RenderContext::logicalFlush()
{
    assert(m_didBeginFrame);

    // Reset clipping state after every logical flush because the clip buffer is
    // not preserved between render passes.
    m_clipContentID = 0;

    // Don't issue any GPU commands between logical flushes. Instead, build up a
    // list of flushes that we will submit all at once at the end of the frame.
    m_logicalFlushes.emplace_back(new LogicalFlush(this));
}

void RenderContext::flush(const FlushResources& flushResources)
{
    RIVE_PROF_SCOPE_L(0)
    assert(m_didBeginFrame);
    assert(flushResources.renderTarget->width() ==
           m_frameDescriptor.renderTargetWidth);
    assert(flushResources.renderTarget->height() ==
           m_frameDescriptor.renderTargetHeight);

    m_clipContentID = 0;

    // Layout this frame's resource buffers and textures.
    LogicalFlush::ResourceCounters totalFrameResourceCounts;
    LogicalFlush::LayoutCounters layoutCounts;
    for (size_t i = 0; i < m_logicalFlushes.size(); ++i)
    {
        m_logicalFlushes[i]->layoutResources(flushResources,
                                             i,
                                             &totalFrameResourceCounts,
                                             &layoutCounts);
    }

    // Determine the minimum required resource allocation sizes to service this
    // flush.
    const ResourceAllocationCounts resourceRequirements = {
        .flushUniformBufferCount = m_logicalFlushes.size(),
        .pathBufferCount =
            totalFrameResourceCounts.pathCount + layoutCounts.pathPaddingCount,
        .paintBufferCount =
            totalFrameResourceCounts.pathCount + layoutCounts.paintPaddingCount,
        .paintAuxBufferCount = totalFrameResourceCounts.pathCount +
                               layoutCounts.paintAuxPaddingCount,
        .contourBufferCount = totalFrameResourceCounts.contourCount +
                              layoutCounts.contourPaddingCount,
        .gradSpanBufferCount =
            layoutCounts.gradSpanCount + layoutCounts.gradSpanPaddingCount,
        .tessSpanBufferCount =
            totalFrameResourceCounts.maxTessellatedSegmentCount,
        .triangleVertexBufferCount =
            totalFrameResourceCounts.maxTriangleVertexCount,
        .imageDrawInstanceBufferCount = totalFrameResourceCounts.imageDrawCount,
        .gradTextureHeight = layoutCounts.maxGradTextureHeight,
        .tessTextureHeight = layoutCounts.maxTessTextureHeight,
        .atlasTextureWidth = layoutCounts.maxAtlasWidth,
        .atlasTextureHeight = layoutCounts.maxAtlasHeight,
        .plsTransientBackingWidth =
            (layoutCounts.maxPLSTransientBackingPlaneCount > 0)
                ? static_cast<size_t>(m_frameDescriptor.renderTargetWidth)
                : 0,
        .plsTransientBackingHeight =
            (layoutCounts.maxPLSTransientBackingPlaneCount > 0)
                ? static_cast<size_t>(m_frameDescriptor.renderTargetHeight)
                : 0,
        .plsTransientBackingPlaneCount =
            layoutCounts.maxPLSTransientBackingPlaneCount,
        .plsAtomicCoverageBackingWidth =
            (frameInterlockMode() == gpu::InterlockMode::atomics)
                ? static_cast<size_t>(m_frameDescriptor.renderTargetWidth)
                : 0,
        .plsAtomicCoverageBackingHeight =
            (frameInterlockMode() == gpu::InterlockMode::atomics)
                ? static_cast<size_t>(m_frameDescriptor.renderTargetHeight)
                : 0,
        .coverageBufferLength = layoutCounts.maxCoverageBufferLength,
    };

    // Ensure we're within hardware limits.
    assert(resourceRequirements.gradTextureHeight <= kMaxTextureHeight);
    assert(resourceRequirements.tessTextureHeight <= kMaxTextureHeight);
    assert(resourceRequirements.atlasTextureWidth <= atlasMaxSize() ||
           resourceRequirements.atlasTextureWidth <=
               frameDescriptor().renderTargetWidth);
    assert(resourceRequirements.atlasTextureHeight <= atlasMaxSize() ||
           resourceRequirements.atlasTextureHeight <=
               frameDescriptor().renderTargetHeight);
    assert(resourceRequirements.plsTransientBackingWidth <=
           m_frameDescriptor.renderTargetWidth);
    assert(resourceRequirements.plsTransientBackingHeight <=
           m_frameDescriptor.renderTargetHeight);
    assert(resourceRequirements.coverageBufferLength <=
           platformFeatures().maxCoverageBufferLength);

    PUSH_DISABLE_CLANG_SIMD_ABI_WARNING()

    // Track m_maxRecentResourceRequirements so we can trim GPU allocations when
    // steady-state usage goes down.
    m_maxRecentResourceRequirements = ResourceAllocationCounts::FromVec(
        simd::max(resourceRequirements.toVec(),
                  m_maxRecentResourceRequirements.toVec()));

    // Grow resources enough to handle this flush.
    // If "allocs" already fits in our current allocations, then don't change
    // them.
    // If they don't fit, overallocate by the specified amount in order to
    // create some slack for growth.
    constexpr static ResourceAllocationCounts OVERALLOC_x4 = {
        .flushUniformBufferCount = 5,        // 125%
        .pathBufferCount = 5,                // 125%
        .paintBufferCount = 5,               // 125%
        .paintAuxBufferCount = 5,            // 125%
        .contourBufferCount = 5,             // 125%
        .gradSpanBufferCount = 5,            // 125%
        .tessSpanBufferCount = 5,            // 125%
        .triangleVertexBufferCount = 5,      // 125%
        .imageDrawInstanceBufferCount = 5,   // 125%
        .gradTextureHeight = 5,              // 125%
        .tessTextureHeight = 5,              // 125%
        .atlasTextureWidth = 5,              // 125%
        .atlasTextureHeight = 5,             // 125%
        .plsTransientBackingWidth = 4,       // 100% (i.e., don't overallocate)
        .plsTransientBackingHeight = 4,      // 100% (i.e., don't overallocate)
        .plsTransientBackingPlaneCount = 4,  // 100% (i.e., don't overallocate)
        .plsAtomicCoverageBackingWidth = 4,  // 100% (i.e., don't overallocate)
        .plsAtomicCoverageBackingHeight = 4, // 100% (i.e., don't overallocate)
        .coverageBufferLength = 5,           // 125%
    };
    ResourceAllocationCounts allocs =
        ResourceAllocationCounts::FromVec(simd::if_then_else(
            resourceRequirements.toVec() <=
                m_currentResourceAllocations.toVec(),
            m_currentResourceAllocations.toVec(),
            (resourceRequirements.toVec() * OVERALLOC_x4.toVec()) >> 2));

    // In case the 25% growth pushed us above limits.
    allocs.gradTextureHeight =
        std::min<size_t>(allocs.gradTextureHeight, kMaxTextureHeight);
    allocs.tessTextureHeight =
        std::min<size_t>(allocs.tessTextureHeight, kMaxTextureHeight);
    allocs.atlasTextureWidth = std::min<size_t>(
        allocs.atlasTextureWidth,
        std::max(atlasMaxSize(), frameDescriptor().renderTargetWidth));
    allocs.atlasTextureHeight = std::min<size_t>(
        allocs.atlasTextureHeight,
        std::max(atlasMaxSize(), frameDescriptor().renderTargetHeight));
    allocs.coverageBufferLength =
        std::min(allocs.coverageBufferLength,
                 platformFeatures().maxCoverageBufferLength);

    // Additionally, every 5 seconds, trim resources down to the most recent
    // steady-state usage.
    double flushTime = m_impl->secondsNow();
    bool needsResourceTrim = flushTime - m_lastResourceTrimTimeInSeconds >= 5;
    if (needsResourceTrim)
    {
        // Trim GPU resource allocations to their maximum recent usage, plus
        // overallocation, and only if the recent usage is below a certain
        // threshold.
        constexpr static ResourceAllocationCounts SHRINK_THRESHOLD_x3 = {
            .flushUniformBufferCount = 2,        // 66.7%
            .pathBufferCount = 2,                // 66.7%
            .paintBufferCount = 2,               // 66.7%
            .paintAuxBufferCount = 2,            // 66.7%
            .contourBufferCount = 2,             // 66.7%
            .gradSpanBufferCount = 2,            // 66.7%
            .tessSpanBufferCount = 2,            // 66.7%
            .triangleVertexBufferCount = 2,      // 66.7%
            .imageDrawInstanceBufferCount = 2,   // 66.7%
            .gradTextureHeight = 2,              // 66.7%
            .tessTextureHeight = 2,              // 66.7%
            .atlasTextureWidth = 2,              // 66.7%
            .atlasTextureHeight = 2,             // 66.7%
            .plsTransientBackingWidth = 3,       // 100% (i.e., always shrink)
            .plsTransientBackingHeight = 3,      // 100% (i.e., always shrink)
            .plsTransientBackingPlaneCount = 3,  // 100% (i.e., always shrink)
            .plsAtomicCoverageBackingWidth = 3,  // 100% (i.e., always shrink)
            .plsAtomicCoverageBackingHeight = 3, // 100% (i.e., always shrink)
            .coverageBufferLength = 2,           // 66.7%
        };
        allocs = ResourceAllocationCounts::FromVec(simd::if_then_else(
            m_maxRecentResourceRequirements.toVec() <=
                (allocs.toVec() * SHRINK_THRESHOLD_x3.toVec()) / size_t(3),
            // TODO: Do we actually need overallocation here?? Or should we just
            // trust the past 5 seconds of steady usage?
            (m_maxRecentResourceRequirements.toVec() * OVERALLOC_x4.toVec()) >>
                2,
            allocs.toVec()));

        // Ensure we stayed within limits.
        assert(allocs.gradTextureHeight <= kMaxTextureHeight);
        assert(allocs.tessTextureHeight <= kMaxTextureHeight);
        assert(allocs.atlasTextureWidth <= atlasMaxSize() ||
               allocs.atlasTextureWidth <= frameDescriptor().renderTargetWidth);
        assert(allocs.atlasTextureHeight <= atlasMaxSize() ||
               allocs.atlasTextureHeight <=
                   frameDescriptor().renderTargetHeight);
        assert(allocs.coverageBufferLength <=
               platformFeatures().maxCoverageBufferLength);

        // Zero out m_maxRecentResourceRequirements for the next interval.
        m_maxRecentResourceRequirements = ResourceAllocationCounts();
        m_lastResourceTrimTimeInSeconds = flushTime;
    }

    assert(simd::all(allocs.toVec() >= resourceRequirements.toVec()));
    POP_DISABLE_CLANG_SIMD_ABI_WARNING()

    setResourceSizes(allocs);

    m_impl->prepareToFlush(flushResources.currentFrameNumber,
                           flushResources.safeFrameNumber);
    if (mapResourceBuffers(resourceRequirements))
    {
        for (const auto& flush : m_logicalFlushes)
        {
            flush->writeResources();
        }

        assert(m_flushUniformData.elementsWritten() == m_logicalFlushes.size());
        assert(m_imageDrawInstanceData.elementsWritten() ==
               totalFrameResourceCounts.imageDrawCount);
        assert(m_pathData.elementsWritten() ==
               totalFrameResourceCounts.pathCount +
                   layoutCounts.pathPaddingCount);
        assert(m_paintData.elementsWritten() ==
               totalFrameResourceCounts.pathCount +
                   layoutCounts.paintPaddingCount);
        assert(m_paintAuxData.elementsWritten() ==
               totalFrameResourceCounts.pathCount +
                   layoutCounts.paintAuxPaddingCount);
        assert(m_contourData.elementsWritten() ==
               totalFrameResourceCounts.contourCount +
                   layoutCounts.contourPaddingCount);
        assert(m_gradSpanData.elementsWritten() ==
               layoutCounts.gradSpanCount + layoutCounts.gradSpanPaddingCount);
        assert(m_tessSpanData.elementsWritten() <=
               totalFrameResourceCounts.maxTessellatedSegmentCount);
        assert(m_triangleVertexData.elementsWritten() <=
               totalFrameResourceCounts.maxTriangleVertexCount);

        unmapResourceBuffers(resourceRequirements);

        // Issue logical flushes to the backend.
        for (const auto& flush : m_logicalFlushes)
        {
            m_impl->flush(flush->desc());
        }
    }
    else
    {
        fprintf(stderr, "Buffer mapping failed, cannot render.\n");
        unmapResourceBuffers(resourceRequirements);
    }

    m_impl->postFlush(flushResources);

    if (!m_logicalFlushes.empty())
    {
        m_logicalFlushes.resize(1);
        m_logicalFlushes.front()->rewind();
    }

    // Drop all memory that was allocated for this frame using
    // TrivialBlockAllocator.
    m_perFrameAllocator.reset();
    m_numChopsAllocator.reset();
    m_chopVerticesAllocator.reset();
    m_tangentPairsAllocator.reset();
    m_polarSegmentCountsAllocator.reset();
    m_parametricSegmentCountsAllocator.reset();

    m_frameDescriptor = FrameDescriptor();

    RIVE_DEBUG_CODE(m_didBeginFrame = false;)

    // Wait to reset CPU-side containers until after the flush has finished.
    if (needsResourceTrim)
    {
        resetContainers();
    }
}

static uint32_t pls_transient_backing_plane_count(
    gpu::InterlockMode interlockMode,
    gpu::DrawContents combinedDrawContents)
{
    switch (interlockMode)
    {
        case gpu::InterlockMode::rasterOrdering:
            return 3; // clip, scratch, coverage
        case gpu::InterlockMode::atomics:
        case gpu::InterlockMode::clockwiseAtomic:
            return 1; // only clip (coverage is atomic)
        case gpu::InterlockMode::clockwise:
        {
            uint32_t n = 1; // coverage
            if (enums::any_flag_set(combinedDrawContents,
                                    gpu::DrawContents::activeClip |
                                        gpu::DrawContents::clipUpdate))
            {
                ++n; // clip
            }
            if (enums::is_flag_set(combinedDrawContents,
                                   gpu::DrawContents::advancedBlend))
            {
                ++n; // scratch color
            }
            return n;
        }
        case gpu::InterlockMode::msaa:
            return 0; // N/A
    }
    RIVE_UNREACHABLE();
}

static bool wants_fixed_function_color_output(
    const gpu::PlatformFeatures& platformFeatures,
    gpu::InterlockMode interlockMode,
    gpu::DrawContents combinedDrawContents,
    bool manuallyResolved)
{
    switch (interlockMode)
    {
        case gpu::InterlockMode::rasterOrdering:
            // rasterOrdering shaders always read the framebuffer, even with
            // srcOver blend.
            return false;

        case gpu::InterlockMode::atomics:
        case gpu::InterlockMode::clockwiseAtomic:
            return !enums::is_flag_set(combinedDrawContents,
                                       gpu::DrawContents::advancedBlend);

        case gpu::InterlockMode::clockwise:
            assert(enums::no_flags_set(combinedDrawContents,
                                       gpu::DrawContents::nonZeroFill |
                                           gpu::DrawContents::evenOddFill));
            return platformFeatures.supportsClockwiseFixedFunctionMode &&
                   !enums::is_flag_set(combinedDrawContents,
                                       gpu::DrawContents::advancedBlend);

        case gpu::InterlockMode::msaa:
            // Manual MSAA resolves read the framebuffer, so they can't use
            // fixedFunctionColorOutput.
            return !manuallyResolved &&
                   !enums::is_flag_set(combinedDrawContents,
                                       gpu::DrawContents::advancedBlend);
    }

    RIVE_UNREACHABLE();
}

void RenderContext::LogicalFlush::layoutResources(
    const FlushResources& flushResources,
    size_t logicalFlushIdx,
    ResourceCounters* runningFrameResourceCounts,
    LayoutCounters* runningFrameLayoutCounts)
{
    RIVE_PROF_SCOPE_L(1)
    assert(!m_hasDoneLayout);

    const FrameDescriptor& frameDescriptor = m_ctx->frameDescriptor();

    // Reserve a path record for the clearColor paint (used by atomic mode).
    // This also allows us to index the storage buffers directly by pathID.
    ++m_resourceCounts.pathCount;

    // Storage buffer offsets are required to be aligned on multiples of 256.
    m_pathPaddingCount =
        math::padding_to_align_up<gpu::kPathBufferAlignmentInElements>(
            m_resourceCounts.pathCount);
    m_paintPaddingCount =
        math::padding_to_align_up<gpu::kPaintBufferAlignmentInElements>(
            m_resourceCounts.pathCount);
    m_paintAuxPaddingCount =
        math::padding_to_align_up<gpu::kPaintAuxBufferAlignmentInElements>(
            m_resourceCounts.pathCount);
    m_contourPaddingCount =
        math::padding_to_align_up<gpu::kContourBufferAlignmentInElements>(
            m_resourceCounts.contourCount);

    // Metal requires vertex buffers to be 256-byte aligned.
    m_gradSpanPaddingCount =
        math::padding_to_align_up<gpu::kGradSpanBufferAlignmentInElements>(
            m_pendingGradSpanCount);

    size_t totalTessVertexCountWithPadding = 0;
    if ((m_resourceCounts.midpointFanTessVertexCount |
         m_resourceCounts.outerCubicTessVertexCount) != 0)
    {
        // midpointFan tessellation vertices reside at the beginning of the
        // tessellation texture, after 1 patch of padding vertices.
        constexpr uint32_t kPrePadding = gpu::kMidpointFanPatchSegmentSpan;
        m_midpointFanTessVertexIdx = kPrePadding;
        m_midpointFanTessEndLocation =
            m_midpointFanTessVertexIdx +
            math::lossless_numeric_cast<uint32_t>(
                m_resourceCounts.midpointFanTessVertexCount);

        // outerCubic tessellation vertices reside after the midpointFan
        // vertices, aligned on a multiple of the outerCubic patch size.
        uint32_t interiorPadding =
            math::padding_to_align_up<gpu::kOuterCurvePatchSegmentSpan>(
                m_midpointFanTessEndLocation);
        m_outerCubicTessVertexIdx =
            m_midpointFanTessEndLocation + interiorPadding;
        m_outerCubicTessEndLocation =
            m_outerCubicTessVertexIdx +
            math::lossless_numeric_cast<uint32_t>(
                m_resourceCounts.outerCubicTessVertexCount);

        // We need one more padding vertex after all the tessellation vertices.
        constexpr uint32_t kPostPadding = 1;
        totalTessVertexCountWithPadding =
            m_outerCubicTessEndLocation + kPostPadding;

        assert(kPrePadding + interiorPadding + kPostPadding <=
               kMaxTessellationPaddingVertexCount);
        assert(totalTessVertexCountWithPadding <= kMaxTessellationVertexCount);
    }

    uint32_t tessDataHeight = math::lossless_numeric_cast<uint32_t>(
        resource_texture_height<kTessTextureWidth>(
            totalTessVertexCountWithPadding));
    if (m_resourceCounts.maxTessellatedSegmentCount != 0)
    {
        // Conservatively account for line breaks and padding in the
        // tessellation span count. Line breaks potentially introduce a new
        // span. Count the maximum number of line breaks we might encounter,
        // which is at most TWO for every line in the tessellation texture (one
        // for a forward span, and one for its reflection.)
        size_t maxSpanBreakCount = tessDataHeight * 2;
        // The tessellation texture requires 3 separate spans of padding
        // vertices (see above and below).
        constexpr size_t kPaddingSpanCount = 3;
        m_resourceCounts.maxTessellatedSegmentCount +=
            maxSpanBreakCount + kPaddingSpanCount +
            kMaxTessellationAlignmentVertices;
    }

    // Complex gradients begin on the first row immediately after the simple
    // gradients.
    m_gradTextureLayout.complexOffsetY = math::lossless_numeric_cast<uint32_t>(
        resource_texture_height<gpu::kGradTextureWidthInSimpleRamps>(
            m_simpleGradients.size()));

    m_flushDesc.renderTarget = flushResources.renderTarget;
    m_flushDesc.interlockMode = m_ctx->frameInterlockMode();
    m_flushDesc.msaaSampleCount = frameDescriptor.msaaSampleCount;

    // In atomic mode, we may be able to skip the explicit clear of the color
    // buffer and fold it into the atomic "resolve" operation instead.
    bool doClearDuringAtomicResolve = false;

    if (logicalFlushIdx != 0)
    {
        // We always have to preserve the renderTarget between logical flushes.
        m_flushDesc.colorLoadAction = gpu::LoadAction::preserveRenderTarget;
    }
    else if (frameDescriptor.loadAction == gpu::LoadAction::clear)
    {
        // In atomic mode, we can clear during the resolve operation if the
        // clearColor is opaque (because we don't want or have a "source only"
        // blend mode).
        doClearDuringAtomicResolve =
            m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics &&
            colorAlpha(frameDescriptor.clearColor) == 255;
        m_flushDesc.colorLoadAction = doClearDuringAtomicResolve
                                          ? gpu::LoadAction::dontCare
                                          : gpu::LoadAction::clear;
    }
    else
    {
        m_flushDesc.colorLoadAction = frameDescriptor.loadAction;
    }
    m_flushDesc.colorClearValue = frameDescriptor.clearColor;

    if (doClearDuringAtomicResolve)
    {
        // In atomic mode we can accomplish a clear of the color buffer while
        // the shader resolves coverage, instead of actually clearing.
        // writeResources() will configure the fill for pathID=0 to be a solid
        // fill matching the clearColor, so if we just initialize coverage
        // buffer to solid coverage with pathID=0, the resolve step will write
        // out the correct clear color.
        assert(m_flushDesc.interlockMode == gpu::InterlockMode::atomics);
        m_flushDesc.coverageClearValue =
            static_cast<uint32_t>(FIXED_COVERAGE_ONE);
    }
    else if (m_flushDesc.interlockMode == gpu::InterlockMode::atomics)
    {
        // When we don't skip the initial clear in atomic mode, clear the
        // coverage buffer to pathID=0 and a transparent coverage value.
        // pathID=0 meets the requirement that pathID is always monotonically
        // increasing. Transparent coverage makes sure the clearColor doesn't
        // get written out while resolving.
        m_flushDesc.coverageClearValue =
            static_cast<uint32_t>(FIXED_COVERAGE_ZERO);
    }
    else
    {
        // In non-atomic mode, the coverage buffer just needs to be initialized
        // with "pathID=0" to avoid collisions with any pathIDs being rendered.
        m_flushDesc.coverageClearValue = 0;
    }

    // Adjust the clip bounds so that they are as tight on the writes/reads as
    // possible, to enable minimal scissor rectangle sizes.
    // Note: This is done here so that m_combinedDrawBounds are updated before
    // we try to use them, to ensure they're also tightened in on the clipping
    // (when scissor is supported).
    tightenClipBounds();

    if (doClearDuringAtomicResolve ||
        m_flushDesc.colorLoadAction == gpu::LoadAction::clear)
    {
        // If we're clearing then we always update the entire render target.
        m_flushDesc.renderTargetUpdateBounds =
            m_flushDesc.renderTarget->bounds();
    }
    else
    {
        // When we don't clear, we only update the draw bounds.
        m_flushDesc.renderTargetUpdateBounds =
            m_flushDesc.renderTarget->bounds().intersect(m_combinedDrawBounds);
    }
    if (m_flushDesc.renderTargetUpdateBounds.empty())
    {
        // If this is empty it means there are no draws and no clear.
        m_flushDesc.renderTargetUpdateBounds = {0, 0, 0, 0};
    }

    m_flushDesc.virtualTileWidth = frameDescriptor.virtualTileWidth;
    m_flushDesc.virtualTileHeight = frameDescriptor.virtualTileHeight;

    m_flushDesc.manuallyResolved = m_ctx->m_impl->wantsManualRenderPassResolve(
        m_flushDesc.interlockMode,
        m_flushDesc.renderTarget,
        m_flushDesc.renderTargetUpdateBounds,
        m_flushDesc.virtualTileWidth,
        m_flushDesc.virtualTileHeight,
        m_combinedDrawContents);

    m_flushDesc.fixedFunctionColorOutput =
        wants_fixed_function_color_output(m_ctx->platformFeatures(),
                                          m_ctx->frameInterlockMode(),
                                          m_combinedDrawContents,
                                          m_flushDesc.manuallyResolved);
    if (m_flushDesc.fixedFunctionColorOutput)
    {
        m_baselineShaderMiscFlags |=
            gpu::ShaderMiscFlags::fixedFunctionColorOutput;
    }
    m_flushDesc.atlasContentWidth = m_atlasMaxX;
    m_flushDesc.atlasContentHeight = m_atlasMaxY;

    m_flushDesc.flushUniformDataOffsetInBytes =
        logicalFlushIdx * sizeof(gpu::FlushUniforms);
    m_flushDesc.pathCount =
        math::lossless_numeric_cast<uint32_t>(m_resourceCounts.pathCount);
    m_flushDesc.firstPath = runningFrameResourceCounts->pathCount +
                            runningFrameLayoutCounts->pathPaddingCount;
    m_flushDesc.firstPaint = runningFrameResourceCounts->pathCount +
                             runningFrameLayoutCounts->paintPaddingCount;
    m_flushDesc.firstPaintAux = runningFrameResourceCounts->pathCount +
                                runningFrameLayoutCounts->paintAuxPaddingCount;
    m_flushDesc.contourCount =
        math::lossless_numeric_cast<uint32_t>(m_resourceCounts.contourCount);
    m_flushDesc.firstContour = runningFrameResourceCounts->contourCount +
                               runningFrameLayoutCounts->contourPaddingCount;
    m_flushDesc.gradSpanCount =
        math::lossless_numeric_cast<uint32_t>(m_pendingGradSpanCount);
    m_flushDesc.firstGradSpan = runningFrameLayoutCounts->gradSpanCount +
                                runningFrameLayoutCounts->gradSpanPaddingCount;
    m_flushDesc.gradDataHeight = math::lossless_numeric_cast<uint32_t>(
        m_gradTextureLayout.complexOffsetY + m_complexGradients.size());
    m_flushDesc.tessDataHeight = tessDataHeight;
    m_flushDesc.clockwiseFillOverride = frameDescriptor.clockwiseFillOverride;
    m_flushDesc.wireframe = frameDescriptor.wireframe;
    m_flushDesc.ditherMode = m_ctx->frameDescriptor().ditherMode;
#ifdef WITH_RIVE_TOOLS
    m_flushDesc.synthesizedFailureType = frameDescriptor.synthesizedFailureType;
#endif

    m_flushDesc.externalCommandBuffer = flushResources.externalCommandBuffer;

    PUSH_DISABLE_CLANG_SIMD_ABI_WARNING()
    *runningFrameResourceCounts =
        runningFrameResourceCounts->toVec() + m_resourceCounts.toVec();
    POP_DISABLE_CLANG_SIMD_ABI_WARNING()

    runningFrameLayoutCounts->pathPaddingCount += m_pathPaddingCount;
    runningFrameLayoutCounts->paintPaddingCount += m_paintPaddingCount;
    runningFrameLayoutCounts->paintAuxPaddingCount += m_paintAuxPaddingCount;
    runningFrameLayoutCounts->contourPaddingCount += m_contourPaddingCount;
    runningFrameLayoutCounts->gradSpanCount += m_pendingGradSpanCount;
    runningFrameLayoutCounts->gradSpanPaddingCount += m_gradSpanPaddingCount;
    runningFrameLayoutCounts->maxGradTextureHeight =
        std::max(m_flushDesc.gradDataHeight,
                 runningFrameLayoutCounts->maxGradTextureHeight);
    runningFrameLayoutCounts->maxTessTextureHeight =
        std::max(m_flushDesc.tessDataHeight,
                 runningFrameLayoutCounts->maxTessTextureHeight);
    runningFrameLayoutCounts->maxAtlasWidth =
        std::max(m_atlasMaxX, runningFrameLayoutCounts->maxAtlasWidth);
    runningFrameLayoutCounts->maxAtlasHeight =
        std::max(m_atlasMaxY, runningFrameLayoutCounts->maxAtlasHeight);
    runningFrameLayoutCounts->maxPLSTransientBackingPlaneCount =
        std::max(pls_transient_backing_plane_count(m_flushDesc.interlockMode,
                                                   m_combinedDrawContents),
                 runningFrameLayoutCounts->maxPLSTransientBackingPlaneCount);
    runningFrameLayoutCounts->maxCoverageBufferLength =
        std::max<size_t>(m_coverageBufferLength,
                         runningFrameLayoutCounts->maxCoverageBufferLength);

    assert(m_flushDesc.firstPath % gpu::kPathBufferAlignmentInElements == 0);
    assert(m_flushDesc.firstPaint % gpu::kPaintBufferAlignmentInElements == 0);
    assert(m_flushDesc.firstPaintAux %
               gpu::kPaintAuxBufferAlignmentInElements ==
           0);
    assert(m_flushDesc.firstContour % gpu::kContourBufferAlignmentInElements ==
           0);
    assert(m_flushDesc.firstGradSpan %
               gpu::kGradSpanBufferAlignmentInElements ==
           0);
    RIVE_DEBUG_CODE(m_hasDoneLayout = true;)
}

void RenderContext::LogicalFlush::pushBarriers(BarrierFlags barrierFlags)
{
    if (m_ctx->platformFeatures()
            .clockwiseAtomicBorrowedCoverageBarrierNeedsRenderPassInit &&
        enums::is_flag_set(barrierFlags,
                           gpu::BarrierFlags::clockwiseBorrowedCoverage))
    {
        // We need a workaround in order for input attachments to work.
        BarrierFlags workaroundBarriers =
            BarrierFlags::clockwiseBorrowedCoverage | BarrierFlags::plsAtomic;
        if (enums::is_flag_set(m_combinedDrawContents,
                               gpu::DrawContents::advancedBlend))
        {
            workaroundBarriers |= BarrierFlags::dstBlend;
        }
        m_drawList.emplace_back(m_ctx->perFrameAllocator(),
                                gpu::DrawType::renderPassInitialize,
                                m_baselineShaderMiscFlags,
                                gpu::DrawContents::none,
                                1,
                                0,
                                BlendMode::overlay,
                                ImageSampler::LinearClamp(),
                                workaroundBarriers);
        barrierFlags &= ~gpu::BarrierFlags::clockwiseBorrowedCoverage;
    }

    m_pendingBarriers |= barrierFlags;
}

void RenderContext::LogicalFlush::writeResources()
{
    RIVE_PROF_SCOPE_L(1)
    const gpu::PlatformFeatures& platformFeatures = m_ctx->platformFeatures();
    assert(m_hasDoneLayout);
    assert(m_flushDesc.firstPath == m_ctx->m_pathData.elementsWritten());
    assert(m_flushDesc.firstPaint == m_ctx->m_paintData.elementsWritten());
    assert(m_flushDesc.firstPaintAux ==
           m_ctx->m_paintAuxData.elementsWritten());

    // Wait until here before we record these texture sizes; they aren't decided
    // until after all LogicalFlushes have run layoutResources().
    m_flushDesc.atlasTextureWidth = math::lossless_numeric_cast<uint32_t>(
        m_ctx->m_currentResourceAllocations.atlasTextureWidth);
    m_flushDesc.atlasTextureHeight = math::lossless_numeric_cast<uint32_t>(
        m_ctx->m_currentResourceAllocations.atlasTextureHeight);
    m_gradTextureLayout.inverseHeight =
        1.f / m_ctx->m_currentResourceAllocations.gradTextureHeight;

    // Exact tessSpan/triangleVertex counts aren't known until after their data
    // is written out.
    size_t firstTessVertexSpan = m_ctx->m_tessSpanData.elementsWritten();
    size_t initialTriangleVertexDataSize =
        m_ctx->m_triangleVertexData.bytesWritten();

    // Metal requires vertex buffers to be 256-byte aligned.
    size_t tessAlignmentPadding =
        math::padding_to_align_up<gpu::kTessVertexBufferAlignmentInElements>(
            firstTessVertexSpan);
    assert(tessAlignmentPadding <= kMaxTessellationAlignmentVertices);
    m_ctx->m_tessSpanData.push_back_n(nullptr, tessAlignmentPadding);
    m_flushDesc.firstTessVertexSpan =
        firstTessVertexSpan + tessAlignmentPadding;
    assert(m_flushDesc.firstTessVertexSpan ==
           m_ctx->m_tessSpanData.elementsWritten());

    // Write out the simple gradient data.
    constexpr static uint32_t ONE_TEXEL_FIXED = 65536 / gpu::kGradTextureWidth;
    assert(m_simpleGradients.size() == m_pendingSimpleGradDraws.size());
    if (!m_pendingSimpleGradDraws.empty())
    {
        for (size_t i = 0; i < m_pendingSimpleGradDraws.size(); ++i)
        {
            // Render each simple gradient as a single, empty GradientSpan with
            // 1px borders to the left and right.
            auto [color0, color1] = m_pendingSimpleGradDraws[i];
            uint32_t y = math::lossless_numeric_cast<uint32_t>(
                i / gpu::kGradTextureWidthInSimpleRamps);
            size_t centerX = (i % gpu::kGradTextureWidthInSimpleRamps) * 2 + 1;
            uint32_t centerXFixed = math::lossless_numeric_cast<uint32_t>(
                centerX * ONE_TEXEL_FIXED);
            m_ctx->m_gradSpanData.set_back(centerXFixed,
                                           centerXFixed,
                                           y,
                                           GRAD_SPAN_FLAG_LEFT_BORDER |
                                               GRAD_SPAN_FLAG_RIGHT_BORDER,
                                           color0,
                                           color1);
        }
    }

    // Write out the vertex data for rendering complex gradients.
    assert(m_complexGradients.size() == m_pendingComplexGradDraws.size());
    if (!m_pendingComplexGradDraws.empty())
    {
        // The viewport will start at simpleGradDataHeight when rendering color
        // ramps.
        for (uint32_t i = 0; i < m_pendingComplexGradDraws.size(); ++i)
        {
            // Push "GradientSpan" instances that will render each section of
            // this color ramp's gradient.
            const Gradient* gradient = m_pendingComplexGradDraws[i];
            const float* stops = gradient->stops();
            const ColorInt* colors = gradient->colors();
            size_t stopCount = gradient->count();
            uint32_t y = i + m_gradTextureLayout.complexOffsetY;

            // "stop * m + a" converts a stop position to a fixed-point x
            // coordinate in the gradient texture. (In an ideal world, stops
            // would all be aligned on pixel centers for the texture sampling to
            // be identical to the gradient, but here we just stretch it across
            // kGradTextureWidth pixels and hope everything looks ok.)
            float m = (kGradTextureWidth - 1.f) * ONE_TEXEL_FIXED;
            float a = .5f * ONE_TEXEL_FIXED;
            uint32_t lastXFixed = static_cast<uint32_t>(stops[0] * m + a);
            ColorInt lastColor = colors[0];
            assert(stopCount >= 2);
            for (size_t i = 1; i < stopCount; ++i)
            {
                uint32_t xFixed = static_cast<uint32_t>(stops[i] * m + a);
                // stops[] must be ordered.
                assert(lastXFixed <= xFixed && xFixed < 65536);
                uint32_t flags = GRAD_SPAN_FLAG_COMPLEX_BORDER;
                if (i == 1)
                    flags |= GRAD_SPAN_FLAG_LEFT_BORDER;
                if (i == stopCount - 1)
                    flags |= GRAD_SPAN_FLAG_RIGHT_BORDER;
                m_ctx->m_gradSpanData.set_back(lastXFixed,
                                               xFixed,
                                               y,
                                               flags,
                                               lastColor,
                                               colors[i]);
                lastColor = colors[i];
                lastXFixed = xFixed;
            }
        }
    }

    // Write a path record for the clearColor paint (used by atomic mode).
    // This also allows us to index the storage buffers directly by pathID.
    gpu::SimplePaintValue clearColorValue;
    clearColorValue.color = m_ctx->frameDescriptor().clearColor;
    m_ctx->m_pathData.skip_back();
    m_ctx->m_paintData.set_back(gpu::DrawContents::none,
                                PaintType::solidColor,
                                clearColorValue,
                                GradTextureLayout(),
                                /*clipID =*/0,
                                /*hasClipRect =*/false,
                                BlendMode::srcOver);
    m_ctx->m_paintAuxData.skip_back();

    // Render padding vertices in the tessellation texture.
    if (m_flushDesc.tessDataHeight > 0)
    {
        // Padding at the beginning of the tessellation texture.
        pushPaddingVertices(gpu::kMidpointFanPatchSegmentSpan, 0);
        // Padding between patch types in the tessellation texture.
        if (m_outerCubicTessVertexIdx > m_midpointFanTessEndLocation)
        {
            pushPaddingVertices(m_outerCubicTessVertexIdx -
                                    m_midpointFanTessEndLocation,
                                m_midpointFanTessEndLocation);
        }
        // The final vertex of the final patch of each contour crosses over into
        // the next contour. (This is how we wrap around back to the beginning.)
        // Therefore, the final contour of the flush needs an out-of-contour
        // vertex to cross into as well, so we emit a padding vertex here at the
        // end.
        pushPaddingVertices(1, m_outerCubicTessEndLocation);
    }

    // Write out all the data for our high level draws, and build up a low-level
    // draw list.
    if (!platformFeatures.supportsClipScissor &&
        m_ctx->frameInterlockMode() == gpu::InterlockMode::rasterOrdering)
    {
        for (const DrawUniquePtr& draw : m_draws)
        {
            // TODO: We don't currently support a front-to-back prepass in
            // rasterOrdering mode. If we decide to support this, we will either
            // need to walk the draws backwards here, or, more likely, start
            // sorting and re-ordering in rasterOrdering mode as well.
            assert(draw->prepassCount() == 0);
            assert(draw->subpassCount() > 0);
            for (int i = 0; i < draw->subpassCount(); ++i)
            {
                draw->pushToRenderContext(this, i);
            }
        }
    }
    else
    {
        assert(m_drawPassCount <= kMaxReorderedDrawPassCount);

        // Sort the draw list to optimize batching, since we can only batch
        // non-overlapping draws.
        auto& indirectDrawList = m_ctx->m_indirectDrawList;
        indirectDrawList.clear();
        indirectDrawList.reserve(m_drawPassCount);

        // TODO: For clockwiseAtomic, these next values aren't constant (they're
        // constants now just to have stand-in values representing the default
        // case). Instead:
        //  - There would be (at least) three relevant "overlap bits":
        //    - color buffer write
        //    - clip buffer read
        //    - clip buffer write
        //  - groupingType should be GroupingType::overlapAllowed (unless there
        //    is some reason the current draw could *never* overlap anything
        //    else)
        //  - Any draws that write to the color buffer (which may include draws
        //    that also use the *clip* buffer) would set the "color buffer
        //    write" bit in its overlap bits
        //  - Draws that are using advanced blending would set the "color buffer
        //    write" bit in its disallow mask, so that they are not allowed to
        //    overlap things that write to the color buffer (there is nothing
        //    extra for advanced blending that goes into the overlap bits -
        //    advanced blending has no bearing on whether or not things can
        //    overlap on top of it!)
        //  - Any draws that read from the clip buffer:
        //    - set the "clip buffer read" bit in `overlapBits` - this gets
        //      stored with the rectangle and signifies that the rectangle is
        //      involved in a clip buffer read
        //    - sets the "clip buffer write" bit in `disallowOverlapMask` - this
        //      tells the intersection board that if this draw overlaps a clip
        //      buffer write, it needs to go in the next draw group (there needs
        //      to be a barrier)
        //  - Any draws that write to the clip buffer:
        //    - set the "clip buffer write" bit in `overlapBits`
        //    - sets *both* the "clip buffer read/write" bits in
        //      `disallowOverlapMask` - this means that these draws would need a
        //      barrier between any previous overlapping clip buffer reads or
        //      writes.
        //  - Similarly, the ordering of the bits in the sort key would likely
        //    want to change for this mode to ensure that the sorting preserves
        //    proper ordering within a given draw group, since now there are
        //    overlaps and thus draw ordering can matter.
        //    (it also might be worth double checking that there aren't other
        //    modes where a different sort ordering could be more efficient, to
        //    perhaps better group like things together that don't cause
        //    barriers)
        constexpr static uint16_t kOverlapBits = 0;
        constexpr static uint16_t kDisallowOverlapMask = 0;
        constexpr static GroupingType kGroupingType = GroupingType::disjoint;

        if (m_ctx->m_intersectionBoard == nullptr)
        {
            m_ctx->m_intersectionBoard =
                std::make_unique<IntersectionBoard>(kGroupingType);
        }

        assert(m_ctx->m_intersectionBoard->groupingType() == kGroupingType);
        IntersectionBoard* intersectionBoard = m_ctx->m_intersectionBoard.get();
        intersectionBoard->resizeAndReset(m_flushDesc.renderTarget->width(),
                                          m_flushDesc.renderTarget->height());

        static constexpr SortKeyBuilder keyBuilder{
            // Our top priority in re-ordering is to group non-overlapping draws
            // together, in order to maximize batching while preserving
            // correctness.
            {.entry = SortEntry::drawGroup, .bitCount = 15},

            // Within sub-groups of non-overlapping draws, sort similar draw
            // types together.
            {.entry = SortEntry::drawType, .bitCount = 3},

            // Within sub-groups of matching draw type, sort by texture binding.
            {.entry = SortEntry::textureHash, .bitCount = 14},

            // It's less expensive to change the scissorID than texture, but
            // more expensive than the blend mode, so here's where it lives.
            {.entry = SortEntry::scissorID, .bitCount = 15},

            // If using KHR_blend_equation_advanced, we need a batching barrier
            // between draws with different blend modes. If not using
            // KHR_blend_equation_advanced, sorting by blend mode may still give
            // us better branching on the GPU.
            {.entry = SortEntry::blendMode, .bitCount = 4},

            // msaa mode draws strokes, fills, and even/odd with different
            // stencil settings.
            {.entry = SortEntry::drawContents, .bitCount = 9},

            // Finally, we need sorting by subpass. Without this, the MSAA
            // subpasses (and maybe others) won't run in the correct order when
            // allSubpassesInSameDrawGroup was true.
            {.entry = SortEntry::subpassIndex, .bitCount = 3},
        };

        m_ctx->m_scissorIDLookup.clear();

        // Set this to 0, any actual scissor IDs used will then start at 1.
        m_ctx->m_prevScissorID = 0;

        for (int16_t drawIndex = 0; drawIndex < int16_t(m_draws.size());
             ++drawIndex)
        {
            Draw* draw = m_draws[drawIndex].get();

            int16_t scissorID = 0;
            auto drawPixelBoundRect = draw->pixelBounds();

            if (platformFeatures.supportsClipScissor &&
                (draw->clipID() != 0 ||
                 draw->clippingPixelBounds().has_value()))
            {
                const auto drawClipID = draw->clipID();

                // Start with either the clipping pixel bounds (if they exist)
                // or a maximally-large rectangle.
                auto clipBounds =
                    draw->clippingPixelBounds().value_or(IAABB::makeMaximal());

                if (drawClipID != 0)
                {
                    // Intersect with the tightened clip bounds if there was a
                    // clip in the stack (which may be tighter than it was when
                    // originally rendered - but also there may have been a clip
                    // rect that happened after this clip path, which is why the
                    // intersect still needs to happen)
                    clipBounds = clipBounds.intersect(
                        getClipInfo(drawClipID).tightenedBounds);
                }

                const auto drawBounds = draw->pixelBounds();

                if (needsScissor(drawBounds,
                                 clipBounds,
                                 frameDescriptor().renderTargetWidth,
                                 frameDescriptor().renderTargetHeight))
                {
                    drawPixelBoundRect = clipBounds;

                    const auto clipBoundsU16 =
                        clipBounds.clamp_cast<uint16_t>();

                    // If the value is already in the map, get it, otherwise
                    // we'll add the next new ID (which is 1 + the size of
                    // the array, since we're using "0" as "no scissor")
                    auto result = m_ctx->m_scissorIDLookup.try_emplace(
                        clipBoundsU16,
                        m_ctx->m_prevScissorID + 1);
                    scissorID = result.first->second;
                    assert(scissorID > 0);
                    if (scissorID > m_ctx->m_prevScissorID)
                    {
                        ++m_ctx->m_prevScissorID;
                    }

                    // Update the scissor rect for this draw so we can
                    // ensure it doesn't batch with draws with different
                    // scissor rects.
                    draw->setScissorRect(clipBoundsU16);
                }
            }

            int4 drawBounds = simd::load4i(&drawPixelBoundRect);

            // Add one extra pixel of padding to the draw bounds to make
            // absolutely certain we get no overlapping pixels, which destroy
            // the atomic shader.
            constexpr int32_t Max32i = std::numeric_limits<int32_t>::max();
            constexpr int32_t Min32i = std::numeric_limits<int32_t>::min();
            drawBounds = simd::if_then_else(
                drawBounds != int4{Min32i, Min32i, Max32i, Max32i},
                drawBounds + int4{-1, -1, 1, 1},
                drawBounds);
            if (m_ctx->frameInterlockMode() ==
                    gpu::InterlockMode::clockwiseAtomic &&
                enums::is_flag_set(draw->drawContents(),
                                   gpu::DrawContents::clipUpdate))
            {
                // ***FIXME***: until we implement scissors for clipping,
                // clockwiseAtomic clip updates can't be reordered. Expand their
                // pixel bounds to block reordering.
                drawBounds = {
                    0,
                    0,
                    static_cast<int32_t>(
                        m_ctx->frameDescriptor().renderTargetWidth),
                    static_cast<int32_t>(
                        m_ctx->frameDescriptor().renderTargetHeight),
                };
            }

            // When the dstBlend barrier has no other option than to copy out a
            // texture, this copy destroys MSAA information and we can no longer
            // put subpasses in different drawGroups.
            // Otherwise, we put subpasses into different draw groups because it
            // yields better reordering.
            const bool allSubpassesInSameDrawGroup =
                m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa &&
                !platformFeatures.supportsBlendAdvancedKHR &&
                enums::is_flag_set(m_combinedDrawContents,
                                   gpu::DrawContents::advancedBlend);

            // Our top priority in re-ordering is to group non-overlapping draws
            // together, in order to maximize batching while preserving
            // correctness.
            const int8_t maxSubpasses = math::lossless_numeric_cast<int8_t>(
                std::max(draw->prepassCount(), draw->subpassCount()));
            int16_t drawGroupIdx = intersectionBoard->addRectangle(
                drawBounds,
                kOverlapBits,
                kDisallowOverlapMask,
                allSubpassesInSameDrawGroup ? 1 : maxSubpasses);
            assert(drawGroupIdx > 0);
            const auto textureHash =
                (draw->imageTexture() != nullptr)
                    ? draw->imageTexture()->textureResourceHash()
                    : 0;
            int64_t key = keyBuilder.buildKey({
                {SortEntry::blendMode,
                 gpu::ConvertBlendModeToPLSBlendMode(draw->blendMode())},
                {SortEntry::drawContents, draw->drawContents()},
                {SortEntry::drawGroup, drawGroupIdx},
                {SortEntry::drawType, draw->type()},
                {SortEntry::scissorID, scissorID},
                {SortEntry::subpassIndex, 0}, // This gets added later

                // The hash may lose bits in the key
                {SortEntry::textureHash, textureHash, ValidateKeyEntry::no},
            });

            // Add the first prepass and subpass, if any.
            if (draw->prepassCount() > 0)
            {
                // Negating the key is an easy way to sort the prepasses
                // front-to-back, and before the subpasses.
                indirectDrawList.push_back({
                    .sortKey = -key,
                    .drawIndex = drawIndex,
                });
            }
            if (draw->subpassCount() > 0)
            {
                indirectDrawList.push_back({
                    .sortKey = key,
                    .drawIndex = drawIndex,
                });
            }

            // Add any additional passes.
            if (maxSubpasses > 1)
            {
                const auto subpassKeyIncrement =
                    allSubpassesInSameDrawGroup
                        // Special case: All subpasses belong to the same
                        // drawGroup, so only increment subpassIndex.
                        ? keyBuilder.buildPartialKey({
                              {SortEntry::subpassIndex, 1},
                          })
                        // Usual case: Increment the drawGroup and subpassIndex
                        // both at once. (The intersectionBoard already reserved
                        // "maxPasses" layers of drawGroupIndices for us.)
                        : keyBuilder.buildPartialKey({
                              {SortEntry::drawGroup, 1},
                              {SortEntry::subpassIndex, 1},
                          });

                for (int8_t subpassIndex = 1; subpassIndex < maxSubpasses;
                     ++subpassIndex)
                {
                    key += subpassKeyIncrement;

                    assert(keyBuilder.extract<int16_t>(SortEntry::drawGroup,
                                                       key) ==
                           int16_t(allSubpassesInSameDrawGroup
                                       ? drawGroupIdx
                                       : drawGroupIdx + subpassIndex));

                    if (subpassIndex < draw->prepassCount())
                    {
                        // Negating the key is an easy way to sort the prepasses
                        // front-to-back, and before the subpasses.
                        indirectDrawList.push_back({
                            .sortKey = -key,
                            .drawIndex = drawIndex,
                        });
                    }
                    if (subpassIndex < draw->subpassCount())
                    {
                        indirectDrawList.push_back({
                            .sortKey = key,
                            .drawIndex = drawIndex,
                        });
                    }
                }
            }
        }
        assert(indirectDrawList.size() == m_drawPassCount);

        // Re-order the draws
        // TODO: If we have any overlappable draws, then we will actually need
        // to sort using the draw index as well (negatively to go front-to-back
        // for pre-passes and positively for standard passes). Otherwise, the
        // order of draws *within* a given sorted key does not matter at all.
        std::sort(
            indirectDrawList.begin(),
            indirectDrawList.end(),
            [](const auto& a, const auto& b) { return a.sortKey < b.sortKey; });

        assert(m_pendingBarriers == BarrierFlags::none);
        if (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics &&
            platformFeatures.atomicPLSInitNeedsDraw)
        {
            // Atomic mode sometimes needs to initialize PLS with a draw when
            // the backend can't do it with typical clear/load APIs.
            // So far only Metal needs this, and its implementation doesn't
            // require a barrier before or after.
            m_drawList.emplace_back(m_ctx->perFrameAllocator(),
                                    gpu::DrawType::renderPassInitialize,
                                    m_baselineShaderMiscFlags,
                                    gpu::DrawContents::none,
                                    1,
                                    0,
                                    BlendMode::srcOver,
                                    ImageSampler::LinearClamp(),
                                    BarrierFlags::none);
        }
        else if (m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa &&
                 m_flushDesc.colorLoadAction ==
                     gpu::LoadAction::preserveRenderTarget &&
                 platformFeatures.msaaColorPreserveNeedsDraw)
        {
            // When implemented with a transient attachment, MSAA needs us to
            // draw the old renderTarget contents into the framebuffer at the
            // beginning of the render pass when
            // LoadAction::preserveRenderTarget is specified.
            m_drawList.emplace_back(
                m_ctx->perFrameAllocator(),
                gpu::DrawType::renderPassInitialize,
                m_baselineShaderMiscFlags,
                gpu::DrawContents::opaquePaint,
                1,
                0,
                // A more realistic value here would be "BlendMode::none" (which
                // is what actually happens), but since that isn't a Rive blend
                // mode, we just need any value here. It will get ignored by the
                // draw.
                BlendMode::srcOver,
                ImageSampler{.filter = ImageFilter::bilinear},
                // The MSAA init reads the framebuffer, so it needs the
                // equivalent of a "dstBlend" barrier.
                BarrierFlags::dstBlend);
            m_combinedDrawContents |= m_drawList.tail()->drawContents;
            // The draw that follows the this init will need a special
            // "msaaPostInit" barrier.
            pushBarriers(BarrierFlags::msaaPostInit);
            assert(m_dstBlendBarrierListTail == &m_firstDstBlendBarrier);
            assert(m_firstDstBlendBarrier == nullptr);
            m_firstDstBlendBarrier = m_drawList.tail();
            m_dstBlendBarrierListTail = &m_drawList.tail()->nextDstBlendBarrier;
        }

        // Indicates required barriers between draws whose keys differ on the
        // given mask.
        struct BarriersForKeyDiff
        {
            int64_t mask;
            BarrierFlags barrier;
        };
        StackVector<BarriersForKeyDiff, 3> barriersForKeyDiffs;

        // Find a mask that tells us when to insert barriers, and which barriers
        // are needed. When the keys of two adjacent draws differ within this
        // bitmask, we insert a barrier between them.
        switch (m_flushDesc.interlockMode)
        {
            case gpu::InterlockMode::atomics:
            {
                // In atomic mode, we need barriers any time draws overlap.
                // Insert a barrier every time the drawGroupIdx changes.
                barriersForKeyDiffs.push_back(
                    {keyBuilder.mask(SortEntry::drawGroup),
                     BarrierFlags::plsAtomic | BarrierFlags::drawBatchBreak});
                // We need a plsAtomic barrier after the initial clears, loads,
                // etc.
                pushBarriers(BarrierFlags::plsAtomic |
                             BarrierFlags::drawBatchBreak);
                break;
            }

            case gpu::InterlockMode::rasterOrdering:
            case gpu::InterlockMode::clockwise:
                // clockwise and rasterOrdering modes don't need barriers, but
                // we still reorder in order to improve batching.
                break;

            case gpu::InterlockMode::clockwiseAtomic:
            {
                // In clockwiseAtomic mode, we only need a barrier between the
                // borrowedCoverage prepasses and the main rendering. Prepasses
                // have a negative key, so just insert a barrier when the sign
                // changes.
                constexpr static int64_t SIGN_BIT = (1ll << 63);
                barriersForKeyDiffs.push_back(
                    {SIGN_BIT,
                     BarrierFlags::clockwiseBorrowedCoverage |
                         BarrierFlags::drawBatchBreak});
                // Just break batching between draw groups. If we also need a
                // dstBlend or "clip read" (plsAtomic) barrier, that will be
                // handled with more sophisticated logic later on.
                barriersForKeyDiffs.push_back(
                    {keyBuilder.mask(SortEntry::drawGroup),
                     BarrierFlags::drawBatchBreak});
                if (indirectDrawList.empty() ||
                    indirectDrawList[0].sortKey >= 0)
                {
                    // There are no borrowed coverage passes. Initiate the
                    // transition to the main subpass immediately.
                    pushBarriers(BarrierFlags::clockwiseBorrowedCoverage);
                }
                break;
            }

            case gpu::InterlockMode::msaa:
            {
                // MSAA mode can't batch draws that overlap because they both
                // rely on the stencil buffer across subpasses. Stop batching
                // every time the drawGroupIdx changes.
                int64_t needsBreakMask = keyBuilder.mask(SortEntry::drawGroup);
                // MSAA mode draws clips, strokes, fills, and even/odd with
                // different stencil settings, so these can't be batched.
                needsBreakMask |= keyBuilder.mask(SortEntry::drawContents);
                if (platformFeatures.supportsBlendAdvancedKHR)
                {
                    // If using KHR_blend_equation_advanced, we also need to
                    // stop batching between blend modes in order to change the
                    // blend equation.
                    needsBreakMask |= keyBuilder.mask(SortEntry::blendMode);
                }
                // MSAA barriers only need to prevent batching of draws for now.
                // If we also need a dstBlend barrier, that will be decided
                // later.
                barriersForKeyDiffs.push_back(
                    {needsBreakMask, BarrierFlags::drawBatchBreak});
                break;
            }
        }

        // Write out the draw data from the sorted draw list, and build up a
        // condensed/batched list of low-level draws.
        constexpr int64_t BEGIN_KEY = std::numeric_limits<int64_t>::min();
        int64_t priorSignedKey = BEGIN_KEY;
        int16_t currentDrawGroup = -1;
        DrawBatch* firstBatchInCurrentDrawGroup = nullptr;

        // clockwiseAtomic (CWA) needs more sophisticated barrier logic for
        // clips.
        bool hasCWAClipReadBarrier = false;
        bool currentDrawGroupHasCWAClipUpdate = false;

        for (const auto& sortEntry : indirectDrawList)
        {
            auto signedKey = sortEntry.sortKey;
            assert(signedKey >= priorSignedKey);
            // The first draw never gets simple barriers. If barriers are
            // required before the first draw, those get scheduled outside this
            // loop.
            if (priorSignedKey != BEGIN_KEY)
            {
                for (auto [mask, barriers] : barriersForKeyDiffs)
                {
                    if ((priorSignedKey & mask) != (signedKey & mask))
                    {
                        pushBarriers(barriers);
                    }
                }
            }

            auto key = abs(signedKey);
            auto drawIndex = sortEntry.drawIndex;
            auto subpassIndex =
                keyBuilder.extract<int8_t>(SortEntry::subpassIndex, key);
            if (signedKey < 0)
            {
                // Negative keys are a prepass. Update the subpassIndex to be
                // negative.
                subpassIndex = -1 - subpassIndex;
            }
            // FIXME: m_currentZIndex shouldn't be a stateful variable; it
            // should be passed to pushToRenderContext() instead.
            const int16_t drawGroup =
                keyBuilder.extract<int16_t>(SortEntry::drawGroup, key);
            assert(drawGroup > 0);
            m_currentZIndex = drawGroup;

            Draw* draw = m_draws[drawIndex].get();

            assert(
                draw->drawContents() ==
                keyBuilder.extract<gpu::DrawContents>(SortEntry::drawContents,
                                                      key));
            assert(draw->blendMode() != BlendMode::srcOver ==
                   draw->hasAdvancedBlend());

            DrawBatch* batch = draw->pushToRenderContext(this, subpassIndex);

            if (batch != nullptr && platformFeatures.supportsClipScissor)
            {
                batch->scissorRect = draw->scissorRect();
            }

            // Some barriers need more sophisticated logic than "do my keys
            // differ".
            if ((m_ctx->frameInterlockMode() ==
                     gpu::InterlockMode::clockwiseAtomic ||
                 m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa) &&
                subpassIndex == 0 && batch != nullptr)
            {
                // Barriers at this level have to go on the first batch in the
                // current drawGroup. Otherwise we might see something get
                // reordered like this:
                //
                //   - drawA, subpass0
                //   - dstBlendBarrier (because drawB has a dstBlend)
                //   - drawB, subpass0
                //   - drawA, subpass1
                //   - drawB, subpass1
                //
                // In this scenario, drawA gets a dstBlend barrier between
                // subpasses. When dstBlend is implemented as a texture copy, it
                // interrupts the render pass and resolves MSAA, causing the
                // MSAA data to be lost between supbasses of drawA.
                //
                // Since drawA and drawB don't overlap, the correct solution is
                // to only apply barriers on the first batch of a drawGroup:
                //
                //   - dstBlendBarrier (because drawB has a dstBlend)
                //   - drawA, subpass0
                //   - drawB, subpass0
                //   - drawA, subpass1
                //   - drawB, subpass1
                //
                // (This also leads to fewer barriers overall.)
                if (currentDrawGroup != drawGroup)
                {
                    if (currentDrawGroupHasCWAClipUpdate)
                    {
                        // Now that we're moving on to a new drawGroup, reset
                        // hasCWAClipReadBarrier if the clip got written, since
                        // any future clip reads may overlap what was written.
                        hasCWAClipReadBarrier = false;
                        currentDrawGroupHasCWAClipUpdate = false;
                    }
                    firstBatchInCurrentDrawGroup = batch;
                    currentDrawGroup = drawGroup;
                }
                assert(firstBatchInCurrentDrawGroup != nullptr);

                if (draw->hasAdvancedBlend() &&
                    (m_ctx->frameInterlockMode() != gpu::InterlockMode::msaa ||
                     !m_ctx->platformFeatures()
                          .supportsBlendAdvancedCoherentKHR))
                {
                    // An implementation-dependent barrier is required between
                    // overlapping draws. Add a "dstBlend" barrier and build up
                    // a list of "dstReads" for the batch. The dstRead list will
                    // be required in the event that the implementation has to
                    // handle dstReads by copying out a texture.
                    assert(draw->nextDstRead() == nullptr);
                    firstBatchInCurrentDrawGroup->dstReadList =
                        draw->addToDstReadList(
                            firstBatchInCurrentDrawGroup->dstReadList);
                    if (!enums::is_flag_set(
                            firstBatchInCurrentDrawGroup->barriers,
                            BarrierFlags::dstBlend))
                    {
                        firstBatchInCurrentDrawGroup->barriers |=
                            BarrierFlags::dstBlend;
                        addBatchToDstBarrierList(firstBatchInCurrentDrawGroup);
                    }
                    // We either added ourselves to the dstBlendBarrier
                    // list or merged into a batch that was already part
                    // of it.
                    assert(m_dstBlendBarrierListTail ==
                           &firstBatchInCurrentDrawGroup->nextDstBlendBarrier);
                }

                // clockwiseAtomic (CWA) needs more sophisticated barrier logic
                // for clips.
                if (m_ctx->frameInterlockMode() ==
                    gpu::InterlockMode::clockwiseAtomic)
                {
                    if (draw->isClipUpdate())
                    {
                        // Once the clip gets written, it needs a barrier before
                        // it can be read again from fragment shaders.
                        //
                        // NOTE: This won't immediately reset
                        // "hasCWAClipReadBarrier" because clip reads and writes
                        // in the same drawGroup don't overlap. Instead, we
                        // defer resetting hasCWAClipReadBarrier until we begin
                        // the next drawGroup.
                        //
                        // NOTE2: It's ok of activeClip is also set here
                        // (i.e., nested clip updates, or "clipUpdate |
                        // activeClip"). Those don't need a barrier. Nested
                        // clips use hardware blend to apply the existing clip,
                        // rather than reading it in the fragment shader.
                        currentDrawGroupHasCWAClipUpdate = true;
                    }
                    else if (draw->hasActiveClip() && !hasCWAClipReadBarrier)
                    {
                        // Clipped path draws need a barrier because they access
                        // the clip buffer via input attachment in the fragment
                        // shader.
                        firstBatchInCurrentDrawGroup->barriers |=
                            gpu::BarrierFlags::plsAtomic;
                        hasCWAClipReadBarrier = true;
                    }
                }
                else
                {
                    assert(m_ctx->frameInterlockMode() ==
                           gpu::InterlockMode::msaa);

                    // msaa doesn't mix srcOver draws with advanced blend draws.
                    assert(enums::is_flag_set(
                               batch->shaderFeatures,
                               gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND) ==
                           (draw->blendMode() != BlendMode::srcOver));

                    // If using KHR_blend_equation_advanced, we can't mix blend
                    // modes in a batch.
                    assert(
                        !m_ctx->platformFeatures().supportsBlendAdvancedKHR ||
                        batch->firstBlendMode == draw->blendMode());
                }
            }

            priorSignedKey = signedKey;
        }
    }

    // Some modes need one more draw to resolve all the pixels.
    if (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics ||
        m_flushDesc.manuallyResolved)
    {
        m_drawList.emplace_back(
            m_ctx->perFrameAllocator(),
            gpu::DrawType::renderPassResolve,
            m_baselineShaderMiscFlags,
            (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics)
                ? gpu::DrawContents::none
                : gpu::DrawContents::opaquePaint,
            1,
            0,
            BlendMode::srcOver,
            ImageSampler::LinearClamp(),
            (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics)
                ? BarrierFlags::plsAtomicPreResolve
                : BarrierFlags::preManualResolve);
        m_combinedDrawContents |= m_drawList.tail()->drawContents;
    }

    // Write out the draws to the feather atlas. Do this after the main draws
    // (even though the atlas ones execute first) so that our path info and Z
    // index are decided and available to pushAtlasTessellation().
    if (!m_pendingAtlasDraws.empty())
    {
        AABBu16 fullAtlasViewport = {0,
                                     0,
                                     m_flushDesc.atlasContentWidth,
                                     m_flushDesc.atlasContentHeight};
        gpu::AtlasDrawBatch* currentBatch =
            m_ctx->m_perFrameAllocator.makePODArray<gpu::AtlasDrawBatch>(
                m_pendingAtlasDraws.size());
        // Iterate the atlas draws 4 times so we can sort by fill / stroke /
        // scissored / not, and batch together the draws that don't have
        // scissor.
        for (bool stroked : {false, true})
        {
            if (stroked)
            {
                m_flushDesc.atlasStrokeBatches = currentBatch;
            }
            else
            {
                m_flushDesc.atlasFillBatches = currentBatch;
            }
            for (bool scissored : {false, true})
            {
                gpu::AtlasDrawBatch* lastBatch = nullptr;
                for (PathDraw* draw : m_pendingAtlasDraws)
                {
                    if (draw->isStroke() != stroked ||
                        draw->atlasScissorEnabled() != scissored)
                    {
                        continue;
                    }
                    uint32_t tessVertexCount, tessBaseVertex;
                    draw->pushAtlasTessellation(this,
                                                &tessVertexCount,
                                                &tessBaseVertex);
                    if (tessVertexCount == 0)
                    {
                        continue;
                    }
                    uint32_t patchCount =
                        tessVertexCount / gpu::kMidpointFanPatchSegmentSpan;
                    uint32_t basePatch =
                        tessBaseVertex / gpu::kMidpointFanPatchSegmentSpan;
                    assert(patchCount * gpu::kMidpointFanPatchSegmentSpan ==
                           tessVertexCount);
                    assert(basePatch * gpu::kMidpointFanPatchSegmentSpan ==
                           tessBaseVertex);
                    if (lastBatch == nullptr || scissored)
                    {
                        lastBatch = currentBatch++;
                        *lastBatch = {
                            lastBatch->scissor = scissored
                                                     ? draw->atlasScissor()
                                                     : fullAtlasViewport,
                            lastBatch->patchCount = patchCount,
                            lastBatch->basePatch = basePatch,
                        };
                    }
                    else
                    {
                        assert(lastBatch->basePatch + lastBatch->patchCount ==
                               basePatch);
                        lastBatch->patchCount += patchCount;
                    }
                }
            }
            if (stroked)
            {
                m_flushDesc.atlasStrokeBatchCount =
                    currentBatch - m_flushDesc.atlasStrokeBatches;
            }
            else
            {
                m_flushDesc.atlasFillBatchCount =
                    currentBatch - m_flushDesc.atlasFillBatches;
            }
        }
        assert(m_flushDesc.atlasFillBatchCount +
                   m_flushDesc.atlasStrokeBatchCount ==
               currentBatch - m_flushDesc.atlasFillBatches);
        assert(m_flushDesc.atlasFillBatchCount +
                   m_flushDesc.atlasStrokeBatchCount <=
               m_pendingAtlasDraws.size());
    }

    // Pad our buffers to 256-byte alignment.
    m_ctx->m_pathData.push_back_n(nullptr, m_pathPaddingCount);
    m_ctx->m_paintData.push_back_n(nullptr, m_paintPaddingCount);
    m_ctx->m_paintAuxData.push_back_n(nullptr, m_paintAuxPaddingCount);
    m_ctx->m_contourData.push_back_n(nullptr, m_contourPaddingCount);
    m_ctx->m_gradSpanData.push_back_n(nullptr, m_gradSpanPaddingCount);

    assert(m_ctx->m_pathData.elementsWritten() ==
           m_flushDesc.firstPath + m_resourceCounts.pathCount +
               m_pathPaddingCount);
    assert(m_ctx->m_paintData.elementsWritten() ==
           m_flushDesc.firstPaint + m_resourceCounts.pathCount +
               m_paintPaddingCount);
    assert(m_ctx->m_paintAuxData.elementsWritten() ==
           m_flushDesc.firstPaintAux + m_resourceCounts.pathCount +
               m_paintAuxPaddingCount);
    assert(m_ctx->m_contourData.elementsWritten() ==
           m_flushDesc.firstContour + m_resourceCounts.contourCount +
               m_contourPaddingCount);
    assert(m_ctx->m_gradSpanData.elementsWritten() ==
           m_flushDesc.firstGradSpan + m_pendingGradSpanCount +
               m_gradSpanPaddingCount);
    assert(m_midpointFanTessVertexIdx == m_midpointFanTessEndLocation);
    assert(m_outerCubicTessVertexIdx == m_outerCubicTessEndLocation);

    // Some of the flushDescriptor's data isn't known until after
    // writeResources(). Update it now that it's known.
    m_flushDesc.combinedShaderFeatures = m_combinedShaderFeatures;

    if (m_coverageBufferLength > 0)
    {
        assert(m_flushDesc.interlockMode ==
               gpu::InterlockMode::clockwiseAtomic);
        // The coverage buffer prefix gets reset to zero when the buffer is
        // reallocated, so wait until here to get the prefix.
        m_flushDesc.coverageBufferPrefix = m_ctx->incrementCoverageBufferPrefix(
            &m_flushDesc.needsCoverageBufferClear);
    }

    m_flushDesc.tessVertexSpanCount = math::lossless_numeric_cast<uint32_t>(
        m_ctx->m_tessSpanData.elementsWritten() -
        m_flushDesc.firstTessVertexSpan);

    m_flushDesc.hasTriangleVertices =
        m_ctx->m_triangleVertexData.bytesWritten() !=
        initialTriangleVertexDataSize;

    m_flushDesc.drawList = &m_drawList;
    m_flushDesc.firstDstBlendBarrier = m_firstDstBlendBarrier;
    m_flushDesc.unresolvedBarriers = m_pendingBarriers;
    // Write out the uniforms for this flush now that the flushDescriptor is
    // complete.
    m_ctx->m_flushUniformData.emplace_back(m_flushDesc, platformFeatures);

#ifndef NDEBUG
    for (const DrawBatch& batch : *m_flushDesc.drawList)
    {
        assert((batch.drawContents & m_combinedDrawContents) ==
               batch.drawContents);
        assert((batch.shaderFeatures & m_flushDesc.combinedShaderFeatures) ==
               batch.shaderFeatures);
    }
#endif
}

void RenderContext::LogicalFlush::tightenClipBounds()
{
    assert(m_combinedDrawBounds == IAABB::makeMaximallyNegative() &&
           "m_combinedDrawBounds should not have been updated yet");

    // Iterate through the draws in reverse - this ensures that all paths
    // clipped by a given clip update will update read bounds first, then any
    // nested clips will update, and all bounds state should bubble nicely to
    // the top.
    for (size_t i = m_draws.size() - 1; i != size_t(-1); i--)
    {
        const auto& draw = m_draws[i];

        // Depending on whether the platform supports clip scissor or not, use
        // the clipped bounds or the pixel bounds as the default bounds for
        // calculating the combined bounds.
        IAABB drawBoundsForCombinedBounds =
            m_ctx->platformFeatures().supportsClipScissor
                ? draw->clippedPixelBounds()
                : draw->pixelBounds();

        if (draw->clipID() == 0)
        {
            // Do nothing here, but we'll update the combined draw bounds after
            // the `else`s.
        }
        else if (draw->isClipUpdate())
        {
            auto& clipInfo = getWritableClipInfo(draw->clipID());

            // Ensure the clip's write bounds are as tight on both the clip
            // shape and all reads as possible.
            clipInfo.tightenedBounds =
                clipInfo.tightenedBounds.intersect(clipInfo.readBounds);

            if (m_ctx->platformFeatures().supportsClipScissor)
            {
                // Bring in the draw bounds for combining based on the
                // newly-tightened bounds.
                assert(drawBoundsForCombinedBounds.contains(
                    clipInfo.tightenedBounds));
                drawBoundsForCombinedBounds =
                    clipInfo.tightenedBounds.lossless_numeric_cast<int32_t>();
            }

            if (draw->hasActiveClip())
            {
                assert(clipInfo.parentClipID != 0);

                // This is a nested clip so we need to additionally add its
                // adjusted bounds to its parent clip as its read bounds.
                auto& parentClipInfo =
                    getWritableClipInfo(clipInfo.parentClipID);
                parentClipInfo.readBounds =
                    parentClipInfo.readBounds.join(clipInfo.tightenedBounds);
            }
            else
            {
                assert(clipInfo.parentClipID == 0);
            }
        }
        else if (draw->hasActiveClip())
        {
            // Anything else with a clip should add itself to the clip's read
            // bounds.
            auto& clipInfo = getWritableClipInfo(draw->clipID());
            clipInfo.readBounds = clipInfo.readBounds.join(
                draw->clippedPixelBounds().clamp_cast<uint16_t>());
        }

        m_combinedDrawBounds =
            m_combinedDrawBounds.join(drawBoundsForCombinedBounds);
    }
}

void RenderContext::setResourceSizes(ResourceAllocationCounts allocs,
                                     bool forceRealloc)
{
    RIVE_PROF_SCOPE_L(1)
#if 0
    class Logger
    {
    public:
        void logSize(const char* name,
                     size_t oldSize,
                     size_t newSize,
                     size_t newSizeInBytes)
        {
            m_totalSizeInBytes += newSizeInBytes;
            if (oldSize == newSize)
            {
                return;
            }
            if (!m_hasChanged)
            {
                printf("RenderContext::setResourceSizes():\n");
                m_hasChanged = true;
            }
            printf("  resize %s: %zu -> %zu (%zu KiB)\n",
                   name,
                   oldSize,
                   newSize,
                   newSizeInBytes >> 10);
        }

        void logTextureSize(const char* widthName,
                            const char* heightName,
                            size_t oldWidth,
                            size_t oldHeight,
                            size_t newWidth,
                            size_t newHeight,
                            size_t bytesPerPixel)
        {
            m_totalSizeInBytes += newHeight * newWidth * bytesPerPixel;
            if (oldWidth == newWidth && oldHeight == newHeight)
            {
                return;
            }
            if (!m_hasChanged)
            {
                printf("RenderContext::setResourceSizes():\n");
                m_hasChanged = true;
            }
            printf("  resize %s x %s: %zu x %zu -> %zu x %zu (%zu KiB)\n",
                   widthName,
                   heightName,
                   oldWidth,
                   oldHeight,
                   newWidth,
                   newHeight,
                   (newHeight * newWidth * bytesPerPixel) >> 10);
        }

        void logTexture3dSize(const char* name,
                              size_t oldWidth,
                              size_t oldHeight,
                              size_t oldDepth,
                              size_t newWidth,
                              size_t newHeight,
                              size_t newDepth,
                              size_t bytesPerPixel)
        {
            m_totalSizeInBytes += newHeight * newWidth * bytesPerPixel;
            if (oldWidth == newWidth && oldHeight == newHeight &&
                oldDepth == newDepth)
            {
                return;
            }
            if (!m_hasChanged)
            {
                printf("RenderContext::setResourceSizes():\n");
                m_hasChanged = true;
            }
            printf("  resize %s: [%zu x %zu x %zu] -> [%zu x %zu x %zu] "
                   "(%zu KiB)\n",
                   name,
                   oldWidth,
                   oldHeight,
                   oldDepth,
                   newWidth,
                   newHeight,
                   newDepth,
                   (newHeight * newWidth * newDepth * bytesPerPixel) >> 10);
        }

        ~Logger()
        {
            if (!m_hasChanged)
            {
                return;
            }
            printf("  TOTAL GPU resource usage: %zu KiB\n",
                   m_totalSizeInBytes >> 10);
        }

    private:
        size_t m_totalSizeInBytes = 0;
        bool m_hasChanged = false;
    } logger;
#define LOG_BUFFER_RING_SIZE(NAME, ITEM_SIZE_IN_BYTES)                         \
    logger.logSize(#NAME,                                                      \
                   m_currentResourceAllocations.NAME,                          \
                   allocs.NAME,                                                \
                   allocs.NAME* ITEM_SIZE_IN_BYTES* gpu::kBufferRingSize)
#define LOG_TEXTURE_SIZE(NAME, BYTES_PER_VALUE)                                \
    logger.logSize(#NAME,                                                      \
                   m_currentResourceAllocations.NAME,                          \
                   allocs.NAME,                                                \
                   allocs.NAME*(BYTES_PER_VALUE))
#define LOG_TEXTURE_2D_SIZE(NAME, WIDTH_NAME, HEIGHT_NAME, BYTES_PER_PIXEL)    \
    logger.logTexture3dSize(NAME,                                              \
                            m_currentResourceAllocations.WIDTH_NAME,           \
                            m_currentResourceAllocations.HEIGHT_NAME,          \
                            1,                                                 \
                            allocs.WIDTH_NAME,                                 \
                            allocs.HEIGHT_NAME,                                \
                            1,                                                 \
                            BYTES_PER_PIXEL)
#define LOG_TEXTURE_3D_SIZE(NAME,                                              \
                            WIDTH_NAME,                                        \
                            HEIGHT_NAME,                                       \
                            DEPTH_NAME,                                        \
                            BYTES_PER_PIXEL)                                   \
    logger.logTexture3dSize(NAME,                                              \
                            m_currentResourceAllocations.WIDTH_NAME,           \
                            m_currentResourceAllocations.HEIGHT_NAME,          \
                            m_currentResourceAllocations.DEPTH_NAME,           \
                            allocs.WIDTH_NAME,                                 \
                            allocs.HEIGHT_NAME,                                \
                            allocs.DEPTH_NAME,                                 \
                            BYTES_PER_PIXEL)
#define LOG_BUFFER_SIZE(NAME, BYTES_PER_ELEMENT)                               \
    logger.logSize(#NAME,                                                      \
                   m_currentResourceAllocations.NAME,                          \
                   allocs.NAME,                                                \
                   allocs.NAME* BYTES_PER_ELEMENT)
#else
#define LOG_BUFFER_RING_SIZE(NAME, ITEM_SIZE_IN_BYTES)
#define LOG_TEXTURE_SIZE(NAME, BYTES_PER_ROW)
#define LOG_TEXTURE_2D_SIZE(NAME, WIDTH_NAME, HEIGHT_NAME, BYTES_PER_PIXEL)
#define LOG_TEXTURE_3D_SIZE(NAME,                                              \
                            WIDTH_NAME,                                        \
                            HEIGHT_NAME,                                       \
                            DEPTH_NAME,                                        \
                            BYTES_PER_PIXEL)
#define LOG_BUFFER_SIZE(NAME, BYTES_PER_ELEMENT)
#endif

    LOG_BUFFER_RING_SIZE(flushUniformBufferCount, sizeof(gpu::FlushUniforms));
    if (allocs.flushUniformBufferCount !=
            m_currentResourceAllocations.flushUniformBufferCount ||
        forceRealloc)
    {
        m_impl->resizeFlushUniformBuffer(allocs.flushUniformBufferCount *
                                         sizeof(gpu::FlushUniforms));
    }

    LOG_BUFFER_RING_SIZE(pathBufferCount, sizeof(gpu::PathData));
    if (allocs.pathBufferCount !=
            m_currentResourceAllocations.pathBufferCount ||
        forceRealloc)
    {
        m_impl->resizePathBuffer(allocs.pathBufferCount * sizeof(gpu::PathData),
                                 gpu::PathData::kBufferStructure);
    }

    LOG_BUFFER_RING_SIZE(paintBufferCount, sizeof(gpu::PaintData));
    if (allocs.paintBufferCount !=
            m_currentResourceAllocations.paintBufferCount ||
        forceRealloc)
    {
        m_impl->resizePaintBuffer(allocs.paintBufferCount *
                                      sizeof(gpu::PaintData),
                                  gpu::PaintData::kBufferStructure);
    }

    LOG_BUFFER_RING_SIZE(paintAuxBufferCount, sizeof(gpu::PaintAuxData));
    if (allocs.paintAuxBufferCount !=
            m_currentResourceAllocations.paintAuxBufferCount ||
        forceRealloc)
    {
        m_impl->resizePaintAuxBuffer(allocs.paintAuxBufferCount *
                                         sizeof(gpu::PaintAuxData),
                                     gpu::PaintAuxData::kBufferStructure);
    }

    LOG_BUFFER_RING_SIZE(contourBufferCount, sizeof(gpu::ContourData));
    if (allocs.contourBufferCount !=
            m_currentResourceAllocations.contourBufferCount ||
        forceRealloc)
    {
        m_impl->resizeContourBuffer(allocs.contourBufferCount *
                                        sizeof(gpu::ContourData),
                                    gpu::ContourData::kBufferStructure);
    }

    LOG_BUFFER_RING_SIZE(gradSpanBufferCount, sizeof(gpu::GradientSpan));
    if (allocs.gradSpanBufferCount !=
            m_currentResourceAllocations.gradSpanBufferCount ||
        forceRealloc)
    {
        m_impl->resizeGradSpanBuffer(allocs.gradSpanBufferCount *
                                     sizeof(gpu::GradientSpan));
    }

    LOG_BUFFER_RING_SIZE(tessSpanBufferCount, sizeof(gpu::TessVertexSpan));
    if (allocs.tessSpanBufferCount !=
            m_currentResourceAllocations.tessSpanBufferCount ||
        forceRealloc)
    {
        m_impl->resizeTessVertexSpanBuffer(allocs.tessSpanBufferCount *
                                           sizeof(gpu::TessVertexSpan));
    }

    LOG_BUFFER_RING_SIZE(triangleVertexBufferCount,
                         sizeof(gpu::TriangleVertex));
    if (allocs.triangleVertexBufferCount !=
            m_currentResourceAllocations.triangleVertexBufferCount ||
        forceRealloc)
    {
        m_impl->resizeTriangleVertexBuffer(allocs.triangleVertexBufferCount *
                                           sizeof(gpu::TriangleVertex));
    }

    LOG_BUFFER_RING_SIZE(imageDrawInstanceBufferCount,
                         sizeof(gpu::ImageDrawInstance));
    if (allocs.imageDrawInstanceBufferCount !=
            m_currentResourceAllocations.imageDrawInstanceBufferCount ||
        forceRealloc)
    {
        m_impl->resizeImageDrawInstanceBuffer(
            allocs.imageDrawInstanceBufferCount *
            sizeof(gpu::ImageDrawInstance));
    }

    assert(allocs.gradTextureHeight <= kMaxTextureHeight);
    LOG_TEXTURE_SIZE(gradTextureHeight, gpu::kGradTextureWidth * 4);
    if (allocs.gradTextureHeight !=
            m_currentResourceAllocations.gradTextureHeight ||
        forceRealloc)
    {
        m_impl->resizeGradientTexture(
            gpu::kGradTextureWidth,
            math::lossless_numeric_cast<uint32_t>(allocs.gradTextureHeight));
    }

    assert(allocs.tessTextureHeight <= kMaxTextureHeight);
    LOG_TEXTURE_SIZE(tessTextureHeight, gpu::kTessTextureWidth * 4 * 4);
    if (allocs.tessTextureHeight !=
            m_currentResourceAllocations.tessTextureHeight ||
        forceRealloc)
    {
        m_impl->resizeTessellationTexture(
            gpu::kTessTextureWidth,
            math::lossless_numeric_cast<uint32_t>(allocs.tessTextureHeight));
    }

    assert(allocs.atlasTextureWidth <= atlasMaxSize() ||
           allocs.atlasTextureWidth <= frameDescriptor().renderTargetWidth);
    assert(allocs.atlasTextureHeight <= atlasMaxSize() ||
           allocs.atlasTextureHeight <= frameDescriptor().renderTargetHeight);
    LOG_TEXTURE_2D_SIZE("atlasTexture",
                        atlasTextureWidth,
                        atlasTextureHeight,
                        sizeof(uint16_t));
    if (allocs.atlasTextureWidth !=
            m_currentResourceAllocations.atlasTextureWidth ||
        allocs.atlasTextureHeight !=
            m_currentResourceAllocations.atlasTextureHeight ||
        forceRealloc)
    {
        m_impl->resizeAtlasTexture(
            math::lossless_numeric_cast<uint32_t>(allocs.atlasTextureWidth),
            math::lossless_numeric_cast<uint32_t>(allocs.atlasTextureHeight));
    }

    assert(allocs.plsTransientBackingPlaneCount <=
           RenderContextImpl::PLS_TRANSIENT_BACKING_MAX_PLANE_COUNT);
    LOG_TEXTURE_3D_SIZE("plsTransientBacking",
                        plsTransientBackingWidth,
                        plsTransientBackingHeight,
                        plsTransientBackingPlaneCount,
                        sizeof(uint32_t));
    if (allocs.plsTransientBackingWidth !=
            m_currentResourceAllocations.plsTransientBackingWidth ||
        allocs.plsTransientBackingHeight !=
            m_currentResourceAllocations.plsTransientBackingHeight ||
        allocs.plsTransientBackingPlaneCount !=
            m_currentResourceAllocations.plsTransientBackingPlaneCount ||
        forceRealloc)
    {
        m_impl->resizeTransientPLSBacking(
            math::lossless_numeric_cast<uint32_t>(
                allocs.plsTransientBackingWidth),
            math::lossless_numeric_cast<uint32_t>(
                allocs.plsTransientBackingHeight),
            math::lossless_numeric_cast<uint32_t>(
                allocs.plsTransientBackingPlaneCount));
    }

    assert(allocs.plsAtomicCoverageBackingWidth <=
           allocs.plsTransientBackingWidth);
    assert(allocs.plsAtomicCoverageBackingHeight <=
           allocs.plsTransientBackingHeight);
    LOG_TEXTURE_2D_SIZE("plsAtomicCoverageBacking",
                        plsAtomicCoverageBackingWidth,
                        plsAtomicCoverageBackingHeight,
                        sizeof(uint32_t));
    if (allocs.plsAtomicCoverageBackingWidth !=
            m_currentResourceAllocations.plsAtomicCoverageBackingWidth ||
        allocs.plsAtomicCoverageBackingHeight !=
            m_currentResourceAllocations.plsAtomicCoverageBackingHeight ||
        forceRealloc)
    {
        m_impl->resizeAtomicCoverageBacking(
            math::lossless_numeric_cast<uint32_t>(
                allocs.plsAtomicCoverageBackingWidth),
            math::lossless_numeric_cast<uint32_t>(
                allocs.plsAtomicCoverageBackingHeight));
    }

    assert(allocs.coverageBufferLength <=
           platformFeatures().maxCoverageBufferLength);
    LOG_BUFFER_SIZE(coverageBufferLength, sizeof(uint32_t));
    if (allocs.coverageBufferLength !=
            m_currentResourceAllocations.coverageBufferLength ||
        forceRealloc)
    {
        m_impl->resizeCoverageBuffer(allocs.coverageBufferLength *
                                     sizeof(uint32_t));
        // Start the coverageBufferPrefix over at zero. This ensure the new
        // buffer gets cleared because the only criteria for clearing it is when
        // the prefix wraps around to 0.
        m_coverageBufferPrefix = 0;
    }

    m_currentResourceAllocations = allocs;
}

bool RenderContext::mapResourceBuffers(
    const ResourceAllocationCounts& mapCounts)
{
    RIVE_PROF_SCOPE_L(1)

#define HANDLE_MAP_FAILURE(...)                                                \
    do                                                                         \
    {                                                                          \
        if (!(__VA_ARGS__))                                                    \
        {                                                                      \
            return false;                                                      \
        }                                                                      \
    } while (false)

    if (mapCounts.flushUniformBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(m_flushUniformData.mapElements(
            m_impl.get(),
            &RenderContextImpl::mapFlushUniformBuffer,
            mapCounts.flushUniformBufferCount));
    }
    assert(m_flushUniformData.hasRoomFor(mapCounts.flushUniformBufferCount));

    if (mapCounts.pathBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(
            m_pathData.mapElements(m_impl.get(),
                                   &RenderContextImpl::mapPathBuffer,
                                   mapCounts.pathBufferCount));
    }
    assert(m_pathData.hasRoomFor(mapCounts.pathBufferCount));

    if (mapCounts.paintBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(
            m_paintData.mapElements(m_impl.get(),
                                    &RenderContextImpl::mapPaintBuffer,
                                    mapCounts.paintBufferCount));
    }
    assert(m_paintData.hasRoomFor(mapCounts.paintBufferCount));

    if (mapCounts.paintAuxBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(
            m_paintAuxData.mapElements(m_impl.get(),
                                       &RenderContextImpl::mapPaintAuxBuffer,
                                       mapCounts.paintAuxBufferCount));
    }
    assert(m_paintAuxData.hasRoomFor(mapCounts.paintAuxBufferCount));

    if (mapCounts.contourBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(
            m_contourData.mapElements(m_impl.get(),
                                      &RenderContextImpl::mapContourBuffer,
                                      mapCounts.contourBufferCount));
    }
    assert(m_contourData.hasRoomFor(mapCounts.contourBufferCount));

    if (mapCounts.gradSpanBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(
            m_gradSpanData.mapElements(m_impl.get(),
                                       &RenderContextImpl::mapGradSpanBuffer,
                                       mapCounts.gradSpanBufferCount));
    }
    assert(m_gradSpanData.hasRoomFor(mapCounts.gradSpanBufferCount));

    if (mapCounts.tessSpanBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(m_tessSpanData.mapElements(
            m_impl.get(),
            &RenderContextImpl::mapTessVertexSpanBuffer,
            mapCounts.tessSpanBufferCount));
    }
    assert(m_tessSpanData.hasRoomFor(mapCounts.tessSpanBufferCount));

    if (mapCounts.triangleVertexBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(m_triangleVertexData.mapElements(
            m_impl.get(),
            &RenderContextImpl::mapTriangleVertexBuffer,
            mapCounts.triangleVertexBufferCount));
    }
    assert(
        m_triangleVertexData.hasRoomFor(mapCounts.triangleVertexBufferCount));

    if (mapCounts.imageDrawInstanceBufferCount > 0)
    {
        HANDLE_MAP_FAILURE(m_imageDrawInstanceData.mapElements(
            m_impl.get(),
            &RenderContextImpl::mapImageDrawInstanceBuffer,
            mapCounts.imageDrawInstanceBufferCount));
    }
    assert(m_imageDrawInstanceData.hasRoomFor(
        mapCounts.imageDrawInstanceBufferCount > 0));

#undef HANDLE_MAP_FAILURE
    return true;
}

void RenderContext::unmapResourceBuffers(
    const ResourceAllocationCounts& mapCounts)
{
    RIVE_PROF_SCOPE_L(1)
    if (m_flushUniformData)
    {
        m_flushUniformData.unmapElements(
            m_impl.get(),
            &RenderContextImpl::unmapFlushUniformBuffer,
            mapCounts.flushUniformBufferCount);
    }
    if (m_pathData)
    {
        m_pathData.unmapElements(m_impl.get(),
                                 &RenderContextImpl::unmapPathBuffer,
                                 mapCounts.pathBufferCount);
    }
    if (m_paintData)
    {
        m_paintData.unmapElements(m_impl.get(),
                                  &RenderContextImpl::unmapPaintBuffer,
                                  mapCounts.paintBufferCount);
    }
    if (m_paintAuxData)
    {
        m_paintAuxData.unmapElements(m_impl.get(),
                                     &RenderContextImpl::unmapPaintAuxBuffer,
                                     mapCounts.paintAuxBufferCount);
    }
    if (m_contourData)
    {
        m_contourData.unmapElements(m_impl.get(),
                                    &RenderContextImpl::unmapContourBuffer,
                                    mapCounts.contourBufferCount);
    }
    if (m_gradSpanData)
    {
        m_gradSpanData.unmapElements(m_impl.get(),
                                     &RenderContextImpl::unmapGradSpanBuffer,
                                     mapCounts.gradSpanBufferCount);
    }
    if (m_tessSpanData)
    {
        m_tessSpanData.unmapElements(
            m_impl.get(),
            &RenderContextImpl::unmapTessVertexSpanBuffer,
            mapCounts.tessSpanBufferCount);
    }
    if (m_triangleVertexData)
    {
        m_triangleVertexData.unmapElements(
            m_impl.get(),
            &RenderContextImpl::unmapTriangleVertexBuffer,
            mapCounts.triangleVertexBufferCount);
    }
    if (m_imageDrawInstanceData)
    {
        m_imageDrawInstanceData.unmapElements(
            m_impl.get(),
            &RenderContextImpl::unmapImageDrawInstanceBuffer,
            mapCounts.imageDrawInstanceBufferCount);
    }
}

uint32_t RenderContext::incrementCoverageBufferPrefix(
    bool* needsCoverageBufferClear)
{
    RIVE_PROF_SCOPE_L(1)
    assert(m_didBeginFrame);
    assert(frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic);
    do
    {
        if (m_coverageBufferPrefix == 0)
        {
            // When the prefix wraps around to 0, we need to clear the coverage
            // buffer because our shaders require coverageBufferPrefix to be
            // monotonically increasing.
            *needsCoverageBufferClear = true;
        }
        m_coverageBufferPrefix += CLOCKWISE_COVERAGE_PREFIX_ONE_VALUE;
    } while (m_coverageBufferPrefix == 0);

    return m_coverageBufferPrefix;
}

uint32_t RenderContext::LogicalFlush::allocateMidpointFanTessVertices(
    uint32_t count)
{
    uint32_t location = m_midpointFanTessVertexIdx;
    m_midpointFanTessVertexIdx += count;
    assert(m_midpointFanTessVertexIdx <= m_midpointFanTessEndLocation);
    return location;
}

uint32_t RenderContext::LogicalFlush::allocateOuterCubicTessVertices(
    uint32_t count)
{
    uint32_t location = m_outerCubicTessVertexIdx;
    m_outerCubicTessVertexIdx += count;
    assert(m_outerCubicTessVertexIdx <= m_outerCubicTessEndLocation);
    return location;
}

uint32_t RenderContext::LogicalFlush::pushPath(const PathDraw* draw)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_hasDoneLayout);

    ++m_currentPathID;
    assert(0 < m_currentPathID && m_currentPathID <= m_ctx->m_maxPathID);

    m_ctx->m_pathData.set_back(draw->matrix(),
                               draw->strokeRadius(),
                               draw->featherRadius(),
                               m_currentZIndex,
                               draw->atlasTransform(),
                               draw->coverageBufferRange());
    m_ctx->m_paintData.set_back(draw->drawContents(),
                                draw->paintType(),
                                draw->simplePaintValue(),
                                m_gradTextureLayout,
                                draw->clipID(),
                                draw->hasClipRect(),
                                draw->blendMode());
    m_ctx->m_paintAuxData.set_back(draw->matrix(),
                                   draw->paintType(),
                                   draw->simplePaintValue(),
                                   draw->gradient(),
                                   draw->imageTexture(),
                                   draw->clipRectInverseMatrix(),
                                   m_flushDesc.renderTarget,
                                   m_ctx->platformFeatures());

    assert(m_flushDesc.firstPath + m_currentPathID + 1 ==
           m_ctx->m_pathData.elementsWritten());
    assert(m_flushDesc.firstPaint + m_currentPathID + 1 ==
           m_ctx->m_paintData.elementsWritten());
    assert(m_flushDesc.firstPaintAux + m_currentPathID + 1 ==
           m_ctx->m_paintAuxData.elementsWritten());

    return m_currentPathID;
}

RenderContext::TessellationWriter::TessellationWriter(
    LogicalFlush* flush,
    uint32_t pathID,
    gpu::ContourDirections contourDirections,
    uint32_t forwardTessVertexCount,
    uint32_t forwardTessLocation,
    uint32_t mirroredTessVertexCount,
    uint32_t mirroredTessLocation) :
    m_flush(flush),
    m_tessSpanData(m_flush->m_ctx->m_tessSpanData),
    m_pathID(pathID),
    m_contourDirections(contourDirections),
    m_pathTessLocation(forwardTessLocation),
    m_pathMirroredTessLocation(mirroredTessLocation)
{
    RIVE_PROF_SCOPE_L(2)
    RIVE_DEBUG_CODE(m_expectedPathTessEndLocation =
                        m_pathTessLocation + forwardTessVertexCount;)
    RIVE_DEBUG_CODE(m_expectedPathMirroredTessEndLocation =
                        m_pathMirroredTessLocation - mirroredTessVertexCount;)
    assert(m_flush->m_hasDoneLayout);
    assert(m_flush->m_ctx->m_pathData.elementsWritten() > 0);
    assert(forwardTessVertexCount == 0 || mirroredTessVertexCount == 0 ||
           forwardTessVertexCount == mirroredTessVertexCount);
    assert(!gpu::ContourDirectionsAreDoubleSided(m_contourDirections) ||
           forwardTessVertexCount == mirroredTessVertexCount);
    assert(m_pathTessLocation >= 0);
    assert(m_pathMirroredTessLocation <= kMaxTessellationVertexCount);
    assert(m_expectedPathTessEndLocation <= kMaxTessellationVertexCount);
    assert(m_expectedPathMirroredTessEndLocation >= 0);
}

RenderContext::TessellationWriter::~TessellationWriter()
{
    assert(m_pathTessLocation == m_expectedPathTessEndLocation);
    assert(m_pathMirroredTessLocation == m_expectedPathMirroredTessEndLocation);
}

uint32_t RenderContext::LogicalFlush::pushContour(uint32_t pathID,
                                                  Vec2D midpoint,
                                                  bool isStroke,
                                                  bool closed,
                                                  uint32_t vertexIndex0)
{
    RIVE_PROF_SCOPE_L(2)
    assert(pathID != 0);
    assert(isStroke || closed);

    if (isStroke)
    {
        midpoint.x = closed ? 1 : 0;
    }
    m_ctx->m_contourData.emplace_back(midpoint, pathID, vertexIndex0);

    ++m_currentContourID;
    assert(0 < m_currentContourID && m_currentContourID <= gpu::kMaxContourID);
    assert(m_flushDesc.firstContour + m_currentContourID ==
           m_ctx->m_contourData.elementsWritten());
    return m_currentContourID;
}

uint32_t RenderContext::TessellationWriter::pushContour(
    Vec2D midpoint,
    bool isStroke,
    bool closed,
    uint32_t paddingVertexCount)
{
    RIVE_PROF_SCOPE_L(2)
    // The first curve of the contour will be pre-padded with
    // 'paddingVertexCount' tessellation vertices, colocated at T=0. The caller
    // must use this argument align the end of the contour on a boundary of the
    // patch size. (See math::padding_to_align_up().)
    m_nextCubicPaddingVertexCount = paddingVertexCount;

    return m_flush->pushContour(m_pathID,
                                midpoint,
                                isStroke,
                                closed,
                                nextVertexIndex());
}

void RenderContext::TessellationWriter::pushCubic(
    const Vec2D pts[4],
    gpu::ContourDirections contourDirections,
    Vec2D joinTangent,
    uint32_t parametricSegmentCount,
    uint32_t polarSegmentCount,
    uint32_t joinSegmentCount,
    uint32_t contourIDWithFlags)
{
    RIVE_PROF_SCOPE_L(3)
    assert(0 <= parametricSegmentCount &&
           parametricSegmentCount <= kMaxParametricSegments);
    assert(0 <= polarSegmentCount && polarSegmentCount <= kMaxPolarSegments);
    assert(joinSegmentCount > 0);
    assert((contourIDWithFlags & CONTOUR_ID_MASK) ==
           (m_flush->m_currentContourID & CONTOUR_ID_MASK));
    // contourID can't be zero.
    assert((contourIDWithFlags & CONTOUR_ID_MASK) != 0);
    // contourID can't be out of range in the contour buffer. (Contour buffer
    // indices are 1-based.)
    assert((contourIDWithFlags & CONTOUR_ID_MASK) <=
           m_flush->desc().contourCount);

    // Polar and parametric segments share the same beginning and ending
    // vertices, so the merged *vertex* count is equal to the sum of polar and
    // parametric *segment* counts.
    uint32_t curveMergedVertexCount =
        parametricSegmentCount + polarSegmentCount;
    // -1 because the curve and join share an ending/beginning vertex.
    uint32_t totalVertexCount = m_nextCubicPaddingVertexCount +
                                curveMergedVertexCount + joinSegmentCount - 1;

    // Only the first curve of a contour gets padding vertices.
    m_nextCubicPaddingVertexCount = 0;

    switch (contourDirections)
    {
        case gpu::ContourDirections::forward:
            pushTessellationSpans(pts,
                                  joinTangent,
                                  totalVertexCount,
                                  parametricSegmentCount,
                                  polarSegmentCount,
                                  joinSegmentCount,
                                  contourIDWithFlags);
            break;
        case gpu::ContourDirections::reverse:
            pushMirroredTessellationSpans(pts,
                                          joinTangent,
                                          totalVertexCount,
                                          parametricSegmentCount,
                                          polarSegmentCount,
                                          joinSegmentCount,
                                          contourIDWithFlags);
            break;
        case gpu::ContourDirections::reverseThenForward:
        case gpu::ContourDirections::forwardThenReverse:
            // m_pathTessLocation and m_pathMirroredTessLocation are already
            // configured, so at ths point we don't need to handle
            // reverseThenForward or forwardThenReverse differently.
            pushDoubleSidedTessellationSpans(pts,
                                             joinTangent,
                                             totalVertexCount,
                                             parametricSegmentCount,
                                             polarSegmentCount,
                                             joinSegmentCount,
                                             contourIDWithFlags);
            break;
    }
}

RIVE_ALWAYS_INLINE void RenderContext::TessellationWriter::
    pushTessellationSpans(const Vec2D pts[4],
                          Vec2D joinTangent,
                          uint32_t totalVertexCount,
                          uint32_t parametricSegmentCount,
                          uint32_t polarSegmentCount,
                          uint32_t joinSegmentCount,
                          uint32_t contourIDWithFlags)
{
    RIVE_PROF_SCOPE_L(3)
    assert(totalVertexCount > 0);

    uint32_t y = m_pathTessLocation / kTessTextureWidth;
    int32_t x0 = m_pathTessLocation % kTessTextureWidth;
    int32_t x1 = x0 + totalVertexCount;
    for (;;)
    {
        m_tessSpanData.set_back(pts,
                                joinTangent,
                                static_cast<float>(y),
                                x0,
                                x1,
                                parametricSegmentCount,
                                polarSegmentCount,
                                joinSegmentCount,
                                contourIDWithFlags);
        if (x1 > static_cast<int32_t>(kTessTextureWidth))
        {
            // The span was too long to fit on the current line. Wrap and draw
            // it again, this time behind the left edge of the texture so we
            // capture what got clipped off last time.
            ++y;
            x0 -= kTessTextureWidth;
            x1 -= kTessTextureWidth;
            continue;
        }
        break;
    }
    assert(y ==
           (m_pathTessLocation + totalVertexCount - 1) / kTessTextureWidth);

    m_pathTessLocation += totalVertexCount;
    assert(m_pathTessLocation <= m_expectedPathTessEndLocation);
}

RIVE_ALWAYS_INLINE void RenderContext::TessellationWriter::
    pushMirroredTessellationSpans(const Vec2D pts[4],
                                  Vec2D joinTangent,
                                  uint32_t totalVertexCount,
                                  uint32_t parametricSegmentCount,
                                  uint32_t polarSegmentCount,
                                  uint32_t joinSegmentCount,
                                  uint32_t contourIDWithFlags)
{
    assert(totalVertexCount > 0);

    uint32_t reflectionY = (m_pathMirroredTessLocation - 1) / kTessTextureWidth;
    int32_t reflectionX0 =
        (m_pathMirroredTessLocation - 1) % kTessTextureWidth + 1;
    int32_t reflectionX1 = reflectionX0 - totalVertexCount;

    for (;;)
    {
        m_tessSpanData.set_back(pts,
                                joinTangent,
                                static_cast<float>(reflectionY),
                                reflectionX0,
                                reflectionX1,
                                parametricSegmentCount,
                                polarSegmentCount,
                                joinSegmentCount,
                                contourIDWithFlags);
        if (reflectionX1 < 0)
        {
            --reflectionY;
            reflectionX0 += kTessTextureWidth;
            reflectionX1 += kTessTextureWidth;
            continue;
        }
        break;
    }

    m_pathMirroredTessLocation -= totalVertexCount;
    assert(m_pathMirroredTessLocation >= m_expectedPathMirroredTessEndLocation);
}

RIVE_ALWAYS_INLINE void RenderContext::TessellationWriter::
    pushDoubleSidedTessellationSpans(const Vec2D pts[4],
                                     Vec2D joinTangent,
                                     uint32_t totalVertexCount,
                                     uint32_t parametricSegmentCount,
                                     uint32_t polarSegmentCount,
                                     uint32_t joinSegmentCount,
                                     uint32_t contourIDWithFlags)
{
    assert(totalVertexCount > 0);

    int32_t y = m_pathTessLocation / kTessTextureWidth;
    int32_t x0 = m_pathTessLocation % kTessTextureWidth;
    int32_t x1 = x0 + totalVertexCount;

    uint32_t reflectionY = (m_pathMirroredTessLocation - 1) / kTessTextureWidth;
    int32_t reflectionX0 =
        (m_pathMirroredTessLocation - 1) % kTessTextureWidth + 1;
    int32_t reflectionX1 = reflectionX0 - totalVertexCount;

    for (;;)
    {
        m_tessSpanData.set_back(pts,
                                joinTangent,
                                static_cast<float>(y),
                                x0,
                                x1,
                                static_cast<float>(reflectionY),
                                reflectionX0,
                                reflectionX1,
                                parametricSegmentCount,
                                polarSegmentCount,
                                joinSegmentCount,
                                contourIDWithFlags);
        if (x1 > static_cast<int32_t>(kTessTextureWidth) || reflectionX1 < 0)
        {
            // Either the span or its reflection was too long to fit on the
            // current line. Wrap and draw both of them again, this time beyond
            // the opposite edge of the texture so we capture what got clipped
            // off last time.
            ++y;
            x0 -= kTessTextureWidth;
            x1 -= kTessTextureWidth;

            --reflectionY;
            reflectionX0 += kTessTextureWidth;
            reflectionX1 += kTessTextureWidth;
            continue;
        }
        break;
    }

    m_pathTessLocation += totalVertexCount;
    assert(m_pathTessLocation <= m_expectedPathTessEndLocation);

    m_pathMirroredTessLocation -= totalVertexCount;
    assert(m_pathMirroredTessLocation >= m_expectedPathMirroredTessEndLocation);
}

void RenderContext::LogicalFlush::pushPaddingVertices(uint32_t count,
                                                      uint32_t tessLocation)
{
    RIVE_PROF_SCOPE_L(3)
    assert(m_hasDoneLayout);
    assert(count > 0);

    constexpr static Vec2D kEmptyCubic[4]{};
    TessellationWriter(this,
                       /*pathID=*/0,
                       gpu::ContourDirections::forward,
                       count,
                       tessLocation)
        .pushTessellationSpans(kEmptyCubic,
                               {0, 0},
                               count,
                               0,
                               0,
                               1,
                               INVALID_CONTOUR_ID_WITH_FLAGS);
}

gpu::DrawBatch& RenderContext::LogicalFlush::pushMidpointFanDraw(
    const PathDraw* draw,
    gpu::DrawType drawType,
    uint32_t tessVertexCount,
    uint32_t tessLocation,
    gpu::ShaderMiscFlags shaderMiscFlags)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_hasDoneLayout);

    uint32_t baseInstance = math::lossless_numeric_cast<uint32_t>(
        tessLocation / kMidpointFanPatchSegmentSpan);
    // flush() is responsible for alignment.
    assert(baseInstance * kMidpointFanPatchSegmentSpan == tessLocation);

    uint32_t instanceCount = tessVertexCount / kMidpointFanPatchSegmentSpan;
    // flush() is responsible for alignment.
    assert(instanceCount * kMidpointFanPatchSegmentSpan == tessVertexCount);

    return pushPathDraw(draw,
                        drawType,
                        shaderMiscFlags,
                        instanceCount,
                        baseInstance);
}

gpu::DrawBatch& RenderContext::LogicalFlush::pushOuterCubicsDraw(
    const PathDraw* draw,
    gpu::DrawType drawType,
    uint32_t tessVertexCount,
    uint32_t tessLocation,
    gpu::ShaderMiscFlags shaderMiscFlags)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_hasDoneLayout);

    uint32_t baseInstance = math::lossless_numeric_cast<uint32_t>(
        tessLocation / kOuterCurvePatchSegmentSpan);
    // flush() is responsible for alignment.
    assert(baseInstance * kOuterCurvePatchSegmentSpan == tessLocation);

    uint32_t instanceCount = tessVertexCount / kOuterCurvePatchSegmentSpan;
    // flush() is responsible for alignment.
    assert(instanceCount * kOuterCurvePatchSegmentSpan == tessVertexCount);

    return pushPathDraw(draw,
                        drawType,
                        shaderMiscFlags,
                        instanceCount,
                        baseInstance);
}

gpu::DrawBatch* RenderContext::LogicalFlush::pushInteriorTriangulationDraw(
    const PathDraw* draw,
    uint32_t pathID,
    gpu::WindingFaces windingFaces,
    gpu::ShaderMiscFlags shaderMiscFlags RIVE_DEBUG_CODE(,
                                                         size_t* vertexCounter))
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_hasDoneLayout);
    assert(pathID != 0);

    uint32_t baseVertex = math::lossless_numeric_cast<uint32_t>(
        m_ctx->m_triangleVertexData.elementsWritten());
    size_t actualVertexCount =
        draw->triangulator()->polysToTriangles(pathID,
                                               windingFaces,
                                               &m_ctx->m_triangleVertexData);
    assert(baseVertex + actualVertexCount ==
           m_ctx->m_triangleVertexData.elementsWritten());
    RIVE_DEBUG_CODE(*vertexCounter += actualVertexCount;)
    if (actualVertexCount > 0)
    {
        return &pushPathDraw(
            draw,
            DrawType::interiorTriangulation,
            shaderMiscFlags,
            math::lossless_numeric_cast<uint32_t>(actualVertexCount),
            baseVertex);
    }
    return nullptr;
}

gpu::DrawBatch& RenderContext::LogicalFlush::pushAtlasBlit(PathDraw* draw,
                                                           uint32_t pathID)
{
    RIVE_PROF_SCOPE_L(2)
    auto baseVertex = math::lossless_numeric_cast<uint32_t>(
        m_ctx->m_triangleVertexData.elementsWritten());
    auto [l, t, r, b] = AABB(draw->pixelBounds());
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{l, b}, 1, pathID);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{l, t}, 1, pathID);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, b}, 1, pathID);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, b}, 1, pathID);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{l, t}, 1, pathID);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, t}, 1, pathID);
    return pushPathDraw(draw,
                        DrawType::atlasBlit,
                        m_baselineShaderMiscFlags,
                        6,
                        baseVertex);
}

gpu::DrawBatch& RenderContext::LogicalFlush::pushImageRectDraw(
    ImageRectDraw* draw)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_hasDoneLayout);

    // If we support image paints for paths, the client should use pushPath()
    // with an image paint instead of calling this method.
    assert(!m_ctx->frameSupportsImagePaintForPaths());

    const uint32_t imageDrawBaseInstance =
        math::lossless_numeric_cast<uint32_t>(
            m_ctx->m_imageDrawInstanceData.elementsWritten());
    m_ctx->m_imageDrawInstanceData.emplace_back(draw->matrix(),
                                                draw->opacity(),
                                                draw->clipRectInverseMatrix(),
                                                draw->clipID(),
                                                draw->blendMode(),
                                                m_currentZIndex);

    DrawBatch& batch = pushDraw(draw,
                                DrawType::imageRect,
                                m_baselineShaderMiscFlags,
                                PaintType::image,
                                1,
                                imageDrawBaseInstance);
    return batch;
}

gpu::DrawBatch& RenderContext::LogicalFlush::pushImageMeshDraw(
    ImageMeshDraw* draw)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_hasDoneLayout);

    const uint32_t imageDrawBaseInstance =
        math::lossless_numeric_cast<uint32_t>(
            m_ctx->m_imageDrawInstanceData.elementsWritten());
    m_ctx->m_imageDrawInstanceData.emplace_back(draw->matrix(),
                                                draw->opacity(),
                                                draw->clipRectInverseMatrix(),
                                                draw->clipID(),
                                                draw->blendMode(),
                                                m_currentZIndex);

    DrawBatch& batch = pushDraw(draw,
                                DrawType::imageMesh,
                                m_baselineShaderMiscFlags,
                                PaintType::image,
                                1, // one instance (the mesh)
                                imageDrawBaseInstance);
    batch.indexCountPerInstance = draw->indexCount();
    batch.vertexBuffer = draw->vertexBuffer();
    batch.uvBuffer = draw->uvBuffer();
    batch.indexBuffer = draw->indexBuffer();
    return batch;
}

gpu::DrawBatch& RenderContext::LogicalFlush::pushClipResetDraw(ClipReset* draw)
{
    RIVE_PROF_SCOPE_L(2)
    assert(m_hasDoneLayout);

    uint32_t baseVertex = math::lossless_numeric_cast<uint32_t>(
        m_ctx->m_triangleVertexData.elementsWritten());
    auto [l, t, r, b] = AABB(getClipInfo(draw->previousClipID()).contentBounds);
    uint32_t z = m_currentZIndex;
    assert(AABB(l, t, r, b).round() == draw->pixelBounds());
    assert(draw->resourceCounts().maxTriangleVertexCount == 6);
    assert(m_ctx->m_triangleVertexData.hasRoomFor(6));
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{l, b}, 0, z);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{l, t}, 0, z);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, b}, 0, z);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, b}, 0, z);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{l, t}, 0, z);
    m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, t}, 0, z);
    return pushDraw(draw,
                    DrawType::clipReset,
                    gpu::ShaderMiscFlags::none,
                    PaintType::clipUpdate,
                    6,
                    baseVertex);
}

gpu::DrawBatch& RenderContext::LogicalFlush::pushPathDraw(
    const PathDraw* draw,
    DrawType drawType,
    gpu::ShaderMiscFlags shaderMiscFlags,
    uint32_t vertexCount,
    uint32_t baseVertex)
{
    RIVE_PROF_SCOPE_L(3)
    assert(m_hasDoneLayout);

    // Clockwise fills get their own shaders in rasterOrdering mode.
    // TODO: eventually we will use draw_clockwise_path.frag for these
    // draws in rasterOrdering mode, instead of just making a variant of
    // draw_raster_order_path.frag.
    if (m_ctx->frameInterlockMode() == gpu::InterlockMode::rasterOrdering &&
        enums::is_flag_set(draw->drawContents(),
                           gpu::DrawContents::clockwiseFill))
    {
        shaderMiscFlags |= gpu::ShaderMiscFlags::clockwiseFill;
    }

    DrawBatch& batch = pushDraw(draw,
                                drawType,
                                shaderMiscFlags,
                                draw->paintType(),
                                vertexCount,
                                baseVertex);

    auto pathShaderFeatures = gpu::ShaderFeatures::NONE;
    if (draw->featherRadius() != 0 &&
        drawType != gpu::DrawType::interiorTriangulation &&
        drawType != gpu::DrawType::atlasBlit)
    {
        pathShaderFeatures |= ShaderFeatures::ENABLE_FEATHER;
    }
    if (enums::is_flag_set(draw->drawContents(),
                           gpu::DrawContents::evenOddFill))
    {
        assert(!enums::is_flag_set(batch.shaderMiscFlags,
                                   gpu::ShaderMiscFlags::clockwiseFill));
        pathShaderFeatures |= ShaderFeatures::ENABLE_EVEN_ODD;
    }
    constexpr static gpu::DrawContents NESTED_CLIP_FLAGS =
        gpu::DrawContents::clipUpdate | gpu::DrawContents::activeClip;
    if ((draw->drawContents() & NESTED_CLIP_FLAGS) == NESTED_CLIP_FLAGS)
    {
        pathShaderFeatures |= ShaderFeatures::ENABLE_NESTED_CLIPPING;
    }
    batch.shaderFeatures |=
        pathShaderFeatures & m_ctx->m_frameShaderFeaturesMask;
    assert(
        (batch.shaderFeatures &
         gpu::ShaderFeaturesMaskFor(drawType, m_ctx->frameInterlockMode())) ==
        batch.shaderFeatures);
    m_combinedShaderFeatures |= batch.shaderFeatures;
    return batch;
}

RIVE_ALWAYS_INLINE static bool can_combine_shader_misc_flags(
    const gpu::DrawBatch* batch,
    const Draw* draw,
    gpu::ShaderMiscFlags shaderMiscFlags)
{
    // If a path doesn't have ANY_PATH_FILL bits, it means it's a stroke.
    constexpr static auto ANY_PATH_FILL = gpu::DrawContents::clockwiseFill |
                                          gpu::DrawContents::evenOddFill |
                                          gpu::DrawContents::nonZeroFill;

    gpu::ShaderMiscFlags compareMask = ~gpu::ShaderMiscFlags::none;

    // Strokes draw identically in the clockwise and legacy shaders, so strokes
    // can be combined with paths of any fill type.
    if ((enums::no_flags_set(batch->drawContents, ANY_PATH_FILL) ||
         enums::no_flags_set(draw->drawContents(), ANY_PATH_FILL)))
    {
        compareMask &= ~gpu::ShaderMiscFlags::clockwiseFill;
    }

    return (batch->shaderMiscFlags & compareMask) ==
           (shaderMiscFlags & compareMask);
}

RIVE_ALWAYS_INLINE static bool can_combine_draw_images(
    const Texture* currentDrawTexture,
    const Texture* nextDrawTexture,
    const ImageSampler currentImageSamplerKey,
    const ImageSampler nextImageSamplerKey)
{
    if (currentDrawTexture == nullptr || nextDrawTexture == nullptr)
    {
        // We can always combine two draws if one or both do not use an image
        // paint.
        return true;
    }
    // Since the image paint's texture must be bound to a specific slot, we
    // can't combine draws that use different textures.
    return (currentDrawTexture == nextDrawTexture) &&
           (currentImageSamplerKey == nextImageSamplerKey);
}

constexpr uint32_t patchIndexCount(DrawType drawType)
{
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
            return kMidpointFanPatchIndexCount;
        case DrawType::midpointFanCenterAAPatches:
            return kMidpointFanCenterAAPatchIndexCount;
        case DrawType::outerCurvePatches:
            return kOuterCurvePatchIndexCount;
        case DrawType::msaaStrokes:
            return kMidpointFanPatchBorderIndexCount;
        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFans:
        case DrawType::msaaMidpointFanStencilReset:
        case DrawType::msaaMidpointFanPathsStencil:
        case DrawType::msaaMidpointFanPathsCover:
            return kMidpointFanPatchIndexCount -
                   kMidpointFanPatchBorderIndexCount;
        case DrawType::msaaOuterCubics:
            return kOuterCurvePatchIndexCount -
                   kOuterCurvePatchBorderIndexCount;
        case DrawType::interiorTriangulation:
        case DrawType::atlasBlit:
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::clipReset:
        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            RIVE_UNREACHABLE();
    }
    RIVE_UNREACHABLE();
}

constexpr uint32_t patchBaseIndex(DrawType drawType)
{
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::msaaStrokes:
            return kMidpointFanPatchBaseIndex;
        case DrawType::midpointFanCenterAAPatches:
            return kMidpointFanCenterAAPatchBaseIndex;
        case DrawType::outerCurvePatches:
            return kOuterCurvePatchBaseIndex;
        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFans:
        case DrawType::msaaMidpointFanStencilReset:
        case DrawType::msaaMidpointFanPathsStencil:
        case DrawType::msaaMidpointFanPathsCover:
            return kMidpointFanPatchBaseIndex +
                   kMidpointFanPatchBorderIndexCount;
        case DrawType::msaaOuterCubics:
            return kOuterCurvePatchBaseIndex + kOuterCurvePatchBorderIndexCount;
        case DrawType::interiorTriangulation:
        case DrawType::atlasBlit:
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::clipReset:
        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            RIVE_UNREACHABLE();
    }
    RIVE_UNREACHABLE();
}

static void assignDrawIndices(DrawType drawType, gpu::DrawBatch* batch)
{
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::msaaStrokes:
        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFans:
        case DrawType::msaaMidpointFanStencilReset:
        case DrawType::msaaMidpointFanPathsStencil:
        case DrawType::msaaMidpointFanPathsCover:
        case DrawType::msaaOuterCubics:
            batch->indexCountPerInstance = patchIndexCount(drawType);
            batch->baseIndex = patchBaseIndex(drawType);
            break;
        case DrawType::imageRect:
            batch->indexCountPerInstance = std::size(kImageRectIndices);
            batch->baseIndex = 0;
            break;
        case DrawType::imageMesh:
        case DrawType::interiorTriangulation:
        case DrawType::atlasBlit:
        case DrawType::clipReset:
        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            batch->indexCountPerInstance = 0;
            batch->baseIndex = 0;
            break;
        default:
            RIVE_UNREACHABLE();
    }
}

gpu::DrawBatch& RenderContext::LogicalFlush::pushDraw(
    const Draw* draw,
    DrawType drawType,
    gpu::ShaderMiscFlags shaderMiscFlags,
    gpu::PaintType paintType,
    uint32_t elementCount,
    uint32_t baseElement)
{
    RIVE_PROF_SCOPE_L(3)
    assert(m_hasDoneLayout);
    assert(elementCount > 0);

    shaderMiscFlags |= m_baselineShaderMiscFlags;

    if ((m_ctx->frameInterlockMode() == gpu::InterlockMode::clockwise ||
         (m_ctx->frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic &&
          !enums::is_flag_set(shaderMiscFlags,
                              gpu::ShaderMiscFlags::borrowedCoveragePass))) &&
        enums::is_flag_set(draw->drawContents(), gpu::DrawContents::clipUpdate))
    {
        // Clockwise modes give clip updates a dedicated draw by setting
        // gpu::ShaderMiscFlags::clipUpdateOnly.
        shaderMiscFlags |= gpu::ShaderMiscFlags::clipUpdateOnly;
        if (m_ctx->frameInterlockMode() ==
                gpu::InterlockMode::clockwiseAtomic &&
            enums::is_flag_set(draw->drawContents(),
                               gpu::DrawContents::activeClip))
        {
            // clockwiseAtomic takes it a step futher and separates out nested
            // clip updates into their own draw type.
            shaderMiscFlags |= gpu::ShaderMiscFlags::nestedClipUpdateOnly;
        }
    }

    // In clockwiseAtomic and msaa modes, individual draws can use
    // fixedFunctionColorOutput even if the render pass as a whole does not.
    if (m_ctx->frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic)
    {
        if (enums::is_flag_set(shaderMiscFlags,
                               gpu::ShaderMiscFlags::borrowedCoveragePass) ||
            draw->blendMode() == BlendMode::srcOver)
        {
            shaderMiscFlags |= gpu::ShaderMiscFlags::fixedFunctionColorOutput;
        }
    }
    else if (m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa &&
             draw->blendMode() == BlendMode::srcOver)
    {
        shaderMiscFlags |= gpu::ShaderMiscFlags::fixedFunctionColorOutput;
    }

    bool canMergeWithPreviousBatch;
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::interiorTriangulation:
        case DrawType::atlasBlit:
        case DrawType::msaaStrokes:
        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFans:
        case DrawType::msaaMidpointFanStencilReset:
        case DrawType::msaaMidpointFanPathsStencil:
        case DrawType::msaaMidpointFanPathsCover:
        case DrawType::msaaOuterCubics:
        case DrawType::clipReset:
            if (!m_drawList.empty() &&
                !enums::is_flag_set(m_pendingBarriers,
                                    gpu::BarrierFlags::drawBatchBreak))
            {
                const DrawBatch* currentBatch = m_drawList.tail();
                canMergeWithPreviousBatch =
                    currentBatch->drawType == drawType &&
                    can_combine_shader_misc_flags(currentBatch,
                                                  draw,
                                                  shaderMiscFlags) &&
                    can_combine_draw_images(currentBatch->imageTexture,
                                            draw->imageTexture(),
                                            currentBatch->imageSampler,
                                            draw->imageSampler());
                if (canMergeWithPreviousBatch &&
                    currentBatch->baseElement + currentBatch->elementCount !=
                        baseElement)
                {
                    // In MSAA mode, multiple subpasses reference the same
                    // tessellation data. Although rare, this breaks the
                    // guarantee we have in other modes that mergeable batches
                    // will always have contiguous patches.
                    assert(m_ctx->frameInterlockMode() ==
                           gpu::InterlockMode::msaa);
                    canMergeWithPreviousBatch = false;
                }

                // Also break if there is a scissor rect mismatch
                if (m_ctx->platformFeatures().supportsClipScissor)
                {
                    if (currentBatch->scissorRect != draw->scissorRect())
                    {
                        canMergeWithPreviousBatch = false;
                    }
                }
                break;
            }
            [[fallthrough]];

        // Image draws can't be combined for now because they each have their
        // own unique uniforms.
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            canMergeWithPreviousBatch = false;
            break;
    }

    DrawBatch* batch;
    if (!canMergeWithPreviousBatch)
    {
        batch = m_drawList.emplace_back(m_ctx->perFrameAllocator(),
                                        drawType,
                                        shaderMiscFlags,
                                        draw->drawContents(),
                                        elementCount,
                                        baseElement,
                                        draw->blendMode(),
                                        draw->imageSampler(),
                                        m_pendingBarriers);
        assignDrawIndices(drawType, batch);
    }
    else
    {
        batch = m_drawList.tail();
        assert(batch->drawType == drawType);
        assert(batch->baseElement + batch->elementCount == baseElement);

        batch->elementCount += elementCount;

        // clockwise doesn't mix regular draws and clip updates.
        assert(m_ctx->frameInterlockMode() != gpu::InterlockMode::clockwise ||
               (batch->drawContents & gpu::DrawContents::clipUpdate) ==
                   (draw->drawContents() & gpu::DrawContents::clipUpdate));

        // Feathered fills should never combine with fills, strokes, or
        // feathered strokes because they use a different DrawType.
        assert((batch->drawContents & gpu::DrawContents::featheredFill) ==
               (draw->drawContents() & gpu::DrawContents::featheredFill));

        // msaa can't mix drawContents in a batch.
        assert(m_ctx->frameInterlockMode() != gpu::InterlockMode::msaa ||
               batch->drawContents == draw->drawContents());

        batch->shaderMiscFlags |= shaderMiscFlags;
        batch->drawContents |= draw->drawContents();
        batch->barriers |= m_pendingBarriers;
    }
    m_pendingBarriers = gpu::BarrierFlags::none;

    // If the batch was merged into a previous one, this ensures it was a valid
    // merge.
    assert(batch->drawType == drawType);
    assert(can_combine_draw_images(batch->imageTexture,
                                   draw->imageTexture(),
                                   batch->imageSampler,
                                   draw->imageSampler()));
    assert(m_pendingBarriers == BarrierFlags::none);

    auto shaderFeatures = ShaderFeatures::NONE;
    if (draw->clipID() != 0)
    {
        shaderFeatures |= ShaderFeatures::ENABLE_CLIPPING;
    }
    if (draw->hasClipRect() && paintType != PaintType::clipUpdate)
    {
        shaderFeatures |= ShaderFeatures::ENABLE_CLIP_RECT;
    }

    if (frameDescriptor().ditherMode ==
        gpu::DitherMode::interleavedGradientNoise)
    {
        shaderFeatures |= ShaderFeatures::ENABLE_DITHER;
    }

    if (paintType != PaintType::clipUpdate &&
        !enums::is_flag_set(shaderMiscFlags,
                            gpu::ShaderMiscFlags::borrowedCoveragePass))
    {
        assert(!enums::is_flag_set(shaderMiscFlags,
                                   gpu::ShaderMiscFlags::clipUpdateOnly));
        switch (draw->blendMode())
        {
            case BlendMode::hue:
            case BlendMode::saturation:
            case BlendMode::color:
            case BlendMode::luminosity:
                shaderFeatures |= ShaderFeatures::ENABLE_HSL_BLEND_MODES;
                [[fallthrough]];
            case BlendMode::screen:
            case BlendMode::overlay:
            case BlendMode::darken:
            case BlendMode::lighten:
            case BlendMode::colorDodge:
            case BlendMode::colorBurn:
            case BlendMode::hardLight:
            case BlendMode::softLight:
            case BlendMode::difference:
            case BlendMode::exclusion:
            case BlendMode::multiply:
                shaderFeatures |= ShaderFeatures::ENABLE_ADVANCED_BLEND;
                break;
            case BlendMode::srcOver:
                break;
        }
    }
    batch->shaderFeatures |= shaderFeatures & m_ctx->m_frameShaderFeaturesMask;
    assert(
        (batch->shaderFeatures &
         gpu::ShaderFeaturesMaskFor(drawType, m_ctx->frameInterlockMode())) ==
        batch->shaderFeatures);

    if (paintType == PaintType::image)
    {
        assert(draw->imageTexture() != nullptr);
        if (batch->imageTexture == nullptr)
        {
            batch->imageTexture = draw->imageTexture();
        }
        assert(batch->imageTexture == draw->imageTexture());
    }

    m_combinedShaderFeatures |= batch->shaderFeatures;
    return *batch;
}
} // namespace rive::gpu
