// Graphite-specific vertex shader code

const float $PI = 3.141592653589793238;

///////////////////////////////////////////////////////////////////////////////////////////////////
// Support functions for tessellating path renderers

const float $kCubicCurveType = 0;            // skgpu::tess::kCubicCurveType
const float $kConicCurveType = 1;            // skgpu::tess::kConicCurveType
const float $kTriangularConicCurveType = 2;  // skgpu::tess::kTriangularConicCurveType

// This function can be used on GPUs with infinity support to infer the curve type from the specific
// path control-point encoding used by tessellating path renderers. Calling this function on a
// platform that lacks infinity support may result in a shader compilation error.
$pure float curve_type_using_inf_support(float4 p23) {
    return isinf(p23.z) ? $kTriangularConicCurveType :
           isinf(p23.w) ? $kConicCurveType :
                          $kCubicCurveType;
}

$pure bool $is_conic_curve(float curveType) {
    return curveType != $kCubicCurveType;
}

$pure bool $is_triangular_conic_curve(float curveType) {
    return curveType == $kTriangularConicCurveType;
}

// Wang's formula gives the minimum number of evenly spaced (in the parametric sense) line segments
// that a bezier curve must be chopped into in order to guarantee all lines stay within a distance
// of "1/precision" pixels from the true curve. Its definition for a bezier curve of degree "n" is
// as follows:
//
//     maxLength = max([length(p[i+2] - 2p[i+1] + p[i]) for (0 <= i <= n-2)])
//     numParametricSegments = sqrt(maxLength * precision * n*(n - 1)/8)
//
// (Goldman, Ron. (2003). 5.6.3 Wang's Formula. "Pyramid Algorithms: A Dynamic Programming Approach
// to Curves and Surfaces for Geometric Modeling". Morgan Kaufmann Publishers.)

const float $kDegree = 3;
const float $kPrecision = 4; // Must match skgpu::tess::kPrecision
const float $kLengthTerm     = ($kDegree * ($kDegree - 1) / 8.0) * $kPrecision;
const float $kLengthTermPow2 = (($kDegree * $kDegree) * (($kDegree - 1) * ($kDegree - 1)) / 64.0) *
                               ($kPrecision * $kPrecision);

// Returns the length squared of the largest forward difference from Wang's cubic formula.
$pure float $wangs_formula_max_fdiff_p2(float2 p0, float2 p1, float2 p2, float2 p3,
                                        float2x2 matrix) {
    float2 d0 = matrix * (fma(float2(-2), p1, p2) + p0);
    float2 d1 = matrix * (fma(float2(-2), p2, p3) + p1);
    return max(dot(d0,d0), dot(d1,d1));
}

$pure float $wangs_formula_cubic(float2 p0, float2 p1, float2 p2, float2 p3,
                                 float2x2 matrix) {
    float m = $wangs_formula_max_fdiff_p2(p0, p1, p2, p3, matrix);
    return max(ceil(sqrt($kLengthTerm * sqrt(m))), 1.0);
}

$pure float $wangs_formula_cubic_log2(float2 p0, float2 p1, float2 p2, float2 p3,
                                      float2x2 matrix) {
    float m = $wangs_formula_max_fdiff_p2(p0, p1, p2, p3, matrix);
    return ceil(log2(max($kLengthTermPow2 * m, 1.0)) * .25);
}

$pure float $wangs_formula_conic_p2(float2 p0, float2 p1, float2 p2, float w) {
    // Translate the bounding box center to the origin.
    float2 C = (min(min(p0, p1), p2) + max(max(p0, p1), p2)) * 0.5;
    p0 -= C;
    p1 -= C;
    p2 -= C;

    // Compute max length.
    float m = sqrt(max(max(dot(p0,p0), dot(p1,p1)), dot(p2,p2)));

    // Compute forward differences.
    float2 dp = fma(float2(-2.0 * w), p1, p0) + p2;
    float dw = abs(fma(-2.0, w, 2.0));

    // Compute numerator and denominator for parametric step size of linearization. Here, the
    // epsilon referenced from the cited paper is 1/precision.
    float rp_minus_1 = max(0.0, fma(m, $kPrecision, -1.0));
    float numer = length(dp) * $kPrecision + rp_minus_1 * dw;
    float denom = 4 * min(w, 1.0);

    return numer/denom;
}

$pure float $wangs_formula_conic(float2 p0, float2 p1, float2 p2, float w) {
    float n2 = $wangs_formula_conic_p2(p0, p1, p2, w);
    return max(ceil(sqrt(n2)), 1.0);
}

$pure float $wangs_formula_conic_log2(float2 p0, float2 p1, float2 p2, float w) {
    float n2 = $wangs_formula_conic_p2(p0, p1, p2, w);
    return ceil(log2(max(n2, 1.0)) * .5);
}

// Returns the normalized difference between a and b, i.e. normalize(a - b), with care taken for
// if 'a' and/or 'b' have large coordinates.
$pure float2 $robust_normalize_diff(float2 a, float2 b) {
    float2 diff = a - b;
    if (diff == float2(0.0)) {
        return float2(0.0);
    } else {
        float invMag = 1.0 / max(abs(diff.x), abs(diff.y));
        return normalize(invMag * diff);
    }
}

// Returns the cosine of the angle between a and b, assuming a and b are unit vectors already.
// Guaranteed to be between [-1, 1].
$pure float $cosine_between_unit_vectors(float2 a, float2 b) {
    // Since a and b are assumed to be normalized, the cosine is equal to the dot product, although
    // we clamp that to ensure it falls within the expected range of [-1, 1].
    return clamp(dot(a, b), -1.0, 1.0);
}

// Extends the middle radius to either the miter point, or the bevel edge if we surpassed the
// miter limit and need to revert to a bevel join.
$pure float $miter_extent(float cosTheta, float miterLimit) {
    float x = fma(cosTheta, .5, .5);
    return (x * miterLimit * miterLimit >= 1.0) ? inversesqrt(x) : sqrt(x);
}

// Returns the number of radial segments required for each radian of rotation, in order for the
// curve to appear "smooth" as defined by the approximate device-space stroke radius.
$pure float $num_radial_segments_per_radian(float approxDevStrokeRadius) {
    return .5 / acos(max(1.0 - (1.0 / $kPrecision) / approxDevStrokeRadius, -1.0));
}

// Unlike mix(), this does not return b when t==1. But it otherwise seems to get better
// precision than "a*(1 - t) + b*t" for things like chopping cubics on exact cusp points.
// We override this result anyway when t==1 so it shouldn't be a problem.
$pure float $unchecked_mix(float a, float b, float T) {
    return fma(b - a, T, a);
}
$pure float2 $unchecked_mix(float2 a, float2 b, float T) {
    return fma(b - a, float2(T), a);
}
$pure float4 $unchecked_mix(float4 a, float4 b, float4 T) {
    return fma(b - a, T, a);
}

// Compute a vertex position for the curve described by p01 and p23 packed control points,
// tessellated to the given resolve level, and assuming it will be drawn as a filled curve.
$pure float2 tessellate_filled_curve(float2x2 vectorXform,
                                     float resolveLevel, float idxInResolveLevel,
                                     float4 p01, float4 p23,
                                     float curveType) {
    float2 localcoord;
    if ($is_triangular_conic_curve(curveType)) {
        // This patch is an exact triangle.
        localcoord = (resolveLevel != 0)      ? p01.zw
                   : (idxInResolveLevel != 0) ? p23.xy
                                              : p01.xy;
    } else {
        float2 p0=p01.xy, p1=p01.zw, p2=p23.xy, p3=p23.zw;
        float w = -1;  // w < 0 tells us to treat the instance as an integral cubic.
        float maxResolveLevel;
        if ($is_conic_curve(curveType)) {
            // Conics are 3 points, with the weight in p3.
            w = p3.x;
            maxResolveLevel = $wangs_formula_conic_log2(vectorXform*p0,
                                                        vectorXform*p1,
                                                        vectorXform*p2, w);
            p1 *= w;  // Unproject p1.
            p3 = p2;  // Duplicate the endpoint for shared code that also runs on cubics.
        } else {
            // The patch is an integral cubic.
            maxResolveLevel = $wangs_formula_cubic_log2(p0, p1, p2, p3, vectorXform);
        }
        if (resolveLevel > maxResolveLevel) {
            // This vertex is at a higher resolve level than we need. Demote to a lower
            // resolveLevel, which will produce a degenerate triangle.
            idxInResolveLevel = floor(ldexp(idxInResolveLevel,
                                            int(maxResolveLevel - resolveLevel)));
            resolveLevel = maxResolveLevel;
        }
        // Promote our location to a discrete position in the maximum fixed resolve level.
        // This is extra paranoia to ensure we get the exact same fp32 coordinates for
        // colocated points from different resolve levels (e.g., the vertices T=3/4 and
        // T=6/8 should be exactly colocated).
        float fixedVertexID = floor(.5 + ldexp(idxInResolveLevel, int(5 - resolveLevel)));
        if (0 < fixedVertexID && fixedVertexID < 32) {
            float T = fixedVertexID * (1 / 32.0);

            // Evaluate at T. Use De Casteljau's for its accuracy and stability.
            float2 ab = mix(p0, p1, T);
            float2 bc = mix(p1, p2, T);
            float2 cd = mix(p2, p3, T);
            float2 abc = mix(ab, bc, T);
            float2 bcd = mix(bc, cd, T);
            float2 abcd = mix(abc, bcd, T);

            // Evaluate the conic weight at T.
            float u = mix(1.0, w, T);
            float v = w + 1 - u;  // == mix(w, 1, T)
            float uv = mix(u, v, T);

            localcoord = (w < 0) ? /*cubic*/ abcd : /*conic*/ abc/uv;
        } else {
            localcoord = (fixedVertexID == 0) ? p0.xy : p3.xy;
        }
    }
    return localcoord;
}

// Device coords are in xy, local coords are in zw, since for now perspective isn't supported.
$pure float4 tessellate_stroked_curve(float edgeID, float maxEdges,
                                      float2x2 affineMatrix,
                                      float2 translate,
                                      float maxScale /* derived from affineMatrix */,
                                      float4 p01, float4 p23,
                                      float2 lastControlPoint,
                                      float2 strokeParams,
                                      float curveType) {
    float2 p0=p01.xy, p1=p01.zw, p2=p23.xy, p3=p23.zw;
    float w = -1;  // w<0 means the curve is an integral cubic.
    if ($is_conic_curve(curveType)) {
        // Conics are 3 points, with the weight in p3.
        w = p3.x;
        p3 = p2;  // Setting p3 equal to p2 works for the remaining rotational logic.
    }

    // Call Wang's formula to determine parametric segments before transform points for hairlines
    // so that it is consistent with how the CPU tested the control points for chopping.
    float numParametricSegments;
    if (w < 0) {
        if (p0 == p1 && p2 == p3) {
            numParametricSegments = 1; // a line
        } else {
            numParametricSegments = $wangs_formula_cubic(p0, p1, p2, p3, affineMatrix);
        }
    } else {
        numParametricSegments = $wangs_formula_conic(affineMatrix * p0,
                                                     affineMatrix * p1,
                                                     affineMatrix * p2, w);
    }

    // Matches skgpu::tess::StrokeParams
    float strokeRadius = strokeParams.x;
    float joinType = strokeParams.y; // <0 = round join, ==0 = bevel join, >0 encodes miter limit
    bool isHairline = strokeParams.x == 0.0;
    float numRadialSegmentsPerRadian;
    if (isHairline) {
        numRadialSegmentsPerRadian = $num_radial_segments_per_radian(1.0);
        strokeRadius = 0.5;
    } else {
        numRadialSegmentsPerRadian = $num_radial_segments_per_radian(maxScale * strokeParams.x);
    }

    if (isHairline) {
        // Hairline case. Transform the points before tessellation. We can still hold off on the
        // translate until the end; we just need to perform the scale and skew right now.
        p0 = affineMatrix * p0;
        p1 = affineMatrix * p1;
        p2 = affineMatrix * p2;
        p3 = affineMatrix * p3;
        lastControlPoint = affineMatrix * lastControlPoint;
    }

    // Find the starting and ending tangents.
    float2 tan0 = $robust_normalize_diff((p0 == p1) ? ((p1 == p2) ? p3 : p2) : p1, p0);
    float2 tan1 = $robust_normalize_diff(p3, (p3 == p2) ? ((p2 == p1) ? p0 : p1) : p2);
    if (tan0 == float2(0)) {
        // The stroke is a point. This special case tells us to draw a stroke-width circle as a
        // 180 degree point stroke instead.
        tan0 = float2(1,0);
        tan1 = float2(-1,0);
    }

    // Determine how many edges to give to the join. We emit the first and final edges
    // of the join twice: once full width and once restricted to half width. This guarantees
    // perfect seaming by matching the vertices from the join as well as from the strokes on
    // either side.
    float numEdgesInJoin;
    if (joinType >= 0 /*Is the join not a round type?*/) {
        // Bevel(0) and miter(+) joins get 1 and 2 segments respectively.
        // +2 because we emit the beginning and ending edges twice (see above comments).
        numEdgesInJoin = sign(joinType) + (1 + 2);
    } else {
        float2 prevTan = $robust_normalize_diff(p0, lastControlPoint);
        float joinRads = acos($cosine_between_unit_vectors(prevTan, tan0));
        float numRadialSegmentsInJoin = max(ceil(joinRads * numRadialSegmentsPerRadian), 1);
        // +2 because we emit the beginning and ending edges twice (see above comment).
        numEdgesInJoin = numRadialSegmentsInJoin + 2;
        // The stroke section needs at least two edges. Don't assign more to the join than
        // "maxEdges - 2". (This is only relevant when the ideal max edge count calculated
        // on the CPU had to be limited to maxEdges in the draw call).
        numEdgesInJoin = min(numEdgesInJoin, maxEdges - 2);
    }

    // Find which direction the curve turns.
    // NOTE: Since the curve is not allowed to inflect, we can just check F'(.5) x F''(.5).
    // NOTE: F'(.5) x F''(.5) has the same sign as (P2 - P0) x (P3 - P1)
    float turn = cross_length_2d(p2 - p0, p3 - p1);
    float combinedEdgeID = abs(edgeID) - numEdgesInJoin;
    if (combinedEdgeID < 0) {
        tan1 = tan0;
        // Don't let tan0 become zero. The code as-is isn't built to handle that case. tan0=0
        // means the join is disabled, and to disable it with the existing code we can leave
        // tan0 equal to tan1.
        if (lastControlPoint != p0) {
            tan0 = $robust_normalize_diff(p0, lastControlPoint);
        }
        turn = cross_length_2d(tan0, tan1);
    }

    // Calculate the curve's starting angle and rotation.
    float cosTheta = $cosine_between_unit_vectors(tan0, tan1);
    float rotation = acos(cosTheta);
    if (turn < 0) {
        // Adjust sign of rotation to match the direction the curve turns.
        rotation = -rotation;
    }

    float numRadialSegments;
    float strokeOutset = sign(edgeID);
    if (combinedEdgeID < 0) {
        // We belong to the preceding join. The first and final edges get duplicated, so we only
        // have "numEdgesInJoin - 2" segments.
        numRadialSegments = numEdgesInJoin - 2;
        numParametricSegments = 1;  // Joins don't have parametric segments.
        p3 = p2 = p1 = p0;  // Colocate all points on the junction point.
        // Shift combinedEdgeID to the range [-1, numRadialSegments]. This duplicates the first
        // edge and lands one edge at the very end of the join. (The duplicated final edge will
        // actually come from the section of our strip that belongs to the stroke.)
        combinedEdgeID += numRadialSegments + 1;
        if (combinedEdgeID < 0) {
            combinedEdgeID = 0;
        } else {
            // We normally restrict the join on one side of the junction, but if the tangents are
            // nearly equivalent this could theoretically result in bad seaming and/or cracks on the
            // side we don't put it on. If the tangents are nearly equivalent then we leave the join
            // double-sided.
            const float sinEpsilon = 1e-2;  // ~= sin(180deg / 3000)
            bool tangentsNearlyParallel =
                    (abs(turn) * inversesqrt(dot(tan0, tan0) * dot(tan1, tan1))) < sinEpsilon;
            if (!tangentsNearlyParallel || dot(tan0, tan1) < 0) {
                // There are two edges colocated at the beginning. Leave the first one double sided
                // for seaming with the previous stroke. (The double sided edge at the end will
                // actually come from the section of our strip that belongs to the stroke.)
                strokeOutset = (turn < 0) ? min(strokeOutset, 0) : max(strokeOutset, 0);
            }
        }
    } else {
        // We belong to the stroke. Unless numRadialSegmentsPerRadian is incredibly high,
        // clamping to maxCombinedSegments will be a no-op because the draw call was invoked with
        // sufficient vertices to cover the worst case scenario of 180 degree rotation.
        float maxCombinedSegments = maxEdges - numEdgesInJoin - 1;
        numRadialSegments = max(ceil(abs(rotation) * numRadialSegmentsPerRadian), 1);
        numRadialSegments = min(numRadialSegments, maxCombinedSegments);
        numParametricSegments = min(numParametricSegments,
                                    maxCombinedSegments - numRadialSegments + 1);
    }

    // Additional parameters for final tessellation evaluation.
    float radsPerSegment = rotation / numRadialSegments;
    float numCombinedSegments = numParametricSegments + numRadialSegments - 1;
    bool isFinalEdge = (combinedEdgeID >= numCombinedSegments);
    if (combinedEdgeID > numCombinedSegments) {
        strokeOutset = 0;  // The strip has more edges than we need. Drop this one.
    }
    // Edge #2 extends to the miter point.
    if (abs(edgeID) == 2 && joinType > 0/*Is the join a miter type?*/) {
        strokeOutset *= $miter_extent(cosTheta, joinType/*miterLimit*/);
    }

    float2 tangent, strokeCoord;
    if (combinedEdgeID != 0 && !isFinalEdge) {
        // Compute the location and tangent direction of the stroke edge with the integral id
        // "combinedEdgeID", where combinedEdgeID is the sorted-order index of parametric and radial
        // edges. Start by finding the tangent function's power basis coefficients. These define a
        // tangent direction (scaled by some uniform value) as:
        //                                                 |T^2|
        //     Tangent_Direction(T) = dx,dy = |A  2B  C| * |T  |
        //                                    |.   .  .|   |1  |
        float2 A, B, C = p1 - p0;
        float2 D = p3 - p0;
        if (w >= 0.0) {
            // P0..P2 represent a conic and P3==P2. The derivative of a conic has a cumbersome
            // order-4 denominator. However, this isn't necessary if we are only interested in a
            // vector in the same *direction* as a given tangent line. Since the denominator scales
            // dx and dy uniformly, we can throw it out completely after evaluating the derivative
            // with the standard quotient rule. This leaves us with a simpler quadratic function
            // that we use to find a tangent.
            C *= w;
            B = .5*D - C;
            A = (w - 1.0) * D;
            p1 *= w;
        } else {
            float2 E = p2 - p1;
            B = E - C;
            A = fma(float2(-3), E, D);
        }
        // FIXME(crbug.com/800804,skbug.com/11268): Consider normalizing the exponents in A,B,C at
        // this point in order to prevent fp32 overflow.

        // Now find the coefficients that give a tangent direction from a parametric edge ID:
        //
        //                                                                 |parametricEdgeID^2|
        //     Tangent_Direction(parametricEdgeID) = dx,dy = |A  B_  C_| * |parametricEdgeID  |
        //                                                   |.   .   .|   |1                 |
        //
        float2 B_ = B * (numParametricSegments * 2.0);
        float2 C_ = C * (numParametricSegments * numParametricSegments);

        // Run a binary search to determine the highest parametric edge that is located on or before
        // the combinedEdgeID. A combined ID is determined by the sum of complete parametric and
        // radial segments behind it. i.e., find the highest parametric edge where:
        //
        //    parametricEdgeID + floor(numRadialSegmentsAtParametricT) <= combinedEdgeID
        //
        float lastParametricEdgeID = 0.0;
        float maxParametricEdgeID = min(numParametricSegments - 1.0, combinedEdgeID);
        float negAbsRadsPerSegment = -abs(radsPerSegment);
        float maxRotation0 = (1.0 + combinedEdgeID) * abs(radsPerSegment);
        for (float exp = 32.0; exp >= 1.0; exp *= 0.5) {
            // Test the parametric edge at lastParametricEdgeID + (32, 16, 8, 4, 2, 1).
            float testParametricID = lastParametricEdgeID + exp;
            if (testParametricID <= maxParametricEdgeID) {
                float2 testTan = fma(float2(testParametricID), A, B_);
                testTan = fma(float2(testParametricID), testTan, C_);
                float cosRotation = dot(normalize(testTan), tan0);
                float maxRotation = fma(testParametricID, negAbsRadsPerSegment, maxRotation0);
                maxRotation = min(maxRotation, $PI);
                // Is rotation <= maxRotation? (i.e., is the number of complete radial segments
                // behind testT, + testParametricID <= combinedEdgeID?)
                if (cosRotation >= cos(maxRotation)) {
                    // testParametricID is on or before the combinedEdgeID. Keep it!
                    lastParametricEdgeID = testParametricID;
                }
            }
        }

        // Find the T value of the parametric edge at lastParametricEdgeID.
        float parametricT = lastParametricEdgeID / numParametricSegments;

        // Now that we've identified the highest parametric edge on or before the
        // combinedEdgeID, the highest radial edge is easy:
        float lastRadialEdgeID = combinedEdgeID - lastParametricEdgeID;

        // Find the angle of tan0, i.e. the angle between tan0 and the positive x axis.
        float angle0 = acos(clamp(tan0.x, -1.0, 1.0));
        angle0 = tan0.y >= 0.0 ? angle0 : -angle0;

        // Find the tangent vector on the edge at lastRadialEdgeID. By construction it is already
        // normalized.
        float radialAngle = fma(lastRadialEdgeID, radsPerSegment, angle0);
        tangent = float2(cos(radialAngle), sin(radialAngle));
        float2 norm = float2(-tangent.y, tangent.x);

        // Find the T value where the tangent is orthogonal to norm. This is a quadratic:
        //
        //     dot(norm, Tangent_Direction(T)) == 0
        //
        //                         |T^2|
        //     norm * |A  2B  C| * |T  | == 0
        //            |.   .  .|   |1  |
        //
        float a=dot(norm,A), b_over_2=dot(norm,B), c=dot(norm,C);
        float discr_over_4 = max(b_over_2*b_over_2 - a*c, 0.0);
        float q = sqrt(discr_over_4);
        if (b_over_2 > 0.0) {
            q = -q;
        }
        q -= b_over_2;

        // Roots are q/a and c/q. Since each curve section does not inflect or rotate more than 180
        // degrees, there can only be one tangent orthogonal to "norm" inside 0..1. Pick the root
        // nearest .5.
        float _5qa = -.5*q*a;
        float2 root = (abs(fma(q,q,_5qa)) < abs(fma(a,c,_5qa))) ? float2(q,a) : float2(c,q);

        // The root finder above can become unstable when lastRadialEdgeID == 0 (e.g., if there are
        // roots at exatly 0 and 1 both). radialT should always equal 0 in this case.
        float radialT = (lastRadialEdgeID != 0.0 && root.t != 0.0)
                            ? saturate(root.s / root.t)
                            : 0.0;

        // Now that we've identified the T values of the last parametric and radial edges, our final
        // T value for combinedEdgeID is whichever is larger.
        float T = max(parametricT, radialT);

        // Evaluate the cubic at T. Use De Casteljau's for its accuracy and stability.
        float2 ab = $unchecked_mix(p0, p1, T);
        float2 bc = $unchecked_mix(p1, p2, T);
        float2 cd = $unchecked_mix(p2, p3, T);
        float2 abc = $unchecked_mix(ab, bc, T);
        float2 bcd = $unchecked_mix(bc, cd, T);
        float2 abcd = $unchecked_mix(abc, bcd, T);

        // Evaluate the conic weight at T.
        float u = $unchecked_mix(1.0, w, T);
        float v = w + 1 - u;  // == mix(w, 1, T)
        float uv = $unchecked_mix(u, v, T);

        // If we went with T=parametricT, then update the tangent. Otherwise leave it at the radial
        // tangent found previously. (In the event that parametricT == radialT, we keep the radial
        // tangent.)
        if (T != radialT) {
            // We must re-normalize here because the tangent is determined by the curve coefficients
            tangent = w >= 0.0 ? $robust_normalize_diff(bc*u, ab*v)
                               : $robust_normalize_diff(bcd, abc);
        }

        strokeCoord = (w >= 0.0) ? abc/uv : abcd;
    } else {
        // Edges at the beginning and end of the strip use exact endpoints and tangents. This
        // ensures crack-free seaming between instances.
        tangent = (combinedEdgeID == 0) ? tan0 : tan1;
        strokeCoord = (combinedEdgeID == 0) ? p0 : p3;
    }

    // At this point 'tangent' is normalized, so the orthogonal vector is also normalized.
    float2 ortho = float2(tangent.y, -tangent.x);
    strokeCoord += ortho * (strokeRadius * strokeOutset);

    if (isHairline) {
        // Hairline case. The scale and skew already happened before tessellation.
        // TODO: There's probably a more efficient way to tessellate the hairline that lets us
        // avoid inverting the affine matrix to get back to local coords, but it's just a 2x2 so
        // this works for now.
        return float4(strokeCoord + translate, inverse(affineMatrix) * strokeCoord);
    } else {
        // Normal case. Do the transform after tessellation.
        return float4(affineMatrix * strokeCoord + translate, strokeCoord);
    }
}

float4 analytic_rrect_vertex_fn(// Vertex Attributes
                                float2 position,
                                float2 normal,
                                float normalScale,
                                float centerWeight,
                                // Instance Attributes
                                float4 xRadiiOrFlags,
                                float4 radiiOrQuadXs,
                                float4 ltrbOrQuadYs,
                                float4 center,
                                float depth,
                                float3x3 localToDevice,
                                // Varyings
                                out float4 jacobian,
                                out float4 edgeDistances,
                                out float4 xRadii,
                                out float4 yRadii,
                                out float2 strokeParams,
                                out float2 perPixelControl,
                                // Render Step
                                out float2 stepLocalCoords) {
    const uint kCornerVertexCount = 9; // KEEP IN SYNC WITH C++'s
                                       // AnalyticRRectRenderStep::kCornerVertexCount
    const float kMiterScale = 1.0;
    const float kBevelScale = 0.0;
    const float kRoundScale = 0.41421356237; // sqrt(2)-1

    const float kEpsilon = 0.00024; // SK_ScalarNearlyZero

    // Default to miter'ed vertex positioning. Corners with sufficiently large corner radii, or
    // bevel'ed strokes will adjust vertex placement on a per corner basis. This will not affect
    // the final coverage calculations in the fragment shader.
    float joinScale = kMiterScale;

    // Unpack instance-level state that determines the vertex placement and style of shape.
    bool bidirectionalCoverage = center.z <= 0.0;
    bool deviceSpaceDistances = false;
    float4 xs, ys; // ordered TL, TR, BR, BL
    float4 edgeAA = float4(1.0); // ordered L,T,R,B. 1 = AA, 0 = no AA
    bool strokedLine = false;
    if (xRadiiOrFlags.x < -1.0) {
        // Stroked [round] rect or line
        // If y > 0, unpack the line end points, otherwise unpack the rect edges
        strokedLine = xRadiiOrFlags.y > 0.0;
        xs = strokedLine ? ltrbOrQuadYs.LLRR : ltrbOrQuadYs.LRRL;
        ys = ltrbOrQuadYs.TTBB;

        if (xRadiiOrFlags.y < 0.0) {
            // A hairline [r]rect so the X radii are encoded as negative values in this field,
            // and Y radii are stored directly in the subsequent float4.
            xRadii = -xRadiiOrFlags - 2.0;
            yRadii = radiiOrQuadXs;

            // All hairlines use miter joins (join style > 0)
            strokeParams = float2(0.0, 1.0);
        } else {
            xRadii = radiiOrQuadXs;
            yRadii = xRadii; // regular strokes are circular
            strokeParams = xRadiiOrFlags.zw;

            // `sign(strokeParams.y)` evaluates to kMiterScale (1.0) when the
            // input is positive, and kBevelScale (0.0) when it is zero.
            // kRoundScale uses the stroke radius to round rectangular corners.
            joinScale = (strokeParams.y < 0.0) ? kRoundScale
                                               : sign(strokeParams.y);
        }
    } else if (any(greaterThan(xRadiiOrFlags, float4(0.0)))) {
        // Filled round rect
        xs = ltrbOrQuadYs.LRRL;
        ys = ltrbOrQuadYs.TTBB;

        xRadii = xRadiiOrFlags;
        yRadii = radiiOrQuadXs;

        strokeParams = float2(0.0, -1.0); // A negative join style is "round"
    } else {
        // Per-edge quadrilateral, so we have to calculate the corner's basis from the
        // quad's edges.
        xs = radiiOrQuadXs;
        ys = ltrbOrQuadYs;
        edgeAA = -xRadiiOrFlags; // AA flags needed to be < 0 on upload, so flip the sign.

        xRadii = float4(0.0);
        yRadii = float4(0.0);

        strokeParams = float2(0.0, 1.0); // Will be ignored, but set to a "miter"
        deviceSpaceDistances = true;
    }

    // Adjust state on a per-corner basis
    uint cornerID = uint(sk_VertexID) / kCornerVertexCount;
    float2 cornerRadii = float2(xRadii[cornerID], yRadii[cornerID]);
    if (cornerID % 2 != 0) {
        // Corner radii are uploaded in the local coordinate frame, but vertex placement happens
        // in a consistent winding before transforming to final local coords, so swap the
        // radii for odd corners.
        cornerRadii = cornerRadii.yx;
    }

    float2 cornerAspectRatio = float2(1.0);
    if (all(greaterThan(cornerRadii, float2(0.0)))) {
        // Position vertices for an elliptical corner; overriding any previous join style since
        // that only applies when radii are 0.
        joinScale = kRoundScale;
        cornerAspectRatio = cornerRadii.yx;
    }

    // Calculate the local edge vectors, ordered L, T, R, B starting from the bottom left point.
    // For quadrilaterals these are not necessarily axis-aligned, but in all cases they orient
    // the +X/+Y normalized vertex template for each corner.
    float4 dx = xs - xs.wxyz;
    float4 dy = ys - ys.wxyz;
    float4 edgeSquaredLen = dx*dx + dy*dy;

    float4 edgeMask = sign(edgeSquaredLen); // 0 for zero-length edge, 1 for non-zero edge.
    float4 edgeBias = float4(0.0); // adjustment to edge distance for butt cap correction
    float2 strokeRadius = float2(strokeParams.x);
    if (any(equal(edgeMask, float4(0.0)))) {
        // Must clean up (dx,dy) depending on the empty edge configuration
        if (all(equal(edgeMask, float4(0.0)))) {
            // A point so use the canonical basis
            dx = float4( 0.0, 1.0, 0.0, -1.0);
            dy = float4(-1.0, 0.0, 1.0,  0.0);
            edgeSquaredLen = float4(1.0);
        } else {
            // Triangles (3 non-zero edges) copy the adjacent edge. Otherwise it's a line so
            // replace empty edges with the left-hand normal vector of the adjacent edge.
            bool triangle = (edgeMask[0] + edgeMask[1] + edgeMask[2] + edgeMask[3]) > 2.5;
            float4 edgeX = triangle ? dx.yzwx :  dy.yzwx;
            float4 edgeY = triangle ? dy.yzwx : -dx.yzwx;

            dx = mix(edgeX, dx, edgeMask);
            dy = mix(edgeY, dy, edgeMask);
            edgeSquaredLen = mix(edgeSquaredLen.yzwx, edgeSquaredLen, edgeMask);
            edgeAA = mix(edgeAA.yzwx, edgeAA, edgeMask);

            if (!triangle && joinScale == kBevelScale) {
                // Don't outset by stroke radius for butt caps on the zero-length edge, but
                // adjust edgeBias and strokeParams to calculate an AA miter'ed shape with the
                // non-uniform stroke outset.
                strokeRadius *= float2(edgeMask[cornerID], edgeMask.yzwx[cornerID]);
                edgeBias = (edgeMask - 1.0) * strokeParams.x;
                strokeParams.y = 1.0;
                joinScale = kMiterScale;
            }
        }
    }

    float4 inverseEdgeLen = inversesqrt(edgeSquaredLen);
    dx *= inverseEdgeLen;
    dy *= inverseEdgeLen;

    // Calculate local coordinate for the vertex (relative to xAxis and yAxis at first).
    float2 xAxis = -float2(dx.yzwx[cornerID], dy.yzwx[cornerID]);
    float2 yAxis =  float2(dx.xyzw[cornerID], dy.xyzw[cornerID]);
    float2 localPos;
    bool snapToCenter = false;
    if (normalScale < 0.0) {
        // Vertex is inset from the base shape, so we scale by (cornerRadii - strokeRadius)
        // and have to check for the possibility of an inner miter. It is always inset by an
        // additional conservative AA amount.
        if (center.w < 0.0 || centerWeight * center.z != 0.0) {
            snapToCenter = true;
        } else {
            float localAARadius = center.w;
            float2 insetRadii =
                    cornerRadii + (bidirectionalCoverage ? -strokeRadius : strokeRadius);
            if (joinScale == kMiterScale ||
                any(lessThanEqual(insetRadii, float2(localAARadius)))) {
                // Miter the inset position
                localPos = (insetRadii - localAARadius);
            } else {
                localPos = insetRadii*position - localAARadius*normal;
            }
        }
    } else {
        // Vertex is outset from the base shape (and possibly with an additional AA outset later
        // in device space).
        localPos = (cornerRadii + strokeRadius) * (position + joinScale*position.yx);
    }

    if (snapToCenter) {
        // Center is already relative to true local coords, not the corner basis.
        localPos = center.xy;
    } else {
        // Transform from corner basis to true local coords.
        localPos -= cornerRadii;
        localPos = float2(xs[cornerID], ys[cornerID]) + xAxis*localPos.x + yAxis*localPos.y;
    }

    // Calculate edge distances and device space coordinate for the vertex
    edgeDistances = dy*(xs - localPos.x) - dx*(ys - localPos.y) + edgeBias;

    // NOTE: This 3x3 inverse is different than just taking the 1st two columns of the 4x4
    // inverse of the original SkM44 local-to-device matrix. We could calculate the 3x3 inverse
    // and upload it, but it does not seem to be a bottleneck and saves on bandwidth to
    // calculate it here instead.
    float3x3 deviceToLocal = inverse(localToDevice);
    float3 devPos = localToDevice * localPos.xy1;
    jacobian = float4(deviceToLocal[0].xy - deviceToLocal[0].z*localPos,
                      deviceToLocal[1].xy - deviceToLocal[1].z*localPos);

    if (deviceSpaceDistances) {
        // Apply the Jacobian in the vertex shader so any quadrilateral normals do not have to
        // be passed to the fragment shader. However, it's important to use the Jacobian at a
        // vertex on the edge, not the current vertex's Jacobian.
        float4 gx = -dy*(deviceToLocal[0].x - deviceToLocal[0].z*xs) +
                     dx*(deviceToLocal[0].y - deviceToLocal[0].z*ys);
        float4 gy = -dy*(deviceToLocal[1].x - deviceToLocal[1].z*xs) +
                     dx*(deviceToLocal[1].y - deviceToLocal[1].z*ys);
        // NOTE: The gradient is missing a W term so edgeDistances must still be multiplied by
        // 1/w in the fragment shader. The same goes for the encoded coverage scale.
        edgeDistances *= inversesqrt(gx*gx + gy*gy);

        // Bias non-AA edge distances by device W so its coverage contribution is >= 1.0
        edgeDistances += (1 - edgeAA)*abs(devPos.z);

        // Mixed edge AA shapes do not use subpixel scale+bias for coverage, since they tile
        // to a large shape of unknown--but likely not subpixel--size. Triangles and quads do
        // not use subpixel coverage since the scale+bias is not constant over the shape, but
        // we can't evaluate per-fragment since we aren't passing down their arbitrary normals.
        bool subpixelCoverage = edgeAA == float4(1.0) &&
                                dot(abs(dx*dx.yzwx + dy*dy.yzwx), float4(1.0)) < kEpsilon;
        if (subpixelCoverage) {
            // Reconstructs the actual device-space width and height for all rectangle vertices.
            float2 dim = edgeDistances.xy + edgeDistances.zw;
            perPixelControl.y = 1.0 + min(min(dim.x, dim.y), abs(devPos.z));
        } else {
            perPixelControl.y = 1.0 + abs(devPos.z); // standard 1px width pre W division.
        }
    }

    // Only outset for a vertex that is in front of the w=0 plane to avoid dealing with outset
    // triangles rasterizing differently from the main triangles as w crosses 0.
    if (normalScale > 0.0 && devPos.z > 0.0) {
        // Note that when there's no perspective, the jacobian is equivalent to the normal
        // matrix (inverse transpose), but produces correct results when there's perspective
        // because it accounts for the position's influence on a line's projected direction.
        float2x2 J = float2x2(jacobian);

        float2 edgeAANormal = float2(edgeAA[cornerID], edgeAA.yzwx[cornerID]) * normal;
        float2 nx = cornerAspectRatio.x * edgeAANormal.x * perp(-yAxis) * J;
        float2 ny = cornerAspectRatio.y * edgeAANormal.y * perp( xAxis) * J;

        bool isMidVertex = all(notEqual(edgeAANormal, float2(0)));
        if (joinScale == kMiterScale && isMidVertex) {
            // Produce a bisecting vector in device space.
            nx = normalize(nx);
            ny = normalize(ny);
            if (dot(nx, ny) < -0.8) {
                // Normals are in nearly opposite directions, so adjust to avoid float error.
                float s = sign(cross_length_2d(nx, ny));
                nx =  s*perp(nx);
                ny = -s*perp(ny);
            }
        }
        // Adding the normal components together directly results in what we'd have
        // calculated if we'd just transformed 'normal' in one go, assuming they weren't
        // normalized in the if-block above. If they were normalized, the sum equals the
        // bisector between the original nx and ny.
        //
        // We multiply by W so that after perspective division the new point is offset by the
        // now-unit normal.
        // NOTE: (nx + ny) can become the zero vector if the device outset is for an edge
        // marked as non-AA. In this case normalize() could produce the zero vector or NaN.
        // Until a counter-example is found, GPUs seem to discard triangles with NaN vertices,
        // which has the same effect as outsetting by the zero vector with this mesh, so we
        // don't bother guarding the normalize() (yet).
        devPos.xy += devPos.z * normalize(nx + ny);

        // By construction these points are 1px away from the outer edge in device space.
        if (deviceSpaceDistances) {
            // Apply directly to edgeDistances to save work per pixel later on.
            edgeDistances -= devPos.z;
        } else {
            // Otherwise store separately so edgeDistances can be used to reconstruct corner pos
            perPixelControl.y = -devPos.z;
        }
    } else if (!deviceSpaceDistances) {
        // Triangles are within the original shape so there's no additional outsetting to
        // take into account for coverage calculations.
        perPixelControl.y = 0.0;
    }

    perPixelControl.x = (centerWeight != 0.0)
            // A positive value signals that a pixel is trivially full coverage.
            ? 1.0
            // A negative value signals bidirectional coverage, and a zero value signals a solid
            // interior with per-pixel coverage.
            : bidirectionalCoverage ? -1.0 : 0.0;

    // The fragment shader operates in a canonical basis (x-axis = (1,0), y-axis = (0,1)). For
    // stroked lines, incorporate their local orientation into the Jacobian to preserve this.
    if (strokedLine) {
        // The updated Jacobian is J' = B^-1 * J, where B is float2x2(xAxis, yAxis) for the
        // top-left corner (so that B^-1 is constant over the whole shape). Since it's a line
        // the basis was constructed to be orthonormal, det(B) = 1 and B^-1 is trivial.
        // NOTE: float2x2 is column-major.
        jacobian = float4(float2x2(dy[0], -dy[1], -dx[0], dx[1]) * float2x2(jacobian));
    }

    // Write out final results
    stepLocalCoords = localPos;
    return float4(devPos.xy, devPos.z*depth, devPos.z);
}

float4 per_edge_aa_quad_vertex_fn(// Vertex Attributes
                                  float2 normal,
                                  // Instance Attributes
                                  float4 edgeAA,
                                  float4 xs, // ordered TL, TR, BR, BL
                                  float4 ys,
                                  float depth,
                                  float3x3 localToDevice,
                                  // Varyings
                                  out float4 edgeDistances,
                                  // Render Step
                                  out float2 stepLocalCoords) {
    const uint kCornerVertexCount = 4; // KEEP IN SYNC WITH C++'s
                                       // PerEdgeAAQuadRenderStep::kCornerVertexCount

    const float kEpsilon = 0.00024; // SK_ScalarNearlyZero

    // Calculate the local edge vectors, ordered L, T, R, B starting from the bottom left point.
    // For quadrilaterals these are not necessarily axis-aligned, but in all cases they orient
    // the +X/+Y normalized vertex template for each corner.
    float4 dx = xs - xs.wxyz;
    float4 dy = ys - ys.wxyz;
    float4 edgeSquaredLen = dx*dx + dy*dy;

    float4 edgeMask = sign(edgeSquaredLen); // 0 for zero-length edge, 1 for non-zero edge.
    if (any(equal(edgeMask, float4(0.0)))) {
        // Must clean up (dx,dy) depending on the empty edge configuration
        if (all(equal(edgeMask, float4(0.0)))) {
            // A point so use the canonical basis
            dx = float4( 0.0, 1.0, 0.0, -1.0);
            dy = float4(-1.0, 0.0, 1.0,  0.0);
            edgeSquaredLen = float4(1.0);
        } else {
            // Triangles (3 non-zero edges) copy the adjacent edge. Otherwise it's a line so
            // replace empty edges with the left-hand normal vector of the adjacent edge.
            bool triangle = (edgeMask[0] + edgeMask[1] + edgeMask[2] + edgeMask[3]) > 2.5;
            float4 edgeX = triangle ? dx.yzwx :  dy.yzwx;
            float4 edgeY = triangle ? dy.yzwx : -dx.yzwx;

            dx = mix(edgeX, dx, edgeMask);
            dy = mix(edgeY, dy, edgeMask);
            edgeSquaredLen = mix(edgeSquaredLen.yzwx, edgeSquaredLen, edgeMask);
            edgeAA = mix(edgeAA.yzwx, edgeAA, edgeMask);
        }
    }

    float4 inverseEdgeLen = inversesqrt(edgeSquaredLen);
    dx *= inverseEdgeLen;
    dy *= inverseEdgeLen;

    // Calculate local coordinate for the vertex (relative to xAxis and yAxis at first).
    uint cornerID = uint(sk_VertexID) / kCornerVertexCount;
    float2 xAxis = -float2(dx.yzwx[cornerID], dy.yzwx[cornerID]);
    float2 yAxis =  float2(dx.xyzw[cornerID], dy.xyzw[cornerID]);

    // Vertex is outset from the base shape (and possibly with an additional AA outset later
    // in device space).
    float2 localPos = float2(xs[cornerID], ys[cornerID]);

    // Calculate edge distances and device space coordinate for the vertex
    edgeDistances = dy*(xs - localPos.x) - dx*(ys - localPos.y);

    // NOTE: This 3x3 inverse is different than just taking the 1st two columns of the 4x4
    // inverse of the original SkM44 local-to-device matrix. We could calculate the 3x3 inverse
    // and upload it, but it does not seem to be a bottleneck and saves on bandwidth to
    // calculate it here instead.
    float3x3 deviceToLocal = inverse(localToDevice);
    float3 devPos = localToDevice * localPos.xy1;

    // Apply the Jacobian in the vertex shader so any quadrilateral normals do not have to
    // be passed to the fragment shader. However, it's important to use the Jacobian at a
    // vertex on the edge, not the current vertex's Jacobian.
    float4 gx = -dy*(deviceToLocal[0].x - deviceToLocal[0].z*xs) +
                 dx*(deviceToLocal[0].y - deviceToLocal[0].z*ys);
    float4 gy = -dy*(deviceToLocal[1].x - deviceToLocal[1].z*xs) +
                 dx*(deviceToLocal[1].y - deviceToLocal[1].z*ys);
    // NOTE: The gradient is missing a W term so edgeDistances must still be multiplied by
    // 1/w in the fragment shader. The same goes for the encoded coverage scale.
    edgeDistances *= inversesqrt(gx*gx + gy*gy);

    // Bias non-AA edge distances by device W so its coverage contribution is >= 1.0
    // Add additional 1/2 bias here so we don't have to do so in the fragment shader.
    edgeDistances += (1.5 - edgeAA)*abs(devPos.z);

    // Only outset for a vertex that is in front of the w=0 plane to avoid dealing with outset
    // triangles rasterizing differently from the main triangles as w crosses 0.
    if (any(notEqual(normal, float2(0.0))) && devPos.z > 0.0) {
        // Note that when there's no perspective, the jacobian is equivalent to the normal
        // matrix (inverse transpose), but produces correct results when there's perspective
        // because it accounts for the position's influence on a line's projected direction.
        float2x2 J = float2x2(deviceToLocal[0].xy - deviceToLocal[0].z*localPos,
                              deviceToLocal[1].xy - deviceToLocal[1].z*localPos);

        float2 edgeAANormal = float2(edgeAA[cornerID], edgeAA.yzwx[cornerID]) * normal;
        float2 nx = edgeAANormal.x * perp(-yAxis) * J;
        float2 ny = edgeAANormal.y * perp( xAxis) * J;

        bool isMidVertex = all(notEqual(edgeAANormal, float2(0)));
        if (isMidVertex) {
            // Produce a bisecting vector in device space.
            nx = normalize(nx);
            ny = normalize(ny);
            if (dot(nx, ny) < -0.8) {
                // Normals are in nearly opposite directions, so adjust to avoid float error.
                float s = sign(cross_length_2d(nx, ny));
                nx =  s*perp(nx);
                ny = -s*perp(ny);
            }
        }
        // Adding the normal components together directly results in what we'd have
        // calculated if we'd just transformed 'normal' in one go, assuming they weren't
        // normalized in the if-block above. If they were normalized, the sum equals the
        // bisector between the original nx and ny.
        //
        // We multiply by W so that after perspective division the new point is offset by the
        // now-unit normal.
        // NOTE: (nx + ny) can become the zero vector if the device outset is for an edge
        // marked as non-AA. In this case normalize() could produce the zero vector or NaN.
        // Until a counter-example is found, GPUs seem to discard triangles with NaN vertices,
        // which has the same effect as outsetting by the zero vector with this mesh, so we
        // don't bother guarding the normalize() (yet).
        devPos.xy += devPos.z * normalize(nx + ny);

        // By construction these points are 1px away from the outer edge in device space.
        // Apply directly to edgeDistances to save work per pixel later on.
        edgeDistances -= devPos.z;
    }

    // Write out final results
    stepLocalCoords = localPos;
    return float4(devPos.xy, devPos.z*depth, devPos.z);
}

float4 circular_arc_vertex_fn(float3 position,
                              // Instance Attributes
                              float4 centerScales,
                              float3 radiiAndFlags,
                              float3 geoClipPlane,
                              float3 fragClipPlane0,
                              float3 fragClipPlane1,
                              float4 inRoundCapPos,
                              float depth,
                              float3x3 localToDevice,
                              // Varyings
                              out float4 circleEdge,
                              out float3 clipPlane,
                              out float3 isectPlane,
                              out float3 unionPlane,
                              out float  roundCapRadius,
                              out float4 roundCapPos,
                              // Render Step
                              out float2 stepLocalCoords) {
    // TODO: clip offset against clip planes
    float2 localCenter = centerScales.xy;
    float2 localPos = localCenter;
    // do geometric clip in normalized space
    float dist = min(dot(position.xy, geoClipPlane.xy) + geoClipPlane.z, 0);
    position.xy -= geoClipPlane.xy * dist;
    // Get the new length to use below for scaling the offset
    // (origLength is the initial length of position.xy).
    float offsetScale = length(position.xy);

    // scale and translate to local space
    if (position.z > 0) {
        localPos += position.xy * centerScales.z;
    } else {
        localPos += position.xy * centerScales.w;
    }

    float3 devPos = localToDevice * localPos.xy1;
    float3 devCenter = localToDevice * localCenter.xy1;
    float2 offset = devPos.xy - devCenter.xy;
    // offset for AA and correct length of offset
    if (offset != float2(0)) {
        offset = normalize(offset);
        devPos.xy += position.z*offset;
        if (position.z > 0) {
            // Scale using distance from center of unit octagon to the vertex
            // Because of geometry clipping we need to scale by 1.0823922*newLength/origLength
            // But the original length is 1.0823922 so the offsetScale is just newLength
            offset *= offsetScale;
        } else {
            // Because of geometry clipping we need to scale by innerRadius*newLength/origLength
            // But the original length is 1 so this is just innerRadius*newLength
            offset *= offsetScale*radiiAndFlags.y;
        }
    }

    circleEdge = float4(offset, radiiAndFlags.xy);
    if (radiiAndFlags.z > 0) {
        clipPlane = fragClipPlane0;
        isectPlane = fragClipPlane1;
        unionPlane = float3(0, 0, 0);
    } else {
        clipPlane = fragClipPlane0;
        isectPlane = float3(0, 0, 1);
        unionPlane = fragClipPlane1;
    }
    if (abs(radiiAndFlags.z) > 1) {
        // This is the cap radius in normalized space where the outer radius is 1 and
        // radii.y is the normalized inner radius.
        roundCapRadius = (1.0 - radiiAndFlags.y) / 2.0;
    } else {
        roundCapRadius = 0;
    }
    roundCapPos = inRoundCapPos;
    stepLocalCoords = localPos;

    // We assume no perspective
    return float4(devPos.xy, depth, 1);
}

float4 text_vertex_fn(float2 baseCoords,
                      // Uniforms
                      float4x4 subRunDeviceMatrix,
                      float4x4 deviceToLocal,
                      float2 atlasSizeInv,
                      // Instance Attributes
                      float2 size,
                      float2 uvPos,
                      float2 xyPos,
                      float strikeToSourceScale,
                      float depth,
                      // Varyings
                      out float2 textureCoords,
                      out float2 unormTexCoords,  // used as varying in SDFText
                      // Render Step
                      out float2 stepLocalCoords) {
    baseCoords.xy *= float2(size);

    // Sub runs have a decomposed transform and are sometimes already transformed into device
    // space, in which `subRunCoords` represents the bounds projected to device space without
    // the local-to-device translation and `subRunDeviceMatrix` contains the translation.
    float2 subRunCoords = strikeToSourceScale * baseCoords + xyPos;
    float4 position = subRunDeviceMatrix * subRunCoords.xy01;

    // Calculate the local coords used for shading.
    // TODO(b/246963258): This is incorrect if the transform has perspective, which would
    // require a division + a valid z coordinate (which is currently set to 0).
    stepLocalCoords = (deviceToLocal * position).xy;

    unormTexCoords = baseCoords + uvPos;
    textureCoords = unormTexCoords * atlasSizeInv;

    return float4(position.xy, depth*position.w, position.w);
}

float4 coverage_mask_vertex_fn(float2 quadCoords,
                               // Uniforms
                               float3x3 maskToDeviceRemainder,
                               // Instance Attributes
                               float4 drawBounds,
                               float4 maskBoundsIn,
                               float2 deviceOrigin,
                               float depth,
                               float3x3 deviceToLocal,
                               // Varyings
                               out float4 maskBounds,
                               out float2 textureCoords,
                               out half invert,
                               // Render Step
                               out float2 stepLocalCoords) {
    // An atlas shape is an axis-aligned rectangle tessellated as a triangle strip.
    //
    // The bounds coordinates are in an intermediate space, pixel-aligned with the mask texture
    // that's sampled in the fragment shader. The coords must be transformed by both
    // maskToDeviceRemainder and translated by deviceOrigin to get device coords.
    textureCoords = mix(drawBounds.xy, drawBounds.zw, quadCoords);
    float3 drawCoords = maskToDeviceRemainder*((textureCoords + deviceOrigin).xy1);

    // Local coordinates used for shading are derived from the final device coords and the inverse
    // of the original local-to-device matrix.
    float3 localCoords = deviceToLocal * drawCoords;
    // TODO: Support float3 local coordinates if the matrix has perspective so that W is
    // interpolated correctly to the fragment shader.
    stepLocalCoords = localCoords.xy / localCoords.z;

    // For an inverse fill, `textureCoords` will get clamped to `maskBounds` and the edge pixels
    // will always land on a 0-coverage border pixel assuming the atlas was prepared with 1px
    // padding around each mask entry. This includes inverse fills where the mask was fully clipped
    // out, since then maskBounds.RBLT == (0,0,-1,-1) and we sample the top-left-most pixel of the
    // atlas, which is guaranteed to be transparent.
    if (all(lessThanEqual(maskBoundsIn.LT, maskBoundsIn.RB))) {
        // Regular fill
        maskBounds = maskBoundsIn;
        invert = 0;
    } else {
        // Re-arrange the mask bounds to sorted order for texture clamping in the fragment shader
        maskBounds = maskBoundsIn.RBLT;
        invert = 1;
    }

    return float4(drawCoords.xy, depth*drawCoords.z, drawCoords.z);
}

float4 cover_bounds_vertex_fn(float2 corner,
                              float4 bounds,
                              float depth,
                              float3x3 matrix,
                              out float2 stepLocalCoords) {
    if (all(lessThanEqual(bounds.LT, bounds.RB))) {
        // A regular fill
        corner = mix(bounds.LT, bounds.RB, corner);
        float3 devCorner = matrix * corner.xy1;
        stepLocalCoords = corner;
        return float4(devCorner.xy, depth*devCorner.z, devCorner.z);
    } else {
        // An inverse fill
        corner = mix(bounds.RB, bounds.LT, corner);
        // TODO(b/351923375): Get the 3x3 inverse  of the local-to-device transform from the CPU
        // if it can be computed fast enough on the CPU from the cached 4x4 inverse.
        float3 localCoords = inverse(matrix) * corner.xy1;
        // Dividing the inverse mapped local coords by its homogenous coordinate reconstructs the
        // original local coords.
        float invW = 1.0 / localCoords.z;
        stepLocalCoords = localCoords.xy * invW;

        // 1/W also happens to be equal to (matrix*stepLocalCoords.xy1).z, which is the device-space
        // homogenous coordinate we want perspective interpolation to respect. We multiply the
        // output position by 1/W and set the output position's homogenous coord to that same 1/W
        // which ensures the projected vertices are still the device-space corners, but
        // stepLocalCoords will be correctly perspective interpolated by HW.
        return float4(corner*invW, depth*invW, invW);
    }
}
