/*
 * Copyright 2022 Rive
 */

#include "rive/renderer/gpu.hpp"

#include "rive/renderer/render_context.hpp"
#include "rive/renderer/render_target.hpp"
#include "shaders/constants.glsl"
#include "rive/renderer/texture.hpp"
#include "rive_render_paint.hpp"
#include "gradient.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);

uint32_t ShaderUniqueKey(DrawType drawType,
                         ShaderFeatures shaderFeatures,
                         InterlockMode interlockMode,
                         ShaderMiscFlags miscFlags)
{
    if (miscFlags & ShaderMiscFlags::coalescedResolveAndTransfer)
    {
        assert(drawType == DrawType::renderPassResolve);
        assert(shaderFeatures & ShaderFeatures::ENABLE_ADVANCED_BLEND);
        assert(interlockMode == InterlockMode::atomics);
    }
    if (miscFlags & (ShaderMiscFlags::storeColorClear |
                     ShaderMiscFlags::swizzleColorBGRAToRGBA))
    {
        assert(drawType == DrawType::renderPassInitialize);
        assert(interlockMode == InterlockMode::atomics);
    }
    uint32_t drawTypeKey;
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::msaaStrokes:
        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFans:
        case DrawType::msaaMidpointFanStencilReset:
        case DrawType::msaaMidpointFanPathsStencil:
        case DrawType::msaaMidpointFanPathsCover:
        case DrawType::msaaOuterCubics:
            drawTypeKey = 0;
            break;
        case DrawType::interiorTriangulation:
            drawTypeKey = 1;
            break;
        case DrawType::atlasBlit:
            drawTypeKey = 2;
            break;
        case DrawType::imageRect:
            drawTypeKey = 3;
            break;
        case DrawType::imageMesh:
            drawTypeKey = 4;
            break;
        case DrawType::msaaStencilClipReset:
            assert(interlockMode == InterlockMode::msaa);
            drawTypeKey = 7;
            break;
        case DrawType::renderPassInitialize:
            assert(interlockMode == InterlockMode::atomics ||
                   interlockMode == InterlockMode::msaa ||
                   interlockMode == InterlockMode::clockwiseAtomic);
            drawTypeKey = 5;
            break;
        case DrawType::renderPassResolve:
            assert(interlockMode == InterlockMode::rasterOrdering ||
                   interlockMode == InterlockMode::atomics ||
                   interlockMode == InterlockMode::msaa);
            drawTypeKey = 6;
            break;
    }
    uint32_t key = static_cast<uint32_t>(miscFlags);
    assert(static_cast<uint32_t>(interlockMode) <
           1 << INTERLOCK_MODE_BIT_COUNT);
    key = (key << INTERLOCK_MODE_BIT_COUNT) |
          static_cast<uint32_t>(interlockMode);
    key = (key << kShaderFeatureCount) |
          (shaderFeatures & ShaderFeaturesMaskFor(drawType, interlockMode))
              .bits();
    assert(drawTypeKey < 1 << 3);
    key = (key << 3) | drawTypeKey;
    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;
    }
    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
                                   ? kOuterCurvePatchSegmentSpan
                                   : 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);
    static_assert((int)PaintType::image == IMAGE_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 / 255;
    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)
    // gets drawn to the top of thew viewport.
    // This requires a Y inversion if Rive pixel space and clip space have
    // opposing senses of which way is up.
    if (platformFeatures.clipSpaceBottomUp)
    {
        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_atlasTextureInverseSize(1.f / flushDesc.atlasTextureWidth,
                              1.f / flushDesc.atlasTextureHeight),
    m_atlasContentInverseViewport(2.f / flushDesc.atlasContentWidth,
                                  (platformFeatures.clipSpaceBottomUp !=
                                           platformFeatures.framebufferBottomUp
                                       ? -2.f
                                       : 2.f) /
                                      flushDesc.atlasContentHeight),
    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)
{}

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

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

void PaintData::set(DrawContents singleDrawContents,
                    PaintType paintType,
                    SimplePaintValue simplePaintValue,
                    GradTextureLayout gradTextureLayout,
                    uint32_t clipID,
                    bool hasClipRect,
                    BlendMode blendMode)
{
    uint32_t shiftedClipID = clipID << 16;
    uint32_t shiftedBlendMode = ConvertBlendModeToPLSBlendMode(blendMode) << 4;
    uint32_t localParams = paint_type_to_glsl_id(paintType);
    switch (paintType)
    {
        case PaintType::solidColor:
        {
            // Swizzle the riveColor to little-endian RGBA (the order expected
            // by GLSL).
            m_color = SwizzleRiveColorToRGBA(simplePaintValue.color);
            localParams |= shiftedClipID | shiftedBlendMode;
            break;
        }
        case PaintType::linearGradient:
        case PaintType::radialGradient:
        {
            uint32_t row = simplePaintValue.colorRampLocation.row;
            if (simplePaintValue.colorRampLocation.isComplex())
            {
                // Complex gradients rows are offset after the simple gradients.
                row += gradTextureLayout.complexOffsetY;
            }
            m_gradTextureY = (static_cast<float>(row) + .5f) *
                             gradTextureLayout.inverseHeight;
            localParams |= shiftedClipID | shiftedBlendMode;
            break;
        }
        case PaintType::image:
        {
            m_opacity = simplePaintValue.imageOpacity;
            localParams |= shiftedClipID | shiftedBlendMode;
            break;
        }
        case PaintType::clipUpdate:
        {
            m_shiftedClipReplacementID = shiftedClipID;
            localParams |= simplePaintValue.outerClipID << 16;
            break;
        }
    }
    if (singleDrawContents & DrawContents::nonZeroFill)
    {
        localParams |= PAINT_FLAG_NON_ZERO_FILL;
    }
    else if (singleDrawContents & DrawContents::evenOddFill)
    {
        localParams |= PAINT_FLAG_EVEN_ODD_FILL;
    }
    if (hasClipRect)
    {
        localParams |= PAINT_FLAG_HAS_CLIP_RECT;
    }
    m_params = localParams;
}

void PaintAuxData::set(const Mat2D& viewMatrix,
                       PaintType paintType,
                       SimplePaintValue simplePaintValue,
                       const Gradient* gradient,
                       const Texture* imageTexture,
                       const ClipRectInverseMatrix* clipRectInverseMatrix,
                       const RenderTarget* renderTarget,
                       const PlatformFeatures& platformFeatures)
{
    switch (paintType)
    {
        case PaintType::solidColor:
        {
            break;
        }
        case PaintType::linearGradient:
        case PaintType::radialGradient:
        case PaintType::image:
        {
            Mat2D paintMatrix;
            viewMatrix.invert(&paintMatrix);
            if (platformFeatures.framebufferBottomUp)
            {
                // Flip _fragCoord.y.
                paintMatrix =
                    paintMatrix * Mat2D(1, 0, 0, -1, 0, renderTarget->height());
            }
            if (paintType == PaintType::image)
            {
                // 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 = paintMatrix.xx() * imageTexture->width();
                float dudy = paintMatrix.yx() * imageTexture->height();
                float dvdx = paintMatrix.xy() * imageTexture->width();
                float dvdy = paintMatrix.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;
            }
            else
            {
                assert(gradient != nullptr);
                const float* gradCoeffs = gradient->coeffs();
                if (paintType == PaintType::linearGradient)
                {
                    paintMatrix = Mat2D(gradCoeffs[0],
                                        0,
                                        gradCoeffs[1],
                                        0,
                                        gradCoeffs[2],
                                        0) *
                                  paintMatrix;
                }
                else
                {
                    assert(paintType == PaintType::radialGradient);
                    float w = 1 / gradCoeffs[2];
                    paintMatrix = Mat2D(w,
                                        0,
                                        0,
                                        w,
                                        -gradCoeffs[0] * w,
                                        -gradCoeffs[1] * w) *
                                  paintMatrix;
                }
                float left, right;
                if (simplePaintValue.colorRampLocation.isComplex())
                {
                    left = 0;
                    right = kGradTextureWidth;
                }
                else
                {
                    left = simplePaintValue.colorRampLocation.col;
                    right = left + 2;
                }
                m_gradTextureHorizontalSpan[0] =
                    (right - left - 1) * GRAD_TEXTURE_INVERSE_WIDTH;
                m_gradTextureHorizontalSpan[1] =
                    (left + .5f) * GRAD_TEXTURE_INVERSE_WIDTH;
            }
            write_matrix(m_matrix, paintMatrix);
            break;
        }
        case PaintType::clipUpdate:
        {
            break;
        }
    }

    if (clipRectInverseMatrix != nullptr)
    {
        Mat2D m = clipRectInverseMatrix->inverseMatrix();
        if (platformFeatures.framebufferBottomUp)
        {
            // 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;
    }
}

ImageDrawUniforms::ImageDrawUniforms(
    const Mat2D& matrix,
    float opacity,
    const ClipRectInverseMatrix* clipRectInverseMatrix,
    uint32_t clipID,
    BlendMode blendMode,
    uint32_t zIndex)
{
    write_matrix(m_matrix, matrix);
    m_opacity = opacity;
    write_matrix(m_clipRectInverseMatrix,
                 clipRectInverseMatrix != nullptr
                     ? clipRectInverseMatrix->inverseMatrix()
                     : ClipRectInverseMatrix::WideOpen().inverseMatrix());
    m_clipID = clipID;
    m_blendMode = ConvertBlendModeToPLSBlendMode(blendMode);
    m_zIndex = zIndex;
}

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

static void get_depth_state(InterlockMode interlockMode,
                            DrawType drawType,
                            DrawContents drawContents,
                            PipelineState* pipelineState)
{
    if (interlockMode != InterlockMode::msaa)
    {
        pipelineState->depthTestEnabled = false;
        pipelineState->depthWriteEnabled = false;
        return;
    }

    switch (drawType)
    {
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::atlasBlit:
        case DrawType::outerCurvePatches:
            pipelineState->depthTestEnabled = true;
            pipelineState->depthWriteEnabled = false;
            break;

        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFanPathsStencil:
        case DrawType::msaaStencilClipReset:
            pipelineState->depthTestEnabled = true;
            pipelineState->depthWriteEnabled = false;
            break;

        case DrawType::msaaStrokes:
        case DrawType::msaaOuterCubics:
            pipelineState->depthTestEnabled = true;
            pipelineState->depthWriteEnabled = true;
            break;

        case DrawType::msaaMidpointFans:
        case DrawType::msaaMidpointFanPathsCover:
            pipelineState->depthTestEnabled = true;
            pipelineState->depthWriteEnabled =
                !(drawContents & DrawContents::clipUpdate);
            break;

        case DrawType::msaaMidpointFanStencilReset:
            pipelineState->depthTestEnabled = true;
            pipelineState->depthWriteEnabled =
                !(drawContents &
                  (DrawContents::clockwiseFill | DrawContents::clipUpdate));
            break;

        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            pipelineState->depthTestEnabled = false;
            pipelineState->depthWriteEnabled = false;
            break;

        case DrawType::interiorTriangulation:
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
            RIVE_UNREACHABLE();
    }
}

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

    pipelineState->stencilTestEnabled = true;

    // Draw contents that affect on the stencil settings for this particular
    // drawType.
    struct
    {
        bool isClockwiseFill = false;
        bool isEvenOddFill = false;
        bool hasActiveClip = false;
        bool isClipUpdate = false;
    } effectiveDrawContents;

    uint8_t stencilKey = 0;

    switch (drawType)
    {
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::atlasBlit:
        case DrawType::msaaStrokes:
        case DrawType::msaaOuterCubics:
        {
            effectiveDrawContents.hasActiveClip =
                drawContents & DrawContents::activeClip;
            pipelineState->stencilCompareMask = 0xff;
            pipelineState->stencilWriteMask = 0xff;
            pipelineState->stencilReference = 0x80;
            pipelineState->stencilFrontOps = {
                .failOp = StencilOp::keep,
                .passOp = StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .compareOp = effectiveDrawContents.hasActiveClip
                                 ? StencilCompareOp::equal
                                 : StencilCompareOp::always,
            };
            pipelineState->stencilDoubleSided = false;
            stencilKey = 1;
            break;
        }

        case DrawType::msaaMidpointFanBorrowedCoverage:
        {
            // Count backward triangle hits (negative coverage) in the stencil
            // buffer.
            effectiveDrawContents.hasActiveClip =
                drawContents & DrawContents::activeClip;
            pipelineState->stencilCompareMask = 0xff;
            pipelineState->stencilWriteMask = 0x7f;
            pipelineState->stencilReference = 0x80;
            pipelineState->stencilFrontOps = {
                .failOp = StencilOp::keep,
                .passOp = StencilOp::incrWrap,
                .depthFailOp = StencilOp::keep,
                .compareOp = effectiveDrawContents.hasActiveClip
                                 ? StencilCompareOp::lessOrEqual
                                 : StencilCompareOp::always,
            };
            pipelineState->stencilDoubleSided = false;
            stencilKey = 2;
            break;
        }

        case DrawType::msaaMidpointFans:
        {
            // Draw forward triangles, clipped by the backward triangle counts.
            // (The depth test prevents double hits.)
            effectiveDrawContents.hasActiveClip =
                drawContents & DrawContents::activeClip;
            effectiveDrawContents.isClipUpdate =
                drawContents & DrawContents::clipUpdate;
            pipelineState->stencilCompareMask =
                effectiveDrawContents.hasActiveClip ? 0xff : 0x7f;
            pipelineState->stencilWriteMask =
                effectiveDrawContents.isClipUpdate ? 0xff : 0x7f;
            pipelineState->stencilReference = 0x80;
            pipelineState->stencilFrontOps = {
                .failOp = StencilOp::decrClamp, // Don't wrap; 0 must stay 0
                                                // outside the clip.
                .passOp = effectiveDrawContents.isClipUpdate
                              ? StencilOp::replace
                              : StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .compareOp = StencilCompareOp::equal,
            };
            pipelineState->stencilBackOps = {
                .failOp = StencilOp::keep,
                .passOp = effectiveDrawContents.isClipUpdate
                              ? StencilOp::replace
                              : StencilOp::zero,
                .depthFailOp = StencilOp::keep,
                .compareOp = StencilCompareOp::less,
            };
            pipelineState->stencilDoubleSided = true;
            stencilKey = 3;
            break;
        }

        case DrawType::msaaMidpointFanStencilReset:
        {
            // Clean up backward triangles in the stencil buffer, (also filling
            // negative winding numbers for nonZero fill).
            effectiveDrawContents.isClockwiseFill =
                drawContents & DrawContents::clockwiseFill;
            effectiveDrawContents.hasActiveClip =
                drawContents & DrawContents::activeClip;
            effectiveDrawContents.isClipUpdate =
                drawContents & DrawContents::clipUpdate;
            pipelineState->stencilCompareMask =
                effectiveDrawContents.hasActiveClip ? 0xff : 0x7f;
            pipelineState->stencilWriteMask =
                effectiveDrawContents.isClockwiseFill
                    // For clockwise fill, disable clip-bit writes when cleaning
                    // up backward triangles. Clockwise only fills in forward
                    // triangles.
                    ? 0x7f
                    : (effectiveDrawContents.isClipUpdate ? 0xff : 0x7f);
            pipelineState->stencilReference = 0x80;
            pipelineState->stencilFrontOps = {
                .failOp = StencilOp::decrClamp, // Don't wrap; 0 must stay 0
                                                // outside the clip.
                .passOp = effectiveDrawContents.isClipUpdate
                              ? StencilOp::replace
                              : StencilOp::keep,
                .depthFailOp = StencilOp::keep,
                .compareOp = StencilCompareOp::equal,
            };
            pipelineState->stencilBackOps = {
                .failOp = StencilOp::keep,
                .passOp = effectiveDrawContents.isClipUpdate
                              ? StencilOp::replace
                              : StencilOp::zero,
                .depthFailOp = StencilOp::keep,
                .compareOp = StencilCompareOp::less,
            };
            pipelineState->stencilDoubleSided = true;
            stencilKey = 4;
            break;
        }

        case DrawType::msaaMidpointFanPathsStencil:
        {
            // Just stencil the path into the stencil buffer. This is used for
            // nested clip updates and for evenOdd paths.
            assert(drawContents & (DrawContents::evenOddFill) ||
                   (drawContents & kNestedClipUpdateMask) ==
                       kNestedClipUpdateMask);
            effectiveDrawContents.isEvenOddFill =
                drawContents & DrawContents::evenOddFill;
            effectiveDrawContents.hasActiveClip =
                drawContents & DrawContents::activeClip;
            pipelineState->stencilCompareMask = 0xff;
            pipelineState->stencilWriteMask =
                effectiveDrawContents.isEvenOddFill ? 0x1 : 0x7f;
            pipelineState->stencilReference = 0x80;
            // Decrement front-facing triangles so the MSB is set when
            // clockwise.
            pipelineState->stencilFrontOps = {
                .failOp = StencilOp::keep,
                .passOp = StencilOp::decrWrap,
                .depthFailOp = StencilOp::keep,
                .compareOp = effectiveDrawContents.hasActiveClip
                                 ? StencilCompareOp::lessOrEqual
                                 : StencilCompareOp::always,
            };
            pipelineState->stencilBackOps = {
                .failOp = pipelineState->stencilFrontOps.failOp,
                .passOp = StencilOp::incrWrap,
                .depthFailOp = pipelineState->stencilFrontOps.depthFailOp,
                .compareOp = pipelineState->stencilFrontOps.compareOp,
            };
            pipelineState->stencilDoubleSided = true;
            stencilKey = 5;
            break;
        }

        case DrawType::msaaMidpointFanPathsCover:
        {
            // Draw & reset stencil winding numbers. This is only needed for
            // evenOdd paths.
            assert(drawContents & DrawContents::evenOddFill);
            effectiveDrawContents.isClipUpdate =
                drawContents & DrawContents::clipUpdate;
            pipelineState->stencilCompareMask = 0x7f;
            pipelineState->stencilWriteMask =
                effectiveDrawContents.isClipUpdate ? 0xff : 0x1;
            pipelineState->stencilReference = 0x80;
            pipelineState->stencilFrontOps = {
                .failOp = StencilOp::keep,
                .passOp = effectiveDrawContents.isClipUpdate
                              ? StencilOp::replace
                              : StencilOp::zero,
                .depthFailOp = StencilOp::keep,
                .compareOp = StencilCompareOp::notEqual,
            };
            pipelineState->stencilDoubleSided = false;
            stencilKey = 6;
            break;
        }

        case DrawType::msaaStencilClipReset:
        {
            if ((drawContents & kNestedClipUpdateMask) == kNestedClipUpdateMask)
            {
                // 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.)
                effectiveDrawContents.isClockwiseFill =
                    drawContents & DrawContents::clockwiseFill;
                pipelineState->stencilCompareMask =
                    effectiveDrawContents.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 = {
                    .failOp = StencilOp::zero,
                    .passOp = StencilOp::replace,
                    .depthFailOp = StencilOp::keep,
                    .compareOp = StencilCompareOp::less,
                };
                pipelineState->stencilDoubleSided = false;
                stencilKey = 7;
            }
            else
            {
                // Clear the entire previous clip.
                pipelineState->stencilCompareMask = 0xff;
                pipelineState->stencilWriteMask = 0xff;
                pipelineState->stencilReference = 0x00;
                pipelineState->stencilFrontOps = {
                    .failOp = StencilOp::keep,
                    .passOp = StencilOp::zero,
                    .depthFailOp = StencilOp::keep,
                    .compareOp = StencilCompareOp::notEqual,
                };
                pipelineState->stencilDoubleSided = false;
                stencilKey = 8;
            }
            break;
        }

        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
        {
            pipelineState->stencilTestEnabled = false;
            pipelineState->stencilWriteMask = 0;
            break;
        }

        case DrawType::interiorTriangulation:
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
            RIVE_UNREACHABLE();
    }

    assert(stencilKey != 0 || drawType == DrawType::renderPassInitialize ||
           drawType == DrawType::renderPassResolve);
    assert(stencilKey < 1 << 4);
    if (effectiveDrawContents.hasActiveClip)
        stencilKey |= (1 << 4);
    if (effectiveDrawContents.isClipUpdate)
        stencilKey |= (1 << 5);
    if (effectiveDrawContents.isClockwiseFill)
        stencilKey |= (1 << 6);
    if (effectiveDrawContents.isEvenOddFill)
        stencilKey |= (1 << 7);
    return stencilKey;
}

static CullFace get_cull_face(DrawType drawType)
{
    switch (drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::interiorTriangulation:
        case DrawType::atlasBlit:
        case DrawType::msaaStrokes:
        case DrawType::msaaMidpointFans:
        case DrawType::msaaStencilClipReset:
            return CullFace::counterclockwise;
        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFanStencilReset:
            // 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::msaaMidpointFanPathsStencil:
        case DrawType::msaaMidpointFanPathsCover:
        case DrawType::msaaOuterCubics:
        case DrawType::renderPassResolve:
        case DrawType::renderPassInitialize:
            return CullFace::none;
    }
    RIVE_UNREACHABLE();
}

static BlendEquation get_blend_equation(
    const FlushDescriptor& flushDesc,
    const DrawBatch& batch,
    const PlatformFeatures& platformFeatures)
{
    switch (flushDesc.interlockMode)
    {
        case InterlockMode::rasterOrdering:
        case InterlockMode::atomics:
        case InterlockMode::clockwise:
            return flushDesc.fixedFunctionColorOutput ? BlendEquation::srcOver
                                                      : BlendEquation::none;

        case InterlockMode::clockwiseAtomic:
            if ((batch.shaderMiscFlags &
                 gpu::ShaderMiscFlags::borrowedCoveragePass) ||
                batch.drawType == DrawType::renderPassInitialize)
            {
                return BlendEquation::none;
            }
            else
            {
                // clockwiseAtomic uses src-over to accumulate coverage, even
                // with advanced blend.
                return BlendEquation::srcOver;
            }

        case InterlockMode::msaa:
            if (batch.drawContents & DrawContents::opaquePaint)
            {
                return BlendEquation::none;
            }
            else if (!platformFeatures.supportsBlendAdvancedKHR ||
                     batch.firstBlendMode == 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(batch.drawType != DrawType::renderPassInitialize &&
                       batch.drawType != DrawType::renderPassResolve);
                return BlendEquation::srcOver;
            }
            else
            {
                // When m_platformFeatures.supportsBlendAdvancedKHR is true in
                // MSAA mode, the renderContext does not combine draws that have
                // different blend modes.
                assert(batch.drawType != DrawType::renderPassInitialize &&
                       batch.drawType != DrawType::renderPassResolve);
                return static_cast<BlendEquation>(batch.firstBlendMode);
            }
    }

    RIVE_UNREACHABLE();
}

static bool get_color_writemask(const FlushDescriptor& flushDesc,
                                const DrawBatch& batch)
{
    switch (batch.drawType)
    {
        case DrawType::midpointFanPatches:
        case DrawType::midpointFanCenterAAPatches:
        case DrawType::outerCurvePatches:
        case DrawType::interiorTriangulation:
        case DrawType::atlasBlit:
        case DrawType::imageRect:
        case DrawType::imageMesh:
        case DrawType::renderPassInitialize:
        case DrawType::renderPassResolve:
            if (batch.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 flushDesc.fixedFunctionColorOutput ||
                   flushDesc.interlockMode == InterlockMode::msaa;
        case DrawType::msaaStrokes:
        case DrawType::msaaOuterCubics:
            return true;
        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFanPathsStencil:
        case DrawType::msaaStencilClipReset:
            return false;
        case DrawType::msaaMidpointFans:
        case DrawType::msaaMidpointFanPathsCover:
            return !(batch.drawContents & DrawContents::clipUpdate);
        case DrawType::msaaMidpointFanStencilReset:
            // For clockwise fill, disable color writes when cleaning up
            // backward triangles. Clockwise only fills in forward triangles.
            return !(batch.drawContents &
                     (DrawContents::clockwiseFill | DrawContents::clipUpdate));
    }
    return false;
}

void get_pipeline_state(const DrawBatch& batch,
                        const FlushDescriptor& flushDesc,
                        const PlatformFeatures& platformFeatures,
                        PipelineState* pipelineState)
{
#ifndef NDEBUG
    // Ensure drawType is compatible with the interlock mode.
    switch (batch.drawType)
    {
        case DrawType::atlasBlit:
        case DrawType::imageMesh:
            break;

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

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

        case DrawType::renderPassInitialize:
            assert(flushDesc.interlockMode == InterlockMode::atomics ||
                   flushDesc.interlockMode == InterlockMode::msaa ||
                   flushDesc.interlockMode == InterlockMode::clockwiseAtomic);
            break;

        case DrawType::msaaStrokes:
        case DrawType::msaaMidpointFans:
        case DrawType::msaaMidpointFanBorrowedCoverage:
        case DrawType::msaaMidpointFanStencilReset:
        case DrawType::msaaMidpointFanPathsStencil:
        case DrawType::msaaMidpointFanPathsCover:
        case DrawType::msaaOuterCubics:
        case DrawType::msaaStencilClipReset:
            assert(flushDesc.interlockMode == InterlockMode::msaa);
            break;
    }
#endif

    get_depth_state(flushDesc.interlockMode,
                    batch.drawType,
                    batch.drawContents,
                    pipelineState);
    uint8_t stencilKey = get_stencil_settings(flushDesc.interlockMode,
                                              batch.drawType,
                                              batch.drawContents,
                                              pipelineState);
    pipelineState->cullFace = get_cull_face(batch.drawType);
    pipelineState->blendEquation =
        get_blend_equation(flushDesc, batch, platformFeatures);
    pipelineState->colorWriteEnabled = get_color_writemask(flushDesc, batch);

    // Work out a pipeline key (for backends that cache pipelines objects).
    uint32_t key = pipelineState->depthTestEnabled;
    key = (key << 1) | static_cast<uint32_t>(pipelineState->depthWriteEnabled);
    key = (key << 8) | stencilKey;
    assert(static_cast<uint32_t>(pipelineState->cullFace) < 1 << 2);
    key = (key << 2) | static_cast<uint32_t>(pipelineState->cullFace);
    assert(static_cast<uint32_t>(pipelineState->blendEquation) < 1 << 5);
    key = (key << 5) | static_cast<uint32_t>(pipelineState->blendEquation);
    key = (key << 1) | static_cast<uint32_t>(pipelineState->colorWriteEnabled);
    assert(key < 1 << PipelineState::UNIQUE_KEY_BIT_COUNT);
    pipelineState->uniqueKey = key;
}

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

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