/*
 * Copyright 2022 Rive
 */

// undef COVERAGE_TYPE first because this file gets included multiple times with
// different defines in the Metal library.
#undef COVERAGE_TYPE
#ifdef @ENABLE_FEATHER
  #define COVERAGE_TYPE float4
#else
  #define COVERAGE_TYPE half2
#endif

#ifdef @VERTEX
ATTR_BLOCK_BEGIN(Attrs)
  #if defined(@DRAW_INTERIOR_TRIANGLES) || defined(@FEATHER_ATLAS_BLIT)
ATTR(0, packed_float3, @a_triangleVertex);
  #else
// Unreal compiler breaks if these declarations are multi line.
// clang-format off
ATTR(0, float4, @a_patchVertexData); // [localVertexID, outset, fillCoverage, vertexType]
// clang-format on
ATTR(1, float4, @a_mirroredVertexData);
  #endif
ATTR_BLOCK_END
#endif

VARYING_BLOCK_BEGIN
NO_PERSPECTIVE VARYING(0, float4, v_paint);

#ifdef @FEATHER_ATLAS_BLIT
NO_PERSPECTIVE VARYING(1, float2, v_atlasCoord);
#elif !defined(@RENDER_MODE_DEPTH_STENCIL)
  #ifdef @DRAW_INTERIOR_TRIANGLES
@OPTIONALLY_FLAT VARYING(1, half, v_windingWeight);
  #else
NO_PERSPECTIVE VARYING(2, COVERAGE_TYPE, v_coverages);
  #endif //@DRAW_INTERIOR_TRIANGLES
@OPTIONALLY_FLAT VARYING(3, half, v_pathID);
#endif   // !@RENDER_MODE_DEPTH_STENCIL

#ifdef @ENABLE_CLIPPING
  #ifdef @FEATHER_ATLAS_BLIT
@OPTIONALLY_FLAT VARYING(4, half, v_clipID); // [clipID, outerClipID]
  #else
@OPTIONALLY_FLAT VARYING(4, half2, v_clipIDs); // [clipID, outerClipID]
  #endif
#endif // @ENABLE_CLIPPING
#if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_DEPTH_STENCIL)
NO_PERSPECTIVE VARYING(5, float4, v_clipRect);
#endif
#ifdef @ENABLE_ADVANCED_BLEND
@OPTIONALLY_FLAT VARYING(6, half, v_blendMode);
#endif
#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC
FLAT VARYING(7, uint2, v_coveragePlacement);
VARYING(8, float2, v_coverageCoord);
#endif
#ifdef @ENABLE_MODULATED_IMAGE
NO_PERSPECTIVE VARYING(9, float3, v_image);
#endif

VARYING_BLOCK_END

#ifdef @VERTEX

VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
{
  #if defined(@DRAW_INTERIOR_TRIANGLES) || defined(@FEATHER_ATLAS_BLIT)
  ATTR_UNPACK(_vertexID, attrs, @a_triangleVertex, float3);
  #else
  ATTR_UNPACK(_vertexID, attrs, @a_patchVertexData, float4);
  ATTR_UNPACK(_vertexID, attrs, @a_mirroredVertexData, float4);
  #endif

  VARYING_INIT(v_paint, float4);
  #if defined(@ENABLE_MODULATED_IMAGE)
  VARYING_INIT(v_image, float3);
  #endif

  #ifdef @FEATHER_ATLAS_BLIT
  VARYING_INIT(v_atlasCoord, float2);
  #elif !defined(@RENDER_MODE_DEPTH_STENCIL)
    #ifdef @DRAW_INTERIOR_TRIANGLES
  VARYING_INIT(v_windingWeight, half);
    #else
  VARYING_INIT(v_coverages, COVERAGE_TYPE);
    #endif //@DRAW_INTERIOR_TRIANGLES
  VARYING_INIT(v_pathID, half);
  #endif   // !@RENDER_MODE_DEPTH_STENCIL

  #ifdef @ENABLE_CLIPPING
    #ifdef @FEATHER_ATLAS_BLIT
  VARYING_INIT(v_clipID, half);
    #else
  VARYING_INIT(v_clipIDs, half2);
    #endif
  #endif // @ENABLE_CLIPPING
  #if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_DEPTH_STENCIL)
  VARYING_INIT(v_clipRect, float4);
  #endif
  #ifdef @ENABLE_ADVANCED_BLEND
  VARYING_INIT(v_blendMode, half);
  #endif
  #ifdef @RENDER_MODE_CLOCKWISE_ATOMIC
  VARYING_INIT(v_coveragePlacement, uint2);
  VARYING_INIT(v_coverageCoord, float2);
  #endif

  bool shouldDiscardVertex = false;
  uint pathID;
  float2 vertexPosition;
  #ifdef @RENDER_MODE_DEPTH_STENCIL
  ushort pathZIndex;
  #endif

  #ifdef @FEATHER_ATLAS_BLIT
  vertexPosition = unpack_atlas_coverage_vertex(
      @a_triangleVertex,
      pathID,
    #ifdef @RENDER_MODE_DEPTH_STENCIL
      pathZIndex,
    #endif
      v_atlasCoord VERTEX_CONTEXT_UNPACK);
  #elif defined(@DRAW_INTERIOR_TRIANGLES)
  vertexPosition = unpack_interior_triangle_vertex(
      @a_triangleVertex,
      pathID
    #ifdef @RENDER_MODE_DEPTH_STENCIL
      ,
      pathZIndex
    #else
      ,
      v_windingWeight
    #endif
          VERTEX_CONTEXT_UNPACK);
  #else // !@DRAW_INTERIOR_TRIANGLES
  float4 coverages;
  shouldDiscardVertex = !unpack_tessellated_path_vertex(
      @a_patchVertexData,
      @a_mirroredVertexData,
      _instanceID,
      pathID,
      vertexPosition
    #ifndef @RENDER_MODE_DEPTH_STENCIL
      ,
      coverages
    #else
      ,
      pathZIndex
    #endif
          VERTEX_CONTEXT_UNPACK);
    #ifndef @RENDER_MODE_DEPTH_STENCIL
      #ifdef @ENABLE_FEATHER
  v_coverages = coverages;
      #else
  v_coverages.xy = cast_float2_to_half2(coverages.xy);
      #endif
    #endif
  #endif // !DRAW_INTERIOR_TRIANGLES

  // The paint lives in the second half of the path record's second uint4.
  uint2 paintData = STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 1u).zw;

  #if !defined(@FEATHER_ATLAS_BLIT) && !defined(@RENDER_MODE_DEPTH_STENCIL)
  // Encode the integral pathID as a "half" that we know the hardware will see
  // as a unique value in the fragment shader.
  v_pathID = id_bits_to_f16(pathID, uniforms.pathIDGranularity);

  // Indicate even-odd fill rule by making pathID negative.
  if ((paintData.x & PAINT_FLAG_EVEN_ODD_FILL) != 0u)
    v_pathID = -v_pathID;
  #endif // !@FEATHER_ATLAS_BLIT && !@RENDER_MODE_DEPTH_STENCIL

  uint paintType = paintData.x & 0xfu;
  #ifdef @ENABLE_CLIPPING
  if (@ENABLE_CLIPPING)
  {
    uint clipIDBits = (paintType == CLIP_UPDATE_PAINT_TYPE ? paintData.y
                                                           : paintData.x) >>
                      16;
    half clipID = id_bits_to_f16(clipIDBits, uniforms.pathIDGranularity);
    // Negative clipID means to update the clip buffer instead of the color
    // buffer.
    if (paintType == CLIP_UPDATE_PAINT_TYPE)
      clipID = -clipID;
    #ifdef @FEATHER_ATLAS_BLIT
    v_clipID = clipID;
    #else
    v_clipIDs.x = clipID;
    #endif
  }
  #endif
  #ifdef @ENABLE_ADVANCED_BLEND
  if (@ENABLE_ADVANCED_BLEND)
  {
    v_blendMode = float((paintData.x >> 4) & 0xfu);
  }
  #endif

  // Paint matrices operate on the fragment shader's "_fragCoord", which
  // counts from memory row 0. A bottom up target needs it flipped into Rive
  // pixel space.
  float2 fragCoord = vertexPosition;
  #ifdef @ENABLE_RENDER_TARGET_BOTTOM_UP
  if (uniforms.renderTargetBottomUp != 0u)
  {
    fragCoord.y = float(uniforms.renderTargetHeight) - fragCoord.y;
  }
  #endif

  #ifdef @ENABLE_CLIP_RECT
  if (@ENABLE_CLIP_RECT)
  {
    // clipRectInverseMatrix transforms from pixel coordinates to a space
    // where the clipRect is the normalized rectangle: [-1, -1, 1, 1].
    float2x2 clipRectInverseMatrix = make_float2x2(STORAGE_BUFFER_LOAD4(
        @paintAuxBuffer,
        pathID * PAINT_AUX_ENTRY_ELEMENT_COUNT + 2u));
    float4 clipRectInverseTranslate = STORAGE_BUFFER_LOAD4(
        @paintAuxBuffer,
        pathID * PAINT_AUX_ENTRY_ELEMENT_COUNT + 3u);
    #ifndef @RENDER_MODE_DEPTH_STENCIL
    v_clipRect = find_clip_rect_coverage_distances(
        clipRectInverseMatrix,
        clipRectInverseTranslate.xy,
        fragCoord);
    #else  // !@RENDER_MODE_DEPTH_STENCIL => @RENDER_MODE_DEPTH_STENCIL
    set_clip_rect_plane_distances(
        clipRectInverseMatrix,
        clipRectInverseTranslate.xy,
        fragCoord CLIP_CONTEXT_UNPACK);
    #endif // @RENDER_MODE_DEPTH_STENCIL
  }
  #endif // ENABLE_CLIP_RECT

  // Unpack the paint once we have a position.
  if (paintType == SOLID_COLOR_PAINT_TYPE)
  {
    v_paint = float4(unpackUnorm4x8(paintData.y));
  }
  #if defined(@ENABLE_CLIPPING) && !defined(@FEATHER_ATLAS_BLIT)
  else if (@ENABLE_CLIPPING && paintType == CLIP_UPDATE_PAINT_TYPE)
  {
    half outerClipID = id_bits_to_f16(
        paintData.x >> 16,
        uniforms.pathIDGranularity);
    v_clipIDs.y = outerClipID;
  }
  #endif
  else
  {
    float2x2 paintMatrix = make_float2x2(STORAGE_BUFFER_LOAD4(
        @paintAuxBuffer,
        pathID * PAINT_AUX_ENTRY_ELEMENT_COUNT));
    float4 paintTranslate = STORAGE_BUFFER_LOAD4(
        @paintAuxBuffer,
        pathID * PAINT_AUX_ENTRY_ELEMENT_COUNT + 1u);

    float additivenessComplement = uintBitsToFloat(paintData.y);
    v_paint = packGradientData(
        fragCoord,
        paintMatrix,
        paintTranslate.xy,
        paintTranslate.zw,
        paintType,
        additivenessComplement,
        1.0); // coverage
  }

  #if defined(@ENABLE_MODULATED_IMAGE)
  if (@ENABLE_MODULATED_IMAGE && (paintData.x & PAINT_FLAG_HAS_IMAGE) != 0u)
  {
    float2x2 imageMatrix = make_float2x2(STORAGE_BUFFER_LOAD4(
        @paintAuxBuffer,
        pathID * PAINT_AUX_ENTRY_ELEMENT_COUNT + 4u));
    float4 paintTranslateAndLOD = STORAGE_BUFFER_LOAD4(
        @paintAuxBuffer,
        pathID * PAINT_AUX_ENTRY_ELEMENT_COUNT + 5u);
    float2 imageCoord = MUL(imageMatrix, fragCoord) + paintTranslateAndLOD.xy;

    // Add 1 to the LOD because a z value of 0 means "we don't have an
    // image"
    float imageZ = 1. + paintTranslateAndLOD.z;
    if ((paintData.x & PAINT_FLAG_LAYER_MASK) != 0u)
    {
      // A layer-mask apply. The sampled texel is coverage, not color, so
      // the fragment shader has to treat it differently -- and there is
      // no varying to spare for a per-draw flag. Signal it by making z
      // negative and packing the mode into it, the same sentinel idiom
      // this shader already uses twice (a negative paint.a means
      // "gradient", a zero image.z means "no image"). The mask is always
      // sampled 1:1 with the target, so LOD 0 is exact and there is
      // nothing lost by giving up the LOD field here.
      uint mode = (paintData.x & PAINT_LAYER_MASK_MODE_MASK) >>
                  PAINT_LAYER_MASK_MODE_SHIFT;
      imageZ = -(1. + float(mode));
    }
    v_image = float3(imageCoord.x, imageCoord.y, imageZ);
  }
  else
  {
    v_image = float3(0.0, 0.0, 0.0);
  }
  #endif

  float4 pos;
  if (!shouldDiscardVertex)
  {
    pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);
  #ifdef @POST_INVERT_Y
    pos.y = -pos.y;
  #endif
  #ifdef @RENDER_MODE_DEPTH_STENCIL
    pos.z = packNormalizedDepth(pathZIndex, 0xffu);
  #elif defined(@RENDER_MODE_CLOCKWISE_ATOMIC)
    uint4 coverageData = STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u);
    v_coveragePlacement = coverageData.xy;
    v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw);
  #endif
  }
  else
  {
    pos = float4(
        uniforms.vertexDiscardValue,
        uniforms.vertexDiscardValue,
        uniforms.vertexDiscardValue,
        uniforms.vertexDiscardValue);
  }

  VARYING_PACK(v_paint);
  #if defined(@ENABLE_MODULATED_IMAGE)
  VARYING_PACK(v_image);
  #endif
  #ifdef @FEATHER_ATLAS_BLIT
  VARYING_PACK(v_atlasCoord);
  #elif !defined(@RENDER_MODE_DEPTH_STENCIL)
    #ifdef @DRAW_INTERIOR_TRIANGLES
  VARYING_PACK(v_windingWeight);
    #else
  VARYING_PACK(v_coverages);
    #endif //@DRAW_INTERIOR_TRIANGLES
  VARYING_PACK(v_pathID);
  #endif   // !@RENDER_MODE_DEPTH_STENCIL

  #ifdef @ENABLE_CLIPPING
    #ifdef @FEATHER_ATLAS_BLIT
  VARYING_PACK(v_clipID);
    #else
  VARYING_PACK(v_clipIDs);
    #endif
  #endif // @ENABLE_CLIPPING
  #if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_DEPTH_STENCIL)
  VARYING_PACK(v_clipRect);
  #endif
  #ifdef @ENABLE_ADVANCED_BLEND
  VARYING_PACK(v_blendMode);
  #endif
  #ifdef @RENDER_MODE_CLOCKWISE_ATOMIC
  VARYING_PACK(v_coveragePlacement);
  VARYING_PACK(v_coverageCoord);
  #endif
  EMIT_VERTEX(pos);
}
#endif

#ifdef @FRAGMENT

FRAG_STORAGE_BUFFER_BLOCK_BEGIN
FRAG_STORAGE_BUFFER_BLOCK_END

// Add a function here for fragments to unpack the paint since we're the ones
// who packed it in the vertex shader.
INLINE half4 find_paint_color(
  #ifdef @ENABLE_MODULATED_IMAGE
    float3 image,
  #endif
  #ifdef @ENABLE_ADVANCED_BLEND
    ushort blendMode,
  #endif
    float4 paint FRAGMENT_CONTEXT_DECL)
{
  #ifdef @ENABLE_ADVANCED_BLEND
  bool paintHasAdvancedBlend = @ENABLE_ADVANCED_BLEND &&
                               blendMode != BLEND_SRC_OVER;
  #else
  const bool paintHasAdvancedBlend = false;
  #endif
  half4 color;
  if (paint.a >= .0) // Is the paint a solid color?
  {
    // The CPU sent 'paint' unmultiplied for advanced-blend draws and
    // premultiplied otherwise, matching paintHasAdvancedBlend.
    color = cast_float4_to_half4(paint);
  }
  else // Paint is a gradient (linear or radial)?
  {
    float2 gradientTexCoord = getGradientUV(
        paint,
        uniforms.gradTextureYScale,
        uniforms.gradTextureYBias);
    color = TEXTURE_SAMPLE_LOD(@gradTexture, gradSampler, gradientTexCoord, .0);

    // Gradients are always unmultiplied so we don't lose color data while
    // doing the hardware filter.
    if (!paintHasAdvancedBlend)
    {
      half additivenessComplement = getGradientAdditivenessComplement(paint);
      color.rgb *= color.a;
      color.a *= additivenessComplement;
    }
  }

  #if defined(@ENABLE_MODULATED_IMAGE)
  if (@ENABLE_MODULATED_IMAGE && image.z < 0.0)
  {
    // Layer mask: the texel *is* the coverage. Return it premultiplied and
    // unmodulated -- the blend step derives the factor from it and never
    // composites it as color. Luminance is taken on the premultiplied value
    // on purpose: luma(rgb/a)*a == dot(rgb, coeffs) identically, with no
    // divide and no 0/0 at a == 0.
    return TEXTURE_SAMPLE_DYNAMIC_LOD(
        @imageTexture,
        imageSampler,
        image.rg,
        make_half(.0));
  }
  if (@ENABLE_MODULATED_IMAGE && image.z > 0.0)
  {
    half lod = image.z - 1.;
    half4 imageColor = TEXTURE_SAMPLE_DYNAMIC_LOD(
        @imageTexture,
        imageSampler,
        image.rg,
        lod);

    // Images are always premultiplied so the (transparent) background color
    // doesn't bleed into the edges during the hardware filter; unmultiply
    // to match this draw's convention if needed.
    if (paintHasAdvancedBlend)
      imageColor = make_half4(unmultiply_rgb(imageColor), imageColor.a);

    color *= imageColor;
  }
  #endif
  return color;
}

  #if !defined(@DRAW_INTERIOR_TRIANGLES) && !defined(@FEATHER_ATLAS_BLIT)

// Add functions here for fragments to unpack and evaluate coverage since we're
// the ones who packed the coverage components in the vertex shader.
INLINE half find_stroke_coverage(COVERAGE_TYPE coverages TEXTURE_CONTEXT_DECL)
{
    #ifdef @ENABLE_FEATHER
  if (@ENABLE_FEATHER && is_feathered_stroke(coverages))
    return eval_feathered_stroke(coverages TEXTURE_CONTEXT_FORWARD);
  else
    #endif // @ENABLE_FEATHER
    return min(coverages.x, coverages.y);
}

INLINE half find_fill_coverage(COVERAGE_TYPE coverages TEXTURE_CONTEXT_DECL)
{
    #if defined(@ENABLE_FEATHER)
  if (@ENABLE_FEATHER && is_feathered_fill(coverages))
    return eval_feathered_fill(coverages TEXTURE_CONTEXT_FORWARD);
  else
    #endif // @ENABLE_FEATHER
    return coverages.x;
}

INLINE half find_frag_coverage(COVERAGE_TYPE coverages TEXTURE_CONTEXT_DECL)
{
  if (is_stroke(coverages))
    return find_stroke_coverage(coverages TEXTURE_CONTEXT_FORWARD);
  else // Fill. (Back-face culling handles the sign of coverages.x.)
    return find_fill_coverage(coverages TEXTURE_CONTEXT_FORWARD);
}

INLINE half apply_frag_coverage(
    half initialCoverage,
    COVERAGE_TYPE coverages TEXTURE_CONTEXT_DECL)
{
  if (is_stroke(coverages))
  {
    half fragCoverage = find_stroke_coverage(coverages TEXTURE_CONTEXT_FORWARD);
    return max(fragCoverage, initialCoverage);
  }
  else // Fill. (Back-face culling handles the sign of coverages.x.)
  {
    half fragCoverage = find_fill_coverage(coverages TEXTURE_CONTEXT_FORWARD);
    return initialCoverage + fragCoverage;
  }
}

  #endif // !@DRAW_INTERIOR_TRIANGLES && !@FEATHER_ATLAS_BLIT

#endif // @FRAGMENT
