/*
 * Copyright 2023 Rive
 */

#ifdef @DRAW_PATH
#ifdef @VERTEX
ATTR_BLOCK_BEGIN(Attrs)
ATTR(0,
     float4,
     @a_patchVertexData); // [localVertexID, outset, fillCoverage, vertexType]
ATTR(1, float4, @a_mirroredVertexData);
ATTR_BLOCK_END
#endif

VARYING_BLOCK_BEGIN
#ifdef @ENABLE_FEATHER
NO_PERSPECTIVE VARYING(0, float4, v_coverages);
#else
NO_PERSPECTIVE VARYING(0, half2, v_coverages);
#endif
FLAT VARYING(1, ushort, v_pathID);
VARYING_BLOCK_END

#ifdef @VERTEX
VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
{
    ATTR_UNPACK(_vertexID, attrs, @a_patchVertexData, float4);
    ATTR_UNPACK(_vertexID, attrs, @a_mirroredVertexData, float4);

#ifdef @ENABLE_FEATHER
    VARYING_INIT(v_coverages, float4);
#else
    VARYING_INIT(v_coverages, half2);
#endif
    VARYING_INIT(v_pathID, ushort);

    float4 pos;
    uint pathID;
    float2 vertexPosition;
    float4 coverages;
    if (unpack_tessellated_path_vertex(@a_patchVertexData,
                                       @a_mirroredVertexData,
                                       _instanceID,
                                       pathID,
                                       vertexPosition,
                                       coverages VERTEX_CONTEXT_UNPACK))
    {
#ifdef @ENABLE_FEATHER
        v_coverages = coverages;
#else
        v_coverages.xy = cast_float2_to_half2(coverages.xy);
#endif
        v_pathID = cast_uint_to_ushort(pathID);
        pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);
    }
    else
    {
        pos = float4(uniforms.vertexDiscardValue,
                     uniforms.vertexDiscardValue,
                     uniforms.vertexDiscardValue,
                     uniforms.vertexDiscardValue);
    }

    VARYING_PACK(v_coverages);
    VARYING_PACK(v_pathID);
    EMIT_VERTEX(pos);
}
#endif // VERTEX
#endif // DRAW_PATH

#if defined(@DRAW_INTERIOR_TRIANGLES) || defined(@ATLAS_BLIT)
#ifdef @VERTEX
ATTR_BLOCK_BEGIN(Attrs)
ATTR(0, packed_float3, @a_triangleVertex);
ATTR_BLOCK_END
#endif

VARYING_BLOCK_BEGIN
#ifdef @ATLAS_BLIT
NO_PERSPECTIVE VARYING(0, float2, v_atlasCoord);
#else
@OPTIONALLY_FLAT VARYING(0, half, v_windingWeight);
#endif
FLAT VARYING(1, ushort, v_pathID);
VARYING_BLOCK_END

#ifdef @VERTEX
VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
{
    ATTR_UNPACK(_vertexID, attrs, @a_triangleVertex, float3);

#ifdef @ATLAS_BLIT
    VARYING_INIT(v_atlasCoord, float2);
#else
    VARYING_INIT(v_windingWeight, half);
#endif
    VARYING_INIT(v_pathID, ushort);

    uint pathID;
    float2 vertexPosition;
#ifdef @ATLAS_BLIT
    vertexPosition =
        unpack_atlas_coverage_vertex(@a_triangleVertex,
                                     pathID,
                                     v_atlasCoord VERTEX_CONTEXT_UNPACK);
#else
    vertexPosition =
        unpack_interior_triangle_vertex(@a_triangleVertex,
                                        pathID,
                                        v_windingWeight VERTEX_CONTEXT_UNPACK);
#endif
    v_pathID = cast_uint_to_ushort(pathID);
    float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);

#ifdef @ATLAS_BLIT
    VARYING_PACK(v_atlasCoord);
#else
    VARYING_PACK(v_windingWeight);
#endif
    VARYING_PACK(v_pathID);
    EMIT_VERTEX(pos);
}
#endif // @VERTEX
#endif // @DRAW_INTERIOR_TRIANGLES || @ATLAS_BLIT

#ifdef @DRAW_IMAGE_RECT
#ifdef @VERTEX
ATTR_BLOCK_BEGIN(Attrs)
ATTR(0, float4, @a_imageRectVertex);
ATTR_BLOCK_END
#endif

VARYING_BLOCK_BEGIN
NO_PERSPECTIVE VARYING(0, float2, v_texCoord);
NO_PERSPECTIVE VARYING(1, half, v_edgeCoverage);
#ifdef @ENABLE_CLIP_RECT
NO_PERSPECTIVE VARYING(2, float4, v_clipRect);
#endif
VARYING_BLOCK_END

#ifdef @VERTEX
IMAGE_RECT_VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
{
    ATTR_UNPACK(_vertexID, attrs, @a_imageRectVertex, float4);

    VARYING_INIT(v_texCoord, float2);
    VARYING_INIT(v_edgeCoverage, half);
#ifdef @ENABLE_CLIP_RECT
    VARYING_INIT(v_clipRect, float4);
#endif

    bool isOuterVertex =
        @a_imageRectVertex.z == .0 || @a_imageRectVertex.w == .0;
    v_edgeCoverage = isOuterVertex ? .0 : 1.;

    float2 vertexPosition = @a_imageRectVertex.xy;
    float2x2 M = make_float2x2(imageDrawUniforms.viewMatrix);
    float2x2 MIT = transpose(inverse(M));
    if (!isOuterVertex)
    {
        // Inset the inner vertices to the point where coverage == 1.
        // NOTE: if width/height ever change from 1, these equations need to be
        // updated.
        float aaRadiusX =
            AA_RADIUS * manhattan_width(MIT[1]) / dot(M[1], MIT[1]);
        if (aaRadiusX >= .5)
        {
            vertexPosition.x = .5;
            v_edgeCoverage *= cast_float_to_half(.5 / aaRadiusX);
        }
        else
        {
            vertexPosition.x += aaRadiusX * @a_imageRectVertex.z;
        }
        float aaRadiusY =
            AA_RADIUS * manhattan_width(MIT[0]) / dot(M[0], MIT[0]);
        if (aaRadiusY >= .5)
        {
            vertexPosition.y = .5;
            v_edgeCoverage *= cast_float_to_half(.5 / aaRadiusY);
        }
        else
        {
            vertexPosition.y += aaRadiusY * @a_imageRectVertex.w;
        }
    }

    v_texCoord = vertexPosition;
    vertexPosition = MUL(M, vertexPosition) + imageDrawUniforms.translate;

    if (isOuterVertex)
    {
        // Outset the outer vertices to the point where coverage == 0.
        float2 n = MUL(MIT, @a_imageRectVertex.zw);
        n *= manhattan_width(n) / dot(n, n);
        vertexPosition += AA_RADIUS * n;
    }

#ifdef @ENABLE_CLIP_RECT
    if (@ENABLE_CLIP_RECT)
    {
        v_clipRect = find_clip_rect_coverage_distances(
            make_float2x2(imageDrawUniforms.clipRectInverseMatrix),
            imageDrawUniforms.clipRectInverseTranslate,
            vertexPosition);
    }
#endif

    float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);

    VARYING_PACK(v_texCoord);
    VARYING_PACK(v_edgeCoverage);
#ifdef @ENABLE_CLIP_RECT
    VARYING_PACK(v_clipRect);
#endif
    EMIT_VERTEX(pos);
}
#endif // VERTEX

#elif defined(@DRAW_IMAGE_MESH)
#ifdef @VERTEX
ATTR_BLOCK_BEGIN(PositionAttr)
ATTR(0, float2, @a_position);
ATTR_BLOCK_END

ATTR_BLOCK_BEGIN(UVAttr)
ATTR(1, float2, @a_texCoord);
ATTR_BLOCK_END
#endif

VARYING_BLOCK_BEGIN
NO_PERSPECTIVE VARYING(0, float2, v_texCoord);
#ifdef @ENABLE_CLIP_RECT
NO_PERSPECTIVE VARYING(1, float4, v_clipRect);
#endif
VARYING_BLOCK_END

#ifdef @VERTEX
IMAGE_MESH_VERTEX_MAIN(@drawVertexMain,
                       PositionAttr,
                       position,
                       UVAttr,
                       uv,
                       _vertexID)
{
    ATTR_UNPACK(_vertexID, position, @a_position, float2);
    ATTR_UNPACK(_vertexID, uv, @a_texCoord, float2);

    VARYING_INIT(v_texCoord, float2);
#ifdef @ENABLE_CLIP_RECT
    VARYING_INIT(v_clipRect, float4);
#endif

    float2x2 M = make_float2x2(imageDrawUniforms.viewMatrix);
    float2 vertexPosition = MUL(M, @a_position) + imageDrawUniforms.translate;
    v_texCoord = @a_texCoord;

#ifdef @ENABLE_CLIP_RECT
    if (@ENABLE_CLIP_RECT)
    {
        v_clipRect = find_clip_rect_coverage_distances(
            make_float2x2(imageDrawUniforms.clipRectInverseMatrix),
            imageDrawUniforms.clipRectInverseTranslate,
            vertexPosition);
    }
#endif

    float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);

    VARYING_PACK(v_texCoord);
#ifdef @ENABLE_CLIP_RECT
    VARYING_PACK(v_clipRect);
#endif
    EMIT_VERTEX(pos);
}
#endif // VERTEX
#endif // DRAW_IMAGE_MESH

#ifdef @DRAW_RENDER_TARGET_UPDATE_BOUNDS
#ifdef @VERTEX
ATTR_BLOCK_BEGIN(Attrs)
ATTR_BLOCK_END
#endif // VERTEX

VARYING_BLOCK_BEGIN
VARYING_BLOCK_END

#ifdef @VERTEX
VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
{
    int2 coord;
    coord.x = (_vertexID & 1) == 0 ? uniforms.renderTargetUpdateBounds.x
                                   : uniforms.renderTargetUpdateBounds.z;
    coord.y = (_vertexID & 2) == 0 ? uniforms.renderTargetUpdateBounds.y
                                   : uniforms.renderTargetUpdateBounds.w;
    float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(float2(coord));
    EMIT_VERTEX(pos);
}
#endif // VERTEX
#endif // DRAW_RENDER_TARGET_UPDATE_BOUNDS

#ifdef @DRAW_IMAGE
#define NEEDS_IMAGE_TEXTURE
#endif

#ifdef @FRAGMENT
PLS_BLOCK_BEGIN
// We only bind the framebuffer as PLS when there are blend modes. Otherwise, we
// render to it as a normal color attachment.
#ifndef @FIXED_FUNCTION_COLOR_OUTPUT
#ifdef @COLOR_PLANE_IDX_OVERRIDE
// D3D11 doesn't let us bind the framebuffer UAV to slot 0 when there is a
// color output.
#define LOCAL_COLOR_PLANE_IDX @COLOR_PLANE_IDX_OVERRIDE
#else
#define LOCAL_COLOR_PLANE_IDX COLOR_PLANE_IDX
#endif
#ifdef @COALESCED_PLS_RESOLVE_AND_TRANSFER
PLS_DECL4F_READONLY(LOCAL_COLOR_PLANE_IDX, colorBuffer);
#else
PLS_DECL4F(LOCAL_COLOR_PLANE_IDX, colorBuffer);
#endif
#endif // !FIXED_FUNCTION_COLOR_OUTPUT
#ifdef @PLS_BLEND_SRC_OVER
// When PLS has src-over blending enabled, the clip buffer is RGBA8 so we
// can preserve clip contents by emitting a=0 instead of loading the current
// value. This is also is a hint to the hardware that it doesn't need to
// write anything to the clip attachment.
#define CLIP_VALUE_TYPE half4
#define PLS_LOAD_CLIP_TYPE PLS_LOAD4F
#define MAKE_NON_UPDATING_CLIP_VALUE make_half4(.0)
#define HAS_UPDATED_CLIP_VALUE(X) ((X).a != .0)
#ifdef @ENABLE_CLIPPING
#ifndef @RESOLVE_PLS
PLS_DECL4F(CLIP_PLANE_IDX, clipBuffer);
#else
PLS_DECL4F_READONLY(CLIP_PLANE_IDX, clipBuffer);
#endif
#endif // ENABLE_CLIPPING
#else
// When PLS does not have src-over blending, the clip buffer the usual
// packed R32UI.
#define CLIP_VALUE_TYPE uint
#define MAKE_NON_UPDATING_CLIP_VALUE 0u
#define PLS_LOAD_CLIP_TYPE PLS_LOADUI
#define HAS_UPDATED_CLIP_VALUE(X) ((X) != 0u)
#ifdef @ENABLE_CLIPPING
PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer);
#endif // ENABLE_CLIPPING
#endif // !PLS_BLEND_SRC_OVER
PLS_DECLUI_UAV(COVERAGE_PLANE_IDX, coverageAtomicBuffer);
PLS_BLOCK_END

FRAG_STORAGE_BUFFER_BLOCK_BEGIN
STORAGE_BUFFER_U32x2(PAINT_BUFFER_IDX, PaintBuffer, @paintBuffer);
STORAGE_BUFFER_F32x4(PAINT_AUX_BUFFER_IDX, PaintAuxBuffer, @paintAuxBuffer);
FRAG_STORAGE_BUFFER_BLOCK_END

INLINE uint to_fixed(float x)
{
    return uint(round(x * FIXED_COVERAGE_PRECISION + FIXED_COVERAGE_ZERO));
}

INLINE half from_fixed(uint x)
{
    return cast_float_to_half(
        float(x) * FIXED_COVERAGE_INVERSE_PRECISION +
        (-FIXED_COVERAGE_ZERO * FIXED_COVERAGE_INVERSE_PRECISION));
}

ushort apply_driver_workaround_for_path_id(ushort pathID)
{
#ifdef @NEEDS_PATH_ID_CLAMP_WORKAROUND
    // We have observed that on some hardware, inactive threads or helper lanes
    // appear to issue calls that access storage textures, even though they
    // should be NO-OP. clamping the path ID prevents crashes in these
    // scenarios.
    pathID = min(pathID, uniforms.maxPathId);
#endif
    return pathID;
}

#ifdef @ENABLE_CLIPPING
INLINE void apply_clip(uint clipID,
                       CLIP_VALUE_TYPE clipData,
                       INOUT(half) coverage)
{
#ifdef @PLS_BLEND_SRC_OVER
    // The clipID is packed into r & g of clipData. Use a fuzzy equality test
    // since we lose precision when the clip value gets stored to and from the
    // attachment.
    if (all(lessThan(abs(clipData.rg - unpackUnorm4x8(clipID).rg),
                     make_half2(.25 / 255.))))
        coverage = min(coverage, clipData.b);
    else
        coverage = .0;
#else
    // The clipID is the top 16 bits of clipData.
    if (clipID == clipData >> 16)
        coverage = min(coverage, unpackHalf2x16(clipData).r);
    else
        coverage = .0;
#endif
}
#endif

INLINE void resolve_paint(uint pathID,
                          half coverageCount,
                          OUT(half4) fragColorOut
#if defined(@ENABLE_CLIPPING) && !defined(@RESOLVE_PLS)
                          ,
                          INOUT(CLIP_VALUE_TYPE) fragClipOut
#endif
                              FRAGMENT_CONTEXT_DECL PLS_CONTEXT_DECL)
{
    uint2 paintData = STORAGE_BUFFER_LOAD2(@paintBuffer, pathID);
    half coverage = coverageCount;
    if ((paintData.x & (PAINT_FLAG_NON_ZERO_FILL | PAINT_FLAG_EVEN_ODD_FILL)) !=
        0u)
    {
        // This path has a legacy (non-clockwise) fill.
        coverage = abs(coverage);
#ifdef @ENABLE_EVEN_ODD
        if (@ENABLE_EVEN_ODD && (paintData.x & PAINT_FLAG_EVEN_ODD_FILL) != 0u)
        {
            coverage = 1. - abs(fract(coverage * .5) * 2. + -1.);
        }
#endif
    }
    // This also caps stroke coverage, which can be >1.
    coverage = clamp(coverage, make_half(.0), make_half(1.));
#ifdef @ENABLE_CLIPPING
    if (@ENABLE_CLIPPING)
    {
        uint clipID = paintData.x >> 16u;
        if (clipID != 0u)
        {
            apply_clip(clipID, PLS_LOAD_CLIP_TYPE(clipBuffer), coverage);
        }
    }
#endif // ENABLE_CLIPPING
#ifdef @ENABLE_CLIP_RECT
    if (@ENABLE_CLIP_RECT && (paintData.x & PAINT_FLAG_HAS_CLIP_RECT) != 0u)
    {
        float2x2 M = make_float2x2(
            STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u + 2u));
        float4 translate =
            STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u + 3u);
        float2 clipCoord = MUL(M, _fragCoord) + translate.xy;
        // translate.zw contains -1 / fwidth(clipCoord), which we use to
        // calculate antialiasing.
        half2 distXY =
            cast_float2_to_half2(abs(clipCoord) * translate.zw - translate.zw);
        half clipRectCoverage = clamp(min(distXY.x, distXY.y) + .5, .0, 1.);
        coverage = min(coverage, clipRectCoverage);
    }
#endif // ENABLE_CLIP_RECT
    uint paintType = paintData.x & 0xfu;
    if (paintType <= SOLID_COLOR_PAINT_TYPE) // CLIP_UPDATE_PAINT_TYPE or
                                             // SOLID_COLOR_PAINT_TYPE
    {
        fragColorOut = unpackUnorm4x8(paintData.y);
#ifdef @ENABLE_CLIPPING
        if (@ENABLE_CLIPPING && paintType == CLIP_UPDATE_PAINT_TYPE)
        {
#ifndef @RESOLVE_PLS
#ifdef @PLS_BLEND_SRC_OVER
            // This was actually a clip update. fragColorOut contains the packed
            // clipID.
            fragClipOut.rg = fragColorOut.ba; // Pack the clipID into r & g.
            fragClipOut.b = coverage;         // Put the clipCoverage in b.
            fragClipOut.a =
                1.; // a=1 so we replace the value in the clipBuffer.
#else
            fragClipOut = paintData.y | packHalf2x16(make_half2(coverage, .0));
#endif
#endif
            // Don't update the colorBuffer when this is a clip update.
            fragColorOut = make_half4(.0);
        }
#endif
    }
    else // LINEAR_GRADIENT_PAINT_TYPE or RADIAL_GRADIENT_PAINT_TYPE
    {
        float2x2 M =
            make_float2x2(STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u));
        float4 translate =
            STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u + 1u);
        float2 paintCoord = MUL(M, _fragCoord) + translate.xy;
        float t = paintType == LINEAR_GRADIENT_PAINT_TYPE
                      ? /*linear*/ paintCoord.x
                      : /*radial*/ length(paintCoord);
        t = clamp(t, .0, 1.);
        float x = t * translate.z + translate.w;
        float y = uintBitsToFloat(paintData.y);
        fragColorOut =
            TEXTURE_SAMPLE_LOD(@gradTexture, gradSampler, float2(x, y), .0);
    }
    fragColorOut.a *= coverage;

#if !defined(@FIXED_FUNCTION_COLOR_OUTPUT) && defined(@ENABLE_ADVANCED_BLEND)
    // Apply the advanced blend mode, if applicable.
    ushort blendMode;
    if (@ENABLE_ADVANCED_BLEND && fragColorOut.a != .0 &&
        (blendMode = cast_uint_to_ushort((paintData.x >> 4) & 0xfu)) !=
            BLEND_SRC_OVER)
    {
        half4 dstColorPremul = PLS_LOAD4F(colorBuffer);
        fragColorOut.rgb =
            advanced_color_blend(fragColorOut.rgb, dstColorPremul, blendMode);
    }
#endif // !FIXED_FUNCTION_COLOR_OUTPUT && ENABLE_ADVANCED_BLEND

// Certain platforms give us less control of the format of what we are
// rendering too. Specifically, we are auto converted from linear -> sRGB on
// render target writes in unreal. In those cases we made need to end up in
// linear color space
#if defined(@NEEDS_GAMMA_CORRECTION) &&                                        \
    (defined(@FIXED_FUNCTION_COLOR_OUTPUT) || defined(@RESOLVE_PLS))
    fragColorOut = gamma_to_linear(fragColorOut);
#endif

    fragColorOut.rgb *= fragColorOut.a;
}

#if !defined(@FIXED_FUNCTION_COLOR_OUTPUT) &&                                  \
    !defined(@COALESCED_PLS_RESOLVE_AND_TRANSFER)
INLINE void blend_pls_color_src_over(half4 fragColorOut PLS_CONTEXT_DECL)
{
#ifndef @PLS_BLEND_SRC_OVER
    if (fragColorOut.a == .0)
        return;
    float oneMinusSrcAlpha = 1. - fragColorOut.a;
    if (oneMinusSrcAlpha != .0)
        fragColorOut += PLS_LOAD4F(colorBuffer) * oneMinusSrcAlpha;
#endif
    PLS_STORE4F(colorBuffer, fragColorOut);
}
#endif // !@FIXED_FUNCTION_COLOR_OUTPUT &&
       // !@COALESCED_PLS_RESOLVE_AND_TRANSFER

#if defined(@ENABLE_CLIPPING) && !defined(@RESOLVE_PLS)
INLINE void emit_pls_clip(CLIP_VALUE_TYPE fragClipOut PLS_CONTEXT_DECL)
{
#ifdef @PLS_BLEND_SRC_OVER
    PLS_STORE4F(clipBuffer, fragClipOut);
#else
    if (fragClipOut != 0u)
        PLS_STOREUI(clipBuffer, fragClipOut);
#endif
}
#endif // ENABLE_CLIPPING && !RESOLVE_PLS

#ifdef @FIXED_FUNCTION_COLOR_OUTPUT
#define ATOMIC_PLS_MAIN PLS_FRAG_COLOR_MAIN
#define ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS                                    \
    PLS_FRAG_COLOR_MAIN_WITH_IMAGE_UNIFORMS
#define EMIT_ATOMIC_PLS EMIT_PLS_AND_FRAG_COLOR
#else // !FIXED_FUNCTION_COLOR_OUTPUT
#define ATOMIC_PLS_MAIN PLS_MAIN
#define ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS PLS_MAIN_WITH_IMAGE_UNIFORMS
#define EMIT_ATOMIC_PLS EMIT_PLS
#endif

#ifdef @DRAW_PATH
ATOMIC_PLS_MAIN(@drawFragmentMain)
{
#ifdef @ENABLE_FEATHER
    VARYING_UNPACK(v_coverages, float4);
#else
    VARYING_UNPACK(v_coverages, half2);
#endif
    VARYING_UNPACK(v_pathID, ushort);

    half fragmentCoverage;

#ifdef @ENABLE_FEATHER
    if (@ENABLE_FEATHER && is_feathered_stroke(v_coverages))
    {
        fragmentCoverage =
            eval_feathered_stroke(v_coverages TEXTURE_CONTEXT_FORWARD);
    }
    else if (@ENABLE_FEATHER && is_feathered_fill(v_coverages))
    {
        fragmentCoverage =
            eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD);
    }
    else
#endif
    {
        // Cover stroke and fill both in a branchless expression.
        fragmentCoverage =
            min(min(make_half(v_coverages.x), abs(make_half(v_coverages.y))),
                make_half(1.));
    }

    half4 fragColorOut = make_half4(.0);
#ifdef @ENABLE_CLIPPING
    CLIP_VALUE_TYPE fragClipOut = MAKE_NON_UPDATING_CLIP_VALUE;
#endif

    // Since v_pathID increases monotonically with every draw, and since it
    // lives in the most significant bits of the coverage data, an atomic max()
    // function will serve 3 purposes:
    //
    //    * The invocation that changes the pathID is the single first fragment
    //      invocation to hit the new path, and the one that should resolve the
    //      previous path in the framebuffer.
    //    * Properly resets coverage to zero when we do cross over into
    //      processing a new path.
    //    * Accumulates coverage for strokes.
    //
    uint fixedCoverage = to_fixed(fragmentCoverage);
    uint minCoverageData =
        (make_uint(v_pathID) << FIXED_COVERAGE_BIT_COUNT) | fixedCoverage;
    uint lastCoverageData =
        PLS_ATOMIC_MAX(coverageAtomicBuffer, minCoverageData);
    ushort lastPathID =
        cast_uint_to_ushort(lastCoverageData >> FIXED_COVERAGE_BIT_COUNT);

    lastPathID = apply_driver_workaround_for_path_id(lastPathID);

    if (lastPathID == v_pathID)
    {
        // This is not the first fragment of the current path to touch this
        // pixel. We already resolved the previous path, so just update coverage
        // (if we're a fill) and move on.
        if (!is_stroke(v_coverages))
        {
            // Only apply the effect of the min() the first time we cross into a
            // path.
            fixedCoverage +=
                lastCoverageData - max(minCoverageData, lastCoverageData);
            fixedCoverage -=
                FIXED_COVERAGE_ZERO_UINT; // Only apply the zero bias once.
            PLS_ATOMIC_ADD(coverageAtomicBuffer,
                           fixedCoverage); // Count coverage.
        }
    }
    else
    {
        // We crossed into a new path! Resolve the previous path now that we
        // know its exact coverage.
        half coverageCount = from_fixed(lastCoverageData & FIXED_COVERAGE_MASK);
        resolve_paint(lastPathID,
                      coverageCount,
                      fragColorOut
#ifdef @ENABLE_CLIPPING
                      ,
                      fragClipOut
#endif
                          FRAGMENT_CONTEXT_UNPACK PLS_CONTEXT_UNPACK);
    }

    fragColorOut.rgb = add_dither(fragColorOut.rgb,
                                  _fragCoord.xy,
                                  uniforms.ditherScale,
                                  uniforms.ditherBias);
#ifdef @FIXED_FUNCTION_COLOR_OUTPUT
    _fragColor = fragColorOut;
#else
    blend_pls_color_src_over(fragColorOut PLS_CONTEXT_UNPACK);
#endif
#ifdef @ENABLE_CLIPPING
    emit_pls_clip(fragClipOut PLS_CONTEXT_UNPACK);
#endif

    EMIT_ATOMIC_PLS
}
#endif // DRAW_PATH

#if defined(@DRAW_INTERIOR_TRIANGLES) || defined(@ATLAS_BLIT)
ATOMIC_PLS_MAIN(@drawFragmentMain)
{
#ifdef @ATLAS_BLIT
    VARYING_UNPACK(v_atlasCoord, float2);
#else
    VARYING_UNPACK(v_windingWeight, half);
#endif
    VARYING_UNPACK(v_pathID, ushort);

    uint lastCoverageData = PLS_LOADUI_UAV(coverageAtomicBuffer);
    ushort lastPathID =
        cast_uint_to_ushort(lastCoverageData >> FIXED_COVERAGE_BIT_COUNT);
    lastPathID = apply_driver_workaround_for_path_id(lastPathID);
    // Update coverageAtomicBuffer with the coverage weight of the current
    // triangle. This does not need to be atomic since interior triangles don't
    // overlap.
    uint currPathCoverageData;
#ifndef @ATLAS_BLIT
    if (lastPathID == v_pathID)
    {
        currPathCoverageData = lastCoverageData;
    }
    else
#endif
    {
        currPathCoverageData =
            (make_uint(v_pathID) << FIXED_COVERAGE_BIT_COUNT) +
            FIXED_COVERAGE_ZERO_UINT;
    }

    half coverage;
#ifdef @ATLAS_BLIT
    coverage = clamp(
        TEXTURE_SAMPLE_LOD(@atlasTexture, atlasSampler, v_atlasCoord, .0).r,
        make_half(.0),
        make_half(1.));
#else
    coverage = v_windingWeight;
#endif

    int coverageDeltaFixed = int(round(coverage * FIXED_COVERAGE_PRECISION));
    PLS_STOREUI_UAV(coverageAtomicBuffer,
                    currPathCoverageData + uint(coverageDeltaFixed));

    half4 fragColorOut = make_half4(.0);
#ifdef @ENABLE_CLIPPING
    CLIP_VALUE_TYPE fragClipOut = MAKE_NON_UPDATING_CLIP_VALUE;
#endif

#ifndef @ATLAS_BLIT
    // If this is not the first fragment of the current path to touch this
    // pixel, then we've already resolved the previous path and can move on.
    if (lastPathID != v_pathID)
#endif
    {
        // We crossed into a new path! Resolve the previous path now that we
        // know its exact coverage.
        half lastCoverageCount =
            from_fixed(lastCoverageData & FIXED_COVERAGE_MASK);
        resolve_paint(lastPathID,
                      lastCoverageCount,
                      fragColorOut
#ifdef @ENABLE_CLIPPING
                      ,
                      fragClipOut
#endif
                          FRAGMENT_CONTEXT_UNPACK PLS_CONTEXT_UNPACK);
    }

    fragColorOut.rgb = add_dither(fragColorOut.rgb,
                                  _fragCoord.xy,
                                  uniforms.ditherScale,
                                  uniforms.ditherBias);
#ifdef @FIXED_FUNCTION_COLOR_OUTPUT
    _fragColor = fragColorOut;
#else
    blend_pls_color_src_over(fragColorOut PLS_CONTEXT_UNPACK);
#endif
#ifdef @ENABLE_CLIPPING
    emit_pls_clip(fragClipOut PLS_CONTEXT_UNPACK);
#endif

    EMIT_ATOMIC_PLS
}
#endif // @DRAW_INTERIOR_TRIANGLES || @ATLAS_BLIT

#ifdef @DRAW_IMAGE
ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain)
{
    VARYING_UNPACK(v_texCoord, float2);
#ifdef @DRAW_IMAGE_RECT
    VARYING_UNPACK(v_edgeCoverage, half);
#endif
#ifdef @ENABLE_CLIP_RECT
    VARYING_UNPACK(v_clipRect, float4);
#endif

    // Start by finding the image color. We have to do this immediately instead
    // of allowing it to get resolved later like other draws because the
    // @imageTexture binding is liable to change, and furthermore in the case of
    // imageMeshes, we can't calculate UV coordinates based on fragment
    // position.
    half4 imageColor =
        TEXTURE_SAMPLE_DYNAMIC(@imageTexture, imageSampler, v_texCoord);
    half imageCoverage = 1.;
#ifdef @DRAW_IMAGE_RECT
    imageCoverage = min(v_edgeCoverage, imageCoverage);
#endif
#ifdef @ENABLE_CLIP_RECT
    if (@ENABLE_CLIP_RECT)
    {
        half clipRectCoverage = min_component(cast_float4_to_half4(v_clipRect));
        imageCoverage = clamp(clipRectCoverage, make_half(.0), imageCoverage);
    }
#endif

    // Resolve the previous path.
    uint lastCoverageData = PLS_LOADUI_UAV(coverageAtomicBuffer);
    ushort lastPathID =
        cast_uint_to_ushort(lastCoverageData >> FIXED_COVERAGE_BIT_COUNT);
    lastPathID = apply_driver_workaround_for_path_id(lastPathID);
    half lastCoverageCount = from_fixed(lastCoverageData & FIXED_COVERAGE_MASK);
    half4 fragColorOut;
#ifdef @ENABLE_CLIPPING
    CLIP_VALUE_TYPE fragClipOut = MAKE_NON_UPDATING_CLIP_VALUE;
#endif
    // TODO: consider not resolving the prior paint if we're solid and the prior
    // paint is not a clip update: (imageColor.a == 1. &&
    //                              imageDrawUniforms.blendMode ==
    //                              BLEND_SRC_OVER && priorPaintType !=
    //                              CLIP_UPDATE_PAINT_TYPE)
    resolve_paint(lastPathID,
                  lastCoverageCount,
                  fragColorOut
#ifdef @ENABLE_CLIPPING
                  ,
                  fragClipOut
#endif
                      FRAGMENT_CONTEXT_UNPACK PLS_CONTEXT_UNPACK);

// Clip the image after resolving the previous path, since that can affect
// the clip buffer.
#ifdef @ENABLE_CLIPPING // TODO! ENABLE_IMAGE_CLIPPING in addition to
                        // ENABLE_CLIPPING?
    if (@ENABLE_CLIPPING && imageDrawUniforms.clipID != 0u)
    {
        CLIP_VALUE_TYPE clipData = HAS_UPDATED_CLIP_VALUE(fragClipOut)
                                       ? fragClipOut
                                       : PLS_LOAD_CLIP_TYPE(clipBuffer);
        apply_clip(imageDrawUniforms.clipID, clipData, imageCoverage);
    }
#endif // ENABLE_CLIPPING

// Prepare imageColor for premultiplied src-over blending.
#if !defined(@FIXED_FUNCTION_COLOR_OUTPUT) && defined(@ENABLE_ADVANCED_BLEND)
    if (@ENABLE_ADVANCED_BLEND && imageDrawUniforms.blendMode != BLEND_SRC_OVER)
    {
        // Calculate what dstColorPremul will be after applying fragColorOut.
        half4 dstColorPremul =
            PLS_LOAD4F(colorBuffer) * (1. - fragColorOut.a) + fragColorOut;
        // Calculate the imageColor to emit *BEFORE* src-over blending, such
        // that the post-src-over-blend result is equivalent to the blendMode.
        imageColor.rgb = advanced_color_blend(
                             unmultiply_rgb(imageColor),
                             dstColorPremul,
                             cast_uint_to_ushort(imageDrawUniforms.blendMode)) *
                         imageColor.a;
    }
#endif // !FIXED_FUNCTION_COLOR_OUTPUT && ENABLE_ADVANCED_BLEND
    imageColor *= imageCoverage * cast_float_to_half(imageDrawUniforms.opacity);

#if defined(@NEEDS_GAMMA_CORRECTION)
    imageColor = gamma_to_linear(imageColor);
#endif

    // Leverage the property that premultiplied src-over blending is associative
    // and blend the imageColor and fragColorOut before passing them on to the
    // blending pipeline.
    fragColorOut = fragColorOut * (1. - imageColor.a) + imageColor;

    fragColorOut.rgb = add_dither(fragColorOut.rgb,
                                  _fragCoord.xy,
                                  uniforms.ditherScale,
                                  uniforms.ditherBias);
#ifdef @FIXED_FUNCTION_COLOR_OUTPUT
    _fragColor = fragColorOut;
#else
    blend_pls_color_src_over(fragColorOut PLS_CONTEXT_UNPACK);
#endif
#ifdef @ENABLE_CLIPPING
    emit_pls_clip(fragClipOut PLS_CONTEXT_UNPACK);
#endif

    // Write out a coverage value of "zero at pathID=0" so a future resolve
    // attempt doesn't affect this pixel.
    PLS_STOREUI_UAV(coverageAtomicBuffer, FIXED_COVERAGE_ZERO_UINT);

    EMIT_ATOMIC_PLS
}
#endif // DRAW_IMAGE

#ifdef @INITIALIZE_PLS

ATOMIC_PLS_MAIN(@drawFragmentMain)
{
#ifdef @STORE_COLOR_CLEAR
    PLS_STORE4F(colorBuffer, unpackUnorm4x8(uniforms.colorClearValue));
#endif
#ifdef @SWIZZLE_COLOR_BGRA_TO_RGBA
    half4 color = PLS_LOAD4F(colorBuffer);
    PLS_STORE4F(colorBuffer, color.bgra);
#endif
    PLS_STOREUI_UAV(coverageAtomicBuffer, uniforms.coverageClearValue);
#ifdef @ENABLE_CLIPPING
    if (@ENABLE_CLIPPING)
    {
        PLS_STOREUI(clipBuffer, 0u);
    }
#endif
#ifdef @FIXED_FUNCTION_COLOR_OUTPUT
    discard;
#endif
    EMIT_ATOMIC_PLS
}

#endif // INITIALIZE_PLS

#ifdef @RESOLVE_PLS

#ifdef @COALESCED_PLS_RESOLVE_AND_TRANSFER
PLS_FRAG_COLOR_MAIN(@drawFragmentMain)
#else
ATOMIC_PLS_MAIN(@drawFragmentMain)
#endif
{
    uint lastCoverageData = PLS_LOADUI_UAV(coverageAtomicBuffer);
    half coverageCount = from_fixed(lastCoverageData & FIXED_COVERAGE_MASK);
    ushort lastPathID =
        cast_uint_to_ushort(lastCoverageData >> FIXED_COVERAGE_BIT_COUNT);
    lastPathID = apply_driver_workaround_for_path_id(lastPathID);
    half4 fragColorOut;
    resolve_paint(lastPathID,
                  coverageCount,
                  fragColorOut FRAGMENT_CONTEXT_UNPACK PLS_CONTEXT_UNPACK);
#ifdef @COALESCED_PLS_RESOLVE_AND_TRANSFER
    float oneMinusSrcAlpha = 1. - fragColorOut.a;
    if (oneMinusSrcAlpha != .0)
        fragColorOut += PLS_LOAD4F(colorBuffer) * oneMinusSrcAlpha;
    _fragColor = fragColorOut;
    EMIT_PLS_AND_FRAG_COLOR
#else

    fragColorOut.rgb = add_dither(fragColorOut.rgb,
                                  _fragCoord.xy,
                                  uniforms.ditherScale,
                                  uniforms.ditherBias);
#ifdef @FIXED_FUNCTION_COLOR_OUTPUT
    _fragColor = fragColorOut;
#else
    blend_pls_color_src_over(fragColorOut PLS_CONTEXT_UNPACK);
#endif

    EMIT_ATOMIC_PLS
#endif // COALESCED_PLS_RESOLVE_AND_TRANSFER
}
#endif // RESOLVE_PLS
#endif // FRAGMENT
