diff --git a/bench/CubicKLMBench.cpp b/bench/CubicKLMBench.cpp
deleted file mode 100644
index d9ce672..0000000
--- a/bench/CubicKLMBench.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "bench/Benchmark.h"
-
-#include "src/core/SkGeometry.h"
-#include "src/gpu/geometry/GrPathUtils.h"
-
-class CubicKLMBench : public Benchmark {
-public:
-    CubicKLMBench(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
-                  SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)  {
-        fPoints[0].set(x0, y0);
-        fPoints[1].set(x1, y1);
-        fPoints[2].set(x2, y2);
-        fPoints[3].set(x3, y3);
-
-        fName = "cubic_klm_";
-        switch (SkClassifyCubic(fPoints)) {
-            case SkCubicType::kSerpentine:
-                fName.append("serp");
-                break;
-            case SkCubicType::kLoop:
-                fName.append("loop");
-                break;
-            default:
-                SK_ABORT("Unexpected cubic type");
-                break;
-        }
-    }
-
-    bool isSuitableFor(Backend backend) override {
-        return backend == kNonRendering_Backend;
-    }
-
-    const char* onGetName() override {
-        return fName.c_str();
-    }
-
-    void onDraw(int loops, SkCanvas*) override {
-        SkPoint dst[10];
-        SkMatrix klm;
-        int loopIdx;
-        for (int i = 0; i < loops * 50000; ++i) {
-            GrPathUtils::chopCubicAtLoopIntersection(fPoints, dst, &klm, &loopIdx);
-        }
-    }
-
-private:
-    SkPoint     fPoints[4];
-    SkString    fName;
-
-    using INHERITED = Benchmark;
-};
-
-DEF_BENCH( return new CubicKLMBench(285.625f, 499.687f, 411.625f, 808.188f,
-                                    1064.62f, 135.688f, 1042.63f, 585.187f); )
-DEF_BENCH( return new CubicKLMBench(635.625f, 614.687f, 171.625f, 236.188f,
-                                    1064.62f, 135.688f, 516.625f, 570.187f); )
diff --git a/gn/bench.gni b/gn/bench.gni
index 79aa70f..6c31fb0 100644
--- a/gn/bench.gni
+++ b/gn/bench.gni
@@ -38,7 +38,6 @@
   "$_bench/ControlBench.cpp",
   "$_bench/CoverageBench.cpp",
   "$_bench/CreateBackendTextureBench.cpp",
-  "$_bench/CubicKLMBench.cpp",
   "$_bench/CubicMapBench.cpp",
   "$_bench/DDLRecorderBench.cpp",
   "$_bench/DashBench.cpp",
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index d918c18..7e6c394 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -67,7 +67,6 @@
 
     PrimitiveType fPrimitiveType = PrimitiveType::kCubics;
     SkCubicType fCubicType;
-    SkMatrix fCubicKLM;
 
     SkPoint fPoints[4] = {
             {100.05f, 100.05f}, {400.75f, 100.05f}, {400.75f, 300.95f}, {100.05f, 300.95f}};
@@ -154,27 +153,6 @@
     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new Impl; }
 };
 
-static void draw_klm_line(int w, int h, SkCanvas* canvas, const SkScalar line[3], SkColor color) {
-    SkPoint p1, p2;
-    if (SkScalarAbs(line[1]) > SkScalarAbs(line[0])) {
-        // Draw from vertical edge to vertical edge.
-        p1 = {0, -line[2] / line[1]};
-        p2 = {(SkScalar)w, (-line[2] - w * line[0]) / line[1]};
-    } else {
-        // Draw from horizontal edge to horizontal edge.
-        p1 = {-line[2] / line[0], 0};
-        p2 = {(-line[2] - h * line[1]) / line[0], (SkScalar)h};
-    }
-
-    SkPaint linePaint;
-    linePaint.setColor(color);
-    linePaint.setAlpha(128);
-    linePaint.setStyle(SkPaint::kStroke_Style);
-    linePaint.setStrokeWidth(0);
-    linePaint.setAntiAlias(true);
-    canvas->drawLine(p1, p2, linePaint);
-}
-
 void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
     canvas->clear(SK_ColorBLACK);
 
@@ -248,12 +226,6 @@
 
     if (PrimitiveType::kCubics == fPrimitiveType) {
         canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, fPoints, pointsPaint);
-        if (!fDoStroke) {
-            int w = this->width(), h = this->height();
-            draw_klm_line(w, h, canvas, &fCubicKLM[0], SK_ColorYELLOW);
-            draw_klm_line(w, h, canvas, &fCubicKLM[3], SK_ColorBLUE);
-            draw_klm_line(w, h, canvas, &fCubicKLM[6], SK_ColorRED);
-        }
     } else {
         canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, fPoints, pointsPaint);
         canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, fPoints + 3, pointsPaint);
@@ -274,8 +246,6 @@
     fPath.moveTo(fPoints[0]);
 
     if (PrimitiveType::kCubics == fPrimitiveType) {
-        double t[2], s[2];
-        fCubicType = GrPathUtils::getCubicKLM(fPoints, &fCubicKLM, t, s);
         GrCCFillGeometry geometry;
         geometry.beginContour(fPoints[0]);
         geometry.cubicTo(fPoints, kDebugBloat / 2, kDebugBloat / 2);
diff --git a/src/gpu/geometry/GrPathUtils.cpp b/src/gpu/geometry/GrPathUtils.cpp
index 3b5fc01..3e80318 100644
--- a/src/gpu/geometry/GrPathUtils.cpp
+++ b/src/gpu/geometry/GrPathUtils.cpp
@@ -162,54 +162,6 @@
     return a + b;
 }
 
-int GrPathUtils::worstCasePointCount(const SkPath& path, int* subpaths, SkScalar tol) {
-    // You should have called scaleToleranceToSrc, which guarantees this
-    SkASSERT(tol >= gMinCurveTol);
-
-    int pointCount = 0;
-    *subpaths = 1;
-
-    bool first = true;
-
-    SkPath::Iter iter(path, false);
-    SkPath::Verb verb;
-
-    SkPoint pts[4];
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-
-        switch (verb) {
-            case SkPath::kLine_Verb:
-                pointCount += 1;
-                break;
-            case SkPath::kConic_Verb: {
-                SkScalar weight = iter.conicWeight();
-                SkAutoConicToQuads converter;
-                const SkPoint* quadPts = converter.computeQuads(pts, weight, tol);
-                for (int i = 0; i < converter.countQuads(); ++i) {
-                    pointCount += quadraticPointCount(quadPts + 2*i, tol);
-                }
-                [[fallthrough]];
-            }
-            case SkPath::kQuad_Verb:
-                pointCount += quadraticPointCount(pts, tol);
-                break;
-            case SkPath::kCubic_Verb:
-                pointCount += cubicPointCount(pts, tol);
-                break;
-            case SkPath::kMove_Verb:
-                pointCount += 1;
-                if (!first) {
-                    ++(*subpaths);
-                }
-                break;
-            default:
-                break;
-        }
-        first = false;
-    }
-    return pointCount;
-}
-
 void GrPathUtils::QuadUVMatrix::set(const SkPoint qPts[3]) {
     SkMatrix m;
     // We want M such that M * xy_pt = uv_pt
@@ -631,230 +583,3 @@
         convert_noninflect_cubic_to_quads_with_constraint(cubic, tolSqd, dir, quads);
     }
 }
-
-////////////////////////////////////////////////////////////////////////////////
-
-using ExcludedTerm = GrPathUtils::ExcludedTerm;
-
-ExcludedTerm GrPathUtils::calcCubicInverseTransposePowerBasisMatrix(const SkPoint p[4],
-                                                                    SkMatrix* out) {
-    static_assert(SK_SCALAR_IS_FLOAT);
-
-    // First convert the bezier coordinates p[0..3] to power basis coefficients X,Y(,W=[0 0 0 1]).
-    // M3 is the matrix that does this conversion. The homogeneous equation for the cubic becomes:
-    //
-    //                                     | X   Y   0 |
-    // C(t,s) = [t^3  t^2*s  t*s^2  s^3] * | .   .   0 |
-    //                                     | .   .   0 |
-    //                                     | .   .   1 |
-    //
-    const Sk4f M3[3] = {Sk4f(-1, 3, -3, 1),
-                        Sk4f(3, -6, 3, 0),
-                        Sk4f(-3, 3, 0, 0)};
-    // 4th col of M3 =  Sk4f(1, 0, 0, 0)};
-    Sk4f X(p[3].x(), 0, 0, 0);
-    Sk4f Y(p[3].y(), 0, 0, 0);
-    for (int i = 2; i >= 0; --i) {
-        X += M3[i] * p[i].x();
-        Y += M3[i] * p[i].y();
-    }
-
-    // The matrix is 3x4. In order to invert it, we first need to make it square by throwing out one
-    // of the middle two rows. We toss the row that leaves us with the largest absolute determinant.
-    // Since the right column will be [0 0 1], the respective determinants reduce to x0*y2 - y0*x2
-    // and x0*y1 - y0*x1.
-    SkScalar dets[4];
-    Sk4f D = SkNx_shuffle<0,0,2,1>(X) * SkNx_shuffle<2,1,0,0>(Y);
-    D -= SkNx_shuffle<2,3,0,1>(D);
-    D.store(dets);
-    ExcludedTerm skipTerm = SkScalarAbs(dets[0]) > SkScalarAbs(dets[1]) ?
-                            ExcludedTerm::kQuadraticTerm : ExcludedTerm::kLinearTerm;
-    SkScalar det = dets[ExcludedTerm::kQuadraticTerm == skipTerm ? 0 : 1];
-    if (0 == det) {
-        return ExcludedTerm::kNonInvertible;
-    }
-    SkScalar rdet = 1 / det;
-
-    // Compute the inverse-transpose of the power basis matrix with the 'skipRow'th row removed.
-    // Since W=[0 0 0 1], it follows that our corresponding solution will be equal to:
-    //
-    //             |  y1  -x1   x1*y2 - y1*x2 |
-    //     1/det * | -y0   x0  -x0*y2 + y0*x2 |
-    //             |   0    0             det |
-    //
-    SkScalar x[4], y[4], z[4];
-    X.store(x);
-    Y.store(y);
-    (X * SkNx_shuffle<3,3,3,3>(Y) - Y * SkNx_shuffle<3,3,3,3>(X)).store(z);
-
-    int middleRow = ExcludedTerm::kQuadraticTerm == skipTerm ? 2 : 1;
-    out->setAll( y[middleRow] * rdet, -x[middleRow] * rdet,  z[middleRow] * rdet,
-                        -y[0] * rdet,          x[0] * rdet,         -z[0] * rdet,
-                                   0,                    0,                    1);
-
-    return skipTerm;
-}
-
-inline static void calc_serp_kcoeffs(SkScalar tl, SkScalar sl, SkScalar tm, SkScalar sm,
-                                     ExcludedTerm skipTerm, SkScalar outCoeffs[3]) {
-    SkASSERT(ExcludedTerm::kQuadraticTerm == skipTerm || ExcludedTerm::kLinearTerm == skipTerm);
-    outCoeffs[0] = 0;
-    outCoeffs[1] = (ExcludedTerm::kLinearTerm == skipTerm) ? sl*sm : -tl*sm - tm*sl;
-    outCoeffs[2] = tl*tm;
-}
-
-inline static void calc_serp_lmcoeffs(SkScalar t, SkScalar s, ExcludedTerm skipTerm,
-                                      SkScalar outCoeffs[3]) {
-    SkASSERT(ExcludedTerm::kQuadraticTerm == skipTerm || ExcludedTerm::kLinearTerm == skipTerm);
-    outCoeffs[0] = -s*s*s;
-    outCoeffs[1] = (ExcludedTerm::kLinearTerm == skipTerm) ? 3*s*s*t : -3*s*t*t;
-    outCoeffs[2] = t*t*t;
-}
-
-inline static void calc_loop_kcoeffs(SkScalar td, SkScalar sd, SkScalar te, SkScalar se,
-                                     SkScalar tdse, SkScalar tesd, ExcludedTerm skipTerm,
-                                     SkScalar outCoeffs[3]) {
-    SkASSERT(ExcludedTerm::kQuadraticTerm == skipTerm || ExcludedTerm::kLinearTerm == skipTerm);
-    outCoeffs[0] = 0;
-    outCoeffs[1] = (ExcludedTerm::kLinearTerm == skipTerm) ? sd*se : -tdse - tesd;
-    outCoeffs[2] = td*te;
-}
-
-inline static void calc_loop_lmcoeffs(SkScalar t2, SkScalar s2, SkScalar t1, SkScalar s1,
-                                      SkScalar t2s1, SkScalar t1s2, ExcludedTerm skipTerm,
-                                      SkScalar outCoeffs[3]) {
-    SkASSERT(ExcludedTerm::kQuadraticTerm == skipTerm || ExcludedTerm::kLinearTerm == skipTerm);
-    outCoeffs[0] = -s2*s2*s1;
-    outCoeffs[1] = (ExcludedTerm::kLinearTerm == skipTerm) ? s2 * (2*t2s1 + t1s2)
-                                                           : -t2 * (t2s1 + 2*t1s2);
-    outCoeffs[2] = t2*t2*t1;
-}
-
-// For the case when a cubic bezier is actually a quadratic. We duplicate k in l so that the
-// implicit becomes:
-//
-//     k^3 - l*m == k^3 - l*k == k * (k^2 - l)
-//
-// In the quadratic case we can simply assign fixed values at each control point:
-//
-//     | ..K.. |     | pts[0]  pts[1]  pts[2]  pts[3] |      | 0   1/3  2/3  1 |
-//     | ..L.. |  *  |   .       .       .       .    |  ==  | 0     0  1/3  1 |
-//     | ..K.. |     |   1       1       1       1    |      | 0   1/3  2/3  1 |
-//
-static void calc_quadratic_klm(const SkPoint pts[4], double d3, SkMatrix* klm) {
-    SkMatrix klmAtPts;
-    klmAtPts.setAll(0,  1.f/3,  1,
-                    0,      0,  1,
-                    0,  1.f/3,  1);
-
-    SkMatrix inversePts;
-    inversePts.setAll(pts[0].x(),  pts[1].x(),  pts[3].x(),
-                      pts[0].y(),  pts[1].y(),  pts[3].y(),
-                               1,           1,           1);
-    SkAssertResult(inversePts.invert(&inversePts));
-
-    klm->setConcat(klmAtPts, inversePts);
-
-    // If d3 > 0 we need to flip the orientation of our curve
-    // This is done by negating the k and l values
-    if (d3 > 0) {
-        klm->postScale(-1, -1);
-    }
-}
-
-// For the case when a cubic bezier is actually a line. We set K=0, L=1, M=-line, which results in
-// the following implicit:
-//
-//     k^3 - l*m == 0^3 - 1*(-line) == -(-line) == line
-//
-static void calc_line_klm(const SkPoint pts[4], SkMatrix* klm) {
-    SkScalar ny = pts[0].x() - pts[3].x();
-    SkScalar nx = pts[3].y() - pts[0].y();
-    SkScalar k = nx * pts[0].x() + ny * pts[0].y();
-    klm->setAll(  0,   0, 0,
-                  0,   0, 1,
-                -nx, -ny, k);
-}
-
-SkCubicType GrPathUtils::getCubicKLM(const SkPoint src[4], SkMatrix* klm, double tt[2],
-                                     double ss[2]) {
-    double d[4];
-    SkCubicType type = SkClassifyCubic(src, tt, ss, d);
-
-    if (SkCubicType::kLineOrPoint == type) {
-        calc_line_klm(src, klm);
-        return SkCubicType::kLineOrPoint;
-    }
-
-    if (SkCubicType::kQuadratic == type) {
-        calc_quadratic_klm(src, d[3], klm);
-        return SkCubicType::kQuadratic;
-    }
-
-    SkMatrix CIT;
-    ExcludedTerm skipTerm = calcCubicInverseTransposePowerBasisMatrix(src, &CIT);
-    if (ExcludedTerm::kNonInvertible == skipTerm) {
-        // This could technically also happen if the curve were quadratic, but SkClassifyCubic
-        // should have detected that case already with tolerance.
-        calc_line_klm(src, klm);
-        return SkCubicType::kLineOrPoint;
-    }
-
-    const SkScalar t0 = static_cast<SkScalar>(tt[0]), t1 = static_cast<SkScalar>(tt[1]),
-                   s0 = static_cast<SkScalar>(ss[0]), s1 = static_cast<SkScalar>(ss[1]);
-
-    SkMatrix klmCoeffs;
-    switch (type) {
-        case SkCubicType::kCuspAtInfinity:
-            SkASSERT(1 == t1 && 0 == s1); // Infinity.
-            [[fallthrough]];
-        case SkCubicType::kLocalCusp:
-        case SkCubicType::kSerpentine:
-            calc_serp_kcoeffs(t0, s0, t1, s1, skipTerm, &klmCoeffs[0]);
-            calc_serp_lmcoeffs(t0, s0, skipTerm, &klmCoeffs[3]);
-            calc_serp_lmcoeffs(t1, s1, skipTerm, &klmCoeffs[6]);
-            break;
-        case SkCubicType::kLoop: {
-            const SkScalar tdse = t0 * s1;
-            const SkScalar tesd = t1 * s0;
-            calc_loop_kcoeffs(t0, s0, t1, s1, tdse, tesd, skipTerm, &klmCoeffs[0]);
-            calc_loop_lmcoeffs(t0, s0, t1, s1, tdse, tesd, skipTerm, &klmCoeffs[3]);
-            calc_loop_lmcoeffs(t1, s1, t0, s0, tesd, tdse, skipTerm, &klmCoeffs[6]);
-            break;
-        }
-        default:
-            SK_ABORT("Unexpected cubic type.");
-            break;
-    }
-
-    klm->setConcat(klmCoeffs, CIT);
-    return type;
-}
-
-int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[10], SkMatrix* klm,
-                                             int* loopIndex) {
-    SkSTArray<2, SkScalar> chops;
-    *loopIndex = -1;
-
-    double t[2], s[2];
-    if (SkCubicType::kLoop == GrPathUtils::getCubicKLM(src, klm, t, s)) {
-        SkScalar t0 = static_cast<SkScalar>(t[0] / s[0]);
-        SkScalar t1 = static_cast<SkScalar>(t[1] / s[1]);
-        SkASSERT(t0 <= t1); // Technically t0 != t1 in a loop, but there may be FP error.
-
-        if (t0 < 1 && t1 > 0) {
-            *loopIndex = 0;
-            if (t0 > 0) {
-                chops.push_back(t0);
-                *loopIndex = 1;
-            }
-            if (t1 < 1) {
-                chops.push_back(t1);
-                *loopIndex = chops.count() - 1;
-            }
-        }
-    }
-
-    SkChopCubicAt(src, dst, chops.begin(), chops.count());
-    return chops.count() + 1;
-}
diff --git a/src/gpu/geometry/GrPathUtils.h b/src/gpu/geometry/GrPathUtils.h
index 48f537d..6c21cdc 100644
--- a/src/gpu/geometry/GrPathUtils.h
+++ b/src/gpu/geometry/GrPathUtils.h
@@ -19,199 +19,110 @@
  *  Utilities for evaluating paths.
  */
 namespace GrPathUtils {
-    // Very small tolerances will be increased to a minimum threshold value, to avoid division
-    // problems in subsequent math.
-    SkScalar scaleToleranceToSrc(SkScalar devTol,
-                                 const SkMatrix& viewM,
-                                 const SkRect& pathBounds);
 
-    int worstCasePointCount(const SkPath&,
-                            int* subpaths,
-                            SkScalar tol);
+// Very small tolerances will be increased to a minimum threshold value, to avoid division problems
+// in subsequent math.
+SkScalar scaleToleranceToSrc(SkScalar devTol,
+                             const SkMatrix& viewM,
+                             const SkRect& pathBounds);
 
-    uint32_t quadraticPointCount(const SkPoint points[], SkScalar tol);
+uint32_t quadraticPointCount(const SkPoint points[], SkScalar tol);
 
-    uint32_t generateQuadraticPoints(const SkPoint& p0,
-                                     const SkPoint& p1,
-                                     const SkPoint& p2,
-                                     SkScalar tolSqd,
-                                     SkPoint** points,
-                                     uint32_t pointsLeft);
-
-    uint32_t cubicPointCount(const SkPoint points[], SkScalar tol);
-
-    uint32_t generateCubicPoints(const SkPoint& p0,
+uint32_t generateQuadraticPoints(const SkPoint& p0,
                                  const SkPoint& p1,
                                  const SkPoint& p2,
-                                 const SkPoint& p3,
                                  SkScalar tolSqd,
                                  SkPoint** points,
                                  uint32_t pointsLeft);
 
-    // A 2x3 matrix that goes from the 2d space coordinates to UV space where
-    // u^2-v = 0 specifies the quad. The matrix is determined by the control
-    // points of the quadratic.
-    class QuadUVMatrix {
-    public:
-        QuadUVMatrix() {}
-        // Initialize the matrix from the control pts
-        QuadUVMatrix(const SkPoint controlPts[3]) { this->set(controlPts); }
-        void set(const SkPoint controlPts[3]);
+uint32_t cubicPointCount(const SkPoint points[], SkScalar tol);
 
-        /**
-         * Applies the matrix to vertex positions to compute UV coords.
-         *
-         * vertices is a pointer to the first vertex.
-         * vertexCount is the number of vertices.
-         * stride is the size of each vertex.
-         * uvOffset is the offset of the UV values within each vertex.
-         */
-        void apply(void* vertices, int vertexCount, size_t stride, size_t uvOffset) const {
-            intptr_t xyPtr = reinterpret_cast<intptr_t>(vertices);
-            intptr_t uvPtr = reinterpret_cast<intptr_t>(vertices) + uvOffset;
-            float sx = fM[0];
-            float kx = fM[1];
-            float tx = fM[2];
-            float ky = fM[3];
-            float sy = fM[4];
-            float ty = fM[5];
-            for (int i = 0; i < vertexCount; ++i) {
-                const SkPoint* xy = reinterpret_cast<const SkPoint*>(xyPtr);
-                SkPoint* uv = reinterpret_cast<SkPoint*>(uvPtr);
-                uv->fX = sx * xy->fX + kx * xy->fY + tx;
-                uv->fY = ky * xy->fX + sy * xy->fY + ty;
-                xyPtr += stride;
-                uvPtr += stride;
-            }
+uint32_t generateCubicPoints(const SkPoint& p0,
+                             const SkPoint& p1,
+                             const SkPoint& p2,
+                             const SkPoint& p3,
+                             SkScalar tolSqd,
+                             SkPoint** points,
+                             uint32_t pointsLeft);
+
+// A 2x3 matrix that goes from the 2d space coordinates to UV space where u^2-v = 0 specifies the
+// quad. The matrix is determined by the control points of the quadratic.
+class QuadUVMatrix {
+public:
+    QuadUVMatrix() {}
+    // Initialize the matrix from the control pts
+    QuadUVMatrix(const SkPoint controlPts[3]) { this->set(controlPts); }
+    void set(const SkPoint controlPts[3]);
+
+    /**
+     * Applies the matrix to vertex positions to compute UV coords.
+     *
+     * vertices is a pointer to the first vertex.
+     * vertexCount is the number of vertices.
+     * stride is the size of each vertex.
+     * uvOffset is the offset of the UV values within each vertex.
+     */
+    void apply(void* vertices, int vertexCount, size_t stride, size_t uvOffset) const {
+        intptr_t xyPtr = reinterpret_cast<intptr_t>(vertices);
+        intptr_t uvPtr = reinterpret_cast<intptr_t>(vertices) + uvOffset;
+        float sx = fM[0];
+        float kx = fM[1];
+        float tx = fM[2];
+        float ky = fM[3];
+        float sy = fM[4];
+        float ty = fM[5];
+        for (int i = 0; i < vertexCount; ++i) {
+            const SkPoint* xy = reinterpret_cast<const SkPoint*>(xyPtr);
+            SkPoint* uv = reinterpret_cast<SkPoint*>(uvPtr);
+            uv->fX = sx * xy->fX + kx * xy->fY + tx;
+            uv->fY = ky * xy->fX + sy * xy->fY + ty;
+            xyPtr += stride;
+            uvPtr += stride;
         }
-    private:
-        float fM[6];
-    };
+    }
+private:
+    float fM[6];
+};
 
-    // Input is 3 control points and a weight for a bezier conic. Calculates the
-    // three linear functionals (K,L,M) that represent the implicit equation of the
-    // conic, k^2 - lm.
-    //
-    // Output: klm holds the linear functionals K,L,M as row vectors:
-    //
-    //     | ..K.. |   | x |      | k |
-    //     | ..L.. | * | y |  ==  | l |
-    //     | ..M.. |   | 1 |      | m |
-    //
-    void getConicKLM(const SkPoint p[3], const SkScalar weight, SkMatrix* klm);
+// Input is 3 control points and a weight for a bezier conic. Calculates the three linear
+// functionals (K,L,M) that represent the implicit equation of the conic, k^2 - lm.
+//
+// Output: klm holds the linear functionals K,L,M as row vectors:
+//
+//     | ..K.. |   | x |      | k |
+//     | ..L.. | * | y |  ==  | l |
+//     | ..M.. |   | 1 |      | m |
+//
+void getConicKLM(const SkPoint p[3], const SkScalar weight, SkMatrix* klm);
 
-    // Converts a cubic into a sequence of quads. If working in device space
-    // use tolScale = 1, otherwise set based on stretchiness of the matrix. The
-    // result is sets of 3 points in quads. This will preserve the starting and
-    // ending tangent vectors (modulo FP precision).
-    void convertCubicToQuads(const SkPoint p[4],
-                             SkScalar tolScale,
-                             SkTArray<SkPoint, true>* quads);
+// Converts a cubic into a sequence of quads. If working in device space use tolScale = 1, otherwise
+// set based on stretchiness of the matrix. The result is sets of 3 points in quads. This will
+// preserve the starting and ending tangent vectors (modulo FP precision).
+void convertCubicToQuads(const SkPoint p[4],
+                         SkScalar tolScale,
+                         SkTArray<SkPoint, true>* quads);
 
-    // When we approximate a cubic {a,b,c,d} with a quadratic we may have to
-    // ensure that the new control point lies between the lines ab and cd. The
-    // convex path renderer requires this. It starts with a path where all the
-    // control points taken together form a convex polygon. It relies on this
-    // property and the quadratic approximation of cubics step cannot alter it.
-    // This variation enforces this constraint. The cubic must be simple and dir
-    // must specify the orientation of the contour containing the cubic.
-    void convertCubicToQuadsConstrainToTangents(const SkPoint p[4],
-                                                SkScalar tolScale,
-                                                SkPathFirstDirection dir,
-                                                SkTArray<SkPoint, true>* quads);
+// When we approximate a cubic {a,b,c,d} with a quadratic we may have to ensure that the new control
+// point lies between the lines ab and cd. The convex path renderer requires this. It starts with a
+// path where all the control points taken together form a convex polygon. It relies on this
+// property and the quadratic approximation of cubics step cannot alter it. This variation enforces
+// this constraint. The cubic must be simple and dir must specify the orientation of the contour
+// containing the cubic.
+void convertCubicToQuadsConstrainToTangents(const SkPoint p[4],
+                                            SkScalar tolScale,
+                                            SkPathFirstDirection dir,
+                                            SkTArray<SkPoint, true>* quads);
 
-    enum class ExcludedTerm {
-        kNonInvertible,
-        kQuadraticTerm,
-        kLinearTerm
-    };
+// When tessellating curved paths into linear segments, this defines the maximum distance in screen
+// space which a segment may deviate from the mathematically correct value. Above this value, the
+// segment will be subdivided.
+// This value was chosen to approximate the supersampling accuracy of the raster path (16 samples,
+// or one quarter pixel).
+static const SkScalar kDefaultTolerance = SkDoubleToScalar(0.25);
 
-    // Computes the inverse-transpose of the cubic's power basis matrix, after removing a specific
-    // row of coefficients.
-    //
-    // E.g. if the cubic is defined in power basis form as follows:
-    //
-    //                                         | x3   y3   0 |
-    //     C(t,s) = [t^3  t^2*s  t*s^2  s^3] * | x2   y2   0 |
-    //                                         | x1   y1   0 |
-    //                                         | x0   y0   1 |
-    //
-    // And the excluded term is "kQuadraticTerm", then the resulting inverse-transpose will be:
-    //
-    //     | x3   y3   0 | -1 T
-    //     | x1   y1   0 |
-    //     | x0   y0   1 |
-    //
-    // (The term to exclude is chosen based on maximizing the resulting matrix determinant.)
-    //
-    // This can be used to find the KLM linear functionals:
-    //
-    //     | ..K.. |   | ..kcoeffs.. |
-    //     | ..L.. | = | ..lcoeffs.. | * inverse_transpose_power_basis_matrix
-    //     | ..M.. |   | ..mcoeffs.. |
-    //
-    // NOTE: the same term that was excluded here must also be removed from the corresponding column
-    // of the klmcoeffs matrix.
-    //
-    // Returns which row of coefficients was removed, or kNonInvertible if the cubic was degenerate.
-    ExcludedTerm calcCubicInverseTransposePowerBasisMatrix(const SkPoint p[4], SkMatrix* out);
+// We guarantee that no quad or cubic will ever produce more than this many points
+static const int kMaxPointsPerCurve = 1 << 10;
 
-    // Computes the KLM linear functionals for the cubic implicit form. The "right" side of the
-    // curve (when facing in the direction of increasing parameter values) will be the area that
-    // satisfies:
-    //
-    //     k^3 < l*m
-    //
-    // Output:
-    //
-    // klm: Holds the linear functionals K,L,M as row vectors:
-    //
-    //          | ..K.. |   | x |      | k |
-    //          | ..L.. | * | y |  ==  | l |
-    //          | ..M.. |   | 1 |      | m |
-    //
-    // NOTE: the KLM lines are calculated in the same space as the input control points. If you
-    // transform the points the lines will also need to be transformed. This can be done by mapping
-    // the lines with the inverse-transpose of the matrix used to map the points.
-    //
-    // t[],s[]: These are set to the two homogeneous parameter values at which points the lines L&M
-    // intersect with K (See SkClassifyCubic).
-    //
-    // Returns the cubic's classification.
-    SkCubicType getCubicKLM(const SkPoint src[4], SkMatrix* klm, double t[2], double s[2]);
-
-    // Chops the cubic bezier passed in by src, at the double point (intersection point)
-    // if the curve is a cubic loop. If it is a loop, there will be two parametric values for
-    // the double point: t1 and t2. We chop the cubic at these values if they are between 0 and 1.
-    // Return value:
-    // Value of 3: t1 and t2 are both between (0,1), and dst will contain the three cubics,
-    //             dst[0..3], dst[3..6], and dst[6..9] if dst is not nullptr
-    // Value of 2: Only one of t1 and t2 are between (0,1), and dst will contain the two cubics,
-    //             dst[0..3] and dst[3..6] if dst is not nullptr
-    // Value of 1: Neither t1 nor t2 are between (0,1), and dst will contain the one original cubic,
-    //             src[0..3]
-    //
-    // Output:
-    //
-    // klm: Holds the linear functionals K,L,M as row vectors. (See getCubicKLM().)
-    //
-    // loopIndex: This value will tell the caller which of the chopped sections (if any) are the
-    //            actual loop. A value of -1 means there is no loop section. The caller can then use
-    //            this value to decide how/if they want to flip the orientation of this section.
-    //            The flip should be done by negating the k and l values as follows:
-    //
-    //            KLM.postScale(-1, -1)
-    int chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[10], SkMatrix* klm,
-                                    int* loopIndex);
-
-    // When tessellating curved paths into linear segments, this defines the maximum distance
-    // in screen space which a segment may deviate from the mathmatically correct value.
-    // Above this value, the segment will be subdivided.
-    // This value was chosen to approximate the supersampling accuracy of the raster path (16
-    // samples, or one quarter pixel).
-    static const SkScalar kDefaultTolerance = SkDoubleToScalar(0.25);
-
-    // We guarantee that no quad or cubic will ever produce more than this many points
-    static const int kMaxPointsPerCurve = 1 << 10;
 }  // namespace GrPathUtils
+
 #endif
