/*
 * Copyright 2022 Rive
 */

#include "shaders/constants.glsl"
#include "rive/shapes/paint/paint_outset.hpp"
#include "rive/math/bitwise.hpp"
#include "rive/renderer/gpu.hpp"
#include "rive/renderer/render_context.hpp"
#include "rive/renderer/render_target.hpp"
#include "rive/renderer/texture.hpp"
#include "gradient.hpp"
#include "image_draw_attributes.hpp"
#include "rive_render_paint.hpp"

#include <limits>

#include "generated/shaders/draw_path.vert.exports.h"

namespace rive::gpu
{
static_assert(kGradTextureWidth == GRAD_TEXTURE_WIDTH);
static_assert(kTessTextureWidth == TESS_TEXTURE_WIDTH);
static_assert(kTessTextureWidthLog2 == TESS_TEXTURE_WIDTH_LOG2);
static_assert(kMidpointFanPatchSegmentSpan == MIDPOINT_FAN_PATCH_SEGMENT_SPAN);
static_assert(OuterCubicPatchSegmentSpan == OUTER_CUBIC_PATCH_SEGMENT_SPAN);
static_assert(OuterCubicPatchSegmentSpanPlusBowtie ==
              OUTER_CUBIC_PATCH_SEGMENT_SPAN_PLUS_BOWTIE);

static_assert(DSMidpointFanFillPatchStrideLog2 == DS_MIDPOINT_FAN_STRIDE_LOG2);
static_assert(DSOuterCubicFillPatchStrideLog2 == DS_OUTER_CUBIC_STRIDE_LOG2);
static_assert(DSFillVertexFlagsShift == VERTEX_FLAGS_SHIFT);
static_assert(DSFillVertexFlagDisableColorWrite ==
              VERTEX_FLAG_DISABLE_COLOR_WRITE);
static_assert(DSFillVertexFlagOuterCubic == VERTEX_FLAG_OUTER_CUBIC);

static_assert(DS_MIDPOINT_VERTEX_ID == MIDPOINT_FAN_PATCH_SEGMENT_SPAN + 1);
static_assert(DS_MIDPOINT_VERTEX_ID < DS_PATCH_STRIDE(/*outerCubic=*/false));
static_assert(OUTER_CUBIC_PATCH_SEGMENT_SPAN <
              DS_PATCH_STRIDE(/*outerCubic=*/true));
// Since index patterns use a pow2 vertex stride, their vertex IDs span the
// entire uint16 range.
static_assert(DS_PATCH_STRIDE(/*outerCubic=*/false) *
                  DSMidpointFanFillPatchMaxReps ==
              1u << 16);
static_assert(DS_PATCH_STRIDE(/*outerCubic=*/true) *
                  DSOuterCubicFillPatchMaxReps ==
              1u << 16);

static_assert(sizeof(PaintAuxData) / StorageBufferElementSizeInBytes(
                                         PaintAuxData::kBufferStructure) ==
              PAINT_AUX_ENTRY_ELEMENT_COUNT);

// packNormalizedDepth() only supports 23 bits of payload. (See common.glsl.)
static_assert(DEPTH_Z_INDEX_BIT_COUNT + DEPTH_COVERAGE_BIT_COUNT == 23);

static Span<const DrawType> get_valid_draw_types(InterlockMode mode)
{
    switch (mode)
    {
        case InterlockMode::rasterOrdering:
        {
            static constexpr DrawType types[] = {
                DrawType::midpointFanPatches,
                DrawType::midpointFanCenterAAPatches,
                DrawType::outerCurvePatches,
                DrawType::interiorTriangulation,
                DrawType::featherAtlasBlit,
                DrawType::imageMesh,
                DrawType::renderPassResolve,
            };
            return make_span(types);
        }

        case InterlockMode::clockwise:
        {
            static constexpr DrawType types[] = {
                DrawType::midpointFanPatches,
                DrawType::midpointFanCenterAAPatches,
                DrawType::outerCurvePatches,
                DrawType::interiorTriangulation,
                DrawType::featherAtlasBlit,
                DrawType::imageMesh,
            };
            return make_span(types);
        }
        case InterlockMode::atomics:
        {
            static constexpr DrawType types[] = {
                DrawType::midpointFanPatches,
                DrawType::midpointFanCenterAAPatches,
                DrawType::outerCurvePatches,
                DrawType::interiorTriangulation,
                DrawType::featherAtlasBlit,
                DrawType::imageRect,
                DrawType::imageMesh,
                DrawType::renderPassInitialize,
                DrawType::renderPassResolve,
            };
            return make_span(types);
        }
        case InterlockMode::clockwiseAtomic:
        {
            static constexpr DrawType types[] = {
                DrawType::midpointFanPatches,
                DrawType::midpointFanCenterAAPatches,
                DrawType::outerCurvePatches,
                DrawType::interiorTriangulation,
                DrawType::featherAtlasBlit,
                DrawType::imageMesh,
                DrawType::clipReset,
                DrawType::renderPassInitialize,
            };
            return make_span(types);
        }
        case InterlockMode::depthStencil:
        {
            static constexpr DrawType types[] = {
                DrawType::featherAtlasBlit,
                DrawType::imageMesh,
                DrawType::depthStrokes,
                DrawType::stencilMidpointFanBorrowedCoverage,
                DrawType::stencilMidpointFans,
                DrawType::stencilMidpointFanReset,
                DrawType::stencilMidpointFanWinding,
                DrawType::stencilMidpointFanCover,
                DrawType::stencilDynamicMidpointFans,
                DrawType::stencilOuterCubicBorrowedCoverage,
                DrawType::stencilOuterCubics,
                DrawType::stencilOuterCubicReset,
                DrawType::stencilDynamicOuterCubics,
                DrawType::stencilOuterCubicWinding,
                DrawType::stencilOuterCubicCover,
                DrawType::clipReset,
                DrawType::renderPassInitialize,
                DrawType::renderPassResolve,
            };
            return make_span(types);
        }
    }

    assert(false && "Unexpected interlock mode");
    return {};
}

static ShaderMiscFlags get_valid_shader_misc_flags(DrawType drawType,
                                                   InterlockMode mode)
{
    ShaderMiscFlags outFlags = ShaderMiscFlags::none;

    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::interiorTriangulation:
        case DrawType::clipReset:
            // Clockwise modes introduce borrowed coverage and dedicated clip
            // draws for paths.
            if (mode == InterlockMode::clockwise ||
                mode == InterlockMode::clockwiseAtomic)
            {
                if (drawType == DrawType::interiorTriangulation ||
                    mode == InterlockMode::clockwiseAtomic)
                {
                    outFlags |= ShaderMiscFlags::borrowedCoveragePass;
                }

                // midpointFanCenterAAPatches is only used for feathers, and
                // feathers are never clips.
                if (drawType != DrawType::midpointFanCenterAAPatches)
                {
                    outFlags |= ShaderMiscFlags::clipUpdateOnly;
                    if (mode == InterlockMode::clockwiseAtomic)
                    {
                        outFlags |= ShaderMiscFlags::nestedClipUpdateOnly;
                    }
                }
            }
            break;

        case DrawType::renderPassInitialize:
            if (mode == InterlockMode::atomics)
            {
                outFlags |= ShaderMiscFlags::storeColorClear |
                            ShaderMiscFlags::swizzleColorBGRAToRGBA |
                            ShaderMiscFlags::loadColorFromDstTexture;
            }
            break;
        case DrawType::renderPassResolve:
            if (mode == InterlockMode::atomics)
            {
                outFlags |= ShaderMiscFlags::coalescedResolveAndTransfer;
            }
            break;

        case DrawType::featherAtlasBlit:
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::depthStrokes:
        case DrawType::stencilMidpointFanBorrowedCoverage:
        case DrawType::stencilDynamicMidpointFans:
        case DrawType::stencilDynamicOuterCubics:
        case DrawType::stencilMidpointFans:
        case DrawType::stencilMidpointFanReset:
        case DrawType::stencilMidpointFanWinding:
        case DrawType::stencilMidpointFanCover:
        case DrawType::stencilOuterCubicBorrowedCoverage:
        case DrawType::stencilOuterCubics:
        case DrawType::stencilOuterCubicReset:
        case DrawType::stencilOuterCubicWinding:
        case DrawType::stencilOuterCubicCover:
            break;
    }

    switch (mode)
    {
        case InterlockMode::rasterOrdering:
            outFlags |= ShaderMiscFlags::clockwiseFill;
            // FIXME(https://github.com/rive-app/rive/issues/14021): Some
            // backends generate fixedFunctionColorOutput for rasterOrdering
            // mode. Remove once this is resolved.
            outFlags |= ShaderMiscFlags::fixedFunctionColorOutput;
            break;

        case InterlockMode::atomics:
        case InterlockMode::clockwise:
        case InterlockMode::clockwiseAtomic:
            outFlags |= ShaderMiscFlags::fixedFunctionColorOutput;
            break;

        case InterlockMode::depthStencil:
            outFlags |= ShaderMiscFlags::fixedFunctionColorOutput;
            if (drawType != DrawType::renderPassInitialize)
            {
                outFlags |= ShaderMiscFlags::msaaDstRead;
            }
            break;
    }

    return outFlags;
}

// Returns the mask of ShaderMiscFlags that are valid for the given
// InterlockMode.
// This allows us to pack the ShaderMiscFlags into shader keys more densely, by
// only including the relevant bits (since InterlockMode is part of the shader
// key anyway).
constexpr static ShaderMiscFlags shaderMiscFlagKeyMask(InterlockMode mode)
{
    switch (mode)
    {
        case InterlockMode::rasterOrdering:
            // FIXME(https://github.com/rive-app/rive/issues/14021): Some
            // backends generate fixedFunctionColorOutput for rasterOrdering
            // mode. Remove once this is resolved.
            return ShaderMiscFlags::clockwiseFill |
                   ShaderMiscFlags::fixedFunctionColorOutput;

        case InterlockMode::atomics:
            return ShaderMiscFlags::fixedFunctionColorOutput |
                   ShaderMiscFlags::storeColorClear |
                   ShaderMiscFlags::loadColorFromDstTexture |
                   ShaderMiscFlags::swizzleColorBGRAToRGBA |
                   ShaderMiscFlags::coalescedResolveAndTransfer;

        case InterlockMode::clockwise:
            return ShaderMiscFlags::fixedFunctionColorOutput |
                   ShaderMiscFlags::clipUpdateOnly |
                   ShaderMiscFlags::borrowedCoveragePass;

        case InterlockMode::clockwiseAtomic:
            return ShaderMiscFlags::fixedFunctionColorOutput |
                   ShaderMiscFlags::clipUpdateOnly |
                   ShaderMiscFlags::nestedClipUpdateOnly |
                   ShaderMiscFlags::borrowedCoveragePass;

        case InterlockMode::depthStencil:
            return ShaderMiscFlags::fixedFunctionColorOutput |
                   ShaderMiscFlags::msaaDstRead;
    }
    RIVE_UNREACHABLE();
}

constexpr static uint32_t maxShaderMiscFlagKeyMaskBitCount()
{
    uint32_t maxBitCount = 0;
    for (size_t i = 0; i < INTERLOCK_MODE_COUNT; ++i)
    {
        const uint32_t bitCount = math::count_set_bits(
            static_cast<uint32_t>(shaderMiscFlagKeyMask(InterlockMode(i))));
        maxBitCount = std::max(maxBitCount, bitCount);
    }
    return maxBitCount;
}

// ShaderMiscFlagKeyBitCount must be exactly enough for the widest key mask.
static_assert(maxShaderMiscFlagKeyMaskBitCount() == ShaderMiscFlagKeyBitCount);

void ForEachUbershaderPermutation(
    InterlockMode interlockMode,
    const PlatformFeatures& platformFeatures,
    const std::function<bool(DrawType, ShaderFeatures, ShaderMiscFlags)>& func)
{
    // RenderPassInitialize is only needed in these two specific scenarios, and
    // should be skipped otherwise.
    const bool allowRenderPassInitialize =
        (interlockMode == InterlockMode::atomics &&
         platformFeatures.atomicPLSInitNeedsDraw) ||
        (interlockMode == InterlockMode::clockwiseAtomic &&
         platformFeatures
             .clockwiseAtomicBorrowedCoverageBarrierNeedsRenderPassInit) ||
        (interlockMode == InterlockMode::depthStencil &&
         platformFeatures.msaaColorPreserveNeedsDraw);

    for (auto drawType : get_valid_draw_types(interlockMode))
    {
        if (drawType == DrawType::renderPassInitialize &&
            !allowRenderPassInitialize)
        {
            continue;
        }

        // Don't build an ubershader for a DrawType we don't support.
        if (drawTypeHasPipelineDynamicState(drawType) &&
            !platformFeatures.supportsPipelineDynamicState)
        {
            continue;
        }

        const auto allValidMiscFlags =
            get_valid_shader_misc_flags(drawType, interlockMode);

        for (auto curMiscFlags :
             math::iterate_bit_combinations_in_mask(allValidMiscFlags))
        {
            // Filter out any invalid combinations of ShaderMiscFlags
            switch (interlockMode)
            {
                case InterlockMode::atomics:
                    if (enums::is_flag_set(
                            curMiscFlags,
                            ShaderMiscFlags::coalescedResolveAndTransfer))
                    {
                        if (enums::is_flag_set(
                                curMiscFlags,
                                ShaderMiscFlags::fixedFunctionColorOutput))
                        {
                            continue;
                        }
                    }
                    break;

                case InterlockMode::clockwiseAtomic:
                    if (enums::is_flag_set(
                            curMiscFlags,
                            ShaderMiscFlags::borrowedCoveragePass))
                    {
                        // Borrowed coverage clockwiseAtomic passes always set
                        // fixedFunctionColorOutput because they never read (or
                        // even write, for that matter) the color buffer.
                        if (!enums::is_flag_set(
                                curMiscFlags,
                                ShaderMiscFlags::fixedFunctionColorOutput))
                        {
                            continue;
                        }
                        // Borrowed coverage clockwiseAtomic passes never update
                        // clip.
                        if (enums::any_flag_set(
                                curMiscFlags,
                                ShaderMiscFlags::clipUpdateOnly |
                                    ShaderMiscFlags::nestedClipUpdateOnly))
                        {
                            continue;
                        }
                    }
                    break;

                case InterlockMode::depthStencil:
                    // fixedFunctionColorOutput does no dstRead, by definition.
                    if (enums::all_flags_set(
                            curMiscFlags,
                            ShaderMiscFlags::msaaDstRead |
                                ShaderMiscFlags::fixedFunctionColorOutput))
                    {
                        continue;
                    }
                    break;

                case InterlockMode::rasterOrdering:
                case InterlockMode::clockwise:
                    break;
            }

            // Get the minimal set of ubershader features (with no optional
            // flags)
            const auto minUbershaderFeatures =
                UbershaderFeaturesMaskFor(ShaderFeatures::NONE,
                                          drawType,
                                          interlockMode,
                                          curMiscFlags,
                                          platformFeatures);

            // Now find the ubershader that has *all* flags set
            const auto maxUbershaderFeatures = UbershaderFeaturesMaskFor(
                ShaderFeaturesMaskFor(drawType, interlockMode),
                drawType,
                interlockMode,
                curMiscFlags,
                platformFeatures);

            // Get the flags that still change ubershader behavior
            const ShaderFeatures allOptionalUbershaderFeatures =
                minUbershaderFeatures ^ maxUbershaderFeatures;

            // Now iterate the
            for (auto curOptionalFeatures :
                 math::iterate_bit_combinations_in_mask(
                     allOptionalUbershaderFeatures))
            {
                ShaderFeatures features =
                    curOptionalFeatures | minUbershaderFeatures;

                if (!func(drawType, features, curMiscFlags))
                {
                    // Function returned false to stop iterating.
                    return;
                }
            }
        }
    }
}

// Collapses drawType down to DrawTypeKeyBitCount bits. Many drawTypes share
// a value because they use the same shader. (They only differ in the input
// triangle patch.)
static uint32_t drawTypeKey(DrawType drawType, InterlockMode interlockMode)
{
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::depthStrokes:
            return 0;
        // depthStencil fills have their own, attribute-free vertex
        // shader, so they can't share a key with the patch draws above.
        case DrawType::stencilMidpointFanBorrowedCoverage:
        case DrawType::stencilDynamicMidpointFans:
        case DrawType::stencilDynamicOuterCubics:
        case DrawType::stencilMidpointFans:
        case DrawType::stencilMidpointFanReset:
        case DrawType::stencilMidpointFanWinding:
        case DrawType::stencilMidpointFanCover:
        case DrawType::stencilOuterCubicBorrowedCoverage:
        case DrawType::stencilOuterCubics:
        case DrawType::stencilOuterCubicReset:
        case DrawType::stencilOuterCubicWinding:
        case DrawType::stencilOuterCubicCover:
            assert(interlockMode == InterlockMode::depthStencil);
            return 1;
        case DrawType::interiorTriangulation:
            return 2;
        case DrawType::featherAtlasBlit:
            return 3;
        case DrawType::imageRect:
            return 4;
        case DrawType::imageMesh:
            return 5;
        case DrawType::clipReset:
            assert(interlockMode == InterlockMode::clockwiseAtomic ||
                   interlockMode == InterlockMode::depthStencil);
            return 6;
        case DrawType::renderPassInitialize:
            assert(interlockMode == InterlockMode::atomics ||
                   interlockMode == InterlockMode::depthStencil ||
                   interlockMode == InterlockMode::clockwiseAtomic);
            return 7;
        case DrawType::renderPassResolve:
            assert(interlockMode == InterlockMode::rasterOrdering ||
                   interlockMode == InterlockMode::atomics ||
                   interlockMode == InterlockMode::depthStencil);
            return 8;
    }
    RIVE_UNREACHABLE();
}

// Collapses shaderMiscFlags down to ShaderMiscFlagKeyBitCount bits. Since
// shader keys also pack the interlockMode and drawType, they don't have to pack
// the entire ShaderMiscFlags mask -- only the relevant bits from
// shaderMiscFlagKeyMask().
static uint32_t shaderMiscFlagKey(ShaderMiscFlags shaderMiscFlags,
                                  DrawType drawType,
                                  InterlockMode interlockMode)
{
    const ShaderMiscFlags keyMask = shaderMiscFlagKeyMask(interlockMode);
#ifndef NDEBUG
    // Every valid flag for the drawType must be in keyMask.
    const ShaderMiscFlags validFlagsForDrawType =
        get_valid_shader_misc_flags(drawType, interlockMode);
    assert(enums::no_flags_set(validFlagsForDrawType, ~keyMask));
    // And every flag we were given must be valid for this specific drawType
    // (which also validates they're valid for the interlockMode).
    assert(enums::no_flags_set(shaderMiscFlags, ~validFlagsForDrawType));
    assert(math::count_set_bits(uint32_t(keyMask)) <=
           ShaderMiscFlagKeyBitCount);
#endif
    return math::compact_bitmask_value(uint32_t(shaderMiscFlags),
                                       uint32_t(keyMask));
}

uint32_t ShaderUniqueKey(DrawType drawType,
                         ShaderFeatures shaderFeatures,
                         InterlockMode interlockMode,
                         ShaderMiscFlags shaderMiscFlags)
{
    if (enums::is_flag_set(shaderMiscFlags,
                           ShaderMiscFlags::coalescedResolveAndTransfer))
    {
        assert(drawType == DrawType::renderPassResolve);
        assert(enums::is_flag_set(shaderFeatures,
                                  ShaderFeatures::ENABLE_ADVANCED_BLEND));
        assert(interlockMode == InterlockMode::atomics);
    }
    if (enums::any_flag_set(shaderMiscFlags,
                            ShaderMiscFlags::storeColorClear |
                                ShaderMiscFlags::swizzleColorBGRAToRGBA))
    {
        assert(drawType == DrawType::renderPassInitialize);
        assert(interlockMode == InterlockMode::atomics);
    }
    uint32_t key = shaderMiscFlagKey(shaderMiscFlags, drawType, interlockMode);
    assert(static_cast<uint32_t>(interlockMode) < 1 << InterlockModeBitCount);
    key = (key << InterlockModeBitCount) | static_cast<uint32_t>(interlockMode);
    key = (key << ShaderFeatureCount) |
          uint32_t(shaderFeatures &
                   ShaderFeaturesMaskFor(drawType, interlockMode));
    key = (key << DrawTypeKeyBitCount) | drawTypeKey(drawType, interlockMode);
    return key;
}

const char* GetShaderFeatureGLSLName(ShaderFeatures feature)
{
    switch (feature)
    {
        case ShaderFeatures::NONE:
            RIVE_UNREACHABLE();
        case ShaderFeatures::ENABLE_CLIPPING:
            return GLSL_ENABLE_CLIPPING;
        case ShaderFeatures::ENABLE_CLIP_RECT:
            return GLSL_ENABLE_CLIP_RECT;
        case ShaderFeatures::ENABLE_ADVANCED_BLEND:
            return GLSL_ENABLE_ADVANCED_BLEND;
        case ShaderFeatures::ENABLE_FEATHER:
            return GLSL_ENABLE_FEATHER;
        case ShaderFeatures::ENABLE_EVEN_ODD:
            return GLSL_ENABLE_EVEN_ODD;
        case ShaderFeatures::ENABLE_NESTED_CLIPPING:
            return GLSL_ENABLE_NESTED_CLIPPING;
        case ShaderFeatures::ENABLE_HSL_BLEND_MODES:
            return GLSL_ENABLE_HSL_BLEND_MODES;
        case ShaderFeatures::ENABLE_DITHER:
            return GLSL_ENABLE_DITHER;
        case ShaderFeatures::ENABLE_MODULATED_IMAGE:
            return GLSL_ENABLE_MODULATED_IMAGE;
    }
    RIVE_UNREACHABLE();
}

constexpr static float pack_params(int32_t patchSegmentSpan, int32_t vertexType)
{
    return static_cast<float>((patchSegmentSpan << 2) | vertexType);
}

static void generate_buffer_data_for_patch_type(PatchType patchType,
                                                PatchVertex vertices[],
                                                uint16_t indices[],
                                                uint16_t baseVertex)
{
    // AA border vertices. "Inner tessellation curves" have one more segment
    // without a fan triangle whose purpose is to be a bowtie join.
    size_t vertexCount = 0;
    int32_t patchSegmentSpan = patchType == PatchType::outerCurves
                                   ? OuterCubicPatchSegmentSpanPlusBowtie
                                   : kMidpointFanPatchSegmentSpan;
    for (int i = 0; i < patchSegmentSpan; ++i)
    {
        float params = pack_params(patchSegmentSpan, STROKE_VERTEX);
        float l = static_cast<float>(i);
        float r = l + 1;
        if (patchType == PatchType::outerCurves)
        {
            vertices[vertexCount + 0].set(l, 0.f, .5f, params);
            vertices[vertexCount + 1].set(l, 1.f, .0f, params);
            vertices[vertexCount + 2].set(r, 0.f, .5f, params);
            vertices[vertexCount + 3].set(r, 1.f, .0f, params);

            // Give the vertex an alternate position when mirrored so the border
            // has the same diagonals whether mirrored or not.
            vertices[vertexCount + 0].setMirroredPosition(r, 0.f, .5f);
            vertices[vertexCount + 1].setMirroredPosition(l, 0.f, .5f);
            vertices[vertexCount + 2].setMirroredPosition(r, 1.f, .0f);
            vertices[vertexCount + 3].setMirroredPosition(l, 1.f, .0f);
        }
        else if (patchType == PatchType::midpointFanCenterAA)
        {
            vertices[vertexCount + 0].set(l, 0.f, .5f, params);
            vertices[vertexCount + 1].set(l, 1.f, .0f, params);
            vertices[vertexCount + 2].set(r, 0.f, .5f, params);
            vertices[vertexCount + 3].set(r, 1.f, .0f, params);

            // Give the vertex an alternate position when mirrored so the border
            // has the same diagonals whether mirrored or not.
            vertices[vertexCount + 0].setMirroredPosition(r - 1.f, 0.f, .5f);
            vertices[vertexCount + 1].setMirroredPosition(l - 1.f, 0.f, .5f);
            vertices[vertexCount + 2].setMirroredPosition(r - 1.f, 1.f, .0f);
            vertices[vertexCount + 3].setMirroredPosition(l - 1.f, 1.f, .0f);
        }
        else
        {
            assert(patchType == PatchType::midpointFan);
            vertices[vertexCount + 0].set(l, -1.f, 1.f, params);
            vertices[vertexCount + 1].set(l, +1.f, 0.f, params);
            vertices[vertexCount + 2].set(r, -1.f, 1.f, params);
            vertices[vertexCount + 3].set(r, +1.f, 0.f, params);

            // Give the vertex an alternate position when mirrored so the border
            // has the same diagonals whether morrored or not.
            vertices[vertexCount + 0].setMirroredPosition(r - 1.f, -1.f, 1.f);
            vertices[vertexCount + 1].setMirroredPosition(l - 1.f, -1.f, 1.f);
            vertices[vertexCount + 2].setMirroredPosition(r - 1.f, +1.f, 0.f);
            vertices[vertexCount + 3].setMirroredPosition(l - 1.f, +1.f, 0.f);
        }
        vertexCount += 4;
    }

    // Bottom (negative coverage) side of the AA border.
    for (int i = 0; i < patchSegmentSpan; ++i)
    {
        float params = pack_params(patchSegmentSpan, STROKE_VERTEX);
        float l = static_cast<float>(i);
        float r = l + 1;
        if (patchType == PatchType::outerCurves)
        {
            vertices[vertexCount + 0].set(l, -0.f, .5f, params);
            vertices[vertexCount + 1].set(r, -0.f, .5f, params);
            vertices[vertexCount + 2].set(l, -1.f, .0f, params);
            vertices[vertexCount + 3].set(r, -1.f, .0f, params);

            // Give the vertex an alternate position when mirrored so the border
            // has the same diagonals whether mirrored or not.
            vertices[vertexCount + 0].setMirroredPosition(r, -0.f, .5f);
            vertices[vertexCount + 1].setMirroredPosition(r, -1.f, .0f);
            vertices[vertexCount + 2].setMirroredPosition(l, -0.f, .5f);
            vertices[vertexCount + 3].setMirroredPosition(l, -1.f, .0f);
            vertexCount += 4;
        }
        else if (patchType == PatchType::midpointFanCenterAA)
        {
            vertices[vertexCount + 0].set(l, -0.f, .5f, params);
            vertices[vertexCount + 1].set(r, -0.f, .5f, params);
            vertices[vertexCount + 2].set(l, -1.f, .0f, params);
            vertices[vertexCount + 3].set(r, -1.f, .0f, params);

            // Give the vertex an alternate position when mirrored so the border
            // has the same diagonals whether mirrored or not.
            vertices[vertexCount + 0].setMirroredPosition(r - 1.f, -0.f, .5f);
            vertices[vertexCount + 1].setMirroredPosition(r - 1.f, -1.f, .0f);
            vertices[vertexCount + 2].setMirroredPosition(l - 1.f, -0.f, .5f);
            vertices[vertexCount + 3].setMirroredPosition(l - 1.f, -1.f, .0f);
            vertexCount += 4;
        }
    }

    // Triangle fan vertices. (These only touch the first "fanSegmentSpan"
    // segments on inner tessellation curves.
    size_t fanVerticesIdx = vertexCount;
    size_t fanSegmentSpan = patchType == PatchType::outerCurves
                                ? patchSegmentSpan - 1
                                : patchSegmentSpan;
    // The fan must be a power of two.
    assert((fanSegmentSpan & (fanSegmentSpan - 1)) == 0);
    for (int i = 0; i <= fanSegmentSpan; ++i)
    {
        float params = pack_params(patchSegmentSpan, FAN_VERTEX);
        if (patchType == PatchType::outerCurves)
        {
            vertices[vertexCount].set(static_cast<float>(i), 0.f, 1, params);
        }
        else if (patchType == PatchType::midpointFanCenterAA)
        {
            vertices[vertexCount].set(static_cast<float>(i), 0, 1, params);
            vertices[vertexCount].setMirroredPosition(static_cast<float>(i) - 1,
                                                      0,
                                                      1);
        }
        else
        {
            vertices[vertexCount].set(static_cast<float>(i), -1.f, 1, params);
            vertices[vertexCount].setMirroredPosition(static_cast<float>(i) - 1,
                                                      -1.f,
                                                      1);
        }
        ++vertexCount;
    }

    // The midpoint vertex isn't included in outer cubic patches.
    size_t midpointIdx = vertexCount;
    if (patchType != PatchType::outerCurves)
    {
        vertices[vertexCount++]
            .set(0, 0, 1, pack_params(patchSegmentSpan, FAN_MIDPOINT_VERTEX));
    }
    if (patchType == PatchType::outerCurves)
        assert(vertexCount == kOuterCurvePatchVertexCount);
    else if (patchType == PatchType::midpointFanCenterAA)
        assert(vertexCount == kMidpointFanCenterAAPatchVertexCount);
    else
        assert(vertexCount == kMidpointFanPatchVertexCount);

    // AA border indices.
    constexpr static size_t kBorderPatternVertexCount = 4;
    constexpr static size_t kBorderPatternIndexCount = 6;
    constexpr static uint16_t kBorderPattern[kBorderPatternIndexCount] =
        {0, 1, 2, 2, 1, 3};
    constexpr static uint16_t kNegativeBorderPattern[kBorderPatternIndexCount] =
        {0, 2, 1, 1, 2, 3};

    size_t indexCount = 0;
    size_t borderEdgeVerticesIdx = 0;
    for (size_t borderSegmentIdx = 0; borderSegmentIdx < patchSegmentSpan;
         ++borderSegmentIdx)
    {
        for (size_t i = 0; i < kBorderPatternIndexCount; ++i)
        {
            indices[indexCount++] =
                baseVertex + borderEdgeVerticesIdx + kBorderPattern[i];
        }
        borderEdgeVerticesIdx += kBorderPatternVertexCount;
    }

    // Bottom (negative coverage) side of the AA border.
    if (patchType == PatchType::midpointFan)
    {
        assert(indexCount == kMidpointFanPatchBorderIndexCount);
    }
    else
    {
        for (size_t borderSegmentIdx = 0; borderSegmentIdx < patchSegmentSpan;
             ++borderSegmentIdx)
        {
            for (size_t i = 0; i < kBorderPatternIndexCount; ++i)
            {
                indices[indexCount++] = baseVertex + borderEdgeVerticesIdx +
                                        kNegativeBorderPattern[i];
            }
            borderEdgeVerticesIdx += kBorderPatternVertexCount;
        }
        if (patchType == PatchType::midpointFanCenterAA)
            assert(indexCount == kMidpointFanCenterAAPatchBorderIndexCount);
        else
            assert(indexCount == kOuterCurvePatchBorderIndexCount);
    }

    assert(borderEdgeVerticesIdx == fanVerticesIdx);

    // Triangle fan indices, in a middle-out topology.
    // Don't include the final bowtie join if this is an "outerStroke" patch.
    // (i.e., use fanSegmentSpan and not "patchSegmentSpan".)
    for (int step = 1; step < fanSegmentSpan; step <<= 1)
    {
        for (int i = 0; i < fanSegmentSpan; i += step * 2)
        {
            indices[indexCount++] = fanVerticesIdx + i + baseVertex;
            indices[indexCount++] = fanVerticesIdx + i + step + baseVertex;
            indices[indexCount++] = fanVerticesIdx + i + step * 2 + baseVertex;
        }
    }
    if (patchType == PatchType::midpointFan ||
        patchType == PatchType::midpointFanCenterAA)
    {
        // Triangle to the contour midpoint.
        indices[indexCount++] = fanVerticesIdx + baseVertex;
        indices[indexCount++] = fanVerticesIdx + fanSegmentSpan + baseVertex;
        indices[indexCount++] = midpointIdx + baseVertex;
        if (patchType == PatchType::midpointFan)
            assert(indexCount == kMidpointFanPatchIndexCount);
        else
            assert(indexCount == kMidpointFanCenterAAPatchIndexCount);
    }
    else
    {
        assert(patchType == PatchType::outerCurves);
        assert(indexCount == kOuterCurvePatchIndexCount);
    }
}

// Writes one patch type's depthStencil fill region, at its own base within the
// shared patch index buffer.
static void generateDepthStencilFillIndices(
    PatchType patchType,
    uint16_t indices[kPatchIndexBufferCount])
{
    const bool isOuterCubic = patchType == PatchType::outerCurves;
    assert(isOuterCubic || patchType == PatchType::midpointFan);
    const uint32_t patchCount = dsFillPatchMaxReps(isOuterCubic);
    indices += dsFillBaseIndex(isOuterCubic);
    const uint32_t fanSegmentSpan = isOuterCubic ? OuterCubicPatchSegmentSpan
                                                 : kMidpointFanPatchSegmentSpan;

    // Per-patch vertex IDs are aligned on pow2 strides, specifically so the
    // shader can decode gl_VertexID without divides and mods. (Using integer
    // division costs 10% total framerate on PowerVR and 3% on Adreno.)
    // NOTE: The patches don't actually have pow2 numbers of vertices; the index
    // buffers just never reference those vertex IDs between the end of one
    // patch and the beginning of another.
    const uint32_t patchStrideLog2 = DS_PATCH_STRIDE_LOG2(isOuterCubic);

    size_t indexCount = 0;
    for (uint32_t patch = 0; patch < patchCount; ++patch)
    {
        const uint32_t patchBaseVertex = patch << patchStrideLog2;
        const auto emitPatchVertex = [&](uint32_t patchVertexID) {
            indices[indexCount++] = math::lossless_numeric_cast<uint16_t>(
                patchBaseVertex + patchVertexID);
        };
        // Middle-out fan topology, matching the fan half of
        // generate_buffer_data_for_patch_type().
        for (uint32_t step = 1; step < fanSegmentSpan; step <<= 1)
        {
            for (uint32_t i = 0; i < fanSegmentSpan; i += step * 2)
            {
                emitPatchVertex(i);
                emitPatchVertex(i + step);
                emitPatchVertex(i + step * 2);
            }
        }
        if (!isOuterCubic)
        {
            // Triangle to the contour midpoint.
            emitPatchVertex(0);
            emitPatchVertex(fanSegmentSpan);
            emitPatchVertex(DS_MIDPOINT_VERTEX_ID);
        }
        else
        {
            // outerCubics tessellate a bowtie vertex at the end of each patch,
            // but it is completely unused by depthStencil fills, so just don't
            // reference it in the index buffer.
        }
    }

    assert(indexCount == patchCount * (isOuterCubic
                                           ? DSOuterCubicFillPatchIndexCount
                                           : DSMidpointFanFillPatchIndexCount));
}

void GeneratePatchBufferData(PatchVertex vertices[kPatchVertexBufferCount],
                             uint16_t indices[kPatchIndexBufferCount])
{
    generate_buffer_data_for_patch_type(PatchType::midpointFan,
                                        vertices,
                                        indices,
                                        0);
    generate_buffer_data_for_patch_type(PatchType::midpointFanCenterAA,
                                        vertices + kMidpointFanPatchVertexCount,
                                        indices + kMidpointFanPatchIndexCount,
                                        kMidpointFanPatchVertexCount);
    generate_buffer_data_for_patch_type(
        PatchType::outerCurves,
        vertices + kMidpointFanPatchVertexCount +
            kMidpointFanCenterAAPatchVertexCount,
        indices + kMidpointFanPatchIndexCount +
            kMidpointFanCenterAAPatchIndexCount,
        kMidpointFanPatchVertexCount + kMidpointFanCenterAAPatchVertexCount);

    for (auto patchType : {PatchType::midpointFan, PatchType::outerCurves})
    {
        generateDepthStencilFillIndices(patchType, indices);
    }
}

void ClipRectInverseMatrix::reset(const Mat2D& clipMatrix, const AABB& clipRect)
{
    // Find the matrix that transforms from pixel space to "normalized clipRect
    // space", where the clipRect is the normalized rectangle: [-1, -1, +1, +1].
    Mat2D m = clipMatrix * Mat2D(clipRect.width() * .5f,
                                 0,
                                 0,
                                 clipRect.height() * .5f,
                                 clipRect.center().x,
                                 clipRect.center().y);
    if (clipRect.width() <= 0 || clipRect.height() <= 0 ||
        !m.invert(&m_inverseMatrix))
    {
        // If the width or height went zero or negative, or if "m" is
        // non-invertible, clip away everything.
        *this = Empty();
    }
}

static uint32_t paint_type_to_glsl_id(PaintType paintType)
{
    return static_cast<uint32_t>(paintType);
    static_assert((int)PaintType::clipUpdate == CLIP_UPDATE_PAINT_TYPE);
    static_assert((int)PaintType::solidColor == SOLID_COLOR_PAINT_TYPE);
    static_assert((int)PaintType::linearGradient == LINEAR_GRADIENT_PAINT_TYPE);
    static_assert((int)PaintType::radialGradient == RADIAL_GRADIENT_PAINT_TYPE);
}

uint32_t ConvertBlendModeToPLSBlendMode(BlendMode riveMode)
{
    switch (riveMode)
    {
        case BlendMode::srcOver:
            return BLEND_SRC_OVER;
        case BlendMode::additive:
            // RiveRenderPaint::blendMode() and RiveRenderer::drawImage() both
            // fold additive into srcOver, so it should never reach here. The
            // case exists to keep the switch exhaustive over BlendMode.
            assert(!"additive should have been resolved to srcOver");
            return BLEND_SRC_OVER;
        case BlendMode::screen:
            return BLEND_MODE_SCREEN;
        case BlendMode::overlay:
            return BLEND_MODE_OVERLAY;
        case BlendMode::darken:
            return BLEND_MODE_DARKEN;
        case BlendMode::lighten:
            return BLEND_MODE_LIGHTEN;
        case BlendMode::colorDodge:
            return BLEND_MODE_COLORDODGE;
        case BlendMode::colorBurn:
            return BLEND_MODE_COLORBURN;
        case BlendMode::hardLight:
            return BLEND_MODE_HARDLIGHT;
        case BlendMode::softLight:
            return BLEND_MODE_SOFTLIGHT;
        case BlendMode::difference:
            return BLEND_MODE_DIFFERENCE;
        case BlendMode::exclusion:
            return BLEND_MODE_EXCLUSION;
        case BlendMode::multiply:
            return BLEND_MODE_MULTIPLY;
        case BlendMode::hue:
            return BLEND_MODE_HUE;
        case BlendMode::saturation:
            return BLEND_MODE_SATURATION;
        case BlendMode::color:
            return BLEND_MODE_COLOR;
        case BlendMode::luminosity:
            return BLEND_MODE_LUMINOSITY;
    }
    RIVE_UNREACHABLE();
}

uint32_t SwizzleRiveColorToRGBAPremul(ColorInt riveColor)
{
    uint4 rgba = (rive::uint4(riveColor) >> uint4{16, 8, 0, 24}) & 0xffu;
    uint32_t alpha = rgba.w;
    rgba.w = 255;
    uint4 premul = (rgba * alpha + 127) / 255;
    return simd::reduce_or(premul << uint4{0, 8, 16, 24});
}

// Swizzles the byte order of ColorInt to little-endian RGBA, premultiplies
// rgb by alpha, and scales only the A channel by
// complementAdditiveness (1.0 - additiveness)
static uint32_t swizzleRiveColorToRGBAPremulAdditive(
    ColorInt riveColor,
    float complementAdditiveness)
{
    uint4 rgba = (rive::uint4(riveColor) >> uint4{16, 8, 0, 24}) & 0xffu;
    uint32_t alpha = rgba.w;
    uint4 premul = (rgba * alpha + 127) / 255;
    premul.w = static_cast<uint32_t>(
        static_cast<float>(alpha) * complementAdditiveness + .5f);
    return simd::reduce_or(premul << uint4{0, 8, 16, 24});
}

FlushUniforms::InverseViewports::InverseViewports(
    const FlushDescriptor& flushDesc,
    const PlatformFeatures& platformFeatures)
{
    float4 numerators = 2;
    // When rendering to the gradient and tessellation textures, ensure that
    // row 0 in input coordinates gets written to row 0 in texture memory.
    // This requires a Y inversion if clip space and framebuffer space have
    // opposing senses of which way is up.
    if (platformFeatures.clipSpaceBottomUp !=
        platformFeatures.framebufferBottomUp)
    {
        numerators.xy = -numerators.xy;
    }
    // When drawing to a render target, ensure that Y=0 (in Rive pixel space)
    // lands on the row the target keeps its visual top in. Clip space and the
    // framebuffer each contribute a possible inversion, and so does a target
    // that stores its bottom in row 0.
    if ((platformFeatures.clipSpaceBottomUp !=
         platformFeatures.framebufferBottomUp) !=
        flushDesc.renderTarget->bottomUp(platformFeatures))
    {
        numerators.w = -numerators.w;
    }
    float4 vals = numerators /
                  float4{static_cast<float>(flushDesc.gradDataHeight),
                         static_cast<float>(flushDesc.tessDataHeight),
                         static_cast<float>(flushDesc.renderTarget->width()),
                         static_cast<float>(flushDesc.renderTarget->height())};
    m_vals[0] = vals[0];
    m_vals[1] = vals[1];
    m_vals[2] = vals[2];
    m_vals[3] = vals[3];
}

FlushUniforms::FlushUniforms(const FlushDescriptor& flushDesc,
                             const PlatformFeatures& platformFeatures) :
    m_inverseViewports(flushDesc, platformFeatures),
    m_renderTargetWidth(flushDesc.renderTarget->width()),
    m_renderTargetHeight(flushDesc.renderTarget->height()),
    m_colorClearValue(SwizzleRiveColorToRGBAPremul(flushDesc.colorClearValue)),
    m_coverageClearValue(flushDesc.coverageClearValue),
    m_renderTargetUpdateBounds(flushDesc.renderTargetUpdateBounds),
    m_featherAtlasTextureInverseSize(1.f / flushDesc.featherAtlasTextureWidth,
                                     1.f / flushDesc.featherAtlasTextureHeight),
    m_featherAtlasContentInverseViewport(
        2.f / flushDesc.featherAtlasContentWidth,
        (platformFeatures.clipSpaceBottomUp !=
                 platformFeatures.framebufferBottomUp
             ? -2.f
             : 2.f) /
            flushDesc.featherAtlasContentHeight),
    m_coverageBufferPrefix(flushDesc.coverageBufferPrefix),
    m_epsilonForPseudoMemoryBarrier(1e-9f),
    m_pathIDGranularity(platformFeatures.pathIDGranularity),
    m_vertexDiscardValue(std::numeric_limits<float>::quiet_NaN()),
    m_mipMapLODBias(MIP_MAP_LOD_BIAS),
    m_maxPathId(flushDesc.pathCount),
    m_ditherScale((flushDesc.ditherMode == DitherMode::none) ? 0.0f
                                                             : (1.0f / 256.0f)),
    m_ditherBias(m_ditherScale * -0.5f),
    // Negate dither when storing to RGB10, in order to get some more variation.
    m_ditherConversionToRGB10((flushDesc.ditherMode == DitherMode::none)
                                  ? 0.0f
                                  : (-1.0f / 1024.0f) / m_ditherScale),
    m_wireframeEnabled(flushDesc.wireframe),
    m_renderTargetBottomUp(flushDesc.renderTarget->bottomUp(platformFeatures)),
    m_gradTextureYScale(1.f / flushDesc.gradTextureHeight),
    // Use a bias of -0.5 here as we encode the row+1 so we can negate it
    // robustly
    m_gradTextureYBias(-0.5f / flushDesc.gradTextureHeight)
{}

static void write_matrix(volatile float* dst, const Mat2D& matrix)
{
    const float* vals = matrix.values();
    for (size_t i = 0; i < 6; ++i)
    {
        dst[i] = vals[i];
    }
}

// Writes just the 2x2 (scale & skew) part of a Mat2D.
static void write2x2(volatile float* dst, const Mat2D& matrix)
{
    const float* vals = matrix.values();
    for (size_t i = 0; i < 4; ++i)
    {
        dst[i] = vals[i];
    }
}

// Writes just the translation part of a Mat2D.
static void writeTranslate(volatile float* dst, const Mat2D& matrix)
{
    const float* vals = matrix.values();
    dst[0] = vals[4];
    dst[1] = vals[5];
}

void PathData::set(const Mat2D& m,
                   float strokeRadius,
                   float featherRadius,
                   uint32_t zIndex,
                   const AtlasTransform& featherAtlasTransform,
                   const CoverageBufferRange& coverageBufferRange)
{
    write_matrix(m_matrix, m);
    m_strokeRadius = strokeRadius; // 0 if the path is filled.
    m_zIndex = zIndex;
    m_featherRadius = featherRadius;
    m_featherAtlasTransform.scaleFactor = featherAtlasTransform.scaleFactor;
    m_featherAtlasTransform.translateX = featherAtlasTransform.translateX;
    m_featherAtlasTransform.translateY = featherAtlasTransform.translateY;
    m_coverageBufferRange.offset = coverageBufferRange.offset;
    m_coverageBufferRange.pitch = coverageBufferRange.pitch;
    m_coverageBufferRange.offsetX = coverageBufferRange.offsetX;
    m_coverageBufferRange.offsetY = coverageBufferRange.offsetY;
}

// Returns integral row number
uint32_t getGradientRow(ColorRampLocation rampLocation,
                        GradTextureLayout gradTextureLayout)
{
    uint32_t row = rampLocation.row;
    if (rampLocation.isComplex())
    {
        // Complex gradients rows are offset after the simple gradients.
        row += gradTextureLayout.complexOffsetY;
    }

    return row;
}

// Returns Normalized value for row in the texture
float getGradientY(ColorRampLocation rampLocation,
                   GradTextureLayout gradTextureLayout)
{
    uint32_t row = getGradientRow(rampLocation, gradTextureLayout);
    return (static_cast<float>(row) + .5f) * gradTextureLayout.inverseHeight;
}

void PaintData::set(DrawContents singleDrawContents,
                    PaintType paintType,
                    SimplePaintValue simplePaintValue,
                    GradTextureLayout gradTextureLayout,
                    uint32_t clipID,
                    bool hasClipRect,
                    bool hasImage,
                    BlendMode blendMode,
                    bool solidUnmultiplied,
                    float additiveness,
                    bool isLayerMask,
                    LayerMaskMode layerMaskMode)
{
    uint32_t shiftedClipID = clipID << 16;
    uint32_t shiftedBlendMode = ConvertBlendModeToPLSBlendMode(blendMode) << 4;
    uint32_t localParams = paint_type_to_glsl_id(paintType);

    assert(additiveness >= 0.f && additiveness <= 1.f); // Draw clamps it.
    // GPU wants 1.0 - additiveness as this is used to scale the final alpha
    // Input of 0.0 leads to GPU using 1.0 which is no scale.
    // Input of 1.0 leads to GPU using 0.0 which is full scale
    float complementAdditiveness =
        blendMode != BlendMode::srcOver ? 1.f : 1.f - additiveness;
    switch (paintType)
    {
        case PaintType::solidColor:
        {
            // Swizzle the riveColor to little-endian RGBA (the order expected
            // by GLSL).
            // Advanced-blend draws take unmultiplied color and ignore
            // additiveness. srcOver draws are premultiplied with additiveness
            // baked into alpha. The KHR fixed-function blend path is
            // premultiplied with no additiveness.
            m_color = solidUnmultiplied
                          ? SwizzleRiveColorToRGBA(simplePaintValue.color)
                          : swizzleRiveColorToRGBAPremulAdditive(
                                simplePaintValue.color,
                                complementAdditiveness);
            localParams |= shiftedClipID | shiftedBlendMode;
            break;
        }
        case PaintType::linearGradient:
        case PaintType::radialGradient:
        {
            // Pack the gradient texture row in the integer part and
            // Additiveness in range 0/256 to 255/256, in the fraction.
            // The row is biased +1 so we can always negate a non zero value
            uint32_t gradTextureRow =
                getGradientRow(simplePaintValue.colorRampLocation,
                               gradTextureLayout);
            assert(gradTextureRow <= 0xffffu);
            m_gradTextureRowAndAdditiveness =
                static_cast<float>(gradTextureRow + 1) +
                static_cast<float>(static_cast<uint32_t>(
                    complementAdditiveness * 255.f + .5f)) *
                    (1.f / 256.f);
            localParams |= shiftedClipID | shiftedBlendMode;
            break;
        }
        case PaintType::clipUpdate:
        {
            m_shiftedClipReplacementID = shiftedClipID;
            localParams |= simplePaintValue.outerClipID << 16;
            break;
        }
    }
    if (enums::is_flag_set(singleDrawContents, DrawContents::nonZeroFill))
    {
        localParams |= PAINT_FLAG_NON_ZERO_FILL;
    }
    else if (enums::is_flag_set(singleDrawContents, DrawContents::evenOddFill))
    {
        localParams |= PAINT_FLAG_EVEN_ODD_FILL;
    }
    if (hasClipRect)
    {
        localParams |= PAINT_FLAG_HAS_CLIP_RECT;
    }
    if (hasImage)
    {
        localParams |= PAINT_FLAG_HAS_IMAGE;
    }
    if (isLayerMask)
    {
        localParams |= PAINT_FLAG_LAYER_MASK;
        // Masked so an unknown mode can't spill into the clipID bits above.
        localParams |= (static_cast<uint32_t>(layerMaskMode)
                        << PAINT_LAYER_MASK_MODE_SHIFT) &
                       PAINT_LAYER_MASK_MODE_MASK;
    }
    m_params = localParams;
}

void getGradientMatrixAndSpan(const Gradient* gradient,
                              ColorRampLocation rampLocation,
                              const Mat2D& viewMatrix,
                              const RenderTarget* renderTarget,
                              const PlatformFeatures& platformFeatures,
                              Mat2D& paintMatrixOut,
                              float (&gradTextureHorizontalSpanOut)[2])
{
    assert(gradient != nullptr);
    const float* gradCoeffs = gradient->coeffs();

    // TODO: This inverse actually failed in the fuzz tests because the view
    // scale was all 0s - we could probably detect that case and just skip
    // drawing (at a higher level than here) if the scale is 0. Either way,
    // this would end up as a degenerate draw and it doesn't matter that it
    // failed.
    paintMatrixOut = viewMatrix.invertOrIdentity();

    if (renderTarget->bottomUp(platformFeatures))
    {
        // Flip _fragCoord.y.
        paintMatrixOut *= Mat2D(1, 0, 0, -1, 0, renderTarget->height());
    }

    if (gradient->paintType() == PaintType::linearGradient)
    {
        paintMatrixOut =
            Mat2D(gradCoeffs[0], 0, gradCoeffs[1], 0, gradCoeffs[2], 0) *
            paintMatrixOut;
    }
    else
    {
        assert(gradient->paintType() == PaintType::radialGradient);
        float w = 1 / gradCoeffs[2];
        paintMatrixOut =
            Mat2D(w, 0, 0, w, -gradCoeffs[0] * w, -gradCoeffs[1] * w) *
            paintMatrixOut;
    }

    float left, right;
    if (rampLocation.isComplex())
    {
        left = 0;
        right = kGradTextureWidth;
    }
    else
    {
        left = rampLocation.col;
        right = left + 2;
    }

    // TODO: This could be simplified (both here and in the shader) - the shader
    // only uses value [0] to check whether or not it's a full span (i.e.
    // complex) - which could be done just as effectively with a single value
    // ("-1" for complex, positive left coordinate for simple gradients).
    gradTextureHorizontalSpanOut[0] =
        (right - left - 1) * GRAD_TEXTURE_INVERSE_WIDTH;
    gradTextureHorizontalSpanOut[1] = (left + .5f) * GRAD_TEXTURE_INVERSE_WIDTH;
}

void PaintAuxData::set(const Mat2D& viewMatrix,
                       const Mat2D& imageMatrix,
                       PaintType paintType,
                       SimplePaintValue simplePaintValue,
                       const Gradient* gradient,
                       const Texture* imageTexture,
                       const ClipRectInverseMatrix* clipRectInverseMatrix,
                       const RenderTarget* renderTarget,
                       const PlatformFeatures& platformFeatures)
{
    switch (paintType)
    {
        case PaintType::linearGradient:
        case PaintType::radialGradient:
        {
            assert(gradient != nullptr);
            Mat2D paintMatrix;
            viewMatrix.invert(&paintMatrix);

            float gradTextureHorizontalSpan[2];
            getGradientMatrixAndSpan(gradient,
                                     simplePaintValue.colorRampLocation,
                                     viewMatrix,
                                     renderTarget,
                                     platformFeatures,
                                     paintMatrix,
                                     gradTextureHorizontalSpan);
            m_gradTextureHorizontalSpan[0] = gradTextureHorizontalSpan[0];
            m_gradTextureHorizontalSpan[1] = gradTextureHorizontalSpan[1];
            write_matrix(m_paintMatrix, paintMatrix);
        }

            [[fallthrough]];

        case PaintType::solidColor:
        {
            if (imageTexture != nullptr)
            {
                Mat2D matrix;
                imageMatrix.invert(&matrix);
                if (renderTarget->bottomUp(platformFeatures))
                {
                    // Flip _fragCoord.y.
                    matrix *= Mat2D(1, 0, 0, -1, 0, renderTarget->height());
                }

                // Since we don't use perspective transformations, the image
                // mipmap level-of-detail is constant throughout the entire
                // path. Compute it ahead of time here.
                float dudx = matrix.xx() * imageTexture->width();
                float dudy = matrix.yx() * imageTexture->height();
                float dvdx = matrix.xy() * imageTexture->width();
                float dvdy = matrix.yy() * imageTexture->height();
                float maxScaleFactorPow2 = std::max(dudx * dudx + dvdx * dvdx,
                                                    dudy * dudy + dvdy * dvdy);
                // Instead of finding sqrt(maxScaleFactorPow2), just
                // multiply the log by .5.
                m_imageTextureLOD =
                    (log2f(std::max(maxScaleFactorPow2, 1.f)) * .5f) +
                    MIP_MAP_LOD_BIAS;

                write_matrix(m_imageMatrix, matrix);
            }

            break;
        }
        case PaintType::clipUpdate:
        {
            break;
        }
    }

    if (clipRectInverseMatrix != nullptr)
    {
        Mat2D m = clipRectInverseMatrix->inverseMatrix();
        if (renderTarget->bottomUp(platformFeatures))
        {
            // Flip _fragCoord.y.
            m = m * Mat2D(1, 0, 0, -1, 0, renderTarget->height());
        }
        write_matrix(m_clipRectInverseMatrix, m);
        m_inverseFwidth.x = -1.f / (fabsf(m.xx()) + fabsf(m.xy()));
        m_inverseFwidth.y = -1.f / (fabsf(m.yx()) + fabsf(m.yy()));
    }
    else
    {
        write_matrix(m_clipRectInverseMatrix,
                     ClipRectInverseMatrix::WideOpen().inverseMatrix());
        m_inverseFwidth.x = 0;
        m_inverseFwidth.y = 0;
    }
}

#define STATIC_ASSERT_ATTRIB(Class, member, attribIdx)                         \
    static_assert(                                                             \
        offsetof(Class, member) ==                                             \
        Class##Attributes[attribIdx - IMAGE_FIRST_ATTRIB_IDX].byteOffset)

ImageDrawInstanceBase::ImageDrawInstanceBase(
    const Mat2D& matrix,
    ColorInt color,
    const ClipRectInverseMatrix* clipRectInverseMatrix,
    uint32_t clipID,
    BlendMode blendMode,
    uint32_t zIndex,
    float additiveness)
{
    static_assert(FirstAttribIdx == IMAGE_FIRST_ATTRIB_IDX);
    static_assert(LastAttribIdx == IMAGE_COMMON_LAST_ATTRIB_IDX);

    // Check that our attributes start in the right places
    STATIC_ASSERT_ATTRIB(ImageDrawInstanceBase,
                         m_viewMatrix,
                         IMAGE_VIEW_MATRIX_ATTRIB_IDX);
    STATIC_ASSERT_ATTRIB(ImageDrawInstanceBase,
                         m_clipRectInverseMatrix,
                         IMAGE_CLIP_RECT_INVERSE_MATRIX_ATTRIB_IDX);
    STATIC_ASSERT_ATTRIB(ImageDrawInstanceBase,
                         m_translate,
                         IMAGE_TRANSLATES_ATTRIB_IDX);
    STATIC_ASSERT_ATTRIB(ImageDrawInstanceBase,
                         m_modulatedColor,
                         IMAGE_MODULATED_COLOR_ATTRIB_IDX);
    STATIC_ASSERT_ATTRIB(ImageDrawInstanceBase,
                         m_clipID,
                         IMAGE_CLIP_ID_ATTRIB_IDX);
    STATIC_ASSERT_ATTRIB(ImageDrawInstanceBase,
                         m_blendMode,
                         IMAGE_BLEND_MODE_ATTRIB_IDX);
    STATIC_ASSERT_ATTRIB(ImageDrawInstanceBase,
                         m_zIndex,
                         IMAGE_ZINDEX_ATTRIB_IDX);

    // Now check that the packed values are at the correct offsets
    static_assert(offsetof(ImageDrawInstanceBase, m_clipRectInverseTranslate) ==
                  offsetof(ImageDrawInstanceBase, m_translate) +
                      2 * sizeof(float));

    const Mat2D clipRectInverseMatrixToWrite =
        clipRectInverseMatrix != nullptr
            ? clipRectInverseMatrix->inverseMatrix()
            : ClipRectInverseMatrix::WideOpen().inverseMatrix();

    write2x2(m_viewMatrix, matrix);
    write2x2(m_clipRectInverseMatrix, clipRectInverseMatrixToWrite);
    writeTranslate(m_translate, matrix);
    writeTranslate(m_clipRectInverseTranslate, clipRectInverseMatrixToWrite);
    // The shaders multiply the (premultiplied) image color by this modulated
    // color component-wise, so scaling only its alpha implements additiveness
    // for every image draw with no shader changes.
    assert(additiveness >= 0.f && additiveness <= 1.f); // Draw clamps it.
    // GPU wants 1.0 - additiveness as this is used to scale the final alpha
    // Input of 0.0 leads to GPU using 1.0 which is no scale.
    // Input of 1.0 leads to GPU using 0.0 which is full scale
    float complementAdditiveness =
        blendMode != BlendMode::srcOver ? 1.f : 1.f - additiveness;

    m_modulatedColor =
        swizzleRiveColorToRGBAPremulAdditive(color, complementAdditiveness);
    m_clipID = clipID;
    m_blendMode = ConvertBlendModeToPLSBlendMode(blendMode);
    m_zIndex = zIndex;
}

const std::array<VertexAttribute, ImageDrawInstanceBase::AttributeCount>&
ImageDrawInstanceBase::getAttributes()
{
    return ImageDrawInstanceBaseAttributes;
}

ImageRectInstance::ImageRectInstance(
    const Mat2D& matrix,
    ColorInt color,
    const ClipRectInverseMatrix* clipRectInverseMatrix,
    uint32_t clipID,
    BlendMode blendMode,
    uint32_t zIndex,
    const Mat2D& imageMatrix,
    const Mat2D& gradientMatrix,
    uint32_t gradientType,
    const float (&gradTextureHorizontalSpan)[2],
    float gradTextureY,
    float additiveness) :
    m_commons{matrix,
              color,
              clipRectInverseMatrix,
              clipID,
              blendMode,
              zIndex,
              additiveness}
{
    static_assert(offsetof(ImageRectInstance, m_commons) == 0);
    STATIC_ASSERT_ATTRIB(ImageRectInstance,
                         m_imageMatrix,
                         IMAGE_RECT_IMAGE_MATRIX_ATTRIB_IDX);
    STATIC_ASSERT_ATTRIB(ImageRectInstance,
                         m_gradientMatrix,
                         IMAGE_RECT_GRADIENT_MATRIX_ATTRIB_IDX);

    // These next two are packed together so validate the offset matches our
    // attribute data *and* the attributes are packed into the correct memory
    // locations
    STATIC_ASSERT_ATTRIB(ImageRectInstance,
                         m_imageTranslate,
                         IMAGE_RECT_IMAGE_AND_GRADIENT_TRANSLATES_ATTRIB_IDX);
    static_assert(offsetof(ImageRectInstance, m_gradientTranslate) ==
                  offsetof(ImageRectInstance, m_imageTranslate) +
                      2 * sizeof(float));

    // Same with these three values
    STATIC_ASSERT_ATTRIB(ImageRectInstance,
                         m_gradTextureHorizontalSpan,
                         IMAGE_RECT_PACKED_GRADIENT_DATA);
    static_assert(offsetof(ImageRectInstance, m_gradTextureY) ==
                  offsetof(ImageRectInstance, m_gradTextureHorizontalSpan) +
                      2 * sizeof(float));
    static_assert(offsetof(ImageRectInstance, m_gradientType) ==
                  offsetof(ImageRectInstance, m_gradTextureHorizontalSpan) +
                      3 * sizeof(float));

    write2x2(m_imageMatrix, imageMatrix);
    write2x2(m_gradientMatrix, gradientMatrix);
    writeTranslate(m_imageTranslate, imageMatrix);
    writeTranslate(m_gradientTranslate, gradientMatrix);
    m_gradTextureHorizontalSpan[0] = gradTextureHorizontalSpan[0];
    m_gradTextureHorizontalSpan[1] = gradTextureHorizontalSpan[1];
    m_gradTextureY = gradTextureY;
    m_gradientType = float(gradientType);
}

const std::array<VertexAttribute, ImageRectInstance::AttributeCount>&
ImageRectInstance::getAttributes()
{
    return ImageRectInstanceAttributes;
}

ImageMeshInstance::ImageMeshInstance(
    const Mat2D& matrix,
    ColorInt modulatedColor,
    const ClipRectInverseMatrix* clipRectInverseMatrix,
    uint32_t clipID,
    BlendMode blendMode,
    uint32_t zIndex,
    float additiveness,
    Vec2D uvTranslate,
    Vec2D uvScale) :
    m_commons{matrix,
              modulatedColor,
              clipRectInverseMatrix,
              clipID,
              blendMode,
              zIndex,
              additiveness}
{
    static_assert(offsetof(ImageMeshInstance, m_commons) == 0);
    STATIC_ASSERT_ATTRIB(ImageMeshInstance,
                         m_uvTransform,
                         IMAGE_MESH_UV_TRANSFORM_ATTRIB_IDX);

    m_uvTransform[0] = uvTranslate.x;
    m_uvTransform[1] = uvTranslate.y;
    m_uvTransform[2] = uvScale.x;
    m_uvTransform[3] = uvScale.y;
}

const std::array<VertexAttribute, ImageMeshInstance::AttributeCount>&
ImageMeshInstance::getAttributes()
{
    return ImageMeshInstanceAttributes;
}

std::tuple<uint32_t, uint32_t> StorageTextureSize(
    size_t bufferSizeInBytes,
    StorageBufferStructure bufferStructure)
{
    assert(bufferSizeInBytes %
               gpu::StorageBufferElementSizeInBytes(bufferStructure) ==
           0);
    uint32_t elementCount =
        math::lossless_numeric_cast<uint32_t>(bufferSizeInBytes) /
        gpu::StorageBufferElementSizeInBytes(bufferStructure);
    uint32_t height =
        (elementCount + STORAGE_TEXTURE_WIDTH - 1) / STORAGE_TEXTURE_WIDTH;
    // RenderContext is responsible for breaking up a flush before any storage
    // buffer grows larger than can be supported by a GL texture of width
    // "STORAGE_TEXTURE_WIDTH". (2048 is the min required value for
    // GL_MAX_TEXTURE_SIZE.)
    constexpr int kMaxRequredTextureHeight RIVE_MAYBE_UNUSED = 2048;
    assert(height <= kMaxRequredTextureHeight);
    uint32_t width = std::min<uint32_t>(elementCount, STORAGE_TEXTURE_WIDTH);
    return {width, height};
}

size_t StorageTextureBufferSize(size_t bufferSizeInBytes,
                                StorageBufferStructure bufferStructure)
{
    // The polyfill texture needs to be updated in entire rows at a time. Extend
    // the buffer's length to be able to service a worst-case scenario.
    return bufferSizeInBytes +
           (STORAGE_TEXTURE_WIDTH - 1) *
               gpu::StorageBufferElementSizeInBytes(bufferStructure);
}

float find_transformed_area(const AABB& bounds, const Mat2D& matrix)
{
    Vec2D pts[4] = {{bounds.left(), bounds.top()},
                    {bounds.right(), bounds.top()},
                    {bounds.right(), bounds.bottom()},
                    {bounds.left(), bounds.bottom()}};
    Vec2D screenSpacePts[4];
    matrix.mapPoints(screenSpacePts, pts, 4);
    Vec2D v[3] = {screenSpacePts[1] - screenSpacePts[0],
                  screenSpacePts[2] - screenSpacePts[0],
                  screenSpacePts[3] - screenSpacePts[0]};
    return (fabsf(Vec2D::cross(v[0], v[1])) + fabsf(Vec2D::cross(v[1], v[2]))) *
           .5f;
}

DepthState get_depth_state(InterlockMode interlockMode,
                           DrawType drawType,
                           DrawContents drawContents)
{
    if (interlockMode != InterlockMode::depthStencil)
    {
        return {.depthTestEnabled = false, .depthWriteEnabled = false};
    }

    switch (drawType)
    {
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::featherAtlasBlit:
        case DrawType::stencilMidpointFanBorrowedCoverage:
        case DrawType::stencilMidpointFanWinding:
        case DrawType::stencilOuterCubicBorrowedCoverage:
        case DrawType::stencilOuterCubicWinding:
        case DrawType::clipReset:
            return {.depthTestEnabled = true, .depthWriteEnabled = false};
            break;

        case DrawType::depthStrokes:
            return {.depthTestEnabled = true, .depthWriteEnabled = true};
            break;

        case DrawType::stencilDynamicMidpointFans:
        case DrawType::stencilDynamicOuterCubics:
        case DrawType::stencilMidpointFans:
        case DrawType::stencilMidpointFanCover:
        case DrawType::stencilOuterCubics:
        case DrawType::stencilOuterCubicCover:
            return {
                .depthTestEnabled = true,
                .depthWriteEnabled =
                    !enums::is_flag_set(drawContents, DrawContents::clipUpdate),
            };
            break;

        case DrawType::stencilMidpointFanReset:
        case DrawType::stencilOuterCubicReset:
            return {
                .depthTestEnabled = true,
                .depthWriteEnabled = enums::no_flags_set(
                    drawContents,
                    DrawContents::clockwiseFill | DrawContents::clipUpdate),
            };

        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            return {.depthTestEnabled = false, .depthWriteEnabled = false};

        case DrawType::interiorTriangulation:
        case DrawType::outerCurvePatches:
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
            break;
    }

    RIVE_UNREACHABLE();
}

StencilInfo get_stencil_info(InterlockMode interlockMode,
                             DrawType drawType,
                             DrawContents drawContents)
{
    bool areDrawContentsValid = true;
    if (interlockMode != InterlockMode::depthStencil)
    {
        // Only depthStencil has any valid stencil types
        return {StencilType::disabled,
                DrawContents::none,
                areDrawContentsValid};
    }

    switch (drawType)
    {
        case DrawType::depthStrokes:
            // depthStrokes could be a clip, so handle that.
            if (enums::is_flag_set(drawContents, DrawContents::clipUpdate))
            {
                return {
                    StencilType::clipStroke,
                    DrawContents::activeClip | DrawContents::clipUpdate,
                    areDrawContentsValid,
                };
            }

            [[fallthrough]];
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::featherAtlasBlit:
            if (enums::is_flag_set(drawContents, DrawContents::activeClip))
            {
                return {
                    StencilType::activeStencilClip,
                    DrawContents::activeClip,
                    areDrawContentsValid,
                };
            }
            else
            {
                return {
                    StencilType::disabled,
                    DrawContents::none,
                    areDrawContentsValid,
                };
            }

        case DrawType::stencilMidpointFanBorrowedCoverage:
        case DrawType::stencilOuterCubicBorrowedCoverage:
            return {
                StencilType::borrowedCoverage,
                DrawContents::activeClip,
                areDrawContentsValid,
            };

        case DrawType::stencilDynamicMidpointFans:
        case DrawType::stencilDynamicOuterCubics:
        case DrawType::stencilMidpointFans:
        case DrawType::stencilOuterCubics:
            return {
                StencilType::forwardClippedByBackward,
                DrawContents::activeClip | DrawContents::clipUpdate,
                areDrawContentsValid,
            };

        case DrawType::stencilMidpointFanReset:
        case DrawType::stencilOuterCubicReset:
            return {
                StencilType::backwardTriangleCleanup,
                DrawContents::clockwiseFill | DrawContents::activeClip |
                    DrawContents::clipUpdate,
                areDrawContentsValid,
            };

        case DrawType::stencilMidpointFanWinding:
        case DrawType::stencilOuterCubicWinding:
            areDrawContentsValid =
                enums::is_flag_set(drawContents, DrawContents::evenOddFill) ||
                enums::all_flags_set(drawContents, kNestedClipUpdateMask);
            return {
                StencilType::stencilNestedOrEvenOdd,
                DrawContents::activeClip | DrawContents::evenOddFill,
                areDrawContentsValid,
            };

        case DrawType::stencilMidpointFanCover:
        case DrawType::stencilOuterCubicCover:
            areDrawContentsValid =
                enums::is_flag_set(drawContents, DrawContents::evenOddFill);
            return {StencilType::evenOddDrawAndReset,
                    DrawContents::clipUpdate,
                    areDrawContentsValid};

        case DrawType::clipReset:
            return {
                ((drawContents & kNestedClipUpdateMask) ==
                 kNestedClipUpdateMask)
                    ? StencilType::nestedClipReset
                    : StencilType::clipReset,
                DrawContents::clockwiseFill,
                areDrawContentsValid,
            };

        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            return {
                StencilType::disabled,
                DrawContents::none,
                areDrawContentsValid,
            };

        case DrawType::interiorTriangulation:
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
            break;
    }

    RIVE_UNREACHABLE();
}

// Returns an 8-bit key that uniquely identifies the stencil settings.
static void get_stencil_settings(InterlockMode interlockMode,
                                 DrawType drawType,
                                 DrawContents drawContents,
                                 PipelineState* pipelineState)
{
    if (interlockMode != InterlockMode::depthStencil)
    {
        pipelineState->stencilTestEnabled = false;
        pipelineState->stencilWriteMask = 0;
        return;
    }

    pipelineState->stencilTestEnabled = true;

    // Draw contents that affect on the stencil settings for this particular
    // drawType.
    const auto stencilInfo =
        get_stencil_info(interlockMode, drawType, drawContents);

    assert(stencilInfo.areDrawContentsValid);

    // Apply the mask we were given - if the mask is missing bits, tests will
    // fail.
    drawContents &= stencilInfo.drawContentsMask;

    const bool isClockwiseFill =
        enums::is_flag_set(drawContents, DrawContents::clockwiseFill);
    const bool isEvenOddFill =
        enums::is_flag_set(drawContents, DrawContents::evenOddFill);
    const bool hasActiveClip =
        enums::is_flag_set(drawContents, DrawContents::activeClip);
    const bool isClipUpdate =
        enums::is_flag_set(drawContents, DrawContents::clipUpdate);

    switch (stencilInfo.stencilType)
    {
        case StencilType::disabled:
            pipelineState->stencilTestEnabled = false;
            pipelineState->stencilWriteMask = 0;
            break;

        case StencilType::activeStencilClip:
            assert(hasActiveClip);
            pipelineState->stencilCompareMask = 0xff;
            pipelineState->stencilWriteMask = 0xff;
            pipelineState->stencilReference = 0x80;
            pipelineState->stencilFrontOps = {
                .stencilFailOp = StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp = StencilOp::keep,
                .compareOp = StencilCompareOp::equal,
            };

            pipelineState->stencilDoubleSided = false;
            break;

        case StencilType::clipStroke:
            // If nested, we want to set the low bit of the stencil buffer when
            // we're inside of the parent clip, otherwise we want to always
            // write 0x80.
            pipelineState->stencilCompareMask = 0xff;
            pipelineState->stencilWriteMask = hasActiveClip ? 0x01 : 0xff;
            pipelineState->stencilReference = hasActiveClip ? 0x01 : 0x80;
            pipelineState->stencilFrontOps = {
                .stencilFailOp = StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp = StencilOp::replace,
                .compareOp = hasActiveClip ? StencilCompareOp::lessOrEqual
                                           : StencilCompareOp::always,
            };
            pipelineState->stencilDoubleSided = false;
            break;

        case StencilType::borrowedCoverage:
            // Count backward triangle hits (negative coverage) in the stencil
            // buffer.
            pipelineState->stencilCompareMask = 0xff;
            pipelineState->stencilWriteMask = 0x7f;
            pipelineState->stencilReference = 0x80;

            // Pass: 1 render borrowed coverage, early-rejected by depth.
            // NOTE: Only back faces survive this draw. We set "stencilFrontOps"
            // because "stencilDoubleSided=false" applies these settings to the
            // back face as well.
            pipelineState->stencilFrontOps = {
                .stencilFailOp = StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp = StencilOp::incrWrap,
                .compareOp = hasActiveClip ? StencilCompareOp::lessOrEqual
                                           : StencilCompareOp::always,
            };
            pipelineState->stencilDoubleSided = false;
            break;

        // forwardClippedByBackward and backwardTriangleCleanup share stencil
        // settings (one takes front face and the other takes back).
        case StencilType::forwardClippedByBackward:
        case StencilType::backwardTriangleCleanup:
            pipelineState->stencilCompareMask = hasActiveClip ? 0xff : 0x7f;
            if (stencilInfo.stencilType ==
                    StencilType::backwardTriangleCleanup &&
                isClockwiseFill)
            {
                // For clockwise fill, always disable clip-bit writes when
                // cleaning up backward triangles. Clockwise only fills in
                // forward triangles.
                pipelineState->stencilWriteMask = 0x7f;
            }
            else
            {
                pipelineState->stencilWriteMask = isClipUpdate ? 0xff : 0x7f;
            }
            pipelineState->stencilReference = 0x80;

            // Pass: 2 render forward triangles. Unfortunately, we have to
            // decrement borrowed coverage on a stencil fail, so this may
            // interfere with Hi-Z optimizations.
            pipelineState->stencilFrontOps = {
                .stencilFailOp =
                    StencilOp::decrClamp, // Don't wrap; 0 must stay 0
                                          // outside the clip.
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp =
                    isClipUpdate ? StencilOp::replace : StencilOp::keep,
                .compareOp = StencilCompareOp::equal,
            };

            // Pass 3: clean up borrowed coverage from the stencil.
            pipelineState->stencilBackOps = {
                .stencilFailOp = StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp =
                    isClipUpdate ? StencilOp::replace : StencilOp::zero,
                .compareOp = StencilCompareOp::less,
            };

            pipelineState->stencilDoubleSided = true;
            break;

        case StencilType::stencilNestedOrEvenOdd:
            // Just stencil the path into the stencil buffer. This is used for
            // nested clip updates and for evenOdd paths.
            pipelineState->stencilCompareMask = 0xff;
            pipelineState->stencilWriteMask = isEvenOddFill ? 0x1 : 0x7f;
            pipelineState->stencilReference = 0x80;
            // Decrement front-facing triangles so the MSB is set when
            // clockwise.
            pipelineState->stencilFrontOps = {
                .stencilFailOp = StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp = StencilOp::decrWrap,
                .compareOp = hasActiveClip ? StencilCompareOp::lessOrEqual
                                           : StencilCompareOp::always,
            };
            pipelineState->stencilBackOps = {
                .stencilFailOp = pipelineState->stencilFrontOps.stencilFailOp,
                .depthFailOp = pipelineState->stencilFrontOps.depthFailOp,
                .depthStencilPassOp = StencilOp::incrWrap,
                .compareOp = pipelineState->stencilFrontOps.compareOp,
            };
            pipelineState->stencilDoubleSided = true;
            break;

        case StencilType::evenOddDrawAndReset:
            // Draw & reset stencil winding numbers. This is only needed for
            // evenOdd paths.
            pipelineState->stencilCompareMask = 0x7f;
            pipelineState->stencilWriteMask = isClipUpdate ? 0xff : 0x1;
            pipelineState->stencilReference = 0x80;
            pipelineState->stencilFrontOps = {
                .stencilFailOp = StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp =
                    isClipUpdate ? StencilOp::replace : StencilOp::zero,
                .compareOp = StencilCompareOp::notEqual,
            };
            pipelineState->stencilDoubleSided = false;
            break;

        case StencilType::nestedClipReset:
            // The nested clip just got stencilled and left in the stencil
            // buffer. Intersect it with the existing clip. (Erasing regions of
            // the existing clip that are outside the nested clip.)
            pipelineState->stencilCompareMask =
                isClockwiseFill
                    // clockwise: (0x80 & 0xc0) < (stencilValue & 0xc0)
                    //   => "If clipbit is set and winding is negative"
                    //   => "If clipbit is set and winding is clockwise"
                    //      (because clockwise decrements)
                    //
                    ? 0xc0
                    // non-clockwise: 0x80 < stencilValue
                    //   => "If clipbit is set and winding is nonzero"
                    : 0xff;
            pipelineState->stencilWriteMask = 0xff;
            pipelineState->stencilReference = 0x80;
            pipelineState->stencilFrontOps = {
                .stencilFailOp = StencilOp::zero,
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp = StencilOp::replace,
                .compareOp = StencilCompareOp::less,
            };
            pipelineState->stencilDoubleSided = false;
            break;

        case StencilType::clipReset:
            // Clear the entire previous clip.
            pipelineState->stencilCompareMask = 0xff;
            pipelineState->stencilWriteMask = 0xff;
            pipelineState->stencilReference = 0x00;
            pipelineState->stencilFrontOps = {
                .stencilFailOp = StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .depthStencilPassOp = StencilOp::zero,
                .compareOp = StencilCompareOp::notEqual,
            };
            pipelineState->stencilDoubleSided = false;
            break;
    }
}

CullFace get_cull_face(DrawType drawType)
{
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::interiorTriangulation:
        case DrawType::featherAtlasBlit:
        case DrawType::depthStrokes:
        case DrawType::stencilDynamicMidpointFans:
        case DrawType::stencilDynamicOuterCubics:
        case DrawType::stencilMidpointFans:
        case DrawType::stencilOuterCubics:
        case DrawType::clipReset:
            return CullFace::counterclockwise;
        case DrawType::stencilMidpointFanBorrowedCoverage:
        case DrawType::stencilMidpointFanReset:
        case DrawType::stencilOuterCubicBorrowedCoverage:
        case DrawType::stencilOuterCubicReset:
            // clockwise is always the front face in Rive, but for a couple
            // draws we encode some stencil work in the counterclockwise face.
            // It's done this way because the cull face is often supported as
            // dynamic state, so we're keeping the option open to stuff two
            // operations (clockwise and counterclockwise) into a single
            // pipeline, and then select between them with the dynamic cull
            // face.
            return CullFace::clockwise;
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::stencilMidpointFanWinding:
        case DrawType::stencilMidpointFanCover:
        case DrawType::stencilOuterCubicWinding:
        case DrawType::stencilOuterCubicCover:
        case DrawType::renderPassResolve:
        case DrawType::renderPassInitialize:
            return CullFace::none;
    }
    RIVE_UNREACHABLE();
}

static BlendEquation get_blend_equation(
    DrawType drawType,
    InterlockMode interlockMode,
    ShaderMiscFlags shaderMiscFlags,
    DrawContents drawContents,
    BlendMode blendMode,
    bool fixedFunctionColorOutput,
    const PlatformFeatures& platformFeatures)
{
    switch (interlockMode)
    {
        case InterlockMode::rasterOrdering:
        case InterlockMode::atomics:
        case InterlockMode::clockwise:
            return fixedFunctionColorOutput ? BlendEquation::srcOver
                                            : BlendEquation::none;

        case InterlockMode::clockwiseAtomic:
            if (drawType == DrawType::renderPassInitialize)
            {
                // This draw is a seeming workaround for Qualcomm. Basically,
                // input attachment reads of the clip and color buffers don't
                // work unless we first draw these buffers into themselves
                // between borrowed coverage and the main subpass.
                return fixedFunctionColorOutput
                           // When using fixedFunctionColorOutput, this
                           // workaround doesn't apply to the color buffer, but
                           // we still need to make sure the existing color
                           // content doesn't change. To do this, we use srcOver
                           // blend and emit a color of 0.
                           ? BlendEquation::srcOver
                           // Otherwise, the workaround draws both color and
                           // clip into themselves. Blend needs to be disabled
                           // in this case because the existing color value
                           // might have transparency.
                           : BlendEquation::none;
            }
            else if (enums::is_flag_set(
                         shaderMiscFlags,
                         gpu::ShaderMiscFlags::borrowedCoveragePass))
            {
                // Borrowed coverage passes don't emit color. They only update
                // the coverage buffer.
                return BlendEquation::none;
            }
            else if (enums::is_flag_set(
                         shaderMiscFlags,
                         gpu::ShaderMiscFlags::nestedClipUpdateOnly))
            {
                // The coverage of two intersecting clips is
                // "min(clipCoverageA, clipCoverageB)".
                return BlendEquation::min;
            }
            else if (enums::is_flag_set(shaderMiscFlags,
                                        gpu::ShaderMiscFlags::clipUpdateOnly) &&
                     drawType != gpu::DrawType::clipReset)
            {
                // clockwiseAtomic clips render coverage count directly to the
                // clip buffer.
                return BlendEquation::plus;
            }
            else
            {
                // For normal paths, clockwiseAtomic uses src-over to accumulate
                // coverage, even with advanced blend.
                return BlendEquation::srcOver;
            }

        case InterlockMode::depthStencil:
            if (enums::is_flag_set(drawContents, DrawContents::opaquePaint))
            {
                // A dynamic-state draw may suppress color writes by outputting
                // color == 0, which only works if blending is ENABLED (if you
                // output "color == 0" with blending enabled, it's a no-op like
                // we want; if you output "color == 0" with blending DISABLED,
                // the pixel turns blank and erases whatever used to be there).
                // NOTE: Other than disabling color write, this output is
                // equivalent with or without blend, since opaquePaint emits
                // alpha == 1.
                return drawTypeHasPipelineDynamicState(drawType)
                           ? BlendEquation::srcOver
                           : BlendEquation::none;
            }
            else if (!platformFeatures.supportsBlendAdvancedKHR ||
                     blendMode == BlendMode::srcOver)
            {
                // Normal and in-shader blending both use src-over hardware
                // blend coefficients.
                //
                // When drawing an advanced blend mode, the shader only does the
                // "color" portion of the blend equation, and relies on the
                // hardware blend unit to finish the "alpha" portion.
                assert(drawType != DrawType::renderPassInitialize &&
                       drawType != DrawType::renderPassResolve);
                return BlendEquation::srcOver;
            }
            else
            {
                // When m_platformFeatures.supportsBlendAdvancedKHR is true in
                // depthStencil mode, the renderContext does not combine draws
                // that have different blend modes.
                assert(drawType != DrawType::renderPassInitialize &&
                       drawType != DrawType::renderPassResolve);
                return static_cast<BlendEquation>(blendMode);
            }
    }

    RIVE_UNREACHABLE();
}

bool get_color_write_enable(DrawType drawType,
                            InterlockMode interlockMode,
                            ShaderMiscFlags shaderMiscFlags,
                            bool fixedFunctionColorOutput,
                            DrawContents drawContents)
{
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::interiorTriangulation:
        case DrawType::featherAtlasBlit:
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            if (enums::any_flag_set(shaderMiscFlags,
                                    ShaderMiscFlags::clipUpdateOnly |
                                        ShaderMiscFlags::borrowedCoveragePass))
            {
                // Clip updates and borrowed coverage passes don't output color.
                return false;
            }
            // We generate pipeline state under the assumption that pixel local
            // storage can still be written when colorWriteEnabled is false.
            // Disable color writes when we're rendering only to PLS.
            return fixedFunctionColorOutput ||
                   interlockMode == InterlockMode::depthStencil;
        case DrawType::depthStrokes:
            return enums::no_flags_set(drawContents, DrawContents::clipUpdate);
        case DrawType::stencilMidpointFanBorrowedCoverage:
        case DrawType::stencilMidpointFanWinding:
        case DrawType::stencilOuterCubicBorrowedCoverage:
        case DrawType::stencilOuterCubicWinding:
        case DrawType::clipReset:
            return false;
        case DrawType::stencilDynamicMidpointFans:
        case DrawType::stencilDynamicOuterCubics:
        case DrawType::stencilMidpointFans:
        case DrawType::stencilMidpointFanCover:
        case DrawType::stencilOuterCubics:
        case DrawType::stencilOuterCubicCover:
            return !enums::is_flag_set(drawContents, DrawContents::clipUpdate);
        case DrawType::stencilMidpointFanReset:
        case DrawType::stencilOuterCubicReset:
            // For clockwise fill, disable color writes when cleaning up
            // backward triangles. Clockwise only fills in forward triangles.
            return enums::no_flags_set(drawContents,
                                       DrawContents::clockwiseFill |
                                           DrawContents::clipUpdate);
    }

    RIVE_UNREACHABLE();
}

uint64_t getPipelineUniqueKey(DrawType drawType,
                              ShaderFeatures shaderFeatures,
                              InterlockMode interlockMode,
                              ShaderMiscFlags shaderMiscFlags,
                              DrawContents drawContents,
                              bool fixedFunctionColorOutput,
                              rive::BlendMode blendMode,
                              const PlatformFeatures& platformFeatures)
{
    uint64_t key = gpu::ShaderUniqueKey(drawType,
                                        shaderFeatures,
                                        interlockMode,
                                        shaderMiscFlags);

    constexpr auto VALID_PIPELINE_DRAW_CONTENTS_BIT_COUNT =
        math::count_set_bits(
            uint32_t(DrawContentsForDepthStencilPipelineState));

    const auto stencilInfo = get_stencil_info(
        interlockMode,
        drawType,
        drawContents & DrawContentsForDepthStencilPipelineState);

    const auto drawContentsMask =
        (interlockMode == InterlockMode::depthStencil)
            ? DrawContents(stencilInfo.drawContentsMask |
                           DrawContents::opaquePaint)
            : DrawContents::none;

    assert((drawContentsMask & DrawContentsForDepthStencilPipelineState) ==
           drawContentsMask);

    const auto effectiveDrawContents =
        DrawContents(drawContents & drawContentsMask);

    // Compact the draw contents to only the bits that matter for the pipeline
    // (and, thus, the key)
    key = math::add_bits_to_key(
        key,
        math::compact_bitmask_value(
            uint32_t(effectiveDrawContents),
            uint32_t(DrawContentsForDepthStencilPipelineState)),
        VALID_PIPELINE_DRAW_CONTENTS_BIT_COUNT);

    // Only depthStencil cares about other blend modes during pipeline creation.
    auto effectiveBlendMode = (interlockMode == InterlockMode::depthStencil &&
                               platformFeatures.supportsBlendAdvancedKHR)
                                  ? blendMode
                                  : BlendMode::srcOver;

    assert(uint32_t(effectiveBlendMode) < (1u << BLEND_MODE_BIT_COUNT));

    key = math::add_bits_to_key(key,
                                uint32_t(effectiveBlendMode),
                                BLEND_MODE_BIT_COUNT);

    key = math::add_bits_to_key(key,
                                uint32_t(stencilInfo.stencilType),
                                StencilTypeBitCount);

    const bool colorWriteEnabled =
        get_color_write_enable(drawType,
                               interlockMode,
                               shaderMiscFlags,
                               fixedFunctionColorOutput,
                               effectiveDrawContents);
    key = math::add_bits_to_key(key, uint32_t(colorWriteEnabled), 1);
    const auto depthState =
        get_depth_state(interlockMode, drawType, effectiveDrawContents);
    key = math::add_bits_to_key(key, uint32_t(depthState.depthTestEnabled), 1);
    key = math::add_bits_to_key(key, uint32_t(depthState.depthWriteEnabled), 1);
    key = math::add_bits_to_key(key,
                                uint32_t(get_cull_face(drawType)),
                                CullFaceBitCount);
    return key;
}

void get_pipeline_state(const DrawBatch& batch,
                        const FlushDescriptor& flushDesc,
                        const PlatformFeatures& platformFeatures,
                        PipelineState* pipelineStateOut)
{
    *pipelineStateOut = get_pipeline_state(batch.drawType,
                                           flushDesc.interlockMode,
                                           batch.shaderMiscFlags,
                                           batch.drawContents,
                                           flushDesc.fixedFunctionColorOutput,
                                           batch.firstBlendMode,
                                           platformFeatures);
}

PipelineState get_pipeline_state(DrawType drawType,
                                 InterlockMode interlockMode,
                                 ShaderMiscFlags shaderMiscFlags,
                                 DrawContents drawContents,
                                 bool fixedFunctionColorOutput,
                                 rive::BlendMode blendMode,
                                 const PlatformFeatures& platformFeatures)
{
    // Only some DrawContents flags are relevant (and only for depthStencil at
    // the moment)
    drawContents &= (interlockMode == InterlockMode::depthStencil)
                        ? DrawContentsForDepthStencilPipelineState
                        : DrawContents::none;

#ifndef NDEBUG
    // Ensure drawType is compatible with the interlock mode.
    switch (drawType)
    {
        case DrawType::featherAtlasBlit:
        case DrawType::imageMesh:
            break;

        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::interiorTriangulation:
            assert(interlockMode != InterlockMode::depthStencil);
            break;

        case DrawType::imageRect:
        case DrawType::renderPassResolve:
            assert(interlockMode == InterlockMode::rasterOrdering ||
                   interlockMode == InterlockMode::atomics ||
                   interlockMode == InterlockMode::depthStencil);
            break;

        case DrawType::renderPassInitialize:
            assert(interlockMode == InterlockMode::atomics ||
                   interlockMode == InterlockMode::depthStencil ||
                   interlockMode == InterlockMode::clockwiseAtomic);
            break;

        case DrawType::depthStrokes:
        case DrawType::stencilDynamicMidpointFans:
        case DrawType::stencilDynamicOuterCubics:
        case DrawType::stencilMidpointFans:
        case DrawType::stencilMidpointFanBorrowedCoverage:
        case DrawType::stencilMidpointFanReset:
        case DrawType::stencilMidpointFanWinding:
        case DrawType::stencilMidpointFanCover:
        case DrawType::stencilOuterCubicBorrowedCoverage:
        case DrawType::stencilOuterCubics:
        case DrawType::stencilOuterCubicReset:
        case DrawType::stencilOuterCubicWinding:
        case DrawType::stencilOuterCubicCover:
            assert(interlockMode == InterlockMode::depthStencil);
            break;

        case DrawType::clipReset:
            assert(interlockMode == InterlockMode::clockwiseAtomic ||
                   interlockMode == InterlockMode::depthStencil);
            break;
    }
#endif

    PipelineState pipelineState;
    auto depthState = get_depth_state(interlockMode, drawType, drawContents);
    pipelineState.depthTestEnabled = depthState.depthTestEnabled;
    pipelineState.depthWriteEnabled = depthState.depthWriteEnabled;
    get_stencil_settings(interlockMode, drawType, drawContents, &pipelineState);
    pipelineState.cullFace = get_cull_face(drawType);
    pipelineState.blendEquation = get_blend_equation(drawType,
                                                     interlockMode,
                                                     shaderMiscFlags,
                                                     drawContents,
                                                     blendMode,
                                                     fixedFunctionColorOutput,
                                                     platformFeatures);
    pipelineState.colorWriteEnabled =
        get_color_write_enable(drawType,
                               interlockMode,
                               shaderMiscFlags,
                               fixedFunctionColorOutput,
                               drawContents);
    return pipelineState;
}

// Borrowed from:
// https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion
//
// IEEE-754 16-bit floating-point format (without infinity): 1-5-10, exp-15,
// +-131008.0, +-6.1035156E-5, +-5.9604645E-8, 3.311 digits
float4 cast_f16_to_f32(uint16x4 x16)
{
    uint4 x = simd::cast<uint32_t>(x16);
    uint4 e = (x & 0x7C00) >> 10; // exponent
    uint4 m = (x & 0x03FF) << 13; // mantissa
    // evil log2 bit hack to count leading zeros in denormalized format
    uint4 v = math::bit_cast<uint4>(simd::cast<float>(m)) >> 23;
    // sign : normalized : denormalized
    return math::bit_cast<float4>(
        (x & 0x8000u) << 16 |
        simd::cast<uint32_t>((e != 0u) & 1) * ((e + 112) << 23 | m) |
        simd::cast<uint32_t>((e == 0u) & (m != 0u) & 1) *
            ((v - 37u) << 23 | ((m << (150u - v)) & 0x007FE000u)));
}

// Borrowed from:
// https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion
//
// IEEE-754 16-bit floating-point format (without infinity): 1-5-10, exp-15,
// +-131008.0, +-6.1035156E-5, +-5.9604645E-8, 3.311 digits
uint16x4 cast_f32_to_f16(float4 x)
{
    // round-to-nearest-even: add last bit after truncated mantissa
    uint4 b = math::bit_cast<uint4>(x) + 0x00001000;
    uint4 e = (b & 0x7F800000) >> 23; // exponent
    // mantissa; in line below: 0x007FF000 = 0x00800000-0x00001000 = decimal
    // indicator flag - initial rounding
    uint4 m = b & 0x007FFFFF;
    // sign : normalized : denormalized : saturate
    return simd::cast<uint16_t>(
        ((b & 0x80000000u) >> 16) |
        simd::cast<uint32_t>((e > 112u) & 1) *
            ((((e - 112u) << 10) & 0x7C00u) | m >> 13) |
        simd::cast<uint32_t>((e < 113u) & (e > 101u) & 1) *
            ((((0x007FF000u + m) >> (125u - e)) + 1u) >> 1) |
        simd::cast<uint32_t>((e > 143u) & 1) * 0x7FFFu);
}

float featherRadiusFromFeather(float feather)
{
    // Core owns this now, so the radius a raster is sized for and the radius a
    // draw is culled against cannot drift apart. Kept as a gpu:: symbol because
    // draw.cpp calls it on the hot path; rive_render_path.cpp static_asserts
    // that the constant behind it still matches
    // GAUSSIAN_INTEGRAL_TEXTURE_STDDEVS.
    return ::rive::featherRadiusFromFeather(feather);
}

// Code to generate g_gaussianIntegralTableF16.
#ifdef RIVE_GENERATE_FEATHER_LUT
static float eval_normal_distribution(float x, float mu, float inverseSigma)
{
    constexpr static float ONE_OVER_SQRT_2_PI = 0.398942280401433f;
    float y = (x - mu) * inverseSigma;
    return expf(-.5 * y * y) * inverseSigma * ONE_OVER_SQRT_2_PI;
}

void generate_gausian_integral_table(float (&table)[GAUSSIAN_TABLE_SIZE])
{
    float sigma = GAUSSIAN_TABLE_SIZE / (GAUSSIAN_INTEGRAL_TEXTURE_STDDEVS * 2);
    float inverseSigma = 1 / sigma;
    float mu = GAUSSIAN_TABLE_SIZE * .5f;
    float integral = 0;
    for (size_t i = 0; i < GAUSSIAN_TABLE_SIZE; ++i)
    {
        // Sample the normal distribution in multiple locations for each entry
        // of the table, in order to get a more accurate integral.
        constexpr static int SAMPLES = 7;
        float barCenterX = static_cast<float>(i);
        for (int sample = 0; sample < SAMPLES; ++sample)
        {
            float dx = static_cast<float>(sample - (SAMPLES >> 1)) / SAMPLES;
            integral +=
                eval_normal_distribution(barCenterX + dx, mu, inverseSigma) /
                SAMPLES;
        }
        table[i] = integral;
    }
    // Account for the area under the curve prior to our table by shifting so
    // the middle value of the table is exactly 1/2.
    float shift =
        .5 - ((GAUSSIAN_TABLE_SIZE & 1) ? table[GAUSSIAN_TABLE_SIZE / 2]
                                        : (table[GAUSSIAN_TABLE_SIZE / 2 - 1] +
                                           table[GAUSSIAN_TABLE_SIZE / 2]) /
                                              2);
    table[0] = fminf(fmaxf(0, table[0] + shift), 1);
    for (size_t i = 1; i < GAUSSIAN_TABLE_SIZE; ++i)
    {
        table[i] = fminf(fmaxf(table[i - 1], table[i] + shift), 1);
    }

    //  How many entries to ease in and out, so the table has a soft landing at
    //  0 and 1 on the edges.
    constexpr size_t EASE_IN_OUT_DIST = 8;
    for (size_t i = 0; i < GAUSSIAN_TABLE_SIZE; ++i)
    {
        if (i < EASE_IN_OUT_DIST)
        {
            float fi =
                static_cast<float>(i) / static_cast<float>(EASE_IN_OUT_DIST);
            table[i] *= fi;
        }

        if (i > (GAUSSIAN_TABLE_SIZE - EASE_IN_OUT_DIST) - 1)
        {
            float diffToOne = 1.0 - table[i];
            float fi = static_cast<float>(
                           i - (GAUSSIAN_TABLE_SIZE - EASE_IN_OUT_DIST) + 1) /
                       static_cast<float>(EASE_IN_OUT_DIST);
            table[i] = table[i] + (diffToOne * fi);
        }
    }

    printf("\nconst float g_gaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE] = "
           "{\n");
    for (size_t i = 0; i < GAUSSIAN_TABLE_SIZE; ++i)
    {
        printf("%f, ", table[i]);
    }
    printf("\n};\n");
    printf("\nconst uint16_t g_gaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE] = "
           "{\n");
    for (size_t i = 0; i < GAUSSIAN_TABLE_SIZE; ++i)
    {
        printf("0x%x, ", gpu::cast_f32_to_f16(table[i]).x);
    }
    printf("\n};\n");
}
#endif

const uint16_t g_gaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE] = {
    0x0,    0x9db,  0xe16,  0x10be, 0x1291, 0x1443, 0x154f, 0x166f, 0x17a2,
    0x17ec, 0x181c, 0x1844, 0x186d, 0x1898, 0x18c4, 0x18f1, 0x1920, 0x1951,
    0x1983, 0x19b7, 0x19ec, 0x1a23, 0x1a5d, 0x1a98, 0x1ad4, 0x1b13, 0x1b54,
    0x1b97, 0x1bdc, 0x1c12, 0x1c36, 0x1c5c, 0x1c83, 0x1cac, 0x1cd5, 0x1d00,
    0x1d2c, 0x1d5a, 0x1d89, 0x1db9, 0x1deb, 0x1e1e, 0x1e53, 0x1e89, 0x1ec1,
    0x1efb, 0x1f36, 0x1f73, 0x1fb2, 0x1ff3, 0x201b, 0x203d, 0x2060, 0x2084,
    0x20a9, 0x20d0, 0x20f7, 0x211f, 0x2149, 0x2173, 0x219f, 0x21cc, 0x21fb,
    0x222a, 0x225b, 0x228d, 0x22c0, 0x22f5, 0x232b, 0x2363, 0x239c, 0x23d6,
    0x2409, 0x2428, 0x2447, 0x2468, 0x2489, 0x24ab, 0x24cd, 0x24f1, 0x2516,
    0x253b, 0x2561, 0x2589, 0x25b1, 0x25da, 0x2604, 0x262f, 0x265b, 0x2688,
    0x26b7, 0x26e6, 0x2716, 0x2748, 0x277a, 0x27ae, 0x27e3, 0x280c, 0x2828,
    0x2844, 0x2861, 0x287e, 0x289c, 0x28bb, 0x28da, 0x28fa, 0x291b, 0x293c,
    0x295f, 0x2981, 0x29a5, 0x29c9, 0x29ee, 0x2a13, 0x2a3a, 0x2a61, 0x2a89,
    0x2ab1, 0x2adb, 0x2b05, 0x2b30, 0x2b5c, 0x2b89, 0x2bb6, 0x2be4, 0x2c0a,
    0x2c22, 0x2c3a, 0x2c53, 0x2c6c, 0x2c86, 0x2ca0, 0x2cbb, 0x2cd6, 0x2cf2,
    0x2d0e, 0x2d2a, 0x2d47, 0x2d65, 0x2d82, 0x2da1, 0x2dc0, 0x2ddf, 0x2dff,
    0x2e1f, 0x2e40, 0x2e62, 0x2e84, 0x2ea6, 0x2ec9, 0x2eec, 0x2f10, 0x2f35,
    0x2f5a, 0x2f7f, 0x2fa5, 0x2fcc, 0x2ff3, 0x300d, 0x3021, 0x3036, 0x304a,
    0x305f, 0x3074, 0x308a, 0x309f, 0x30b5, 0x30cc, 0x30e2, 0x30f9, 0x3110,
    0x3127, 0x313f, 0x3157, 0x316f, 0x3187, 0x31a0, 0x31b9, 0x31d2, 0x31eb,
    0x3205, 0x321f, 0x323a, 0x3254, 0x326f, 0x328a, 0x32a5, 0x32c1, 0x32dd,
    0x32f9, 0x3315, 0x3332, 0x334f, 0x336c, 0x338a, 0x33a7, 0x33c5, 0x33e3,
    0x3401, 0x3410, 0x3420, 0x342f, 0x343f, 0x344f, 0x345f, 0x346f, 0x347f,
    0x348f, 0x349f, 0x34b0, 0x34c0, 0x34d1, 0x34e2, 0x34f3, 0x3504, 0x3515,
    0x3526, 0x3537, 0x3548, 0x355a, 0x356b, 0x357d, 0x358f, 0x35a0, 0x35b2,
    0x35c4, 0x35d6, 0x35e8, 0x35fa, 0x360d, 0x361f, 0x3631, 0x3644, 0x3656,
    0x3669, 0x367b, 0x368e, 0x36a0, 0x36b3, 0x36c6, 0x36d9, 0x36ec, 0x36ff,
    0x3711, 0x3724, 0x3737, 0x374a, 0x375d, 0x3771, 0x3784, 0x3797, 0x37aa,
    0x37bd, 0x37d0, 0x37e3, 0x37f6, 0x3805, 0x380e, 0x3818, 0x3822, 0x382b,
    0x3835, 0x383e, 0x3848, 0x3851, 0x385b, 0x3864, 0x386e, 0x3877, 0x3881,
    0x388a, 0x3894, 0x389d, 0x38a6, 0x38b0, 0x38b9, 0x38c2, 0x38cc, 0x38d5,
    0x38de, 0x38e7, 0x38f1, 0x38fa, 0x3903, 0x390c, 0x3915, 0x391e, 0x3927,
    0x3930, 0x3939, 0x3942, 0x394a, 0x3953, 0x395c, 0x3964, 0x396d, 0x3976,
    0x397e, 0x3987, 0x398f, 0x3998, 0x39a0, 0x39a8, 0x39b0, 0x39b9, 0x39c1,
    0x39c9, 0x39d1, 0x39d9, 0x39e1, 0x39e8, 0x39f0, 0x39f8, 0x3a00, 0x3a07,
    0x3a0f, 0x3a16, 0x3a1e, 0x3a25, 0x3a2c, 0x3a33, 0x3a3b, 0x3a42, 0x3a49,
    0x3a50, 0x3a57, 0x3a5d, 0x3a64, 0x3a6b, 0x3a72, 0x3a78, 0x3a7f, 0x3a85,
    0x3a8b, 0x3a92, 0x3a98, 0x3a9e, 0x3aa4, 0x3aaa, 0x3ab0, 0x3ab6, 0x3abc,
    0x3ac2, 0x3ac7, 0x3acd, 0x3ad3, 0x3ad8, 0x3ade, 0x3ae3, 0x3ae8, 0x3aed,
    0x3af3, 0x3af8, 0x3afd, 0x3b02, 0x3b07, 0x3b0b, 0x3b10, 0x3b15, 0x3b19,
    0x3b1e, 0x3b22, 0x3b27, 0x3b2b, 0x3b30, 0x3b34, 0x3b38, 0x3b3c, 0x3b40,
    0x3b44, 0x3b48, 0x3b4c, 0x3b50, 0x3b53, 0x3b57, 0x3b5b, 0x3b5e, 0x3b62,
    0x3b65, 0x3b69, 0x3b6c, 0x3b6f, 0x3b72, 0x3b76, 0x3b79, 0x3b7c, 0x3b7f,
    0x3b82, 0x3b85, 0x3b87, 0x3b8a, 0x3b8d, 0x3b90, 0x3b92, 0x3b95, 0x3b97,
    0x3b9a, 0x3b9c, 0x3b9f, 0x3ba1, 0x3ba3, 0x3ba6, 0x3ba8, 0x3baa, 0x3bac,
    0x3bae, 0x3bb0, 0x3bb2, 0x3bb4, 0x3bb6, 0x3bb8, 0x3bba, 0x3bbc, 0x3bbe,
    0x3bbf, 0x3bc1, 0x3bc3, 0x3bc4, 0x3bc6, 0x3bc7, 0x3bc9, 0x3bca, 0x3bcc,
    0x3bcd, 0x3bcf, 0x3bd0, 0x3bd1, 0x3bd2, 0x3bd4, 0x3bd5, 0x3bd6, 0x3bd7,
    0x3bd8, 0x3bda, 0x3bdb, 0x3bdc, 0x3bdd, 0x3bde, 0x3bdf, 0x3be0, 0x3be1,
    0x3be2, 0x3be2, 0x3be3, 0x3be4, 0x3be5, 0x3be6, 0x3be7, 0x3be7, 0x3be8,
    0x3be9, 0x3bea, 0x3bea, 0x3beb, 0x3bec, 0x3bec, 0x3bed, 0x3bed, 0x3bee,
    0x3bee, 0x3bef, 0x3bf0, 0x3bf0, 0x3bf1, 0x3bf1, 0x3bf2, 0x3bf2, 0x3bf2,
    0x3bf3, 0x3bf3, 0x3bf4, 0x3bf4, 0x3bf5, 0x3bf5, 0x3bf5, 0x3bf6, 0x3bf6,
    0x3bf6, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf9,
    0x3bf9, 0x3bf9, 0x3bf9, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfb,
    0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc,
    0x3bfd, 0x3bfd, 0x3bfe, 0x3bfe, 0x3bff, 0x3bff, 0x3c00, 0x3c00,
};

// Code to generate g_inverseGaussianIntegralTableF32.
#ifdef RIVE_GENERATE_FEATHER_LUT
void generate_inverse_gausian_integral_table(
    float (&table)[GAUSSIAN_TABLE_SIZE])
{
    // Evaluate 32 samples for every table value, for better precision.
    size_t MULTIPLIER = 32;
    float sigma = GAUSSIAN_TABLE_SIZE / (GAUSSIAN_INTEGRAL_TEXTURE_STDDEVS * 2);
    float inverseSigma = 1 / sigma;
    float mu = GAUSSIAN_TABLE_SIZE * .5f;
    size_t samples = GAUSSIAN_TABLE_SIZE * MULTIPLIER;

    // Integrate half the curve in order to determine the initial value of our
    // integral (the table doesn't begin until
    // -GAUSSIAN_INTEGRAL_TEXTURE_STDDEVS).
    float integral = 0;
    for (size_t i = 0; i < (samples + 1) / 2; ++i)
    {
        float barCenterX = static_cast<float>(i) / MULTIPLIER;
        integral +=
            eval_normal_distribution(barCenterX, mu, inverseSigma) / MULTIPLIER;
    }
    integral = .5 - integral;

    // Reboot now that we know the initial integral value and fill in the
    // inverse table this time around.
    float lastInverseX = std::numeric_limits<float>::quiet_NaN(),
          lastInverseY = 0;
    table[0] = 0;
    table[GAUSSIAN_TABLE_SIZE - 1] = 1;
    for (size_t i = 0; i < samples; ++i)
    {
        float barCenterX = static_cast<float>(i) / MULTIPLIER;
        integral +=
            eval_normal_distribution(barCenterX, mu, inverseSigma) / MULTIPLIER;
        float inverseX = fminf(fmaxf(0, integral), 1) * GAUSSIAN_TABLE_SIZE;
        float inverseY = (i + .5f) / samples;
        size_t cell = static_cast<size_t>(inverseX);
        float cellCenterX = cell + .5f;
        if (cellCenterX == mu)
        {
            // Make sure the center value is exactly .5, just because.
            table[cell] = .5f;
        }
        else if (lastInverseX <= cellCenterX && inverseX >= cellCenterX)
        {
            float t = (cellCenterX - lastInverseX) / (inverseX - lastInverseX);
            float y = lerp(lastInverseY, inverseY, t);
            assert(0 <= cell && cell < GAUSSIAN_TABLE_SIZE);
            table[cell] = y;
        }
        lastInverseX = inverseX;
        lastInverseY = inverseY;
    }

    // Use a large enough GAUSSIAN_TABLE_SIZE that the beginning and ending
    // values are 0 and 1!
    assert(table[0] == 0 && table[GAUSSIAN_TABLE_SIZE - 1] == 1);

    printf("\nconst float "
           "g_inverseGaussianIntegralTableF32[GAUSSIAN_TABLE_SIZE] = {\n");
    for (size_t i = 0; i < GAUSSIAN_TABLE_SIZE; ++i)
    {
        printf("%ff, ", table[i]);
    }
    printf("\n};\n");
    printf("\nconst uint16_t "
           "g_inverseGaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE] = "
           "{\n");
    for (size_t i = 0; i < GAUSSIAN_TABLE_SIZE; ++i)
    {
        printf("0x%x, ", gpu::cast_f32_to_f16(table[i]).x);
    }
    printf("\n};\n");
}
#endif

const uint16_t g_inverseGaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE] = {
    0x0,    0x290a, 0x2c62, 0x2da8, 0x2ea4, 0x2f72, 0x3011, 0x305e, 0x30a2,
    0x30e0, 0x3118, 0x314c, 0x317c, 0x31aa, 0x31d4, 0x31fc, 0x3222, 0x3246,
    0x3269, 0x328a, 0x32a9, 0x32c8, 0x32e5, 0x3301, 0x331c, 0x3337, 0x3350,
    0x3369, 0x3381, 0x3399, 0x33af, 0x33c6, 0x33db, 0x33f1, 0x3403, 0x340d,
    0x3417, 0x3420, 0x342a, 0x3433, 0x343c, 0x3445, 0x344e, 0x3457, 0x345f,
    0x3468, 0x3470, 0x3478, 0x3480, 0x3488, 0x348f, 0x3497, 0x349f, 0x34a6,
    0x34ad, 0x34b5, 0x34bc, 0x34c3, 0x34ca, 0x34d1, 0x34d7, 0x34de, 0x34e5,
    0x34eb, 0x34f2, 0x34f8, 0x34fe, 0x3505, 0x350b, 0x3511, 0x3517, 0x351d,
    0x3523, 0x3529, 0x352f, 0x3535, 0x353b, 0x3540, 0x3546, 0x354c, 0x3551,
    0x3557, 0x355c, 0x3562, 0x3567, 0x356c, 0x3572, 0x3577, 0x357c, 0x3581,
    0x3586, 0x358c, 0x3591, 0x3596, 0x359b, 0x35a0, 0x35a5, 0x35aa, 0x35ae,
    0x35b3, 0x35b8, 0x35bd, 0x35c2, 0x35c6, 0x35cb, 0x35d0, 0x35d5, 0x35d9,
    0x35de, 0x35e2, 0x35e7, 0x35ec, 0x35f0, 0x35f5, 0x35f9, 0x35fd, 0x3602,
    0x3606, 0x360b, 0x360f, 0x3613, 0x3618, 0x361c, 0x3620, 0x3625, 0x3629,
    0x362d, 0x3631, 0x3635, 0x363a, 0x363e, 0x3642, 0x3646, 0x364a, 0x364e,
    0x3652, 0x3656, 0x365b, 0x365f, 0x3663, 0x3667, 0x366b, 0x366f, 0x3673,
    0x3676, 0x367a, 0x367e, 0x3682, 0x3686, 0x368a, 0x368e, 0x3692, 0x3696,
    0x3699, 0x369d, 0x36a1, 0x36a5, 0x36a9, 0x36ad, 0x36b0, 0x36b4, 0x36b8,
    0x36bc, 0x36bf, 0x36c3, 0x36c7, 0x36ca, 0x36ce, 0x36d2, 0x36d6, 0x36d9,
    0x36dd, 0x36e1, 0x36e4, 0x36e8, 0x36eb, 0x36ef, 0x36f3, 0x36f6, 0x36fa,
    0x36fd, 0x3701, 0x3705, 0x3708, 0x370c, 0x370f, 0x3713, 0x3716, 0x371a,
    0x371e, 0x3721, 0x3725, 0x3728, 0x372c, 0x372f, 0x3733, 0x3736, 0x373a,
    0x373d, 0x3741, 0x3744, 0x3748, 0x374b, 0x374e, 0x3752, 0x3755, 0x3759,
    0x375c, 0x3760, 0x3763, 0x3767, 0x376a, 0x376d, 0x3771, 0x3774, 0x3778,
    0x377b, 0x377e, 0x3782, 0x3785, 0x3789, 0x378c, 0x378f, 0x3793, 0x3796,
    0x379a, 0x379d, 0x37a0, 0x37a4, 0x37a7, 0x37aa, 0x37ae, 0x37b1, 0x37b5,
    0x37b8, 0x37bb, 0x37bf, 0x37c2, 0x37c5, 0x37c9, 0x37cc, 0x37cf, 0x37d3,
    0x37d6, 0x37d9, 0x37dd, 0x37e0, 0x37e3, 0x37e7, 0x37ea, 0x37ed, 0x37f1,
    0x37f4, 0x37f8, 0x37fb, 0x37fe, 0x3801, 0x3802, 0x3804, 0x3806, 0x3807,
    0x3809, 0x380b, 0x380c, 0x380e, 0x3810, 0x3811, 0x3813, 0x3815, 0x3817,
    0x3818, 0x381a, 0x381c, 0x381d, 0x381f, 0x3821, 0x3822, 0x3824, 0x3826,
    0x3827, 0x3829, 0x382b, 0x382c, 0x382e, 0x3830, 0x3831, 0x3833, 0x3835,
    0x3836, 0x3838, 0x383a, 0x383c, 0x383d, 0x383f, 0x3841, 0x3842, 0x3844,
    0x3846, 0x3847, 0x3849, 0x384b, 0x384d, 0x384e, 0x3850, 0x3852, 0x3853,
    0x3855, 0x3857, 0x3859, 0x385a, 0x385c, 0x385e, 0x3860, 0x3861, 0x3863,
    0x3865, 0x3867, 0x3868, 0x386a, 0x386c, 0x386e, 0x386f, 0x3871, 0x3873,
    0x3875, 0x3876, 0x3878, 0x387a, 0x387c, 0x387e, 0x387f, 0x3881, 0x3883,
    0x3885, 0x3887, 0x3888, 0x388a, 0x388c, 0x388e, 0x3890, 0x3891, 0x3893,
    0x3895, 0x3897, 0x3899, 0x389b, 0x389c, 0x389e, 0x38a0, 0x38a2, 0x38a4,
    0x38a6, 0x38a8, 0x38aa, 0x38ab, 0x38ad, 0x38af, 0x38b1, 0x38b3, 0x38b5,
    0x38b7, 0x38b9, 0x38bb, 0x38bd, 0x38bf, 0x38c1, 0x38c3, 0x38c5, 0x38c7,
    0x38c9, 0x38cb, 0x38cd, 0x38cf, 0x38d1, 0x38d3, 0x38d5, 0x38d7, 0x38d9,
    0x38db, 0x38dd, 0x38df, 0x38e1, 0x38e3, 0x38e5, 0x38e7, 0x38e9, 0x38eb,
    0x38ee, 0x38f0, 0x38f2, 0x38f4, 0x38f6, 0x38f8, 0x38fa, 0x38fd, 0x38ff,
    0x3901, 0x3903, 0x3906, 0x3908, 0x390a, 0x390c, 0x390f, 0x3911, 0x3913,
    0x3916, 0x3918, 0x391a, 0x391d, 0x391f, 0x3921, 0x3924, 0x3926, 0x3929,
    0x392b, 0x392d, 0x3930, 0x3932, 0x3935, 0x3937, 0x393a, 0x393d, 0x393f,
    0x3942, 0x3944, 0x3947, 0x394a, 0x394c, 0x394f, 0x3952, 0x3954, 0x3957,
    0x395a, 0x395d, 0x3960, 0x3963, 0x3965, 0x3968, 0x396b, 0x396e, 0x3971,
    0x3974, 0x3977, 0x397a, 0x397d, 0x3981, 0x3984, 0x3987, 0x398a, 0x398d,
    0x3991, 0x3994, 0x3997, 0x399b, 0x399e, 0x39a2, 0x39a5, 0x39a9, 0x39ad,
    0x39b0, 0x39b4, 0x39b8, 0x39bc, 0x39c0, 0x39c4, 0x39c8, 0x39cc, 0x39d0,
    0x39d4, 0x39d9, 0x39dd, 0x39e2, 0x39e6, 0x39eb, 0x39ef, 0x39f4, 0x39f9,
    0x39fe, 0x3a03, 0x3a09, 0x3a0e, 0x3a14, 0x3a19, 0x3a1f, 0x3a25, 0x3a2b,
    0x3a32, 0x3a38, 0x3a3f, 0x3a46, 0x3a4e, 0x3a55, 0x3a5d, 0x3a65, 0x3a6e,
    0x3a77, 0x3a80, 0x3a8a, 0x3a95, 0x3aa0, 0x3aac, 0x3ab9, 0x3ac7, 0x3ad6,
    0x3ae7, 0x3afa, 0x3b10, 0x3b29, 0x3b48, 0x3b70, 0x3baa, 0x3c00,
};

} // namespace rive::gpu
