/*
 * Copyright 2022 Rive
 */

#include "shaders/constants.glsl"
#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 "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(sizeof(PaintAuxData) / StorageBufferElementSizeInBytes(
                                         PaintAuxData::kBufferStructure) ==
              PAINT_AUX_ENTRY_ELEMENT_COUNT);

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;
            }
            if (drawTypeHasPipelineDynamicState(drawType))
            {
                outFlags |= ShaderMiscFlags::emulateDynamicColorWriteDisable;
            }
            break;
    }

    if (drawTypeHasPipelineDynamicState(drawType))
    {
        outFlags |= ShaderMiscFlags::emulateDynamicColorWriteDisable;
    }

    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::emulateDynamicColorWriteDisable |
                   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:
        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:
            return 0;
        case DrawType::interiorTriangulation:
            return 1;
        case DrawType::featherAtlasBlit:
            return 2;
        case DrawType::imageRect:
            return 3;
        case DrawType::imageMesh:
            return 4;
        case DrawType::clipReset:
            assert(interlockMode == InterlockMode::clockwiseAtomic ||
                   interlockMode == InterlockMode::depthStencil);
            return 7;
        case DrawType::renderPassInitialize:
            assert(interlockMode == InterlockMode::atomics ||
                   interlockMode == InterlockMode::depthStencil ||
                   interlockMode == InterlockMode::clockwiseAtomic);
            return 5;
        case DrawType::renderPassResolve:
            assert(interlockMode == InterlockMode::rasterOrdering ||
                   interlockMode == InterlockMode::atomics ||
                   interlockMode == InterlockMode::depthStencil);
            return 6;
    }
    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
                                   ? OuterCubicPatchSegmentSpanPlusJoin
                                   : 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);
    }
}

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);
}

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::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)
{
    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;
    }
    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) :
    m_commons{matrix,
              modulatedColor,
              clipRectInverseMatrix,
              clipID,
              blendMode,
              zIndex,
              additiveness}
{
    static_assert(offsetof(ImageMeshInstance, m_commons) == 0);
}

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))
            {
                // ShaderMiscFlags::emulateDynamicColorWriteDisable suppresses
                // 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, the output is
                // equivalent with or without blend, since opaquePaint emits
                // alpha == 1.
                return enums::is_flag_set(
                           shaderMiscFlags,
                           ShaderMiscFlags::emulateDynamicColorWriteDisable)
                           ? 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)
{
    // Blur magnitudes in design tools are customarily the width of two standard
    // deviations, or, the length of the range -1stddev .. +1stddev.
    return feather * (GAUSSIAN_INTEGRAL_TEXTURE_STDDEVS / 2);
}

// 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
