/*
 * Copyright 2022 Rive
 */

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

#include <cmath>
#include <limits>

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

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

static_assert(DSMidpointFanFillPatchStrideLog2 == DS_MIDPOINT_FAN_STRIDE_LOG2);
static_assert(DSOuterCubicFillPatchStrideLog2 == DS_OUTER_CUBIC_STRIDE_LOG2);
static_assert(DSVertexFlagsShift == VERTEX_FLAGS_SHIFT);
static_assert(
    DSVertexFlag_DisableColorWrite == VERTEX_FLAG_DISABLE_COLOR_WRITE);
static_assert(DSVertexFlag_OuterCubicFill == VERTEX_FLAG_OUTER_CUBIC_FILL);
static_assert(DSVertexFlag_StrokeDepthPass == VERTEX_FLAG_STROKE_DEPTH_PASS);
static_assert(DSVertexFlag_AAPolarStroke == VERTEX_FLAG_AA_POLAR_STROKE);
static_assert(DSStrokePatchStrideLog2 == DS_STROKE_STRIDE_LOG2);
static_assert(DSAAStrokePatchStrideLog2 == DS_AA_STROKE_STRIDE_LOG2);

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

// Stroke constants. (A stroke that spans N segments has N+1 spokes.)
static_assert(
    (MIDPOINT_FAN_PATCH_SEGMENT_SPAN + 1)
        << DS_STROKE_LANES_PER_SPOKE_LOG2(/*aaStroke=*/false) <=
    DS_STROKE_PATCH_STRIDE(/*aaStroke=*/false));
static_assert(
    (MIDPOINT_FAN_PATCH_SEGMENT_SPAN + 1)
        << DS_STROKE_LANES_PER_SPOKE_LOG2(/*aaStroke=*/true) <=
    DS_STROKE_PATCH_STRIDE(/*aaStroke=*/true));
// Since index patterns use a pow2 vertex stride, their (somewhat sparse) vertex
// IDs span the entire uint16 range.
static_assert(
    DS_STROKE_PATCH_STRIDE(/*aaStroke=*/false) * DSStrokePatchMaxReps ==
    1u << 16);
static_assert(
    DS_STROKE_PATCH_STRIDE(/*aaStroke=*/true) * DSAAStrokePatchMaxReps ==
    1u << 16);

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

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

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

    case InterlockMode::clockwise:
    {
      static constexpr DrawType types[] = {
          DrawType::midpointFanPatches,
          DrawType::midpointFanCenterAAPatches,
          DrawType::outerCurvePatches,
          DrawType::interiorTriangulation,
          DrawType::featherAtlasBlit,
          DrawType::imageMesh,
      };
      return make_span(types);
    }
    case InterlockMode::atomics:
    {
      static constexpr DrawType types[] = {
          DrawType::midpointFanPatches,
          DrawType::midpointFanCenterAAPatches,
          DrawType::outerCurvePatches,
          DrawType::interiorTriangulation,
          DrawType::featherAtlasBlit,
          DrawType::imageRect,
          DrawType::imageMesh,
          DrawType::renderPassInitialize,
          DrawType::renderPassResolve,
      };
      return make_span(types);
    }
    case InterlockMode::clockwiseAtomic:
    {
      static constexpr DrawType types[] = {
          DrawType::midpointFanPatches,
          DrawType::midpointFanCenterAAPatches,
          DrawType::outerCurvePatches,
          DrawType::interiorTriangulation,
          DrawType::featherAtlasBlit,
          DrawType::imageMesh,
          DrawType::clipReset,
          DrawType::renderPassInitialize,
      };
      return make_span(types);
    }
    case InterlockMode::depthStencil:
    {
      static constexpr DrawType types[] = {
          DrawType::featherAtlasBlit,
          DrawType::imageMesh,
          DrawType::stencilMidpointFanBorrowedCoverage,
          DrawType::stencilMidpointFans,
          DrawType::stencilMidpointFanReset,
          DrawType::stencilMidpointFanWinding,
          DrawType::stencilMidpointFanCover,
          DrawType::stencilDynamicMidpointFans,
          DrawType::stencilOuterCubicBorrowedCoverage,
          DrawType::stencilOuterCubics,
          DrawType::stencilOuterCubicReset,
          DrawType::stencilDynamicOuterCubics,
          DrawType::stencilOuterCubicWinding,
          DrawType::stencilOuterCubicCover,
          DrawType::depthStrokes,
          DrawType::depthAAStrokes,
          DrawType::depthAAOuterHairline,
          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::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:
    case DrawType::depthAAOuterHairline:
      // A layer-mask apply is a unit-rect fill, so it only ever lands on
      // the depthStencil fill types, plus the hairline pass that antialiases
      // an inkbleed fill's edge. Every subpass of it carries the flag,
      // including the stencil-only ones, where it is inert because color
      // writes are off.
      if (mode == InterlockMode::depthStencil)
      {
        outFlags |= ShaderMiscFlags::layerMask;
      }
      break;

    case DrawType::featherAtlasBlit:
    case DrawType::imageRect:
    case DrawType::imageMesh:
    case DrawType::depthStrokes:
    case DrawType::depthAAStrokes:
      break;
  }

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

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

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

  return outFlags;
}

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

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

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

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

    case InterlockMode::depthStencil:
      return ShaderMiscFlags::fixedFunctionColorOutput |
             ShaderMiscFlags::msaaDstRead | ShaderMiscFlags::layerMask;
  }
  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;
          }
          if (enums::is_flag_set(curMiscFlags, ShaderMiscFlags::layerMask))
          {
            // A backend that has not implemented the blend
            // equation must never be asked to build it.
            if (!platformFeatures.supportsDepthStencilLayerMask)
            {
              continue;
            }
            // The apply is always a srcOver draw, so it always gets
            // fixedFunctionColorOutput and never a dst read.
            if (!enums::is_flag_set(
                    curMiscFlags,
                    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:
      return 0;
    // depthStencil fills have their own, attribute-free vertex
    // shader, so they can't share a key with the patch draws above.
    case DrawType::stencilMidpointFanBorrowedCoverage:
    case DrawType::stencilDynamicMidpointFans:
    case DrawType::stencilDynamicOuterCubics:
    case DrawType::stencilMidpointFans:
    case DrawType::stencilMidpointFanReset:
    case DrawType::stencilMidpointFanWinding:
    case DrawType::stencilMidpointFanCover:
    case DrawType::stencilOuterCubicBorrowedCoverage:
    case DrawType::stencilOuterCubics:
    case DrawType::stencilOuterCubicReset:
    case DrawType::stencilOuterCubicWinding:
    case DrawType::stencilOuterCubicCover:
      assert(interlockMode == InterlockMode::depthStencil);
      return 1;
    case DrawType::depthStrokes:
    case DrawType::depthAAStrokes:
      assert(interlockMode == InterlockMode::depthStencil);
      // Specialized with @DS_POLAR_STROKE, so need their own shader.
      return 2;
    case DrawType::depthAAOuterHairline:
      assert(interlockMode == InterlockMode::depthStencil);
      // Specialized with @DS_HAIRLINE_STROKE, so needs its own shader.
      return 3;
    case DrawType::interiorTriangulation:
      return 4;
    case DrawType::featherAtlasBlit:
      return 5;
    case DrawType::imageRect:
      return 6;
    case DrawType::imageMesh:
      return 7;
    case DrawType::clipReset:
      assert(
          interlockMode == InterlockMode::clockwiseAtomic ||
          interlockMode == InterlockMode::depthStencil);
      return 8;
    case DrawType::renderPassInitialize:
      assert(
          interlockMode == InterlockMode::atomics ||
          interlockMode == InterlockMode::depthStencil ||
          interlockMode == InterlockMode::clockwiseAtomic);
      return 9;
    case DrawType::renderPassResolve:
      assert(
          interlockMode == InterlockMode::rasterOrdering ||
          interlockMode == InterlockMode::atomics ||
          interlockMode == InterlockMode::depthStencil);
      return 10;
  }
  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;
    case ShaderFeatures::ENABLE_ANGULAR_GRADIENT:
      return GLSL_ENABLE_ANGULAR_GRADIENT;
  }
  RIVE_UNREACHABLE();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  assert(borderEdgeVerticesIdx == fanVerticesIdx);

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

// Writes one patch type's depthStencil fill region, at its own base within the
// shared patch index buffer. Since multiple drawTypes may share one region,
// this only needs to be called once per group.
static void generateDepthStencilFillIndices(
    DrawType drawType,
    uint16_t indices[kPatchIndexBufferCount])
{
  bool isOuterCubic;
  switch (drawType)
  {
    case DrawType::stencilMidpointFans:
      isOuterCubic = false;
      break;
    case DrawType::stencilOuterCubics:
      isOuterCubic = true;
      break;
    default:
      RIVE_UNREACHABLE();
  }
  const uint32_t fanSegmentSpan = isOuterCubic ? OuterCubicPatchSegmentSpan
                                               : kMidpointFanPatchSegmentSpan;
  const uint32_t patchCount = dsPatchMaxReps(drawType);
  indices += isOuterCubic ? DSOuterCubicFillBaseIndex
                          : DSMidpointFanFillBaseIndex;

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

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

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

// Writes one depthStencil stroke region, at its own base within the shared
// patch index buffer.
static void generateDepthStencilStrokeIndices(
    uint16_t indices[kPatchIndexBufferCount],
    DrawType drawType)
{
  const bool isAAStroke = drawType == DrawType::depthAAStrokes;
  assert(isAAStroke || drawType == DrawType::depthStrokes);
  const uint32_t lanesPerSpoke = 1u
                                 << DS_STROKE_LANES_PER_SPOKE_LOG2(isAAStroke);
  const uint32_t bandCount = lanesPerSpoke - 1;
  const uint32_t patchCount = dsPatchMaxReps(drawType);
  const uint32_t patchStrideLog2 = dsPatchStrideLog2(drawType);
  indices += isAAStroke ? DSAAStrokePatchBaseIndex : DSStrokePatchBaseIndex;

  size_t indexCount = 0;
  for (uint32_t patch = 0; patch < patchCount; ++patch)
  {
    const uint32_t patchBaseVertex = patch << patchStrideLog2;
    for (uint32_t seg = 0; seg < kMidpointFanPatchSegmentSpan; ++seg)
    {
      for (uint32_t b = 0; b < bandCount; ++b)
      {
        // Emit the 2-triangle quad for band 'b' at segment 'seg'.
        // Column-major to keep shared vertices close together for
        // the LRU post-transform vertex cache.
        const uint32_t v0 = patchBaseVertex + seg * lanesPerSpoke + b;
        const uint32_t v1 = v0 + lanesPerSpoke;
        const uint32_t v2 = v0 + 1;
        const uint32_t v3 = v1 + 1;
        for (uint32_t v : {v0, v1, v2, v2, v1, v3})
        {
          indices[indexCount++] = math::lossless_numeric_cast<uint16_t>(v);
        }
      }
    }
  }

  assert(
      indexCount == patchCount * kMidpointFanPatchSegmentSpan * 6 * bandCount);
}

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

  for (auto drawType :
       {DrawType::stencilMidpointFans, DrawType::stencilOuterCubics})
  {
    generateDepthStencilFillIndices(drawType, indices);
  }
  for (auto drawType : {DrawType::depthStrokes, DrawType::depthAAStrokes})
  {
    generateDepthStencilStrokeIndices(indices, drawType);
  }
}

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::angularGradient == ANGULAR_GRADIENT_PAINT_TYPE);

  // The gradient paint types need to fit inside of 3 bits for the packing in
  // gradient_packing_common.hlsl to work.
  static_assert(LINEAR_GRADIENT_PAINT_TYPE < 8u);
  static_assert(RADIAL_GRADIENT_PAINT_TYPE < 8u);
  static_assert(ANGULAR_GRADIENT_PAINT_TYPE < 8u);
}

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

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

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

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

FlushUniforms::FlushUniforms(
    const FlushDescriptor& flushDesc,
    const PlatformFeatures& platformFeatures)
    : m_inverseViewports(flushDesc, platformFeatures)
    , m_renderTargetWidth(flushDesc.renderTarget->width())
    , m_renderTargetHeight(flushDesc.renderTarget->height())
    , m_colorClearValue(SwizzleRiveColorToRGBAPremul(flushDesc.colorClearValue))
    , m_coverageClearValue(flushDesc.coverageClearValue)
    , m_renderTargetUpdateBounds(flushDesc.renderTargetUpdateBounds)
    , m_featherAtlasTextureInverseSize(
          1.f / flushDesc.featherAtlasTextureWidth,
          1.f / flushDesc.featherAtlasTextureHeight)
    , m_featherAtlasContentInverseViewport(
          2.f / flushDesc.featherAtlasContentWidth,
          (platformFeatures.clipSpaceBottomUp !=
                   platformFeatures.framebufferBottomUp
               ? -2.f
               : 2.f) /
              flushDesc.featherAtlasContentHeight)
    , m_coverageBufferPrefix(flushDesc.coverageBufferPrefix)
    , m_epsilonForPseudoMemoryBarrier(1e-9f)
    , m_pathIDGranularity(platformFeatures.pathIDGranularity)
    , m_vertexDiscardValue(std::numeric_limits<float>::quiet_NaN())
    , m_mipMapLODBias(MIP_MAP_LOD_BIAS)
    , m_maxPathId(flushDesc.pathCount)
    , m_ditherScale(
          (flushDesc.ditherMode == DitherMode::none) ? 0.0f : (1.0f / 256.0f))
    , m_ditherBias(m_ditherScale * -0.5f)
    ,
    // Negate dither when storing to RGB10, in order to get some more variation.
    m_ditherConversionToRGB10(
        (flushDesc.ditherMode == DitherMode::none)
            ? 0.0f
            : (-1.0f / 1024.0f) / m_ditherScale)
    , m_wireframeEnabled(flushDesc.wireframe)
    , m_renderTargetBottomUp(flushDesc.renderTarget->bottomUp(platformFeatures))
    , m_gradTextureYScale(1.f / flushDesc.gradTextureHeight)
    , 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];
}

PathData::PathData(
    const PathDraw& draw,
    uint32_t zIndex,
    InterlockMode interlockMode,
    const PlatformFeatures& platformFeatures)
{
  assert(zIndex < (1u << 16));

  // First & second uint32x4s.
  write_matrix(m_matrix, draw.paintMatrix());

  uint32_t localParams = paint_type_to_glsl_id(draw.paintType()) |
                         (ConvertBlendModeToPLSBlendMode(draw.blendMode())
                          << 4);
  if (draw.isNonZeroFill())
    localParams |= PAINT_FLAG_NON_ZERO_FILL;
  else if (draw.isEvenOddFill())
    localParams |= PAINT_FLAG_EVEN_ODD_FILL;
  if (draw.hasClipRect())
    localParams |= PAINT_FLAG_HAS_CLIP_RECT;
  if (draw.hasImageTexture())
    localParams |= PAINT_FLAG_HAS_IMAGE;
  if (draw.strokeRadius() != 0 || draw.featherRadius() != 0 ||
      draw.additionalOutset() != 0)
    localParams |= PAINT_FLAG_LOAD_RADIUS_AND_OUTSET_PATH_DATA;
  if (draw.isLayerMask())
  {
    localParams |= PAINT_FLAG_LAYER_MASK;
    // Masked so an unknown mode can't spill into the clipID bits above.
    localParams |= (static_cast<uint32_t>(draw.layerMaskMode())
                    << PAINT_LAYER_MASK_MODE_SHIFT) &
                   PAINT_LAYER_MASK_MODE_MASK;
  }
  // depthStencil uses a zIndex instead of clipIDs. depthStencil does clipping
  // in the stencil buffer.
  if (interlockMode == InterlockMode::depthStencil)
    localParams |= zIndex << 16;
  else if (draw.paintType() == PaintType::clipUpdate)
    localParams |= draw.simplePaintValue().outerClipID << 16;
  else
    localParams |= draw.clipID() << 16;
  m_params = localParams;

  switch (draw.paintType())
  {
    case PaintType::solidColor:
    {
      // GLSL expects little-endian RGBA.
      if (draw.blendMode() == BlendMode::srcOver)
      {
        // srcOver draws are premultiplied with additiveness baked into alpha.
        m_color = swizzleRiveColorToRGBAPremulAdditive(
            draw.simplePaintValue().color,
            1.f - draw.additiveness());
      }
      else if (
          interlockMode == InterlockMode::depthStencil &&
          platformFeatures.supportsBlendAdvancedKHR)
      {
        // KHR-blend draws take premultiplied alpha and ignore additiveness.
        m_color = SwizzleRiveColorToRGBAPremul(draw.simplePaintValue().color);
      }
      else
      {
        // Advanced-blend draws take unmultiplied color and ignore additiveness.
        m_color = SwizzleRiveColorToRGBA(draw.simplePaintValue().color);
      }
      break;
    }

    case PaintType::linearGradient:
    case PaintType::radialGradient:
    case PaintType::angularGradient:
    {
      m_gradientAdditivenessComplement = 1.0f - draw.additiveness();
      break;
    }

    case PaintType::clipUpdate:
    {
      m_shiftedClipReplacementID = draw.clipID() << 16;
      break;
    }
  }

  // Third uint32x4.
  m_strokeRadius = draw.strokeRadius(); // 0 if the path is filled.
  m_featherRadius = draw.featherRadius();
  m_additionalOutset = draw.additionalOutset();

  // Fourth uint32x4. A draw may allocate either a coverage buffer range or a
  // feather atlas region.
  if (draw.coverageType() == PathDraw::CoverageType::clockwiseAtomic)
  {
    const CoverageBufferRange& range = draw.coverageBufferRange();
    m_coverageBufferRange.offset = range.offset;
    m_coverageBufferRange.pitch = range.pitch;
    m_coverageBufferRange.offsetX = range.offsetX;
    m_coverageBufferRange.offsetY = range.offsetY;
  }
  else if (draw.coverageType() == PathDraw::CoverageType::featherAtlas)
  {
    const AtlasTransform& atlasTransform = draw.featherAtlasTransform();
    m_featherAtlasTransform.scaleFactor = atlasTransform.scaleFactor;
    m_featherAtlasTransform.translateX = atlasTransform.translateX;
    m_featherAtlasTransform.translateY = atlasTransform.translateY;
  }
}

PathData::PathData(ColorInt clearColor)
{
  // A premultiplied srcOver solid color with no clip.
  m_params = paint_type_to_glsl_id(PaintType::solidColor) |
             (ConvertBlendModeToPLSBlendMode(BlendMode::srcOver) << 4);
  m_color = swizzleRiveColorToRGBAPremulAdditive(clearColor, 1.f);
}

void getGradientMatrixAndCoord(
    const Gradient* gradient,
    ColorRampLocation rampLocation,
    GradTextureLayout gradTextureLayout,
    const Mat2D& inverseGradientTransform,
    const Mat2D& viewMatrix,
    const RenderTarget* renderTarget,
    const PlatformFeatures& platformFeatures,
    Mat2D& paintMatrixOut,
    int32_t& gradXOut,
    uint32_t& gradYOut)
{
  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());
  }

  paintMatrixOut = inverseGradientTransform * paintMatrixOut;

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

    case PaintType::angularGradient:
      // paintMatrixOut is unchanged.
      break;

    case PaintType::clipUpdate:
    case PaintType::solidColor:
      RIVE_UNREACHABLE();
  }

  gradYOut = rampLocation.row;

  if (rampLocation.isComplex())
  {
    // a negative X signifies a complex gradient.
    gradXOut = -1;
    gradYOut += gradTextureLayout.complexOffsetY;
  }
  else
  {
    gradXOut = rampLocation.col;
  }
}

void PaintAuxData::set(
    const Mat2D& viewMatrix,
    const Mat2D& imageMatrix,
    PaintType paintType,
    SimplePaintValue simplePaintValue,
    GradTextureLayout gradTextureLayout,
    const Gradient* gradient,
    const Mat2D& inverseGradientTransform,
    const Texture* imageTexture,
    const ClipRectInverseMatrix* clipRectInverseMatrix,
    const RenderTarget* renderTarget,
    const PlatformFeatures& platformFeatures)
{
  switch (paintType)
  {
    case PaintType::linearGradient:
    case PaintType::radialGradient:
    case PaintType::angularGradient:
    {
      assert(gradient != nullptr);
      Mat2D paintMatrix;
      // Need local versions of these because the members are `volatile`
      // and won't pass by reference to the function.
      int32_t gradTextureX;
      uint32_t gradTextureY;
      getGradientMatrixAndCoord(
          gradient,
          simplePaintValue.colorRampLocation,
          gradTextureLayout,
          inverseGradientTransform,
          viewMatrix,
          renderTarget,
          platformFeatures,
          paintMatrix,
          gradTextureX,
          gradTextureY);
      m_gradTextureX = float(gradTextureX);
      m_gradTextureY = float(gradTextureY);
      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,
    int32_t gradTextureX,
    uint32_t 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 (plus the leftover padding value)
  STATIC_ASSERT_ATTRIB(
      ImageRectInstance,
      m_gradTextureX,
      IMAGE_RECT_PACKED_GRADIENT_DATA);
  static_assert(
      offsetof(ImageRectInstance, m_gradTextureY) ==
      offsetof(ImageRectInstance, m_gradTextureX) + 1 * sizeof(float));
  static_assert(
      offsetof(ImageRectInstance, m_gradientType) ==
      offsetof(ImageRectInstance, m_gradTextureX) + 2 * sizeof(float));
  static_assert(
      offsetof(ImageRectInstance, m_padding) ==
      offsetof(ImageRectInstance, m_gradTextureX) + 3 * sizeof(float));

  write2x2(m_imageMatrix, imageMatrix);
  write2x2(m_gradientMatrix, gradientMatrix);
  writeTranslate(m_imageTranslate, imageMatrix);
  writeTranslate(m_gradientTranslate, gradientMatrix);
  m_gradTextureX = float(gradTextureX);
  m_gradTextureY = float(gradTextureY);
  m_gradientType = gradientType;
}

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

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

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

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

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

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

float find_transformed_area(const AABB& bounds, const Mat2D& matrix)
{
  // When applying an affine transform to a shape, the shape's area gets
  // multiplied by |det(M)|.
  return fabsf(matrix.determinant()) * bounds.width() * bounds.height();
}

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::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::depthStrokes:
    case DrawType::depthAAStrokes:
    case DrawType::depthAAOuterHairline:
      return {.depthTestEnabled = true, .depthWriteEnabled = true};
      break;

    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:
    case DrawType::depthAAStrokes:
    case DrawType::depthAAOuterHairline:
      // 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::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::stencilDynamicMidpointFans:
    case DrawType::stencilDynamicOuterCubics:
      // The dynamic types do the union of the above 3 sets of drawTypes,
      // so their drawContentsMask are the union of all 3.
      return {
          StencilType::forwardClippedByBackward,
          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::stencilDynamicMidpointFans:
    case DrawType::stencilDynamicOuterCubics:
    case DrawType::stencilMidpointFans:
    case DrawType::stencilOuterCubics:
    case DrawType::clipReset:
    case DrawType::depthStrokes:
    case DrawType::depthAAStrokes:
    case DrawType::depthAAOuterHairline:
      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(shaderMiscFlags, ShaderMiscFlags::layerMask))
      {
        // A layer-mask apply scales what is already in the target.
        // src-over cannot express that: emitting (0, 0, 0, 1 - f) gets
        // the color right but writes 1 - f into the alpha of every
        // transparent texel, so a masked-out region turns opaque black.
        assert(platformFeatures.supportsDepthStencilLayerMask);
        assert(!enums::is_flag_set(drawContents, DrawContents::opaquePaint));
        return BlendEquation::layerMask;
      }
      if (enums::is_flag_set(drawContents, DrawContents::opaquePaint))
      {
        // A dynamic-state draw may suppress color writes by outputting
        // color == 0, which only works if blending is ENABLED (if you
        // output "color == 0" with blending enabled, it's a no-op like
        // we want; if you output "color == 0" with blending DISABLED,
        // the pixel turns blank and erases whatever used to be there).
        // NOTE: Other than disabling color write, this output is
        // equivalent with or without blend, since opaquePaint emits
        // alpha == 1.
        return drawTypeHasPipelineDynamicState(drawType)
                   ? BlendEquation::srcOver
                   : BlendEquation::none;
      }
      else if (
          !platformFeatures.supportsBlendAdvancedKHR ||
          blendMode == BlendMode::srcOver)
      {
        // Normal and in-shader blending both use src-over hardware
        // blend coefficients.
        //
        // When drawing an advanced blend mode, the shader only does the
        // "color" portion of the blend equation, and relies on the
        // hardware blend unit to finish the "alpha" portion.
        assert(
            drawType != DrawType::renderPassInitialize &&
            drawType != DrawType::renderPassResolve);
        return BlendEquation::srcOver;
      }
      else
      {
        // When m_platformFeatures.supportsBlendAdvancedKHR is true in
        // depthStencil mode, the renderContext does not combine draws
        // that have different blend modes.
        assert(
            drawType != DrawType::renderPassInitialize &&
            drawType != DrawType::renderPassResolve);
        return static_cast<BlendEquation>(blendMode);
      }
  }

  RIVE_UNREACHABLE();
}

bool get_color_write_enable(
    DrawType drawType,
    InterlockMode interlockMode,
    ShaderMiscFlags shaderMiscFlags,
    bool fixedFunctionColorOutput,
    DrawContents drawContents)
{
  switch (drawType)
  {
    case DrawType::midpointFanPatches:
    case DrawType::midpointFanCenterAAPatches:
    case DrawType::outerCurvePatches:
    case DrawType::interiorTriangulation:
    case DrawType::featherAtlasBlit:
    case DrawType::imageRect:
    case DrawType::imageMesh:
    case DrawType::renderPassInitialize:
    case DrawType::renderPassResolve:
      if (enums::any_flag_set(
              shaderMiscFlags,
              ShaderMiscFlags::clipUpdateOnly |
                  ShaderMiscFlags::borrowedCoveragePass))
      {
        // Clip updates and borrowed coverage passes don't output color.
        return false;
      }
      // We generate pipeline state under the assumption that pixel local
      // storage can still be written when colorWriteEnabled is false.
      // Disable color writes when we're rendering only to PLS.
      return fixedFunctionColorOutput ||
             interlockMode == InterlockMode::depthStencil;
    case DrawType::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);
    case DrawType::depthStrokes:
    case DrawType::depthAAStrokes:
    case DrawType::depthAAOuterHairline:
      return enums::no_flags_set(drawContents, 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);
}

DSDynamicFillPipelineStates::DSDynamicFillPipelineStates(
    const FlushDescriptor& flushDesc,
    const DrawBatch& batch,
    ShaderMiscFlags shaderMiscFlags,
    const PlatformFeatures& platformFeatures)
{
  assert(drawTypeHasPipelineDynamicState(batch.drawType));
  for (size_t i = 0; i < PassCount; ++i)
  {
    m_states[i] = get_pipeline_state(
        PassDrawTypes[i],
        flushDesc.interlockMode,
        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::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:
    case DrawType::depthStrokes:
    case DrawType::depthAAStrokes:
    case DrawType::depthAAOuterHairline:
      assert(interlockMode == InterlockMode::depthStencil);
      break;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

} // namespace rive::gpu
