diff --git a/src/gpu/tessellate/GrStrokeHardwareTessellator.cpp b/src/gpu/tessellate/GrStrokeHardwareTessellator.cpp
index 1f177b1..619de5b 100644
--- a/src/gpu/tessellate/GrStrokeHardwareTessellator.cpp
+++ b/src/gpu/tessellate/GrStrokeHardwareTessellator.cpp
@@ -12,6 +12,10 @@
 #include "src/gpu/geometry/GrPathUtils.h"
 #include "src/gpu/tessellate/GrWangsFormula.h"
 
+using Tolerances = GrStrokeTessellateShader::Tolerances;
+
+namespace {
+
 static float num_combined_segments(float numParametricSegments, float numRadialSegments) {
     // The first and last edges are shared by both the parametric and radial sets of edges, so
     // the total number of edges is:
@@ -42,48 +46,633 @@
     return xx*xx;
 }
 
-void GrStrokeHardwareTessellator::updateTolerances(Tolerances tolerances, SkPaint::Join joinType) {
-    // Calculate the worst-case numbers of parametric segments our hardware can support for the
-    // current stroke radius, in the event that there are also enough radial segments to rotate
-    // 180 and 360 degrees respectively. These are used for "quick accepts" that allow us to
-    // send almost all curves directly to the hardware without having to chop.
-    float numRadialSegments180 = std::max(std::ceil(
-            SK_ScalarPI * tolerances.fNumRadialSegmentsPerRadian), 1.f);
-    float maxParametricSegments180 = num_parametric_segments(fMaxTessellationSegments,
-                                                             numRadialSegments180);
-    fMaxParametricSegments180_pow4 = pow4(maxParametricSegments180);
+class PatchWriter {
+public:
+    using ShaderFlags = GrStrokeTessellator::ShaderFlags;
+    using PatchChunk = GrStrokeHardwareTessellator::PatchChunk;
 
-    float numRadialSegments360 = std::max(std::ceil(
-            2*SK_ScalarPI * tolerances.fNumRadialSegmentsPerRadian), 1.f);
-    float maxParametricSegments360 = num_parametric_segments(fMaxTessellationSegments,
-                                                             numRadialSegments360);
-    fMaxParametricSegments360_pow4 = pow4(maxParametricSegments360);
+    enum class JoinType {
+        kMiter = SkPaint::kMiter_Join,
+        kRound = SkPaint::kRound_Join,
+        kBevel = SkPaint::kBevel_Join,
+        kBowtie = SkPaint::kLast_Join + 1,  // Double sided round join.
+        kNone
+    };
 
-    // Now calculate the worst-case numbers of parametric segments if we are to integrate a join
-    // into the same patch as the curve.
-    float maxNumSegmentsInJoin;
-    switch (joinType) {
-        case SkPaint::kBevel_Join:
-            maxNumSegmentsInJoin = 1;
-            break;
-        case SkPaint::kMiter_Join:
-            maxNumSegmentsInJoin = 2;
-            break;
-        case SkPaint::kRound_Join:
-            // 180-degree round join.
-            maxNumSegmentsInJoin = numRadialSegments180;
-            break;
+    PatchWriter(ShaderFlags shaderFlags, GrMeshDrawOp::Target* target,
+                SkTArray<PatchChunk>* patchChunks, int totalCombinedVerbCnt)
+            : fShaderFlags(shaderFlags)
+            , fTarget(target)
+            , fPatchChunks(patchChunks)
+            , fPatchStride(GrStrokeTessellateShader::PatchStride(fShaderFlags))
+            // Subtract 2 because the tessellation shader chops every cubic at two locations, and
+            // each chop has the potential to introduce an extra segment.
+            , fMaxTessellationSegments(target->caps().shaderCaps()->maxTessellationSegments() - 2) {
+        // Pre-allocate at least enough vertex space for 1 in 4 strokes to chop, and for 8 caps.
+        int strokePreallocCount = totalCombinedVerbCnt * 5/4;
+        int capPreallocCount = 8;
+        this->allocPatchChunkAtLeast(strokePreallocCount + capPreallocCount);
     }
-    // Subtract an extra 1 off the end because when we integrate a join, the tessellator has to add
-    // a redundant edge between the join and curve.
-    fMaxParametricSegments180_pow4_withJoin = pow4(std::max(
-            maxParametricSegments180 - maxNumSegmentsInJoin - 1, 0.f));
-    fMaxParametricSegments360_pow4_withJoin = pow4(std::max(
-            maxParametricSegments360 - maxNumSegmentsInJoin - 1, 0.f));
-    fMaxCombinedSegments_withJoin = fMaxTessellationSegments - maxNumSegmentsInJoin - 1;
-    fSoloRoundJoinAlwaysFitsInPatch = (numRadialSegments180 <= fMaxTessellationSegments);
-    fTolerances = tolerances;
-}
+
+    ~PatchWriter() {
+        fTarget->putBackVertices(fCurrChunkPatchCapacity - fPatchChunks->back().fPatchCount,
+                                 fPatchStride);
+    }
+
+    void updateTolerances(Tolerances tolerances, SkPaint::Join joinType) {
+        // Calculate the worst-case numbers of parametric segments our hardware can support for the
+        // current stroke radius, in the event that there are also enough radial segments to rotate
+        // 180 and 360 degrees respectively. These are used for "quick accepts" that allow us to
+        // send almost all curves directly to the hardware without having to chop.
+        float numRadialSegments180 = std::max(std::ceil(
+                SK_ScalarPI * tolerances.fNumRadialSegmentsPerRadian), 1.f);
+        float maxParametricSegments180 = num_parametric_segments(fMaxTessellationSegments,
+                                                                 numRadialSegments180);
+        fMaxParametricSegments180_pow4 = pow4(maxParametricSegments180);
+
+        float numRadialSegments360 = std::max(std::ceil(
+                2*SK_ScalarPI * tolerances.fNumRadialSegmentsPerRadian), 1.f);
+        float maxParametricSegments360 = num_parametric_segments(fMaxTessellationSegments,
+                                                                 numRadialSegments360);
+        fMaxParametricSegments360_pow4 = pow4(maxParametricSegments360);
+
+        // Now calculate the worst-case numbers of parametric segments if we are to integrate a join
+        // into the same patch as the curve.
+        float maxNumSegmentsInJoin;
+        switch (joinType) {
+            case SkPaint::kBevel_Join:
+                maxNumSegmentsInJoin = 1;
+                break;
+            case SkPaint::kMiter_Join:
+                maxNumSegmentsInJoin = 2;
+                break;
+            case SkPaint::kRound_Join:
+                // 180-degree round join.
+                maxNumSegmentsInJoin = numRadialSegments180;
+                break;
+        }
+        // Subtract an extra 1 off the end because when we integrate a join, the tessellator has to
+        // add a redundant edge between the join and curve.
+        fMaxParametricSegments180_pow4_withJoin = pow4(std::max(
+                maxParametricSegments180 - maxNumSegmentsInJoin - 1, 0.f));
+        fMaxParametricSegments360_pow4_withJoin = pow4(std::max(
+                maxParametricSegments360 - maxNumSegmentsInJoin - 1, 0.f));
+        fMaxCombinedSegments_withJoin = fMaxTessellationSegments - maxNumSegmentsInJoin - 1;
+        fSoloRoundJoinAlwaysFitsInPatch = (numRadialSegments180 <= fMaxTessellationSegments);
+        fTolerances = tolerances;
+    }
+
+    void updateDynamicStroke(const SkStrokeRec& stroke) {
+        SkASSERT(fShaderFlags & ShaderFlags::kDynamicStroke);
+        fDynamicStroke.set(stroke);
+    }
+
+    void updateDynamicColor(const SkPMColor4f& color) {
+        SkASSERT(fShaderFlags & ShaderFlags::kDynamicColor);
+        bool wideColor = fShaderFlags & ShaderFlags::kWideColor;
+        SkASSERT(wideColor || color.fitsInBytes());
+        fDynamicColor.set(color, wideColor);
+    }
+
+    void moveTo(SkPoint pt) {
+        fCurrContourStartPoint = pt;
+        fHasLastControlPoint = false;
+    }
+
+    void lineTo(JoinType prevJoinType, SkPoint p0, SkPoint p1) {
+        // Zero-length paths need special treatment because they are spec'd to behave differently.
+        if (p0 == p1) {
+            return;
+        }
+
+        if (fMaxCombinedSegments_withJoin < 1) {
+            // The stroke has extremely thick round joins and there aren't enough guaranteed
+            // segments to always combine a join with a line patch. Emit the join in its own
+            // separate patch.
+            this->joinTo(prevJoinType, p0, p1);
+            prevJoinType = JoinType::kNone;
+        }
+
+        SkPoint asPatch[4] = {p0, p0, p1, p1};
+        this->emitPatch(prevJoinType, asPatch, p1);
+    }
+
+    void conicTo(JoinType prevJoinType, const SkPoint p[3], float w, int maxDepth = -1) {
+        // Zero-length paths need special treatment because they are spec'd to behave differently.
+        // If the control point is colocated on an endpoint then this might end up being the case.
+        // Fall back on a lineTo and let it make the final check.
+        if (p[1] == p[0] || p[1] == p[2] || w == 0) {
+            this->lineTo(prevJoinType, p[0], p[2]);
+            return;
+        }
+
+        // Convert to a patch.
+        SkPoint asPatch[4];
+        if (w == 1) {
+            GrPathUtils::convertQuadToCubic(p, asPatch);
+        } else {
+            GrPathShader::WriteConicPatch(p, w, asPatch);
+        }
+
+        // Ensure our hardware supports enough tessellation segments to render the curve. This early
+        // out assumes a worst-case quadratic rotation of 180 degrees and a worst-case number of
+        // segments in the join.
+        //
+        // An informal survey of skottie animations and gms revealed that even with a bare minimum
+        // of 64 tessellation segments, 99.9%+ of quadratics take this early out.
+        float numParametricSegments_pow4 =
+                GrWangsFormula::quadratic_pow4(fTolerances.fParametricIntolerance, p);
+        if (numParametricSegments_pow4 <= fMaxParametricSegments180_pow4_withJoin) {
+            this->emitPatch(prevJoinType, asPatch, p[2]);
+            return;
+        }
+
+        if (numParametricSegments_pow4 <= fMaxParametricSegments180_pow4 || maxDepth == 0) {
+            if (numParametricSegments_pow4 > fMaxParametricSegments180_pow4_withJoin) {
+                // There aren't enough guaranteed segments to include the join. Emit a standalone
+                // patch for the join.
+                this->joinTo(prevJoinType, asPatch);
+                prevJoinType = JoinType::kNone;
+            }
+            this->emitPatch(prevJoinType, asPatch, p[2]);
+            return;
+        }
+
+        // We still might have enough tessellation segments to render the curve. Check again with
+        // the actual rotation.
+        float numRadialSegments =
+                SkMeasureQuadRotation(p) * fTolerances.fNumRadialSegmentsPerRadian;
+        numRadialSegments = std::max(std::ceil(numRadialSegments), 1.f);
+        float numParametricSegments = GrWangsFormula::root4(numParametricSegments_pow4);
+        numParametricSegments = std::max(std::ceil(numParametricSegments), 1.f);
+        float numCombinedSegments = num_combined_segments(numParametricSegments, numRadialSegments);
+        if (numCombinedSegments > fMaxTessellationSegments) {
+            // The hardware doesn't support enough segments for this curve. Chop and recurse.
+            if (maxDepth < 0) {
+                // Decide on an extremely conservative upper bound for when to quit chopping. This
+                // is solely to protect us from infinite recursion in instances where FP error
+                // prevents us from chopping at the correct midtangent.
+                maxDepth = sk_float_nextlog2(numParametricSegments) +
+                           sk_float_nextlog2(numRadialSegments) + 1;
+                maxDepth = std::max(maxDepth, 1);
+            }
+            if (w == 1) {
+                SkPoint chops[5];
+                if (numParametricSegments >= numRadialSegments) {
+                    SkChopQuadAtHalf(p, chops);
+                } else {
+                    SkChopQuadAtMidTangent(p, chops);
+                }
+                this->conicTo(prevJoinType, chops, 1, maxDepth - 1);
+                this->conicTo(JoinType::kBowtie, chops + 2, 1, maxDepth - 1);
+            } else {
+                SkConic conic(p, w);
+                float chopT = (numParametricSegments >= numRadialSegments) ? .5f
+                                                                           : conic.findMidTangent();
+                SkConic chops[2];
+                if (conic.chopAt(chopT, chops)) {
+                    this->conicTo(prevJoinType, chops[0].fPts, chops[0].fW, maxDepth - 1);
+                    this->conicTo(JoinType::kBowtie, chops[1].fPts, chops[1].fW, maxDepth - 1);
+                }
+            }
+            return;
+        }
+
+        if (numCombinedSegments > fMaxCombinedSegments_withJoin) {
+            // There aren't enough guaranteed segments to include the join. Emit a standalone patch
+            // for the join.
+            this->joinTo(prevJoinType, asPatch);
+            prevJoinType = JoinType::kNone;
+        }
+        this->emitPatch(prevJoinType, asPatch, p[2]);
+    }
+
+    // Is a cubic curve convex, and does it rotate no more than 180 degrees?
+    enum class Convex180Status : bool {
+        kUnknown,
+        kYes
+    };
+
+    void cubicTo(JoinType prevJoinType, const SkPoint p[4],
+                 Convex180Status convex180Status = Convex180Status::kUnknown, int maxDepth = -1) {
+        // The stroke tessellation shader assigns special meaning to p0==p1==p2 and p1==p2==p3. If
+        // this is the case then we need to rewrite the cubic.
+        if (p[1] == p[2] && (p[1] == p[0] || p[1] == p[3])) {
+            this->lineTo(prevJoinType, p[0], p[3]);
+            return;
+        }
+
+        // Ensure our hardware supports enough tessellation segments to render the curve. This early
+        // out assumes a worst-case cubic rotation of 360 degrees and a worst-case number of
+        // segments in the join.
+        //
+        // An informal survey of skottie animations revealed that with a bare minimum of 64
+        // tessellation segments, 95% of cubics take this early out.
+        float numParametricSegments_pow4 =
+                GrWangsFormula::cubic_pow4(fTolerances.fParametricIntolerance, p);
+        if (numParametricSegments_pow4 <= fMaxParametricSegments360_pow4_withJoin) {
+            this->emitPatch(prevJoinType, p, p[3]);
+            return;
+        }
+
+        float maxParametricSegments_pow4 = (convex180Status == Convex180Status::kYes) ?
+                fMaxParametricSegments180_pow4 : fMaxParametricSegments360_pow4;
+        if (numParametricSegments_pow4 <= maxParametricSegments_pow4 || maxDepth == 0) {
+            float maxParametricSegments_pow4_withJoin = (convex180Status == Convex180Status::kYes)
+                    ? fMaxParametricSegments180_pow4_withJoin
+                    : fMaxParametricSegments360_pow4_withJoin;
+            if (numParametricSegments_pow4 > maxParametricSegments_pow4_withJoin) {
+                // There aren't enough guaranteed segments to include the join. Emit a standalone
+                // patch for the join.
+                this->joinTo(prevJoinType, p);
+                prevJoinType = JoinType::kNone;
+            }
+            this->emitPatch(prevJoinType, p, p[3]);
+            return;
+        }
+
+        // Ensure the curve does not inflect or rotate >180 degrees before we start subdividing and
+        // measuring rotation.
+        if (convex180Status == Convex180Status::kUnknown) {
+            this->cubicConvex180SegmentsTo(prevJoinType, p);
+            return;
+        }
+
+        // We still might have enough tessellation segments to render the curve. Check again with
+        // its actual rotation.
+        float numRadialSegments =
+                SkMeasureNonInflectCubicRotation(p) * fTolerances.fNumRadialSegmentsPerRadian;
+        numRadialSegments = std::max(std::ceil(numRadialSegments), 1.f);
+        float numParametricSegments = GrWangsFormula::root4(numParametricSegments_pow4);
+        numParametricSegments = std::max(std::ceil(numParametricSegments), 1.f);
+        float numCombinedSegments = num_combined_segments(numParametricSegments, numRadialSegments);
+        if (numCombinedSegments > fMaxTessellationSegments) {
+            // The hardware doesn't support enough segments for this curve. Chop and recurse.
+            SkPoint chops[7];
+            if (maxDepth < 0) {
+                // Decide on an extremely conservative upper bound for when to quit chopping. This
+                // is solely to protect us from infinite recursion in instances where FP error
+                // prevents us from chopping at the correct midtangent.
+                maxDepth = sk_float_nextlog2(numParametricSegments) +
+                           sk_float_nextlog2(numRadialSegments) + 1;
+                maxDepth = std::max(maxDepth, 1);
+            }
+            if (numParametricSegments >= numRadialSegments) {
+                SkChopCubicAtHalf(p, chops);
+            } else {
+                SkChopCubicAtMidTangent(p, chops);
+            }
+            this->cubicTo(prevJoinType, chops, Convex180Status::kYes, maxDepth - 1);
+            this->cubicTo(JoinType::kBowtie, chops + 3, Convex180Status::kYes, maxDepth - 1);
+            return;
+        }
+
+        if (numCombinedSegments > fMaxCombinedSegments_withJoin) {
+            // There aren't enough guaranteed segments to include the join. Emit a standalone patch
+            // for the join.
+            this->joinTo(prevJoinType, p);
+            prevJoinType = JoinType::kNone;
+        }
+        this->emitPatch(prevJoinType, p, p[3]);
+    }
+
+    void cubicConvex180SegmentsTo(JoinType prevJoinType, const SkPoint p[4]) {
+        SkPoint chops[10];
+        float chopT[2];
+        bool areCusps = false;
+        int numChops = GrPathUtils::findCubicConvex180Chops(p, chopT, &areCusps);
+        if (numChops == 0) {
+            // The curve is already convex and rotates no more than 180 degrees.
+            this->cubicTo(prevJoinType, p, Convex180Status::kYes);
+        } else if (numChops == 1) {
+            SkChopCubicAt(p, chops, chopT[0]);
+            if (areCusps) {
+                // When chopping on a perfect cusp, these 3 points will be equal.
+                chops[2] = chops[4] = chops[3];
+            }
+            this->cubicTo(prevJoinType, chops, Convex180Status::kYes);
+            this->cubicTo(JoinType::kBowtie, chops + 3, Convex180Status::kYes);
+        } else {
+            SkASSERT(numChops == 2);
+            SkChopCubicAt(p, chops, chopT[0], chopT[1]);
+            // Two cusps are only possible on a flat line with two 180-degree turnarounds.
+            if (areCusps) {
+                this->lineTo(prevJoinType, chops[0], chops[3]);
+                this->lineTo(JoinType::kBowtie, chops[3], chops[6]);
+                this->lineTo(JoinType::kBowtie, chops[6], chops[9]);
+                return;
+            }
+            this->cubicTo(prevJoinType, chops, Convex180Status::kYes);
+            this->cubicTo(JoinType::kBowtie, chops + 3, Convex180Status::kYes);
+            this->cubicTo(JoinType::kBowtie, chops + 6, Convex180Status::kYes);
+        }
+    }
+
+    void joinTo(JoinType joinType, const SkPoint nextCubic[]) {
+        const SkPoint& nextCtrlPt = (nextCubic[1] == nextCubic[0]) ? nextCubic[2] : nextCubic[1];
+        // The caller should have culled out curves where p0==p1==p2 by this point.
+        SkASSERT(nextCtrlPt != nextCubic[0]);
+        this->joinTo(joinType, nextCubic[0], nextCtrlPt);
+    }
+
+    void joinTo(JoinType joinType, SkPoint junctionPoint, SkPoint nextControlPoint,
+                int maxDepth = -1) {
+        if (!fHasLastControlPoint) {
+            // The first stroke doesn't have a previous join.
+            return;
+        }
+
+        if (!fSoloRoundJoinAlwaysFitsInPatch && maxDepth != 0 &&
+            (joinType == JoinType::kRound || joinType == JoinType::kBowtie)) {
+            SkVector tan0 = junctionPoint - fLastControlPoint;
+            SkVector tan1 = nextControlPoint - junctionPoint;
+            float rotation = SkMeasureAngleBetweenVectors(tan0, tan1);
+            float numRadialSegments = rotation * fTolerances.fNumRadialSegmentsPerRadian;
+            if (numRadialSegments > fMaxTessellationSegments) {
+                // This is a round join that requires more segments than the tessellator supports.
+                // Split it and recurse.
+                if (maxDepth < 0) {
+                    // Decide on an upper bound for when to quit chopping. This is solely to protect
+                    // us from infinite recursion due to FP precision issues.
+                    maxDepth = sk_float_nextlog2(numRadialSegments / fMaxTessellationSegments);
+                    maxDepth = std::max(maxDepth, 1);
+                }
+                // Find the bisector so we can split the join in half.
+                SkPoint bisector = SkFindBisector(tan0, tan1);
+                // c0 will be the "next" control point for the first join half, and c1 will be the
+                // "previous" control point for the second join half.
+                SkPoint c0, c1;
+                // FIXME(skia:11347): This hack ensures "c0 - junctionPoint" gives the exact same
+                // ieee fp32 vector as "-(c1 - junctionPoint)". Tessellated stroking is becoming
+                // less experimental, so t's time to think of a cleaner method to avoid T-junctions
+                // when we chop joins.
+                int maxAttempts = 10;
+                do {
+                    bisector = (junctionPoint + bisector) - (junctionPoint - bisector);
+                    c0 = junctionPoint + bisector;
+                    c1 = junctionPoint - bisector;
+                } while (c0 - junctionPoint != -(c1 - junctionPoint) && --maxAttempts);
+                this->joinTo(joinType, junctionPoint, c0, maxDepth - 1);  // First join half.
+                fLastControlPoint = c1;
+                // Second join half.
+                this->joinTo(joinType, junctionPoint, nextControlPoint, maxDepth - 1);
+                return;
+            }
+        }
+
+        this->emitJoinPatch(joinType, junctionPoint, nextControlPoint);
+    }
+
+    void close(SkPoint contourEndpoint, const SkMatrix& viewMatrix, const SkStrokeRec& stroke) {
+        if (!fHasLastControlPoint) {
+            // Draw caps instead of closing if the subpath is zero length:
+            //
+            //   "Any zero length subpath ...  shall be stroked if the 'stroke-linecap' property has
+            //   a value of round or square producing respectively a circle or a square."
+            //
+            //   (https://www.w3.org/TR/SVG11/painting.html#StrokeProperties)
+            //
+            this->cap(contourEndpoint, viewMatrix, stroke);
+            return;
+        }
+
+        // Draw a line back to the beginning. (This will be discarded if
+        // contourEndpoint == fCurrContourStartPoint.)
+        auto strokeJoinType = JoinType(stroke.getJoin());
+        this->lineTo(strokeJoinType, contourEndpoint, fCurrContourStartPoint);
+        this->joinTo(strokeJoinType, fCurrContourStartPoint, fCurrContourFirstControlPoint);
+
+        fHasLastControlPoint = false;
+    }
+
+    void cap(SkPoint contourEndpoint, const SkMatrix& viewMatrix, const SkStrokeRec& stroke) {
+        if (!fHasLastControlPoint) {
+            // We don't have any control points to orient the caps. In this case, square and round
+            // caps are specified to be drawn as an axis-aligned square or circle respectively.
+            // Assign default control points that achieve this.
+            SkVector outset;
+            if (!stroke.isHairlineStyle()) {
+                outset = {1, 0};
+            } else {
+                // If the stroke is hairline, orient the square on the post-transform x-axis
+                // instead. We don't need to worry about the vector length since it will be
+                // normalized later. Since the matrix cannot have perspective, the below is
+                // equivalent to:
+                //
+                //    outset = inverse(|a b|) * |1| * arbitrary_scale
+                //                     |c d|    |0|
+                //
+                //    == 1/det * | d -b| * |1| * arbitrary_scale
+                //               |-c  a|   |0|
+                //
+                //    == 1/det * | d| * arbitrary_scale
+                //               |-c|
+                //
+                //    == | d|
+                //       |-c|
+                //
+                SkASSERT(!viewMatrix.hasPerspective());
+                float c=viewMatrix.getSkewY(), d=viewMatrix.getScaleY();
+                outset = {d, -c};
+            }
+            fCurrContourFirstControlPoint = fCurrContourStartPoint - outset;
+            fLastControlPoint = fCurrContourStartPoint + outset;
+            fHasLastControlPoint = true;
+            contourEndpoint = fCurrContourStartPoint;
+        }
+
+        switch (stroke.getCap()) {
+            case SkPaint::kButt_Cap:
+                break;
+            case SkPaint::kRound_Cap: {
+                // A round cap is the same thing as a 180-degree round join.
+                // If our join type isn't round we can alternatively use a bowtie.
+                JoinType roundCapJoinType = (stroke.getJoin() == SkPaint::kRound_Join)
+                        ? JoinType::kRound : JoinType::kBowtie;
+                this->joinTo(roundCapJoinType, contourEndpoint, fLastControlPoint);
+                this->moveTo(fCurrContourStartPoint, fCurrContourFirstControlPoint);
+                this->joinTo(roundCapJoinType, fCurrContourStartPoint,
+                             fCurrContourFirstControlPoint);
+                break;
+            }
+            case SkPaint::kSquare_Cap: {
+                // A square cap is the same as appending lineTos.
+                auto strokeJoinType = JoinType(stroke.getJoin());
+                SkVector lastTangent = contourEndpoint - fLastControlPoint;
+                if (!stroke.isHairlineStyle()) {
+                    // Extend the cap by 1/2 stroke width.
+                    lastTangent *= (.5f * stroke.getWidth()) / lastTangent.length();
+                } else {
+                    // Extend the cap by what will be 1/2 pixel after transformation.
+                    lastTangent *=
+                            .5f / viewMatrix.mapVector(lastTangent.fX, lastTangent.fY).length();
+                }
+                this->lineTo(strokeJoinType, contourEndpoint, contourEndpoint + lastTangent);
+                this->moveTo(fCurrContourStartPoint, fCurrContourFirstControlPoint);
+                SkVector firstTangent = fCurrContourFirstControlPoint - fCurrContourStartPoint;
+                if (!stroke.isHairlineStyle()) {
+                    // Set the the cap back by 1/2 stroke width.
+                    firstTangent *= (-.5f * stroke.getWidth()) / firstTangent.length();
+                } else {
+                    // Set the cap back by what will be 1/2 pixel after transformation.
+                    firstTangent *=
+                            -.5f / viewMatrix.mapVector(firstTangent.fX, firstTangent.fY).length();
+                }
+                this->lineTo(strokeJoinType, fCurrContourStartPoint,
+                             fCurrContourStartPoint + firstTangent);
+                break;
+            }
+        }
+
+        fHasLastControlPoint = false;
+    }
+
+private:
+    void moveTo(SkPoint pt, SkPoint lastControlPoint) {
+        fCurrContourStartPoint = pt;
+        fCurrContourFirstControlPoint = fLastControlPoint = lastControlPoint;
+        fHasLastControlPoint = true;
+    }
+
+    void emitPatch(JoinType prevJoinType, const SkPoint p[4], SkPoint endPt) {
+        SkPoint c1 = (p[1] == p[0]) ? p[2] : p[1];
+        SkPoint c2 = (p[2] == endPt) ? p[1] : p[2];
+
+        if (prevJoinType == JoinType::kBowtie) {
+            // Bowties need to go in their own patch if they will have >1 segment. TODO: Investigate
+            // if an optimization like "x < fCosRadiansPerSegment" would be worth it.
+            float rotation = SkMeasureAngleBetweenVectors(p[0] - fLastControlPoint, c1 - p[0]);
+            if (rotation * fTolerances.fNumRadialSegmentsPerRadian > 1) {
+                this->joinTo(prevJoinType, p[0], c1);
+                prevJoinType = JoinType::kNone;
+            }
+        }
+
+        if (!fHasLastControlPoint) {
+            // The first stroke doesn't have a previous join (yet). If the current contour ends up
+            // closing itself, we will add that join as its own patch. TODO: Consider deferring the
+            // first stroke until we know whether the contour will close. This will allow us to use
+            // the closing join as the first patch's previous join.
+            prevJoinType = JoinType::kNone;
+            fCurrContourFirstControlPoint = c1;
+            fHasLastControlPoint = true;
+        } else {
+            // By using JoinType::kNone, the caller promises to have written out their own join that
+            // seams exactly with this curve.
+            SkASSERT((prevJoinType != JoinType::kNone) || fLastControlPoint == c1);
+        }
+
+        if (this->reservePatch()) {
+            // Disable the join section of this patch if prevJoinType is kNone by setting the
+            // previous control point equal to p0.
+            fPatchWriter.write((prevJoinType == JoinType::kNone) ? p[0] : fLastControlPoint);
+            fPatchWriter.writeArray(p, 4);
+            this->emitDynamicAttribs();
+        }
+
+        fLastControlPoint = c2;
+    }
+
+    void emitJoinPatch(JoinType joinType, SkPoint junctionPoint, SkPoint nextControlPoint) {
+        // We should never write out joins before the first curve.
+        SkASSERT(fHasLastControlPoint);
+
+        if (this->reservePatch()) {
+            fPatchWriter.write(fLastControlPoint, junctionPoint);
+            if (joinType == JoinType::kBowtie) {
+                // {prevControlPoint, [p0, p0, p0, p3]} is a reserved patch pattern that means this
+                // patch is a bowtie. The bowtie is anchored on p0 and its tangent angles go from
+                // (p0 - prevControlPoint) to (p3 - p0).
+                fPatchWriter.write(junctionPoint, junctionPoint);
+            } else {
+                SkASSERT(joinType != JoinType::kNone);
+                // {prevControlPoint, [p0, p3, p3, p3]} is a reserved patch pattern that means this
+                // patch is a join only (no curve sections in the patch). The join is anchored on p0 and
+                // its tangent angles go from (p0 - prevControlPoint) to (p3 - p0).
+                fPatchWriter.write(nextControlPoint, nextControlPoint);
+            }
+            fPatchWriter.write(nextControlPoint);
+            this->emitDynamicAttribs();
+        }
+
+        fLastControlPoint = nextControlPoint;
+    }
+
+    void emitDynamicAttribs() {
+        if (fShaderFlags & ShaderFlags::kDynamicStroke) {
+            fPatchWriter.write(fDynamicStroke);
+        }
+        if (fShaderFlags & ShaderFlags::kDynamicColor) {
+            fPatchWriter.write(fDynamicColor);
+        }
+    }
+
+    bool reservePatch() {
+        if (fPatchChunks->back().fPatchCount >= fCurrChunkPatchCapacity) {
+            // The current chunk is full. Time to allocate a new one. (And no need to put back
+            // vertices; the buffer is full.)
+            this->allocPatchChunkAtLeast(fCurrChunkMinPatchAllocCount * 2);
+        }
+        if (!fPatchWriter.isValid()) {
+            SkDebugf("WARNING: Failed to allocate vertex buffer for tessellated stroke.");
+            return false;
+        }
+        SkASSERT(fPatchChunks->back().fPatchCount <= fCurrChunkPatchCapacity);
+        ++fPatchChunks->back().fPatchCount;
+        return true;
+    }
+
+    void allocPatchChunkAtLeast(int minPatchAllocCount) {
+        SkASSERT(fTarget);
+        PatchChunk* chunk = &fPatchChunks->push_back();
+        fPatchWriter = {fTarget->makeVertexSpaceAtLeast(fPatchStride, minPatchAllocCount,
+                                                        minPatchAllocCount, &chunk->fPatchBuffer,
+                                                        &chunk->fBasePatch,
+                                                        &fCurrChunkPatchCapacity)};
+        fCurrChunkMinPatchAllocCount = minPatchAllocCount;
+    }
+
+    const ShaderFlags fShaderFlags;
+    GrMeshDrawOp::Target* const fTarget;
+    SkTArray<PatchChunk>* const fPatchChunks;
+
+    // Size in bytes of a tessellation patch with our shader flags.
+    const size_t fPatchStride;
+
+    // The maximum number of tessellation segments the hardware can emit for a single patch.
+    const int fMaxTessellationSegments;
+
+    // These values contain worst-case numbers of parametric segments, raised to the 4th power, that
+    // our hardware can support for the current stroke radius. They assume curve rotations of 180
+    // and 360 degrees respectively. These are used for "quick accepts" that allow us to send almost
+    // all curves directly to the hardware without having to chop. We raise to the 4th power because
+    // the "pow4" variants of Wang's formula are the quickest to evaluate.
+    GrStrokeTessellateShader::Tolerances fTolerances;
+    float fMaxParametricSegments180_pow4;
+    float fMaxParametricSegments360_pow4;
+    float fMaxParametricSegments180_pow4_withJoin;
+    float fMaxParametricSegments360_pow4_withJoin;
+    float fMaxCombinedSegments_withJoin;
+    bool fSoloRoundJoinAlwaysFitsInPatch;
+
+    // Variables related to the patch chunk that we are currently writing out during prepareBuffers.
+    int fCurrChunkPatchCapacity;
+    int fCurrChunkMinPatchAllocCount;
+    GrVertexWriter fPatchWriter;
+
+    // Variables related to the specific contour that we are currently iterating during
+    // prepareBuffers().
+    bool fHasLastControlPoint = false;
+    SkPoint fCurrContourStartPoint;
+    SkPoint fCurrContourFirstControlPoint;
+    SkPoint fLastControlPoint;
+
+    // Values for the current dynamic state (if any) that will get written out with each patch.
+    GrStrokeTessellateShader::DynamicStroke fDynamicStroke;
+    GrVertexColor fDynamicColor;
+};
+
+}  // namespace
 
 static bool conic_has_cusp(const SkPoint p[3]) {
     SkVector a = p[1] - p[0];
@@ -96,42 +685,33 @@
 
 void GrStrokeHardwareTessellator::prepare(GrMeshDrawOp::Target* target,
                                           const SkMatrix& viewMatrix) {
-    SkASSERT(!fTarget);
-    fTarget = target;
+    using JoinType = PatchWriter::JoinType;
 
     std::array<float, 2> matrixScales;
     if (!viewMatrix.getMinMaxScales(matrixScales.data())) {
         matrixScales.fill(1);
     }
 
-    // Pre-allocate at least enough vertex space for 1 in 4 strokes to chop, and for 8 caps.
-    int strokePreallocCount = fTotalCombinedVerbCnt * 5/4;
-    int capPreallocCount = 8;
-    this->allocPatchChunkAtLeast(strokePreallocCount + capPreallocCount);
-
+    PatchWriter patchWriter(fShaderFlags, target, &fPatchChunks, fTotalCombinedVerbCnt);
     const SkStrokeRec* strokeForTolerances = nullptr;
 
     for (const auto& pathStroke : fPathStrokeList) {
         const SkStrokeRec& stroke = pathStroke.fStroke;
         if (!strokeForTolerances || strokeForTolerances->getWidth() != stroke.getWidth() ||
-            strokeForTolerances->getJoin() != stroke.getJoin()) {
+            strokeForTolerances->getCap() != stroke.getCap()) {
             auto tolerances = Tolerances::MakePreTransform(matrixScales.data(), stroke.getWidth());
-            this->updateTolerances(tolerances, stroke.getJoin());
+            patchWriter.updateTolerances(tolerances, stroke.getJoin());
             strokeForTolerances = &stroke;
         }
-        auto strokeJoinType = JoinType(stroke.getJoin());
-
         if (fShaderFlags & ShaderFlags::kDynamicStroke) {
-            fDynamicStroke.set(stroke);
+            patchWriter.updateDynamicStroke(stroke);
         }
         if (fShaderFlags & ShaderFlags::kDynamicColor) {
-            bool wideColor = fShaderFlags & ShaderFlags::kWideColor;
-            SkASSERT(wideColor || pathStroke.fColor.fitsInBytes());
-            fDynamicColor.set(pathStroke.fColor, wideColor);
+            patchWriter.updateDynamicColor(pathStroke.fColor);
         }
 
         const SkPath& path = pathStroke.fPath;
-        fHasLastControlPoint = false;
+        auto strokeJoinType = JoinType(stroke.getJoin());
         SkPathVerb previousVerb = SkPathVerb::kClose;
         for (auto [verb, p, w] : SkPathPriv::Iterate(path)) {
             switch (verb) {
@@ -139,541 +719,52 @@
                     // "A subpath ... consisting of a single moveto shall not be stroked."
                     // https://www.w3.org/TR/SVG11/painting.html#StrokeProperties
                     if (previousVerb != SkPathVerb::kMove && previousVerb != SkPathVerb::kClose) {
-                        this->cap(p[-1], viewMatrix, stroke);
+                        patchWriter.cap(p[-1], viewMatrix, stroke);
                     }
-                    this->moveTo(p[0]);
+                    patchWriter.moveTo(p[0]);
                     break;
                 case SkPathVerb::kLine:
-                    this->lineTo(strokeJoinType, p[0], p[1]);
+                    patchWriter.lineTo(strokeJoinType, p[0], p[1]);
                     break;
                 case SkPathVerb::kQuad:
                     if (conic_has_cusp(p)) {
                         SkPoint cusp = SkEvalQuadAt(p, SkFindQuadMidTangent(p));
-                        this->lineTo(strokeJoinType, p[0], cusp);
-                        this->lineTo(JoinType::kBowtie, cusp, p[2]);
+                        patchWriter.lineTo(strokeJoinType, p[0], cusp);
+                        patchWriter.lineTo(JoinType::kBowtie, cusp, p[2]);
                     } else {
-                        this->conicTo(strokeJoinType, p, 1);
+                        patchWriter.conicTo(strokeJoinType, p, 1);
                     }
                     break;
                 case SkPathVerb::kConic:
                     if (conic_has_cusp(p)) {
                         SkConic conic(p, *w);
                         SkPoint cusp = conic.evalAt(conic.findMidTangent());
-                        this->lineTo(strokeJoinType, p[0], cusp);
-                        this->lineTo(JoinType::kBowtie, cusp, p[2]);
+                        patchWriter.lineTo(strokeJoinType, p[0], cusp);
+                        patchWriter.lineTo(JoinType::kBowtie, cusp, p[2]);
                     } else {
-                        this->conicTo(strokeJoinType, p, *w);
+                        patchWriter.conicTo(strokeJoinType, p, *w);
                     }
                     break;
                 case SkPathVerb::kCubic:
                     bool areCusps;
                     GrPathUtils::findCubicConvex180Chops(p, nullptr, &areCusps);
                     if (areCusps) {
-                        this->cubicConvex180SegmentsTo(strokeJoinType, p);
+                        patchWriter.cubicConvex180SegmentsTo(strokeJoinType, p);
                     } else {
-                        this->cubicTo(strokeJoinType, p);
+                        patchWriter.cubicTo(strokeJoinType, p);
                     }
                     break;
                 case SkPathVerb::kClose:
-                    this->close(p[0], viewMatrix, stroke);
+                    patchWriter.close(p[0], viewMatrix, stroke);
                     break;
             }
             previousVerb = verb;
         }
         if (previousVerb != SkPathVerb::kMove && previousVerb != SkPathVerb::kClose) {
             const SkPoint* p = SkPathPriv::PointData(path);
-            this->cap(p[path.countPoints() - 1], viewMatrix, stroke);
+            patchWriter.cap(p[path.countPoints() - 1], viewMatrix, stroke);
         }
     }
-
-    fTarget->putBackVertices(fCurrChunkPatchCapacity - fPatchChunks.back().fPatchCount,
-                             fPatchStride);
-
-    fTarget = nullptr;
-}
-
-void GrStrokeHardwareTessellator::moveTo(SkPoint pt) {
-    fCurrContourStartPoint = pt;
-    fHasLastControlPoint = false;
-}
-
-void GrStrokeHardwareTessellator::moveTo(SkPoint pt, SkPoint lastControlPoint) {
-    fCurrContourStartPoint = pt;
-    fCurrContourFirstControlPoint = fLastControlPoint = lastControlPoint;
-    fHasLastControlPoint = true;
-}
-
-void GrStrokeHardwareTessellator::lineTo(JoinType prevJoinType, SkPoint p0, SkPoint p1) {
-    // Zero-length paths need special treatment because they are spec'd to behave differently.
-    if (p0 == p1) {
-        return;
-    }
-
-    if (fMaxCombinedSegments_withJoin < 1) {
-        // The stroke has extremely thick round joins and there aren't enough guaranteed segments to
-        // always combine a join with a line patch. Emit the join in its own separate patch.
-        this->joinTo(prevJoinType, p0, p1);
-        prevJoinType = JoinType::kNone;
-    }
-
-    SkPoint asPatch[4] = {p0, p0, p1, p1};
-    this->emitPatch(prevJoinType, asPatch, p1);
-}
-
-void GrStrokeHardwareTessellator::conicTo(JoinType prevJoinType, const SkPoint p[3], float w,
-                                          int maxDepth) {
-    // Zero-length paths need special treatment because they are spec'd to behave differently. If
-    // the control point is colocated on an endpoint then this might end up being the case. Fall
-    // back on a lineTo and let it make the final check.
-    if (p[1] == p[0] || p[1] == p[2] || w == 0) {
-        this->lineTo(prevJoinType, p[0], p[2]);
-        return;
-    }
-
-    // Convert to a patch.
-    SkPoint asPatch[4];
-    if (w == 1) {
-        GrPathUtils::convertQuadToCubic(p, asPatch);
-    } else {
-        GrPathShader::WriteConicPatch(p, w, asPatch);
-    }
-
-    // Ensure our hardware supports enough tessellation segments to render the curve. This early out
-    // assumes a worst-case quadratic rotation of 180 degrees and a worst-case number of segments in
-    // the join.
-    //
-    // An informal survey of skottie animations and gms revealed that even with a bare minimum of 64
-    // tessellation segments, 99.9%+ of quadratics take this early out.
-    float numParametricSegments_pow4 =
-            GrWangsFormula::quadratic_pow4(fTolerances.fParametricIntolerance, p);
-    if (numParametricSegments_pow4 <= fMaxParametricSegments180_pow4_withJoin) {
-        this->emitPatch(prevJoinType, asPatch, p[2]);
-        return;
-    }
-
-    if (numParametricSegments_pow4 <= fMaxParametricSegments180_pow4 || maxDepth == 0) {
-        if (numParametricSegments_pow4 > fMaxParametricSegments180_pow4_withJoin) {
-            // There aren't enough guaranteed segments to include the join. Emit a standalone patch
-            // for the join.
-            this->joinTo(prevJoinType, asPatch);
-            prevJoinType = JoinType::kNone;
-        }
-        this->emitPatch(prevJoinType, asPatch, p[2]);
-        return;
-    }
-
-    // We still might have enough tessellation segments to render the curve. Check again with the
-    // actual rotation.
-    float numRadialSegments = SkMeasureQuadRotation(p) * fTolerances.fNumRadialSegmentsPerRadian;
-    numRadialSegments = std::max(std::ceil(numRadialSegments), 1.f);
-    float numParametricSegments = GrWangsFormula::root4(numParametricSegments_pow4);
-    numParametricSegments = std::max(std::ceil(numParametricSegments), 1.f);
-    float numCombinedSegments = num_combined_segments(numParametricSegments, numRadialSegments);
-    if (numCombinedSegments > fMaxTessellationSegments) {
-        // The hardware doesn't support enough segments for this curve. Chop and recurse.
-        if (maxDepth < 0) {
-            // Decide on an extremely conservative upper bound for when to quit chopping. This
-            // is solely to protect us from infinite recursion in instances where FP error
-            // prevents us from chopping at the correct midtangent.
-            maxDepth = sk_float_nextlog2(numParametricSegments) +
-                       sk_float_nextlog2(numRadialSegments) + 1;
-            maxDepth = std::max(maxDepth, 1);
-        }
-        if (w == 1) {
-            SkPoint chops[5];
-            if (numParametricSegments >= numRadialSegments) {
-                SkChopQuadAtHalf(p, chops);
-            } else {
-                SkChopQuadAtMidTangent(p, chops);
-            }
-            this->conicTo(prevJoinType, chops, 1, maxDepth - 1);
-            this->conicTo(JoinType::kBowtie, chops + 2, 1, maxDepth - 1);
-        } else {
-            SkConic conic(p, w);
-            float chopT = (numParametricSegments >= numRadialSegments) ? .5f
-                                                                       : conic.findMidTangent();
-            SkConic chops[2];
-            if (conic.chopAt(chopT, chops)) {
-                this->conicTo(prevJoinType, chops[0].fPts, chops[0].fW, maxDepth - 1);
-                this->conicTo(JoinType::kBowtie, chops[1].fPts, chops[1].fW, maxDepth - 1);
-            }
-        }
-        return;
-    }
-
-    if (numCombinedSegments > fMaxCombinedSegments_withJoin) {
-        // There aren't enough guaranteed segments to include the join. Emit a standalone patch for
-        // the join.
-        this->joinTo(prevJoinType, asPatch);
-        prevJoinType = JoinType::kNone;
-    }
-    this->emitPatch(prevJoinType, asPatch, p[2]);
-}
-
-void GrStrokeHardwareTessellator::cubicTo(JoinType prevJoinType, const SkPoint p[4],
-                                          Convex180Status convex180Status, int maxDepth) {
-    // The stroke tessellation shader assigns special meaning to p0==p1==p2 and p1==p2==p3. If this
-    // is the case then we need to rewrite the cubic.
-    if (p[1] == p[2] && (p[1] == p[0] || p[1] == p[3])) {
-        this->lineTo(prevJoinType, p[0], p[3]);
-        return;
-    }
-
-    // Ensure our hardware supports enough tessellation segments to render the curve. This early out
-    // assumes a worst-case cubic rotation of 360 degrees and a worst-case number of segments in the
-    // join.
-    //
-    // An informal survey of skottie animations revealed that with a bare minimum of 64 tessellation
-    // segments, 95% of cubics take this early out.
-    float numParametricSegments_pow4 =
-            GrWangsFormula::cubic_pow4(fTolerances.fParametricIntolerance, p);
-    if (numParametricSegments_pow4 <= fMaxParametricSegments360_pow4_withJoin) {
-        this->emitPatch(prevJoinType, p, p[3]);
-        return;
-    }
-
-    float maxParametricSegments_pow4 = (convex180Status == Convex180Status::kYes) ?
-            fMaxParametricSegments180_pow4 : fMaxParametricSegments360_pow4;
-    if (numParametricSegments_pow4 <= maxParametricSegments_pow4 || maxDepth == 0) {
-        float maxParametricSegments_pow4_withJoin = (convex180Status == Convex180Status::kYes) ?
-                fMaxParametricSegments180_pow4_withJoin : fMaxParametricSegments360_pow4_withJoin;
-        if (numParametricSegments_pow4 > maxParametricSegments_pow4_withJoin) {
-            // There aren't enough guaranteed segments to include the join. Emit a standalone patch
-            // for the join.
-            this->joinTo(prevJoinType, p);
-            prevJoinType = JoinType::kNone;
-        }
-        this->emitPatch(prevJoinType, p, p[3]);
-        return;
-    }
-
-    // Ensure the curve does not inflect or rotate >180 degrees before we start subdividing and
-    // measuring rotation.
-    if (convex180Status == Convex180Status::kUnknown) {
-        this->cubicConvex180SegmentsTo(prevJoinType, p);
-        return;
-    }
-
-    // We still might have enough tessellation segments to render the curve. Check again with
-    // its actual rotation.
-    float numRadialSegments =
-            SkMeasureNonInflectCubicRotation(p) * fTolerances.fNumRadialSegmentsPerRadian;
-    numRadialSegments = std::max(std::ceil(numRadialSegments), 1.f);
-    float numParametricSegments = GrWangsFormula::root4(numParametricSegments_pow4);
-    numParametricSegments = std::max(std::ceil(numParametricSegments), 1.f);
-    float numCombinedSegments = num_combined_segments(numParametricSegments, numRadialSegments);
-    if (numCombinedSegments > fMaxTessellationSegments) {
-        // The hardware doesn't support enough segments for this curve. Chop and recurse.
-        SkPoint chops[7];
-        if (maxDepth < 0) {
-            // Decide on an extremely conservative upper bound for when to quit chopping. This
-            // is solely to protect us from infinite recursion in instances where FP error
-            // prevents us from chopping at the correct midtangent.
-            maxDepth = sk_float_nextlog2(numParametricSegments) +
-                       sk_float_nextlog2(numRadialSegments) + 1;
-            maxDepth = std::max(maxDepth, 1);
-        }
-        if (numParametricSegments >= numRadialSegments) {
-            SkChopCubicAtHalf(p, chops);
-        } else {
-            SkChopCubicAtMidTangent(p, chops);
-        }
-        this->cubicTo(prevJoinType, chops, Convex180Status::kYes, maxDepth - 1);
-        this->cubicTo(JoinType::kBowtie, chops + 3, Convex180Status::kYes, maxDepth - 1);
-        return;
-    }
-
-    if (numCombinedSegments > fMaxCombinedSegments_withJoin) {
-        // There aren't enough guaranteed segments to include the join. Emit a standalone patch for
-        // the join.
-        this->joinTo(prevJoinType, p);
-        prevJoinType = JoinType::kNone;
-    }
-    this->emitPatch(prevJoinType, p, p[3]);
-}
-
-void GrStrokeHardwareTessellator::cubicConvex180SegmentsTo(JoinType prevJoinType,
-                                                           const SkPoint p[4]) {
-    SkPoint chops[10];
-    float chopT[2];
-    bool areCusps = false;
-    int numChops = GrPathUtils::findCubicConvex180Chops(p, chopT, &areCusps);
-    if (numChops == 0) {
-        // The curve is already convex and rotates no more than 180 degrees.
-        this->cubicTo(prevJoinType, p, Convex180Status::kYes);
-    } else if (numChops == 1) {
-        SkChopCubicAt(p, chops, chopT[0]);
-        if (areCusps) {
-            // When chopping on a perfect cusp, these 3 points will be equal.
-            chops[2] = chops[4] = chops[3];
-        }
-        this->cubicTo(prevJoinType, chops, Convex180Status::kYes);
-        this->cubicTo(JoinType::kBowtie, chops + 3, Convex180Status::kYes);
-    } else {
-        SkASSERT(numChops == 2);
-        SkChopCubicAt(p, chops, chopT[0], chopT[1]);
-        // Two cusps are only possible on a flat line with two 180-degree turnarounds.
-        if (areCusps) {
-            this->lineTo(prevJoinType, chops[0], chops[3]);
-            this->lineTo(JoinType::kBowtie, chops[3], chops[6]);
-            this->lineTo(JoinType::kBowtie, chops[6], chops[9]);
-            return;
-        }
-        this->cubicTo(prevJoinType, chops, Convex180Status::kYes);
-        this->cubicTo(JoinType::kBowtie, chops + 3, Convex180Status::kYes);
-        this->cubicTo(JoinType::kBowtie, chops + 6, Convex180Status::kYes);
-    }
-}
-
-void GrStrokeHardwareTessellator::joinTo(JoinType joinType, SkPoint junctionPoint,
-                                         SkPoint nextControlPoint, int maxDepth) {
-    if (!fHasLastControlPoint) {
-        // The first stroke doesn't have a previous join.
-        return;
-    }
-
-    if (!fSoloRoundJoinAlwaysFitsInPatch && maxDepth != 0 &&
-        (joinType == JoinType::kRound || joinType == JoinType::kBowtie)) {
-        SkVector tan0 = junctionPoint - fLastControlPoint;
-        SkVector tan1 = nextControlPoint - junctionPoint;
-        float rotation = SkMeasureAngleBetweenVectors(tan0, tan1);
-        float numRadialSegments = rotation * fTolerances.fNumRadialSegmentsPerRadian;
-        if (numRadialSegments > fMaxTessellationSegments) {
-            // This is a round join that requires more segments than the tessellator supports.
-            // Split it and recurse.
-            if (maxDepth < 0) {
-                // Decide on an upper bound for when to quit chopping. This is solely to protect
-                // us from infinite recursion due to FP precision issues.
-                maxDepth = sk_float_nextlog2(numRadialSegments / fMaxTessellationSegments);
-                maxDepth = std::max(maxDepth, 1);
-            }
-            // Find the bisector so we can split the join in half.
-            SkPoint bisector = SkFindBisector(tan0, tan1);
-            // c0 will be the "next" control point for the first join half, and c1 will be the
-            // "previous" control point for the second join half.
-            SkPoint c0, c1;
-            // FIXME(skia:11347): This hack ensures "c0 - junctionPoint" gives the exact same ieee
-            // fp32 vector as "-(c1 - junctionPoint)". Tessellated stroking is becoming less
-            // experimental, so t's time to think of a cleaner method to avoid T-junctions when we
-            // chop joins.
-            int maxAttempts = 10;
-            do {
-                bisector = (junctionPoint + bisector) - (junctionPoint - bisector);
-                c0 = junctionPoint + bisector;
-                c1 = junctionPoint - bisector;
-            } while (c0 - junctionPoint != -(c1 - junctionPoint) && --maxAttempts);
-            this->joinTo(joinType, junctionPoint, c0, maxDepth - 1);  // First join half.
-            fLastControlPoint = c1;
-            // Second join half.
-            this->joinTo(joinType, junctionPoint, nextControlPoint, maxDepth - 1);
-            return;
-        }
-    }
-
-    this->emitJoinPatch(joinType, junctionPoint, nextControlPoint);
-}
-
-void GrStrokeHardwareTessellator::close(SkPoint contourEndpoint, const SkMatrix& viewMatrix,
-                                        const SkStrokeRec& stroke) {
-    if (!fHasLastControlPoint) {
-        // Draw caps instead of closing if the subpath is zero length:
-        //
-        //   "Any zero length subpath ...  shall be stroked if the 'stroke-linecap' property has a
-        //   value of round or square producing respectively a circle or a square."
-        //
-        //   (https://www.w3.org/TR/SVG11/painting.html#StrokeProperties)
-        //
-        this->cap(contourEndpoint, viewMatrix, stroke);
-        return;
-    }
-
-    // Draw a line back to the beginning. (This will be discarded if
-    // contourEndpoint == fCurrContourStartPoint.)
-    auto strokeJoinType = JoinType(stroke.getJoin());
-    this->lineTo(strokeJoinType, contourEndpoint, fCurrContourStartPoint);
-    this->joinTo(strokeJoinType, fCurrContourStartPoint, fCurrContourFirstControlPoint);
-
-    fHasLastControlPoint = false;
-}
-
-void GrStrokeHardwareTessellator::cap(SkPoint contourEndpoint, const SkMatrix& viewMatrix,
-                                      const SkStrokeRec& stroke) {
-    if (!fHasLastControlPoint) {
-        // We don't have any control points to orient the caps. In this case, square and round caps
-        // are specified to be drawn as an axis-aligned square or circle respectively. Assign
-        // default control points that achieve this.
-        SkVector outset;
-        if (!stroke.isHairlineStyle()) {
-            outset = {1, 0};
-        } else {
-            // If the stroke is hairline, orient the square on the post-transform x-axis instead.
-            // We don't need to worry about the vector length since it will be normalized later.
-            // Since the matrix cannot have perspective, the below is equivalent to:
-            //
-            //    outset = inverse(|a b|) * |1| * arbitrary_scale
-            //                     |c d|    |0|
-            //
-            //    == 1/det * | d -b| * |1| * arbitrary_scale
-            //               |-c  a|   |0|
-            //
-            //    == 1/det * | d| * arbitrary_scale
-            //               |-c|
-            //
-            //    == | d|
-            //       |-c|
-            //
-            SkASSERT(!viewMatrix.hasPerspective());
-            float c=viewMatrix.getSkewY(), d=viewMatrix.getScaleY();
-            outset = {d, -c};
-        }
-        fCurrContourFirstControlPoint = fCurrContourStartPoint - outset;
-        fLastControlPoint = fCurrContourStartPoint + outset;
-        fHasLastControlPoint = true;
-        contourEndpoint = fCurrContourStartPoint;
-    }
-
-    switch (stroke.getCap()) {
-        case SkPaint::kButt_Cap:
-            break;
-        case SkPaint::kRound_Cap: {
-            // A round cap is the same thing as a 180-degree round join.
-            // If our join type isn't round we can alternatively use a bowtie.
-            JoinType roundCapJoinType = (stroke.getJoin() == SkPaint::kRound_Join)
-                    ? JoinType::kRound : JoinType::kBowtie;
-            this->joinTo(roundCapJoinType, contourEndpoint, fLastControlPoint);
-            this->moveTo(fCurrContourStartPoint, fCurrContourFirstControlPoint);
-            this->joinTo(roundCapJoinType, fCurrContourStartPoint,
-                         fCurrContourFirstControlPoint);
-            break;
-        }
-        case SkPaint::kSquare_Cap: {
-            // A square cap is the same as appending lineTos.
-            auto strokeJoinType = JoinType(stroke.getJoin());
-            SkVector lastTangent = contourEndpoint - fLastControlPoint;
-            if (!stroke.isHairlineStyle()) {
-                // Extend the cap by 1/2 stroke width.
-                lastTangent *= (.5f * stroke.getWidth()) / lastTangent.length();
-            } else {
-                // Extend the cap by what will be 1/2 pixel after transformation.
-                lastTangent *= .5f / viewMatrix.mapVector(lastTangent.fX, lastTangent.fY).length();
-            }
-            this->lineTo(strokeJoinType, contourEndpoint, contourEndpoint + lastTangent);
-            this->moveTo(fCurrContourStartPoint, fCurrContourFirstControlPoint);
-            SkVector firstTangent = fCurrContourFirstControlPoint - fCurrContourStartPoint;
-            if (!stroke.isHairlineStyle()) {
-                // Set the the cap back by 1/2 stroke width.
-                firstTangent *= (-.5f * stroke.getWidth()) / firstTangent.length();
-            } else {
-                // Set the cap back by what will be 1/2 pixel after transformation.
-                firstTangent *=
-                        -.5f / viewMatrix.mapVector(firstTangent.fX, firstTangent.fY).length();
-            }
-            this->lineTo(strokeJoinType, fCurrContourStartPoint,
-                         fCurrContourStartPoint + firstTangent);
-            break;
-        }
-    }
-
-    fHasLastControlPoint = false;
-}
-
-void GrStrokeHardwareTessellator::emitPatch(JoinType prevJoinType, const SkPoint p[4],
-                                            SkPoint endPt) {
-    SkPoint c1 = (p[1] == p[0]) ? p[2] : p[1];
-    SkPoint c2 = (p[2] == endPt) ? p[1] : p[2];
-
-    if (prevJoinType == JoinType::kBowtie) {
-        // Bowties need to go in their own patch if they will have >1 segment.
-        // TODO: Investigate if an optimization like "x < fCosRadiansPerSegment" would be worth it.
-        float rotation = SkMeasureAngleBetweenVectors(p[0] - fLastControlPoint, c1 - p[0]);
-        if (rotation * fTolerances.fNumRadialSegmentsPerRadian > 1) {
-            this->joinTo(prevJoinType, p[0], c1);
-            prevJoinType = JoinType::kNone;
-        }
-    }
-
-    if (!fHasLastControlPoint) {
-        // The first stroke doesn't have a previous join (yet). If the current contour ends up
-        // closing itself, we will add that join as its own patch.
-        // TODO: Consider deferring the first stroke until we know whether the contour will close.
-        // This will allow us to use the closing join as the first patch's previous join.
-        prevJoinType = JoinType::kNone;
-        fCurrContourFirstControlPoint = c1;
-        fHasLastControlPoint = true;
-    } else {
-        // By using JoinType::kNone, the caller promises to have written out their own join that
-        // seams exactly with this curve.
-        SkASSERT((prevJoinType != JoinType::kNone) || fLastControlPoint == c1);
-    }
-
-    if (this->reservePatch()) {
-        // Disable the join section of this patch if prevJoinType is kNone by setting the previous
-        // control point equal to p0.
-        fPatchWriter.write((prevJoinType == JoinType::kNone) ? p[0] : fLastControlPoint);
-        fPatchWriter.writeArray(p, 4);
-        this->emitDynamicAttribs();
-    }
-
-    fLastControlPoint = c2;
-}
-
-void GrStrokeHardwareTessellator::emitJoinPatch(JoinType joinType, SkPoint junctionPoint,
-                                                SkPoint nextControlPoint) {
-    // We should never write out joins before the first curve.
-    SkASSERT(fHasLastControlPoint);
-
-    if (this->reservePatch()) {
-        fPatchWriter.write(fLastControlPoint, junctionPoint);
-        if (joinType == JoinType::kBowtie) {
-            // {prevControlPoint, [p0, p0, p0, p3]} is a reserved patch pattern that means this
-            // patch is a bowtie. The bowtie is anchored on p0 and its tangent angles go from
-            // (p0 - prevControlPoint) to (p3 - p0).
-            fPatchWriter.write(junctionPoint, junctionPoint);
-        } else {
-            SkASSERT(joinType != JoinType::kNone);
-            // {prevControlPoint, [p0, p3, p3, p3]} is a reserved patch pattern that means this
-            // patch is a join only (no curve sections in the patch). The join is anchored on p0 and
-            // its tangent angles go from (p0 - prevControlPoint) to (p3 - p0).
-            fPatchWriter.write(nextControlPoint, nextControlPoint);
-        }
-        fPatchWriter.write(nextControlPoint);
-        this->emitDynamicAttribs();
-    }
-
-    fLastControlPoint = nextControlPoint;
-}
-
-void GrStrokeHardwareTessellator::emitDynamicAttribs() {
-    if (fShaderFlags & ShaderFlags::kDynamicStroke) {
-        fPatchWriter.write(fDynamicStroke);
-    }
-    if (fShaderFlags & ShaderFlags::kDynamicColor) {
-        fPatchWriter.write(fDynamicColor);
-    }
-}
-
-bool GrStrokeHardwareTessellator::reservePatch() {
-    if (fPatchChunks.back().fPatchCount >= fCurrChunkPatchCapacity) {
-        // The current chunk is full. Time to allocate a new one. (And no need to put back vertices;
-        // the buffer is full.)
-        this->allocPatchChunkAtLeast(fCurrChunkMinPatchAllocCount * 2);
-    }
-    if (!fPatchWriter.isValid()) {
-        SkDebugf("WARNING: Failed to allocate vertex buffer for tessellated stroke.");
-        return false;
-    }
-    SkASSERT(fPatchChunks.back().fPatchCount <= fCurrChunkPatchCapacity);
-    ++fPatchChunks.back().fPatchCount;
-    return true;
-}
-
-void GrStrokeHardwareTessellator::allocPatchChunkAtLeast(int minPatchAllocCount) {
-    SkASSERT(fTarget);
-    PatchChunk* chunk = &fPatchChunks.push_back();
-    fPatchWriter = {fTarget->makeVertexSpaceAtLeast(fPatchStride, minPatchAllocCount,
-                                                    minPatchAllocCount, &chunk->fPatchBuffer,
-                                                    &chunk->fBasePatch, &fCurrChunkPatchCapacity)};
-    fCurrChunkMinPatchAllocCount = minPatchAllocCount;
 }
 
 void GrStrokeHardwareTessellator::draw(GrOpFlushState* flushState) const {
diff --git a/src/gpu/tessellate/GrStrokeHardwareTessellator.h b/src/gpu/tessellate/GrStrokeHardwareTessellator.h
index a07ed05..37a4041 100644
--- a/src/gpu/tessellate/GrStrokeHardwareTessellator.h
+++ b/src/gpu/tessellate/GrStrokeHardwareTessellator.h
@@ -18,91 +18,6 @@
 // MSAA if antialiasing is desired.
 class GrStrokeHardwareTessellator : public GrStrokeTessellator {
 public:
-    GrStrokeHardwareTessellator(ShaderFlags shaderFlags,
-                                GrSTArenaList<PathStroke>&& pathStrokeList,
-                                int totalCombinedVerbCnt, const GrShaderCaps& shaderCaps)
-            : GrStrokeTessellator(shaderFlags, std::move(pathStrokeList))
-            , fTotalCombinedVerbCnt(totalCombinedVerbCnt)
-            , fPatchStride(GrStrokeTessellateShader::PatchStride(fShaderFlags))
-            // Subtract 2 because the tessellation shader chops every cubic at two locations, and
-            // each chop has the potential to introduce an extra segment.
-            , fMaxTessellationSegments(shaderCaps.maxTessellationSegments() - 2) {
-    }
-
-    void prepare(GrMeshDrawOp::Target*, const SkMatrix&) override;
-
-    void draw(GrOpFlushState*) const override;
-
-private:
-    using Tolerances = GrStrokeTessellateShader::Tolerances;
-
-    enum class JoinType {
-        kMiter = SkPaint::kMiter_Join,
-        kRound = SkPaint::kRound_Join,
-        kBevel = SkPaint::kBevel_Join,
-        kBowtie = SkPaint::kLast_Join + 1,  // Double sided round join.
-        kNone
-    };
-
-    // Is a cubic curve convex, and does it rotate no more than 180 degrees?
-    enum class Convex180Status : bool {
-        kUnknown,
-        kYes
-    };
-
-    // Updates our internal tolerances for determining how much subdivision to do. We need to ensure
-    // every curve we emit requires no more segments than fMaxTessellationSegments.
-    void updateTolerances(Tolerances, SkPaint::Join strokeJoin);
-
-    void moveTo(SkPoint);
-    void moveTo(SkPoint, SkPoint lastControlPoint);
-    void lineTo(JoinType prevJoinType, SkPoint p0, SkPoint p1);
-    void conicTo(JoinType prevJoinType, const SkPoint[3], float w, int maxDepth = -1);
-    void cubicTo(JoinType prevJoinType, const SkPoint[4],
-                 Convex180Status = Convex180Status::kUnknown, int maxDepth = -1);
-    // Chops the curve into 1-3 convex sections that rotate no more than 180 degrees, then calls
-    // cubicTo() for each section.
-    void cubicConvex180SegmentsTo(JoinType prevJoinType, const SkPoint[4]);
-    void joinTo(JoinType joinType, const SkPoint nextCubic[]) {
-        const SkPoint& nextCtrlPt = (nextCubic[1] == nextCubic[0]) ? nextCubic[2] : nextCubic[1];
-        // The caller should have culled out curves where p0==p1==p2 by this point.
-        SkASSERT(nextCtrlPt != nextCubic[0]);
-        this->joinTo(joinType, nextCubic[0], nextCtrlPt);
-    }
-    void joinTo(JoinType, SkPoint junctionPoint, SkPoint nextControlPoint, int maxDepth = -1);
-    void close(SkPoint contourEndpoint, const SkMatrix&, const SkStrokeRec&);
-    void cap(SkPoint contourEndpoint, const SkMatrix&, const SkStrokeRec&);
-    void emitPatch(JoinType prevJoinType, const SkPoint pts[4], SkPoint endPt);
-    void emitJoinPatch(JoinType, SkPoint junctionPoint, SkPoint nextControlPoint);
-    void emitDynamicAttribs();
-    bool reservePatch();
-    void allocPatchChunkAtLeast(int minPatchAllocCount);
-
-    // The combined number of path verbs from all paths in fPathStrokeList.
-    const int fTotalCombinedVerbCnt;
-
-    // Size in bytes of a tessellation patch with our shader flags.
-    const size_t fPatchStride;
-
-    // The maximum number of tessellation segments the hardware can emit for a single patch.
-    const int fMaxTessellationSegments;
-
-    // This will only be valid during prepare() and its callees.
-    GrMeshDrawOp::Target* fTarget = nullptr;
-
-    // These values contain worst-case numbers of parametric segments, raised to the 4th power, that
-    // our hardware can support for the current stroke radius. They assume curve rotations of 180
-    // and 360 degrees respectively. These are used for "quick accepts" that allow us to send almost
-    // all curves directly to the hardware without having to chop. We raise to the 4th power because
-    // the "pow4" variants of Wang's formula are the quickest to evaluate.
-    GrStrokeTessellateShader::Tolerances fTolerances;
-    float fMaxParametricSegments180_pow4;
-    float fMaxParametricSegments360_pow4;
-    float fMaxParametricSegments180_pow4_withJoin;
-    float fMaxParametricSegments360_pow4_withJoin;
-    float fMaxCombinedSegments_withJoin;
-    bool fSoloRoundJoinAlwaysFitsInPatch;
-
     // We generate and store patch buffers in chunks. Normally there will only be one chunk, but in
     // rare cases the first can run out of space if too many cubics needed to be subdivided.
     struct PatchChunk {
@@ -110,24 +25,23 @@
         int fPatchCount = 0;
         int fBasePatch;
     };
+
+    GrStrokeHardwareTessellator(ShaderFlags shaderFlags,
+                                GrSTArenaList<PathStroke>&& pathStrokeList,
+                                int totalCombinedVerbCnt, const GrShaderCaps& shaderCaps)
+            : GrStrokeTessellator(shaderFlags, std::move(pathStrokeList))
+            , fTotalCombinedVerbCnt(totalCombinedVerbCnt) {
+    }
+
+    void prepare(GrMeshDrawOp::Target*, const SkMatrix&) override;
+    void draw(GrOpFlushState*) const override;
+
+private:
+    // The combined number of path verbs from all paths in fPathStrokeList.
+    const int fTotalCombinedVerbCnt;
+
     SkSTArray<1, PatchChunk> fPatchChunks;
 
-    // Variables related to the patch chunk that we are currently writing out during prepareBuffers.
-    int fCurrChunkPatchCapacity;
-    int fCurrChunkMinPatchAllocCount;
-    GrVertexWriter fPatchWriter;
-
-    // Variables related to the specific contour that we are currently iterating during
-    // prepareBuffers().
-    bool fHasLastControlPoint = false;
-    SkPoint fCurrContourStartPoint;
-    SkPoint fCurrContourFirstControlPoint;
-    SkPoint fLastControlPoint;
-
-    // Stateful values for the dynamic state (if any) that will get written out with each patch.
-    GrStrokeTessellateShader::DynamicStroke fDynamicStroke;
-    GrVertexColor fDynamicColor;
-
     friend class GrOp;  // For ctor.
 
 public:
