/*
 * Copyright 2020 Google LLC.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/tessellate/GrStrokeTessellateShader.h"

#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
#include "src/gpu/tessellate/GrWangsFormula.h"

// The built-in atan() is undefined when x==0. This method relieves that restriction, but also can
// return values larger than 2*PI. This shouldn't matter for our purposes.
static const char* kAtan2Fn = R"(
float atan2(float2 v) {
    float bias = 0.0;
    if (abs(v.y) > abs(v.x)) {
        v = float2(v.y, -v.x);
        bias = PI/2.0;
    }
    return atan(v.y, v.x) + bias;
})";

static const char* kCosineBetweenVectorsFn = R"(
float cosine_between_vectors(float2 a, float2 b) {
    float ab_cosTheta = dot(a,b);
    float ab_pow2 = dot(a,a) * dot(b,b);
    return (ab_pow2 == 0) ? 1 : clamp(ab_cosTheta * inversesqrt(ab_pow2), -1, 1);
})";

// 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.
static const char* kMiterExtentFn = R"(
float miter_extent(float cosTheta, float miterLimit) {
    float x = fma(cosTheta, .5, .5);
    return (x * miterLimit * miterLimit >= 1.0) ? inversesqrt(x) : sqrt(x);
})";

static const char* kLengthPow2Fn = R"(
float length_pow2(float2 v) {
    return dot(v, v);
})";

static const char* kNumRadialSegmentsPerRadian = R"(
float num_radial_segments_per_radian(float parametricIntolerance, float strokeRadius) {
    return .5 / acos(max(1.0 - 1.0/(parametricIntolerance * strokeRadius), -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.
static const char* kUncheckedMixFn = R"(
float unchecked_mix(float a, float b, float T) {
    return fma(b - a, T, a);
}
float2 unchecked_mix(float2 a, float2 b, float T) {
    return fma(b - a, float2(T), a);
}
float4 unchecked_mix(float4 a, float4 b, float4 T) {
    return fma(b - a, T, a);
})";

// Calculates the number of evenly spaced (in the parametric sense) segments to chop a cubic into.
// (See GrWangsFormula::cubic() for more documentation on this formula.) The final tessellated strip
// will be a composition of these parametric segments as well as radial segments.
static void append_wangs_formula_fn(SkString* code, bool hasConics) {
    code->appendf(R"(
    float wangs_formula(in float4x2 P, in float w, in float parametricIntolerance) {
        const float CUBIC_TERM_POW2 = %f;
        float l0 = length_pow2(fma(float2(-2), P[1], P[2]) + P[0]);
        float l1 = length_pow2(fma(float2(-2), P[2], P[3]) + P[1]);
        float m = CUBIC_TERM_POW2 * max(l0, l1);)", GrWangsFormula::length_term_pow2<3>(1));
    if (hasConics) {
        code->appendf(R"(
        const float QUAD_TERM_POW2 = %f;
        m = (w > 0) ? QUAD_TERM_POW2 * l0 : m;)", GrWangsFormula::length_term_pow2<2>(1));
    }
    code->append(R"(
        return max(ceil(sqrt(parametricIntolerance * sqrt(m))), 1.0);
    })");
}

class GrStrokeTessellateShader::TessellationImpl : public GrGLSLGeometryProcessor {
public:
    const char* getTessArgsUniformName(const GrGLSLUniformHandler& uniformHandler) const {
        return uniformHandler.getUniformCStr(fTessArgsUniform);
    }
    const char* getTranslateUniformName(const GrGLSLUniformHandler& uniformHandler) const {
        return uniformHandler.getUniformCStr(fTranslateUniform);
    }
    const char* getAffineMatrixUniformName(const GrGLSLUniformHandler& uniformHandler) const {
        return uniformHandler.getUniformCStr(fAffineMatrixUniform);
    }

private:
    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
        const auto& shader = args.fGP.cast<GrStrokeTessellateShader>();
        auto* uniHandler = args.fUniformHandler;
        auto* v = args.fVertBuilder;

        args.fVaryingHandler->emitAttributes(shader);

        v->defineConstant("float", "PI", "3.141592653589793238");

        // The vertex shader chops the curve into 3 sections in order to meet our tessellation
        // requirements. The stroke tessellator does not allow curve sections to inflect or to
        // rotate more than 180 degrees.
        //
        // We start by chopping at inflections (if the curve has any), or else at midtangent. If we
        // still don't have 3 sections after that then we just subdivide uniformly in parametric
        // space.
        using TypeModifier = GrShaderVar::TypeModifier;
        v->defineConstantf("float", "kParametricEpsilon", "1.0 / (%i * 128)",
                           args.fShaderCaps->maxTessellationSegments());  // 1/128 of a segment.

        // [numSegmentsInJoin, innerJoinRadiusMultiplier, prevJoinTangent.xy]
        v->declareGlobal(GrShaderVar("vsJoinArgs0", kFloat4_GrSLType, TypeModifier::Out));

        // [joinAngle0, radsPerJoinSegment, joinOutsetClamp.xy]
        v->declareGlobal(GrShaderVar("vsJoinArgs1", kFloat4_GrSLType, TypeModifier::Out));

        // Curve args.
        v->declareGlobal(GrShaderVar("vsPts01", kFloat4_GrSLType, TypeModifier::Out));
        v->declareGlobal(GrShaderVar("vsPts23", kFloat4_GrSLType, TypeModifier::Out));
        v->declareGlobal(GrShaderVar("vsPts45", kFloat4_GrSLType, TypeModifier::Out));
        v->declareGlobal(GrShaderVar("vsPts67", kFloat4_GrSLType, TypeModifier::Out));
        v->declareGlobal(GrShaderVar("vsPts89", kFloat4_GrSLType, TypeModifier::Out));
        v->declareGlobal(GrShaderVar("vsTans01", kFloat4_GrSLType, TypeModifier::Out));
        v->declareGlobal(GrShaderVar("vsTans23", kFloat4_GrSLType, TypeModifier::Out));
        if (shader.hasDynamicStroke()) {
            // [NUM_RADIAL_SEGMENTS_PER_RADIAN, STROKE_RADIUS]
            v->declareGlobal(GrShaderVar("vsStrokeArgs", kFloat2_GrSLType, TypeModifier::Out));
        }
        if (shader.hasDynamicColor()) {
            v->declareGlobal(GrShaderVar("vsColor", kHalf4_GrSLType, TypeModifier::Out));
        }

        v->insertFunction(kAtan2Fn);
        v->insertFunction(kCosineBetweenVectorsFn);
        v->insertFunction(kMiterExtentFn);
        v->insertFunction(kUncheckedMixFn);
        v->insertFunction(kLengthPow2Fn);
        if (shader.hasDynamicStroke()) {
            v->insertFunction(kNumRadialSegmentsPerRadian);
        }

        if (!shader.hasDynamicStroke()) {
            // [PARAMETRIC_INTOLERANCE, NUM_RADIAL_SEGMENTS_PER_RADIAN, JOIN_TYPE, STROKE_RADIUS]
            const char* tessArgsName;
            fTessArgsUniform = uniHandler->addUniform(nullptr,
                                                      kVertex_GrShaderFlag |
                                                      kTessControl_GrShaderFlag |
                                                      kTessEvaluation_GrShaderFlag,
                                                      kFloat4_GrSLType, "tessArgs", &tessArgsName);
            v->codeAppendf(R"(
            float NUM_RADIAL_SEGMENTS_PER_RADIAN = %s.y;
            float JOIN_TYPE = %s.z;)", tessArgsName, tessArgsName);
        } else {
            const char* parametricIntoleranceName;
            fTessArgsUniform = uniHandler->addUniform(nullptr,
                                                      kVertex_GrShaderFlag |
                                                      kTessControl_GrShaderFlag |
                                                      kTessEvaluation_GrShaderFlag,
                                                      kFloat_GrSLType, "parametricIntolerance",
                                                      &parametricIntoleranceName);
            v->codeAppendf(R"(
            float STROKE_RADIUS = dynamicStrokeAttr.x;
            float NUM_RADIAL_SEGMENTS_PER_RADIAN = num_radial_segments_per_radian(%s,STROKE_RADIUS);
            float JOIN_TYPE = dynamicStrokeAttr.y;)", parametricIntoleranceName);
        }

        if (!shader.viewMatrix().isIdentity()) {
            fTranslateUniform = uniHandler->addUniform(nullptr, kTessEvaluation_GrShaderFlag,
                                                       kFloat2_GrSLType, "translate", nullptr);
            const char* affineMatrixName;
            // Hairlines apply the affine matrix in their vertex shader, prior to tessellation.
            // Otherwise the entire view matrix gets applied at the end of the tess eval shader.
            auto affineMatrixVisibility = (shader.fStroke.isHairlineStyle()) ?
                    kVertex_GrShaderFlag : kTessEvaluation_GrShaderFlag;
            fAffineMatrixUniform = uniHandler->addUniform(nullptr, affineMatrixVisibility,
                                                          kFloat4_GrSLType, "affineMatrix",
                                                          &affineMatrixName);
            if (affineMatrixVisibility & kVertex_GrShaderFlag) {
                v->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n", affineMatrixName);
            }
        }

        v->codeAppend(R"(
        // Unpack the control points.
        float2 prevControlPoint = prevCtrlPtAttr;
        float4x2 P = float4x2(pts01Attr, pts23Attr);)");

        if (shader.fStroke.isHairlineStyle() && !shader.viewMatrix().isIdentity()) {
            // 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.
            if (shader.hasConics()) {
                v->codeAppend(R"(
                P[0] = AFFINE_MATRIX * P[0];
                P[1] = AFFINE_MATRIX * P[1];
                P[2] = AFFINE_MATRIX * P[2];
                P[3] = isinf(P[3].y) ? P[3] : AFFINE_MATRIX * P[3];)");
            } else {
                v->codeAppend(R"(
                P = AFFINE_MATRIX * P;)");
            }
            v->codeAppend(R"(
            prevControlPoint = AFFINE_MATRIX * prevControlPoint;)");
        }

        v->codeAppend(R"(
        // Find the tangents. It's imperative that we compute these tangents from the original
        // (pre-chopping) input points or else the seams might crack.
        float2 prevJoinTangent = P[0] - prevControlPoint;
        float2 tan0 = ((P[1] == P[0]) ? P[2] : P[1]) - P[0];
        float2 tan1 = (P[3] == P[2] || isinf(P[3].y)) ? P[2] - P[1] : P[3] - P[2];

        if (tan0 == float2(0)) {
            // [p0, p0, p0, p3] is a reserved pattern that means this patch is a "bowtie".
            P[3] = P[0];  // Colocate all the points on the center of the bowtie.
            tan0 = prevJoinTangent;  // Use the curve sections to draw the bowtie.
            prevJoinTangent = float2(0);  // Disable the join section.
        }

        if (tan1 == float2(0)) {
            // [p0, p3, p3, p3] is a reserved pattern that means this patch is a join only. Colocate
            // all the curve's points to ensure it gets disabled by the tessellation stages.
            P[1] = P[2] = P[3] = P[0];
        }

        // Calculate the number of segments to chop the join into.
        float cosTheta = cosine_between_vectors(prevJoinTangent, tan0);
        float joinRotation = (cosTheta == 1) ? 0 : acos(cosTheta);
        if (cross(prevJoinTangent, tan0) < 0) {
            joinRotation = -joinRotation;
        }
        float joinRadialSegments = abs(joinRotation) * NUM_RADIAL_SEGMENTS_PER_RADIAN;
        float numSegmentsInJoin = (joinRadialSegments != 0 /*Is the join non-empty?*/ &&
                                   JOIN_TYPE >= 0 /*Is the join not a round type?*/)
                ? sign(JOIN_TYPE) + 1  // Non-empty bevel joins have 1 segment and miters have 2.
                : ceil(joinRadialSegments);  // Otherwise round up the number of radial segments.

        // Extends the middle join edge to the miter point.
        float innerJoinRadiusMultiplier = 1;
        if (JOIN_TYPE > 0 /*Is the join a miter type?*/) {
            innerJoinRadiusMultiplier = miter_extent(cosTheta, JOIN_TYPE/*miterLimit*/);
        }

        // Clamps join geometry to the exterior side of the junction.
        float2 joinOutsetClamp = float2(-1, 1);
        if (joinRadialSegments > .1 /*Does the join rotate more than 1/10 of a segment?*/) {
            // Only clamp if the join angle is large enough to guarantee there won't be cracks on
            // the interior side of the junction.
            joinOutsetClamp = (joinRotation > 0) ? float2(-1, 0) : float2(0, 1);
        }

        // Pack join args for the tessellation control stage.
        vsJoinArgs0 = float4(numSegmentsInJoin, innerJoinRadiusMultiplier, prevJoinTangent);
        vsJoinArgs1 = float4(atan2(prevJoinTangent), joinRotation / numSegmentsInJoin,
                             joinOutsetClamp);

        // Now find where to chop the curve so the resulting sub-curves are convex and do not rotate
        // more than 180 degrees. We don't need to worry about cusps because the caller chops those
        // out on the CPU. Start by finding the cubic's power basis coefficients. These define the
        // bezier curve as:
        //
        //                                    |T^3|
        //     Cubic(T) = x,y = |A  3B  3C| * |T^2| + P0
        //                      |.   .   .|   |T  |
        //
        // And the tangent direction (scaled by a uniform 1/3) will be:
        //
        //                                                 |T^2|
        //     Tangent_Direction(T) = dx,dy = |A  2B  C| * |T  |
        //                                    |.   .  .|   |1  |
        //
        float2 C = P[1] - P[0];
        float2 D = P[2] - P[1];
        float2 E = P[3] - P[0];
        float2 B = D - C;
        float2 A = fma(float2(-3), D, E);

        // Now find the cubic's inflection function. There are inflections where F' x F'' == 0.
        // We formulate this as a quadratic equation:  F' x F'' == aT^2 + bT + c == 0.
        // See: https://www.microsoft.com/en-us/research/wp-content/uploads/2005/01/p1000-loop.pdf
        // NOTE: We only need the roots, so a uniform scale factor does not affect the solution.
        float a = cross(A, B);
        float b = cross(A, C);
        float c = cross(B, C);
        float b_over_2 = b*.5;
        float discr_over_4 = b_over_2*b_over_2 - a*c;

        float2x2 innerTangents = float2x2(0);
        if (discr_over_4 <= 0) {
            // The curve does not inflect. This means it might rotate more than 180 degrees instead.
            // Craft a quadratic whose roots are the points were rotation == 180 deg and 0. (These
            // are the points where the tangent is parallel to tan0.)
            //
            //      Tangent_Direction(T) x tan0 == 0
            //      (AT^2 x tan0) + (2BT x tan0) + (C x tan0) == 0
            //      (A x C)T^2 + (2B x C)T + (C x C) == 0  [[because tan0 == P1 - P0 == C]]
            //      bT^2 + 2cT + 0 == 0  [[because A x C == b, B x C == c]]
            //
            // NOTE: When P0 == P1 then C != tan0, C == 0 and these roots will be undefined. But
            // that's ok because when P0 == P1 the curve cannot rotate more than 180 degrees anyway.
            a = b;
            b_over_2 = c;
            c = 0;
            discr_over_4 = b_over_2*b_over_2;
            innerTangents[0] = -C;
        }

        // Solve our quadratic equation for the chop points. This is inspired by the quadratic
        // formula from Numerical Recipes in C.
        float q = sqrt(discr_over_4);
        if (b_over_2 > 0) {
            q = -q;
        }
        q -= b_over_2;
        float2 chopT = float2((a != 0) ? q/a : 0,
                              (q != 0) ? c/q : 0);

        // Reposition any chop points that fall outside ~0..1 and clear their innerTangent.
        int numOutside = 0;
        if (chopT[0] <= kParametricEpsilon || chopT[0] >= 1 - kParametricEpsilon) {
            innerTangents[0] = float2(0);
            ++numOutside;
        }
        if (chopT[1] <= kParametricEpsilon || chopT[1] >= 1 - kParametricEpsilon) {
            // Swap places with chopT[0]. This ensures chopT[0] is outside when numOutside > 0.
            chopT = chopT.ts;
            innerTangents = float2x2(0,0, innerTangents[0]);
            ++numOutside;
        }
        if (numOutside == 2) {
            chopT[1] = 2/3.0;
        }
        if (numOutside >= 1) {
            chopT[0] = (chopT[1] <= .5) ? chopT[1] * .5 : fma(chopT[1], .5, .5);
        }

        // Sort the chop points.
        if (chopT[0] > chopT[1]) {
            chopT = chopT.ts;
            innerTangents = float2x2(innerTangents[1], innerTangents[0]);
        }

        // If the curve is a straight line, point, or conic, don't chop it into sections after all.
        if ((P[0] == P[1] && P[2] == P[3]) || isinf(P[3].y)) {
            chopT = float2(0);
            innerTangents = float2x2(tan0, tan0);
        }

        // Chop the curve at chopT[0] and chopT[1].
        float4 ab = unchecked_mix(P[0].xyxy, P[1].xyxy, chopT.sstt);
        float4 bc = unchecked_mix(P[1].xyxy, P[2].xyxy, chopT.sstt);
        float4 cd = isinf(P[3].y) ? P[2].xyxy : unchecked_mix(P[2].xyxy, P[3].xyxy, chopT.sstt);
        float4 abc = unchecked_mix(ab, bc, chopT.sstt);
        float4 bcd = unchecked_mix(bc, cd, chopT.sstt);
        float4 abcd = unchecked_mix(abc, bcd, chopT.sstt);
        float4 middle = unchecked_mix(abc, bcd, chopT.ttss);

        // Find tangents at the chop points if an inner tangent wasn't specified.
        if (innerTangents[0] == float2(0)) {
            innerTangents[0] = bcd.xy - abc.xy;
        }
        if (innerTangents[1] == float2(0)) {
            innerTangents[1] = bcd.zw - abc.zw;
        }

        // Pack curve args for the tessellation control stage.
        vsPts01 = float4(P[0], ab.xy);
        vsPts23 = float4(abc.xy, abcd.xy);
        vsPts45 = middle;
        vsPts67 = float4(abcd.zw, bcd.zw);
        vsPts89 = float4(cd.zw, P[3]);
        vsTans01 = float4(tan0, innerTangents[0]);
        vsTans23 = float4(innerTangents[1], tan1);)");
        if (shader.hasDynamicStroke()) {
            v->codeAppend(R"(
            vsStrokeArgs = float2(NUM_RADIAL_SEGMENTS_PER_RADIAN, STROKE_RADIUS);)");
        }
        if (shader.hasDynamicColor()) {
            v->codeAppend(R"(
            vsColor = dynamicColorAttr;)");
        }

        if (!shader.hasDynamicColor()) {
            // The fragment shader just outputs a uniform color.
            const char* colorUniformName;
            fColorUniform = uniHandler->addUniform(nullptr, kFragment_GrShaderFlag, kHalf4_GrSLType,
                                                   "color", &colorUniformName);
            args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUniformName);
        } else {
            // Color gets passed in from the tess evaluation shader.
            SkString flatness(args.fShaderCaps->preferFlatInterpolation() ? "flat" : "");
            args.fFragBuilder->declareGlobal(GrShaderVar(SkString("tesColor"), kHalf4_GrSLType,
                                                         TypeModifier::In, 0, SkString(),
                                                         flatness));
            args.fFragBuilder->codeAppendf("%s = tesColor;", args.fOutputColor);
        }
        args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
    }

    void setData(const GrGLSLProgramDataManager& pdman,
                 const GrPrimitiveProcessor& primProc) override {
        const auto& shader = primProc.cast<GrStrokeTessellateShader>();
        const auto& stroke = shader.fStroke;

        if (!shader.hasDynamicStroke()) {
            Tolerances tolerances;
            if (!stroke.isHairlineStyle()) {
                tolerances.set(shader.viewMatrix().getMaxScale(), stroke.getWidth());
            } else {
                // In the hairline case we transform prior to tessellation. Set up tolerances for an
                // identity viewMatrix and a strokeWidth of 1.
                tolerances.set(1, 1);
            }
            float strokeRadius = (stroke.isHairlineStyle()) ? .5f : stroke.getWidth() * .5;
            pdman.set4f(fTessArgsUniform,
                        tolerances.fParametricIntolerance,  // PARAMETRIC_INTOLERANCE
                        tolerances.fNumRadialSegmentsPerRadian,  // NUM_RADIAL_SEGMENTS_PER_RADIAN
                        GetJoinType(shader.fStroke),  // JOIN_TYPE
                        strokeRadius);  // STROKE_RADIUS
        } else {
            SkASSERT(!stroke.isHairlineStyle());
            pdman.set1f(fTessArgsUniform,
                        Tolerances::CalcParametricIntolerance(shader.viewMatrix().getMaxScale()));
        }

        // Set up the view matrix, if any.
        const SkMatrix& m = shader.viewMatrix();
        if (!m.isIdentity()) {
            pdman.set2f(fTranslateUniform, m.getTranslateX(), m.getTranslateY());
            pdman.set4f(fAffineMatrixUniform, m.getScaleX(), m.getSkewY(), m.getSkewX(),
                        m.getScaleY());
        }

        if (!shader.hasDynamicColor()) {
            pdman.set4fv(fColorUniform, 1, shader.fColor.vec());
        }
    }

    GrGLSLUniformHandler::UniformHandle fTessArgsUniform;
    GrGLSLUniformHandler::UniformHandle fTranslateUniform;
    GrGLSLUniformHandler::UniformHandle fAffineMatrixUniform;
    GrGLSLUniformHandler::UniformHandle fColorUniform;
};

SkString GrStrokeTessellateShader::getTessControlShaderGLSL(
        const GrGLSLPrimitiveProcessor* glslPrimProc, const char* versionAndExtensionDecls,
        const GrGLSLUniformHandler& uniformHandler, const GrShaderCaps& shaderCaps) const {
    SkASSERT(fMode == Mode::kTessellation);
    auto impl = static_cast<const GrStrokeTessellateShader::TessellationImpl*>(glslPrimProc);

    SkString code(versionAndExtensionDecls);
    // Run 3 invocations: 1 for each section that the vertex shader chopped the curve into.
    code.append("layout(vertices = 3) out;\n");
    code.appendf("precision highp float;\n");

    code.appendf("#define float2 vec2\n");
    code.appendf("#define float3 vec3\n");
    code.appendf("#define float4 vec4\n");
    code.appendf("#define float2x2 mat2\n");
    code.appendf("#define float4x2 mat4x2\n");
    code.appendf("#define PI 3.141592653589793238\n");
    code.appendf("#define MAX_TESSELLATION_SEGMENTS %i.0\n", shaderCaps.maxTessellationSegments());
    code.appendf("#define cross cross2d\n");  // GLSL already has a function named "cross".

    const char* tessArgsName = impl->getTessArgsUniformName(uniformHandler);
    if (!this->hasDynamicStroke()) {
        code.appendf("uniform vec4 %s;\n", tessArgsName);
        code.appendf("#define PARAMETRIC_INTOLERANCE %s.x\n", tessArgsName);
        code.appendf("#define NUM_RADIAL_SEGMENTS_PER_RADIAN %s.y\n", tessArgsName);
    } else {
        code.appendf("uniform float %s;\n", tessArgsName);
        code.appendf("#define PARAMETRIC_INTOLERANCE %s\n", tessArgsName);
        code.appendf("#define NUM_RADIAL_SEGMENTS_PER_RADIAN vsStrokeArgs[0].x\n");
    }

    code.append(kLengthPow2Fn);
    append_wangs_formula_fn(&code, this->hasConics());
    code.append(kAtan2Fn);
    code.append(kCosineBetweenVectorsFn);
    code.append(kMiterExtentFn);
    code.append(R"(
    float cross2d(vec2 a, vec2 b) {
        return determinant(mat2(a,b));
    })");

    code.append(R"(
    in vec4 vsJoinArgs0[];
    in vec4 vsJoinArgs1[];
    in vec4 vsPts01[];
    in vec4 vsPts23[];
    in vec4 vsPts45[];
    in vec4 vsPts67[];
    in vec4 vsPts89[];
    in vec4 vsTans01[];
    in vec4 vsTans23[];)");
    if (this->hasDynamicStroke()) {
        code.append(R"(
        in vec2 vsStrokeArgs[];)");
    }
    if (this->hasDynamicColor()) {
        code.append(R"(
        in mediump vec4 vsColor[];)");
    }

    code.append(R"(
    out vec4 tcsPts01[];
    out vec4 tcsPt2Tan0[];
    out vec4 tcsTessArgs[];  // [numCombinedSegments, numParametricSegments, angle0, radsPerSegment]
    patch out vec4 tcsJoinArgs0; // [numSegmentsInJoin, innerJoinRadiusMultiplier,
                                 //  prevJoinTangent.xy]
    patch out vec4 tcsJoinArgs1;  // [joinAngle0, radsPerJoinSegment, joinOutsetClamp.xy]
    patch out vec4 tcsEndPtEndTan;)");
    if (this->hasDynamicStroke()) {
        code.append(R"(
        patch out float tcsStrokeRadius;)");
    }
    if (this->hasDynamicColor()) {
        code.append(R"(
        patch out mediump vec4 tcsColor;)");
    }

    code.append(R"(
    void main() {
        // Forward join args to the evaluation stage.
        tcsJoinArgs0 = vsJoinArgs0[0];
        tcsJoinArgs1 = vsJoinArgs1[0];)");
    if (this->hasDynamicStroke()) {
        code.append(R"(
        tcsStrokeRadius = vsStrokeArgs[0].y;)");
    }
    if (this->hasDynamicColor()) {
        code.append(R"(
        tcsColor = vsColor[0];)");
    }

    code.append(R"(
        // Unpack the curve args from the vertex shader.
        mat4x2 P;
        mat2 tangents;
        if (gl_InvocationID == 0) {
            // This is the first section of the curve.
            P = mat4x2(vsPts01[0], vsPts23[0]);
            tangents = mat2(vsTans01[0]);
        } else if (gl_InvocationID == 1) {
            // This is the middle section of the curve.
            P = mat4x2(vsPts23[0].zw, vsPts45[0], vsPts67[0].xy);
            tangents = mat2(vsTans01[0].zw, vsTans23[0].xy);
        } else {
            // This is the final section of the curve.
            P = mat4x2(vsPts67[0], vsPts89[0]);
            tangents = mat2(vsTans23[0]);
        }

        // Calculate the number of parametric segments. The final tessellated strip will be a
        // composition of these parametric segments as well as radial segments.
        float w = isinf(P[3].y) ? P[3].x : -1.0; // w<0 means the curve is an integral cubic.
        float numParametricSegments = wangs_formula(P, w, PARAMETRIC_INTOLERANCE);
        if (P[0] == P[1] && P[2] == P[3]) {
            // This is how the patch builder articulates lineTos but Wang's formula returns
            // >>1 segment in this scenario. Assign 1 parametric segment.
            numParametricSegments = 1.0;
        }

        // Determine the curve's start angle.
        float angle0 = atan2(tangents[0]);

        // Determine the curve's total rotation. The vertex shader ensures our curve does not rotate
        // more than 180 degrees or inflect, so the inverse cosine has enough range.
        float cosTheta = cosine_between_vectors(tangents[0], tangents[1]);
        float rotation = acos(cosTheta);

        // Adjust sign of rotation to match the 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 = isinf(P[3].y) ? cross2d(P[1] - P[0], P[2] - P[1])
                                   : cross2d(P[2] - P[0], P[3] - P[1]);
        if (turn == 0.0) {  // This is the case for joins and cusps where points are co-located.
            turn = determinant(tangents);
        }
        if (turn < 0.0) {
            rotation = -rotation;
        }

        // Calculate the number of evenly spaced radial segments to chop this section of the curve
        // into. Radial segments divide the curve's rotation into even steps. The final tessellated
        // strip will be a composition of both parametric and radial segments.
        float numRadialSegments = abs(rotation) * NUM_RADIAL_SEGMENTS_PER_RADIAN;
        numRadialSegments = max(ceil(numRadialSegments), 1.0);

        // The first and last edges are shared by both the parametric and radial sets of edges, so
        // the total number of edges is:
        //
        //   numCombinedEdges = numParametricEdges + numRadialEdges - 2
        //
        // It's also important to differentiate between the number of edges and segments in a strip:
        //
        //   numCombinedSegments = numCombinedEdges - 1
        //
        // So the total number of segments in the combined strip is:
        //
        //   numCombinedSegments = numParametricEdges + numRadialEdges - 2 - 1
        //                       = numParametricSegments + 1 + numRadialSegments + 1 - 2 - 1
        //                       = numParametricSegments + numRadialSegments - 1
        //
        float numCombinedSegments = numParametricSegments + numRadialSegments - 1.0;

        if (P[0] == P[3] && tangents[1] == vec2(0)) {
            // The vertex shader intentionally disabled our section. Set numCombinedSegments to 0.
            numCombinedSegments = 0.0;
        }

        // Pack the args for the evaluation stage.
        tcsPts01[gl_InvocationID] = vec4(P[0], P[1]);
        tcsPt2Tan0[gl_InvocationID] = vec4(P[2], tangents[0]);
        tcsTessArgs[gl_InvocationID] = vec4(numCombinedSegments, numParametricSegments, angle0,
                                            rotation / numRadialSegments);
        if (gl_InvocationID == 2) {
            tcsEndPtEndTan = vec4(P[3], tangents[1]);
        }

        barrier();

        // Tessellate a quad strip with enough segments for the join plus all 3 curve sections
        // combined.
        float numTotalCombinedSegments = tcsJoinArgs0.x + tcsTessArgs[0].x + tcsTessArgs[1].x +
                                         tcsTessArgs[2].x;

        if (tcsJoinArgs0.x != 0.0 && tcsJoinArgs0.x != numTotalCombinedSegments) {
            // We are tessellating a quad strip with both a single-sided join and a double-sided
            // stroke. Add one more edge to the join. This new edge will fall parallel with the
            // first edge of the stroke, eliminating artifacts on the transition from single
            // sided to double.
            ++tcsJoinArgs0.x;
            ++numTotalCombinedSegments;
        }

        numTotalCombinedSegments = min(numTotalCombinedSegments, MAX_TESSELLATION_SEGMENTS);
        gl_TessLevelInner[0] = numTotalCombinedSegments;
        gl_TessLevelInner[1] = 2.0;
        gl_TessLevelOuter[0] = 2.0;
        gl_TessLevelOuter[1] = numTotalCombinedSegments;
        gl_TessLevelOuter[2] = 2.0;
        gl_TessLevelOuter[3] = numTotalCombinedSegments;
    })");

    return code;
}

// Computes 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.
static void append_eval_stroke_edge_fn(SkString* code, bool hasConics) {
    code->append(R"(
    void eval_stroke_edge(in float4x2 P, in float w, in float numParametricSegments,
                          in float combinedEdgeID, in float2 tan0, in float radsPerSegment,
                          in float angle0, out float2 tangent, out float2 position) {
        // 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 = P[1] - P[0];
        float2 D = P[3] - P[0];)");
    if (hasConics) {
        code->append(R"(
        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) * D;
            P[1] *= w;
        } else {)");
    } else {
        code->append(R"(
        {)");
    }
    code->append(R"(
            float2 E = P[2] - P[1];
            B = E - C;
            A = fma(float2(-3), E, D);
        }

        // 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);
        float2 tan0norm = normalize(tan0);
        float negAbsRadsPerSegment = -abs(radsPerSegment);
        float maxRotation0 = (1.0 + combinedEdgeID) * abs(radsPerSegment);
        for (int exp = MAX_PARAMETRIC_SEGMENTS_LOG2 - 1; exp >= 0; --exp) {
            // Test the parametric edge at lastParametricEdgeID + 2^exp.
            float testParametricID = lastParametricEdgeID + float(1 << exp);
            if (testParametricID <= maxParametricEdgeID) {
                float2 testTan = fma(float2(testParametricID), A, B_);
                testTan = fma(float2(testParametricID), testTan, C_);
                float cosRotation = dot(normalize(testTan), tan0norm);
                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 tangent vector on the edge at lastRadialEdgeID.
        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 cubic's tangent is orthogonal to norm. This is a quadratic:
        //
        //     dot(norm, Tangent_Direction(T)) == 0
        //
        //                         |T^2|
        //     norm * |A  2B  C| * |T  | == 0
        //            |.   .  .|   |1  |
        //
        float3 coeffs = norm * float3x2(A,B,C);
        float a=coeffs.x, b_over_2=coeffs.y, c=coeffs.z;
        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);
        float radialT = (root.t != 0.0) ? root.s / root.t : 0.0;
        radialT = clamp(radialT, 0.0, 1.0);

        if (lastRadialEdgeID == 0.0) {
            // 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 == 0 in this case.
            radialT = 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(P[0], P[1], T);
        float2 bc = unchecked_mix(P[1], P[2], T);
        float2 cd = unchecked_mix(P[2], P[3], T);
        float2 abc = unchecked_mix(ab, bc, T);
        float2 bcd = unchecked_mix(bc, cd, T);
        float2 abcd = unchecked_mix(abc, bcd, T);)");

    if (hasConics) {
        code->append(R"(
        // Evaluate the conic weights at T.
        float u = unchecked_mix(1.0, w, T);
        float v = unchecked_mix(w, 1.0, T);
        float uv = unchecked_mix(u, v, T);)");
    }

    code->appendf(R"(
        position =%s abcd;)", (hasConics) ? " (w >= 0.0) ? abc/uv :" : "");

    code->appendf(R"(
        // 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) {)");
    code->appendf(R"(
            tangent =%s bcd - abc;)", (hasConics) ? " (w >= 0.0) ? bc*u - ab*v :" : "");
    code->appendf(R"(
        }
    })");
}

SkString GrStrokeTessellateShader::getTessEvaluationShaderGLSL(
        const GrGLSLPrimitiveProcessor* glslPrimProc, const char* versionAndExtensionDecls,
        const GrGLSLUniformHandler& uniformHandler, const GrShaderCaps& shaderCaps) const {
    SkASSERT(fMode == Mode::kTessellation);
    auto impl = static_cast<const GrStrokeTessellateShader::TessellationImpl*>(glslPrimProc);

    SkString code(versionAndExtensionDecls);
    code.append("layout(quads, equal_spacing, ccw) in;\n");
    code.appendf("precision highp float;\n");

    code.appendf("#define float2 vec2\n");
    code.appendf("#define float3 vec3\n");
    code.appendf("#define float4 vec4\n");
    code.appendf("#define float2x2 mat2\n");
    code.appendf("#define float3x2 mat3x2\n");
    code.appendf("#define float4x2 mat4x2\n");
    code.appendf("#define PI 3.141592653589793238\n");
    code.appendf("#define MAX_PARAMETRIC_SEGMENTS_LOG2 %i\n",
                 SkNextLog2(shaderCaps.maxTessellationSegments()));

    if (!this->hasDynamicStroke()) {
        const char* tessArgsName = impl->getTessArgsUniformName(uniformHandler);
        code.appendf("uniform vec4 %s;\n", tessArgsName);
        code.appendf("#define STROKE_RADIUS %s.w\n", tessArgsName);
    } else {
        code.appendf("#define STROKE_RADIUS tcsStrokeRadius\n");
    }

    if (!this->viewMatrix().isIdentity()) {
        const char* translateName = impl->getTranslateUniformName(uniformHandler);
        code.appendf("uniform vec2 %s;\n", translateName);
        code.appendf("#define TRANSLATE %s\n", translateName);
        if (!fStroke.isHairlineStyle()) {
            // In the normal case we need the affine matrix too. (In the hairline case we already
            // applied the affine matrix in the vertex shader.)
            const char* affineMatrixName = impl->getAffineMatrixUniformName(uniformHandler);
            code.appendf("uniform vec4 %s;\n", affineMatrixName);
            code.appendf("#define AFFINE_MATRIX mat2(%s)\n", affineMatrixName);
        }
    }

    code.append(R"(
    in vec4 tcsPts01[];
    in vec4 tcsPt2Tan0[];
    in vec4 tcsTessArgs[];  // [numCombinedSegments, numParametricSegments, angle0, radsPerSegment]
    patch in vec4 tcsJoinArgs0;  // [numSegmentsInJoin, innerJoinRadiusMultiplier,
                                 //  prevJoinTangent.xy]
    patch in vec4 tcsJoinArgs1;  // [joinAngle0, radsPerJoinSegment, joinOutsetClamp.xy]
    patch in vec4 tcsEndPtEndTan;)");
    if (this->hasDynamicStroke()) {
        code.append(R"(
        patch in float tcsStrokeRadius;)");
    }
    if (this->hasDynamicColor()) {
        code.appendf(R"(
        patch in mediump vec4 tcsColor;
        %s out mediump vec4 tesColor;)", shaderCaps.preferFlatInterpolation() ? "flat" : "");
    }

    code.append(R"(
    uniform vec4 sk_RTAdjust;)");

    code.append(kUncheckedMixFn);
    append_eval_stroke_edge_fn(&code, this->hasConics());

    code.append(R"(
    void main() {
        // Our patch is composed of exactly "numTotalCombinedSegments + 1" stroke-width edges that
        // run orthogonal to the curve and make a strip of "numTotalCombinedSegments" quads.
        // Determine which discrete edge belongs to this invocation. An edge can either come from a
        // parametric segment or a radial one.
        float numSegmentsInJoin = tcsJoinArgs0.x;
        float numTotalCombinedSegments = numSegmentsInJoin + tcsTessArgs[0].x + tcsTessArgs[1].x +
                                         tcsTessArgs[2].x;
        float totalEdgeID = round(gl_TessCoord.x * numTotalCombinedSegments);

        // Furthermore, the vertex shader may have chopped the curve into 3 different sections.
        // Determine which section we belong to, and where we fall relative to its first edge.
        float localEdgeID = totalEdgeID;
        mat4x2 P;
        vec2 tan0;
        vec3 tessellationArgs;
        float strokeRadius = STROKE_RADIUS;
        vec2 strokeOutsetClamp = vec2(-1, 1);
        if (localEdgeID < numSegmentsInJoin || numSegmentsInJoin == numTotalCombinedSegments) {
            // Our edge belongs to the join preceding the curve.
            P = mat4x2(tcsPts01[0].xyxy, tcsPts01[0].xyxy);
            tan0 = tcsJoinArgs0.zw;
            tessellationArgs = vec3(1, tcsJoinArgs1.xy);
            strokeRadius *= (localEdgeID == 1.0) ? tcsJoinArgs0.y : 1.0;
            strokeOutsetClamp = tcsJoinArgs1.zw;
        } else if ((localEdgeID -= numSegmentsInJoin) < tcsTessArgs[0].x) {
            // Our edge belongs to the first curve section.
            P = mat4x2(tcsPts01[0], tcsPt2Tan0[0].xy, tcsPts01[1].xy);
            tan0 = tcsPt2Tan0[0].zw;
            tessellationArgs = tcsTessArgs[0].yzw;
        } else if ((localEdgeID -= tcsTessArgs[0].x) < tcsTessArgs[1].x) {
            // Our edge belongs to the second curve section.
            P = mat4x2(tcsPts01[1], tcsPt2Tan0[1].xy, tcsPts01[2].xy);
            tan0 = tcsPt2Tan0[1].zw;
            tessellationArgs = tcsTessArgs[1].yzw;
        } else {
            // Our edge belongs to the third curve section.
            localEdgeID -= tcsTessArgs[1].x;
            P = mat4x2(tcsPts01[2], tcsPt2Tan0[2].xy, tcsEndPtEndTan.xy);
            tan0 = tcsPt2Tan0[2].zw;
            tessellationArgs = tcsTessArgs[2].yzw;
        }
        float numParametricSegments = tessellationArgs.x;
        float angle0 = tessellationArgs.y;
        float radsPerSegment = tessellationArgs.z;

        float w = -1.0;  // w<0 means the curve is an integral cubic.)");

    if (this->hasConics()) {
        code.append(R"(
        if (isinf(P[3].y)) {
            w = P[3].x;  // The curve is actually a conic.
            P[3] = P[2];  // Setting p3 equal to p2 works for the remaining rotational logic.
        })");
    }

    code.append(R"(
        float2 tangent, position;
        eval_stroke_edge(P, w, numParametricSegments, localEdgeID, tan0, radsPerSegment, angle0,
                         tangent, position);

        if (localEdgeID == 0.0) {
            // The first local edge of each section uses the provided tan0. This ensures continuous
            // rotation across chops made by the vertex shader as well as crack-free seaming between
            // patches. (NOTE: position is always equal to P[0] here when localEdgeID==0.)
            tangent = tan0;
        }

        if (gl_TessCoord.x == 1.0) {
            // The final edge of the quad strip always uses the provided endPt and endTan. This
            // ensures crack-free seaming between patches.
            tangent = tcsEndPtEndTan.zw;
            position = P[3];
        }

        // Determine how far to outset our vertex orthogonally from the curve.
        float outset = gl_TessCoord.y * 2.0 - 1.0;
        outset = clamp(outset, strokeOutsetClamp.x, strokeOutsetClamp.y);
        outset *= strokeRadius;

        vec2 vertexPos = position + normalize(vec2(-tangent.y, tangent.x)) * outset;)");

    if (!this->viewMatrix().isIdentity()) {
        if (!fStroke.isHairlineStyle()) {
            // Normal case. Do the transform after tessellation.
            code.append("vertexPos = AFFINE_MATRIX * vertexPos + TRANSLATE;");
        } else {
            // Hairline case. The scale and skew already happened before tessellation.
            code.append("vertexPos = vertexPos + TRANSLATE;");
        }
    }

    code.append(R"(
        gl_Position = vec4(vertexPos * sk_RTAdjust.xz + sk_RTAdjust.yw, 0.0, 1.0);)");

    if (this->hasDynamicColor()) {
        code.append(R"(
        tesColor = tcsColor;)");
    }

    code.append(R"(
    })");

    return code;
}

class GrStrokeTessellateShader::IndirectImpl : public GrGLSLGeometryProcessor {
    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
        const auto& shader = args.fGP.cast<GrStrokeTessellateShader>();
        SkPaint::Join joinType = shader.fStroke.getJoin();
        args.fVaryingHandler->emitAttributes(shader);

        // Constants.
        args.fVertBuilder->defineConstant("MAX_PARAMETRIC_SEGMENTS_LOG2",
                                          GrTessellationPathRenderer::kMaxResolveLevel);
        args.fVertBuilder->defineConstant("float", "PI", "3.141592653589793238");

        // Helper functions.
        if (shader.hasDynamicStroke()) {
            args.fVertBuilder->insertFunction(kNumRadialSegmentsPerRadian);
        }
        args.fVertBuilder->insertFunction(kAtan2Fn);
        args.fVertBuilder->insertFunction(kLengthPow2Fn);
        args.fVertBuilder->insertFunction(kMiterExtentFn);
        args.fVertBuilder->insertFunction(kUncheckedMixFn);
        args.fVertBuilder->insertFunction(kCosineBetweenVectorsFn);
        append_wangs_formula_fn(&args.fVertBuilder->functions(), shader.hasConics());
        append_eval_stroke_edge_fn(&args.fVertBuilder->functions(), shader.hasConics());

        // Tessellation control uniforms and/or dynamic attributes.
        if (!shader.hasDynamicStroke()) {
            // [PARAMETRIC_INTOLERANCE, NUM_RADIAL_SEGMENTS_PER_RADIAN, JOIN_TYPE, STROKE_RADIUS]
            const char* tessArgsName;
            fTessControlArgsUniform = args.fUniformHandler->addUniform(
                    nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "tessControlArgs",
                    &tessArgsName);
            args.fVertBuilder->codeAppendf(R"(
            float PARAMETRIC_INTOLERANCE = %s.x;
            float NUM_RADIAL_SEGMENTS_PER_RADIAN = %s.y;
            float JOIN_TYPE = %s.z;
            float STROKE_RADIUS = %s.w;)", tessArgsName, tessArgsName, tessArgsName, tessArgsName);
        } else {
            const char* parametricIntoleranceName;
            fTessControlArgsUniform = args.fUniformHandler->addUniform(
                    nullptr, kVertex_GrShaderFlag, kFloat_GrSLType, "parametricIntolerance",
                    &parametricIntoleranceName);
            args.fVertBuilder->codeAppendf(R"(
            float PARAMETRIC_INTOLERANCE = %s;
            float STROKE_RADIUS = dynamicStrokeAttr.x;
            float NUM_RADIAL_SEGMENTS_PER_RADIAN = num_radial_segments_per_radian(
                    PARAMETRIC_INTOLERANCE, STROKE_RADIUS);
            float JOIN_TYPE = dynamicStrokeAttr.y;)", parametricIntoleranceName);
        }

        // View matrix uniforms.
        if (!shader.viewMatrix().isIdentity()) {
            const char* translateName, *affineMatrixName;
            fAffineMatrixUniform = args.fUniformHandler->addUniform(
                    nullptr, kVertex_GrShaderFlag, kFloat4_GrSLType, "affineMatrix",
                    &affineMatrixName);
            fTranslateUniform = args.fUniformHandler->addUniform(
                    nullptr, kVertex_GrShaderFlag, kFloat2_GrSLType, "translate", &translateName);
            args.fVertBuilder->codeAppendf("float2x2 AFFINE_MATRIX = float2x2(%s);\n",
                                           affineMatrixName);
            args.fVertBuilder->codeAppendf("float2 TRANSLATE = %s;\n", translateName);
        }

        // Tessellation code.
        args.fVertBuilder->codeAppend(R"(
        float4x2 P = float4x2(pts01Attr, pts23Attr);
        float2 lastControlPoint = argsAttr.xy;
        float w = -1;  // w<0 means the curve is an integral cubic.)");
        if (shader.hasConics()) {
            args.fVertBuilder->codeAppend(R"(
            if (isinf(P[3].y)) {
                w = P[3].x;  // The curve is actually a conic.
                P[3] = P[2];  // Setting p3 equal to p2 works for the remaining rotational logic.
            })");
        }
        if (shader.fStroke.isHairlineStyle() && !shader.viewMatrix().isIdentity()) {
            // 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.
            args.fVertBuilder->codeAppend(R"(
            P = AFFINE_MATRIX * P;
            lastControlPoint = AFFINE_MATRIX * lastControlPoint;)");
        }
        args.fVertBuilder->codeAppend(R"(
        float numTotalEdges = abs(argsAttr.z);

        // Find how many parametric segments this stroke requires.
        float numParametricSegments = min(wangs_formula(P, w, PARAMETRIC_INTOLERANCE),
                                          float(1 << MAX_PARAMETRIC_SEGMENTS_LOG2));
        if (P[0] == P[1] && P[2] == P[3]) {
            // This is how we describe lines, but Wang's formula does not return 1 in this case.
            numParametricSegments = 1;
        }

        // Find the starting and ending tangents.
        float2 tan0 = ((P[0] == P[1]) ? (P[1] == P[2]) ? P[3] : P[2] : P[1]) - P[0];
        float2 tan1 = P[3] - ((P[3] == P[2]) ? (P[2] == P[1]) ? P[0] : P[1] : P[2]);
        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);
        })");

        if (shader.fStroke.getJoin() == SkPaint::kRound_Join || shader.hasDynamicStroke()) {
            args.fVertBuilder->codeAppend(R"(
            // Determine how many edges to give to the round 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 joinRads = acos(cosine_between_vectors(P[0] - lastControlPoint, tan0));
            float numRadialSegmentsInJoin = max(ceil(joinRads * NUM_RADIAL_SEGMENTS_PER_RADIAN), 1);
            // +2 because we emit the beginning and ending edges twice (see above comment).
            float numEdgesInJoin = numRadialSegmentsInJoin + 2;
            // The stroke section needs at least two edges. Don't assign more to the join than
            // "numTotalEdges - 2".
            numEdgesInJoin = min(numEdgesInJoin, numTotalEdges - 2);
            // Lines give all their extra edges to the join.
            if (numParametricSegments == 1) {
                numEdgesInJoin = numTotalEdges - 2;
            }
            // Negative argsAttr.z means the join is a chop, and chop joins get exactly one segment.
            if (argsAttr.z < 0) {
                // +2 because we emit the beginning and ending edges twice (see above comment).
                numEdgesInJoin = 1 + 2;
            })");
            if (shader.hasDynamicStroke()) {
                args.fVertBuilder->codeAppend(R"(
                if (JOIN_TYPE >= 0 /*Is the join not a round type?*/) {
                    // Bevel and miter joins get 1 and 2 segments respectively.
                    // +2 because we emit the beginning and ending edges twice (see above comments).
                    numEdgesInJoin = sign(JOIN_TYPE) + 1 + 2;
                })");
            }
        } else {
            args.fVertBuilder->codeAppendf(R"(
            float numEdgesInJoin = %i;)", NumExtraEdgesInIndirectJoin(joinType));
        }

        args.fVertBuilder->codeAppend(R"(
        // 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(P[2] - P[0], P[3] - P[1]);

        float numCombinedSegments;
        float outset = ((sk_VertexID & 1) == 0) ? +1 : -1;
        float combinedEdgeID = float(sk_VertexID >> 1) - numEdgesInJoin;
        if (combinedEdgeID < 0) {
            // We belong to the preceding join. The first and final edges get duplicated, so we only
            // have "numEdgesInJoin - 2" segments.
            numCombinedSegments = numEdgesInJoin - 2;
            numParametricSegments = 1;  // Joins don't have parametric segments.
            P = float4x2(P[0], P[0], P[0], P[0]);  // Colocate all points on the junction point.
            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 != P[0]) {
                tan0 = P[0] - lastControlPoint;
            }
            turn = cross(tan0, tan1);
            // Shift combinedEdgeID to the range [-1, numCombinedSegments]. 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 += numCombinedSegments + 1;
            // 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.
            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.)
                if (combinedEdgeID >= 0) {
                    outset = (turn < 0) ? min(outset, 0) : max(outset, 0);
                }
            }
            combinedEdgeID = max(combinedEdgeID, 0);
        } else {
            // We belong to the stroke.
            numCombinedSegments = numTotalEdges - numEdgesInJoin - 1;
        }

        // Don't take more parametric segments than there are total segments.
        numParametricSegments = min(numParametricSegments, numCombinedSegments);

        // Any leftover edges go to radial segments.
        float numRadialSegments = numCombinedSegments + 1 - numParametricSegments;

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

        if (joinType == SkPaint::kMiter_Join || shader.hasDynamicStroke()) {
            args.fVertBuilder->codeAppendf(R"(
            // Vertices #4 and #5 belong to the edge of the join that extends to the miter point.
            if ((sk_VertexID | 1) == (4 | 5) && %s) {
                outset *= miter_extent(cosTheta, JOIN_TYPE/*miterLimit*/);
            })", shader.hasDynamicStroke() ? "JOIN_TYPE > 0/*Is the join a miter type?*/" : "true");
        }

        args.fVertBuilder->codeAppendf(R"(
        float2 tangent, strokeCoord;
        eval_stroke_edge(P, w, numParametricSegments, combinedEdgeID, tan0, radsPerSegment, angle0,
                         tangent, strokeCoord);)");

        args.fVertBuilder->codeAppend(R"(
        if (combinedEdgeID == 0) {
            // Edges at the beginning of their section use P[0] and tan0. This ensures crack-free
            // seaming between instances.
            strokeCoord = P[0];
            tangent = tan0;
        }

        if (combinedEdgeID == numCombinedSegments) {
            // Edges at the end of their section use P[1] and tan1. This ensures crack-free seaming
            // between instances.
            strokeCoord = P[3];
            tangent = tan1;
        }

        float2 ortho = normalize(float2(tangent.y, -tangent.x));
        strokeCoord += ortho * (STROKE_RADIUS * outset);)");

        if (shader.viewMatrix().isIdentity()) {
            // No transform matrix.
            gpArgs->fPositionVar.set(kFloat2_GrSLType, "strokeCoord");
            gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "strokeCoord");
        } else if (!shader.fStroke.isHairlineStyle()) {
            // Normal case. Do the transform after tessellation.
            args.fVertBuilder->codeAppend(R"(
            float2 devCoord = AFFINE_MATRIX * strokeCoord + TRANSLATE;)");
            gpArgs->fPositionVar.set(kFloat2_GrSLType, "devCoord");
            gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "strokeCoord");
        } else {
            // Hairline case. The scale and skew already happened before tessellation.
            args.fVertBuilder->codeAppend(R"(
            float2 devCoord = strokeCoord + TRANSLATE;
            float2 localCoord = inverse(AFFINE_MATRIX) * strokeCoord;)");
            gpArgs->fPositionVar.set(kFloat2_GrSLType, "devCoord");
            gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localCoord");
        }

        if (!shader.hasDynamicColor()) {
            // The fragment shader just outputs a uniform color.
            const char* colorUniformName;
            fColorUniform = args.fUniformHandler->addUniform(
                    nullptr, kFragment_GrShaderFlag, kHalf4_GrSLType, "color", &colorUniformName);
            args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUniformName);
        } else {
            // Color gets passed in through an instance attrib.
            args.fVaryingHandler->addPassThroughAttribute(
                    shader.fAttribs.back(), args.fOutputColor,
                    GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
        }
        args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
    }

    void setData(const GrGLSLProgramDataManager& pdman,
                 const GrPrimitiveProcessor& primProc) override {
        const auto& shader = primProc.cast<GrStrokeTessellateShader>();
        const auto& stroke = shader.fStroke;

        if (!shader.hasDynamicStroke()) {
            // Set up the tessellation control uniforms.
            Tolerances tolerances;
            if (!stroke.isHairlineStyle()) {
                tolerances.set(shader.viewMatrix().getMaxScale(), stroke.getWidth());
            } else {
                // In the hairline case we transform prior to tessellation. Set up tolerances for an
                // identity viewMatrix and a strokeWidth of 1.
                tolerances.set(1, 1);
            }
            float strokeRadius = (stroke.isHairlineStyle()) ? .5f : stroke.getWidth() * .5;
            pdman.set4f(fTessControlArgsUniform,
                        tolerances.fParametricIntolerance,  // PARAMETRIC_INTOLERANCE
                        tolerances.fNumRadialSegmentsPerRadian,  // NUM_RADIAL_SEGMENTS_PER_RADIAN
                        GetJoinType(shader.fStroke),  // JOIN_TYPE
                        strokeRadius);  // STROKE_RADIUS
        } else {
            SkASSERT(!stroke.isHairlineStyle());
            pdman.set1f(fTessControlArgsUniform,
                        Tolerances::CalcParametricIntolerance(shader.viewMatrix().getMaxScale()));
        }

        // Set up the view matrix, if any.
        const SkMatrix& m = shader.viewMatrix();
        if (!m.isIdentity()) {
            pdman.set2f(fTranslateUniform, m.getTranslateX(), m.getTranslateY());
            pdman.set4f(fAffineMatrixUniform, m.getScaleX(), m.getSkewY(), m.getSkewX(),
                        m.getScaleY());
        }

        if (!shader.hasDynamicColor()) {
            pdman.set4fv(fColorUniform, 1, shader.fColor.vec());
        }
    }

    GrGLSLUniformHandler::UniformHandle fTessControlArgsUniform;
    GrGLSLUniformHandler::UniformHandle fTranslateUniform;
    GrGLSLUniformHandler::UniformHandle fAffineMatrixUniform;
    GrGLSLUniformHandler::UniformHandle fColorUniform;
};

void GrStrokeTessellateShader::getGLSLProcessorKey(const GrShaderCaps&,
                                                   GrProcessorKeyBuilder* b) const {
    bool keyNeedsJoin = (fMode == Mode::kIndirect) && !(fShaderFlags & ShaderFlags::kDynamicStroke);
    SkASSERT(fStroke.getJoin() >> 2 == 0);
    // Attribs get worked into the key automatically during GrPrimitiveProcessor::getAttributeKey().
    // When color is in a uniform, it's always wide. kWideColor doesn't need to be considered here.
    uint32_t key = (uint32_t)(fShaderFlags & ~ShaderFlags::kWideColor);
    key = (key << 1) | (uint32_t)fMode;
    key = (key << 2) | ((keyNeedsJoin) ? fStroke.getJoin() : 0);
    key = (key << 1) | (uint32_t)fStroke.isHairlineStyle();
    key = (key << 1) | (uint32_t)this->viewMatrix().isIdentity();
    b->add32(key);
}

GrGLSLPrimitiveProcessor* GrStrokeTessellateShader::createGLSLInstance(
        const GrShaderCaps&) const {
    return (fMode == Mode::kTessellation) ?
            (GrGLSLPrimitiveProcessor*)new TessellationImpl : new IndirectImpl;
}
