Revert "ccpr: Tessellate fans for very large and/or simple paths"

This reverts commit 4138c972effe4eb0227fbb96571df290f3d1979b.

Reason for revert: broke android flutter build

Original change's description:
> ccpr: Tessellate fans for very large and/or simple paths
> 
> This increases CPU work, but reduces overdraw on the GPU as compared to
> Redbook fanning.
> 
> Bug: skia:
> Change-Id: I47239c964261e0014a94266a71223eab0597bfb8
> Reviewed-on: https://skia-review.googlesource.com/105203
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Chris Dalton <csmartdalton@google.com>

TBR=bsalomon@google.com,csmartdalton@google.com

Change-Id: I98b5c10b97c3fa603de5122d9bb47ca07659242c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/106620
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.cpp b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
index 2c3166d..c875625 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
@@ -66,11 +66,8 @@
 
 void GrCCCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&,
                                                 GrProcessorKeyBuilder* b) const {
-    int key = (int)fRenderPass << 2;
-    if (WindMethod::kInstanceData == fWindMethod) {
-        key |= 2;
-    }
-    if (Impl::kVertexShader == fImpl) {
+    int key = (int)fRenderPass << 1;
+    if (Impl::kGeometryShader == fImpl) {
         key |= 1;
     }
 #ifdef SK_DEBUG
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.h b/src/gpu/ccpr/GrCCCoverageProcessor.h
index e6adfff..1296e08 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.h
@@ -33,9 +33,8 @@
  */
 class GrCCCoverageProcessor : public GrGeometryProcessor {
 public:
-    // Defines a single primitive shape with 3 input points (i.e. Triangles and Quadratics).
-    // X,Y point values are transposed.
-    struct TriPointInstance {
+    // Defines a single triangle or closed quadratic bezier, with transposed x,y point values.
+    struct TriangleInstance {
         float fX[3];
         float fY[3];
 
@@ -43,15 +42,12 @@
         void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans);
     };
 
-    // Defines a single primitive shape with 4 input points, or 3 input points plus a W parameter
-    // duplicated in both 4th components (i.e. Cubics or Triangles with a custom winding number).
-    // X,Y point values are transposed.
-    struct QuadPointInstance {
+    // Defines a single closed cubic bezier, with transposed x,y point values.
+    struct CubicInstance {
         float fX[4];
         float fY[4];
 
         void set(const SkPoint[4], float dx, float dy);
-        void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans, float w);
     };
 
     // All primitive shapes (triangles and closed, convex bezier curves) require more than one
@@ -97,29 +93,24 @@
                caps.shaderCaps()->geometryShaderSupport();
     }
 
-    enum class WindMethod : bool {
-        kCrossProduct, // Calculate wind = +/-1 by sign of the cross product.
-        kInstanceData // Instance data provides custom, signed wind values of any magnitude.
-                      // (For tightly-wound tessellated triangles.)
-    };
-
-    GrCCCoverageProcessor(GrResourceProvider* rp, RenderPass pass, WindMethod windMethod)
+    GrCCCoverageProcessor(GrResourceProvider* rp, RenderPass pass, const GrCaps& caps)
             : INHERITED(kGrCCCoverageProcessor_ClassID)
             , fRenderPass(pass)
-            , fWindMethod(windMethod)
-            , fImpl(rp->caps()->shaderCaps()->geometryShaderSupport() ? Impl::kGeometryShader
-                                                                      : Impl::kVertexShader) {
-        SkASSERT(DoesRenderPass(pass, *rp->caps()));
+            , fImpl(caps.shaderCaps()->geometryShaderSupport() ? Impl::kGeometryShader
+                                                               : Impl::kVertexShader) {
+        SkASSERT(DoesRenderPass(pass, caps));
         if (Impl::kGeometryShader == fImpl) {
             this->initGS();
         } else {
-            this->initVS(rp);
+            this->initVS(rp, caps);
         }
     }
 
     // Appends a GrMesh that will draw the provided instances. The instanceBuffer must be an array
-    // of either TriPointInstance or QuadPointInstance, depending on this processor's RendererPass,
-    // with coordinates in the desired shape's final atlas-space position.
+    // of either TriangleInstance or CubicInstance, depending on this processor's RendererPass, with
+    // coordinates in the desired shape's final atlas-space position.
+    //
+    // NOTE: Quadratics use TriangleInstance since both have 3 points.
     void appendMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
                     SkTArray<GrMesh>* out) {
         if (Impl::kGeometryShader == fImpl) {
@@ -236,7 +227,7 @@
     };
 
     void initGS();
-    void initVS(GrResourceProvider*);
+    void initVS(GrResourceProvider*, const GrCaps&);
 
     void appendGSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
                       SkTArray<GrMesh>* out) const;
@@ -247,7 +238,6 @@
     GrGLSLPrimitiveProcessor* createVSImpl(std::unique_ptr<Shader>) const;
 
     const RenderPass fRenderPass;
-    const WindMethod fWindMethod;
     const Impl fImpl;
     SkDEBUGCODE(float fDebugBloat = 0);
 
@@ -260,11 +250,11 @@
     typedef GrGeometryProcessor INHERITED;
 };
 
-inline void GrCCCoverageProcessor::TriPointInstance::set(const SkPoint p[3], const Sk2f& trans) {
+inline void GrCCCoverageProcessor::TriangleInstance::set(const SkPoint p[3], const Sk2f& trans) {
     this->set(p[0], p[1], p[2], trans);
 }
 
-inline void GrCCCoverageProcessor::TriPointInstance::set(const SkPoint& p0, const SkPoint& p1,
+inline void GrCCCoverageProcessor::TriangleInstance::set(const SkPoint& p0, const SkPoint& p1,
                                                          const SkPoint& p2, const Sk2f& trans) {
     Sk2f P0 = Sk2f::Load(&p0) + trans;
     Sk2f P1 = Sk2f::Load(&p1) + trans;
@@ -272,23 +262,13 @@
     Sk2f::Store3(this, P0, P1, P2);
 }
 
-inline void GrCCCoverageProcessor::QuadPointInstance::set(const SkPoint p[4], float dx, float dy) {
+inline void GrCCCoverageProcessor::CubicInstance::set(const SkPoint p[4], float dx, float dy) {
     Sk4f X,Y;
     Sk4f::Load2(p, &X, &Y);
     (X + dx).store(&fX);
     (Y + dy).store(&fY);
 }
 
-inline void GrCCCoverageProcessor::QuadPointInstance::set(const SkPoint& p0, const SkPoint& p1,
-                                                          const SkPoint& p2, const Sk2f& trans,
-                                                          float w) {
-    Sk2f P0 = Sk2f::Load(&p0) + trans;
-    Sk2f P1 = Sk2f::Load(&p1) + trans;
-    Sk2f P2 = Sk2f::Load(&p2) + trans;
-    Sk2f W = Sk2f(w);
-    Sk2f::Store4(this, P0, P1, P2, W);
-}
-
 inline bool GrCCCoverageProcessor::RenderPassIsCubic(RenderPass pass) {
     switch (pass) {
         case RenderPass::kTriangleHulls:
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
index 224533b..0754389 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
@@ -31,7 +31,7 @@
 
         // The vertex shader simply forwards transposed x or y values to the geometry shader.
         SkASSERT(1 == proc.numAttribs());
-        gpArgs->fPositionVar.set(GrVertexAttribTypeToSLType(proc.getAttrib(0).fType),
+        gpArgs->fPositionVar.set(4 == proc.numInputPoints() ? kFloat4_GrSLType : kFloat3_GrSLType,
                                  proc.getAttrib(0).fName);
 
         // Geometry shader.
@@ -57,20 +57,11 @@
 
         GrShaderVar wind("wind", kHalf_GrSLType);
         g->declareGlobal(wind);
-        if (WindMethod::kCrossProduct == proc.fWindMethod) {
-            g->codeAppend ("float area_x2 = determinant(float2x2(pts[0] - pts[1], "
-                                                                "pts[0] - pts[2]));");
-            if (4 == numInputPoints) {
-                g->codeAppend ("area_x2 += determinant(float2x2(pts[0] - pts[2], "
-                                                               "pts[0] - pts[3]));");
-            }
-            g->codeAppendf("%s = sign(area_x2);", wind.c_str());
-        } else {
-            SkASSERT(WindMethod::kInstanceData == proc.fWindMethod);
-            SkASSERT(3 == numInputPoints);
-            SkASSERT(kFloat4_GrVertexAttribType == proc.getAttrib(0).fType);
-            g->codeAppendf("%s = sk_in[0].sk_Position.w;", wind.c_str());
+        g->codeAppend ("float area_x2 = determinant(float2x2(pts[0] - pts[1], pts[0] - pts[2]));");
+        if (4 == numInputPoints) {
+            g->codeAppend ("area_x2 += determinant(float2x2(pts[0] - pts[2], pts[0] - pts[3]));");
         }
+        g->codeAppendf("%s = sign(area_x2);", wind.c_str());
 
         SkString emitVertexFn;
         SkSTArray<2, GrShaderVar> emitArgs;
@@ -331,17 +322,12 @@
 
 void GrCCCoverageProcessor::initGS() {
     SkASSERT(Impl::kGeometryShader == fImpl);
-    if (RenderPassIsCubic(fRenderPass) || WindMethod::kInstanceData == fWindMethod) {
-        SkASSERT(WindMethod::kCrossProduct == fWindMethod || 3 == this->numInputPoints());
-        this->addVertexAttrib("x_or_y_values", kFloat4_GrVertexAttribType);
-        SkASSERT(sizeof(QuadPointInstance) == this->getVertexStride() * 2);
-        SkASSERT(offsetof(QuadPointInstance, fY) == this->getVertexStride());
-        GR_STATIC_ASSERT(0 == offsetof(QuadPointInstance, fX));
+    if (RenderPassIsCubic(fRenderPass)) {
+        this->addVertexAttrib("x_or_y_values", kFloat4_GrVertexAttribType); // (See appendMesh.)
+        SkASSERT(sizeof(CubicInstance) == this->getVertexStride() * 2);
     } else {
-        this->addVertexAttrib("x_or_y_values", kFloat3_GrVertexAttribType);
-        SkASSERT(sizeof(TriPointInstance) == this->getVertexStride() * 2);
-        SkASSERT(offsetof(TriPointInstance, fY) == this->getVertexStride());
-        GR_STATIC_ASSERT(0 == offsetof(TriPointInstance, fX));
+        this->addVertexAttrib("x_or_y_values", kFloat3_GrVertexAttribType); // (See appendMesh.)
+        SkASSERT(sizeof(TriangleInstance) == this->getVertexStride() * 2);
     }
     this->setWillUseGeoShader();
 }
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp
index 4ac6443..8f2884a 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp
@@ -35,25 +35,15 @@
         GrGLSLVertexBuilder* v = args.fVertBuilder;
         int numInputPoints = proc.numInputPoints();
 
-        const char* swizzle = (4 == numInputPoints) ? "xyzw" : "xyz";
-        v->codeAppendf("float%ix2 pts = transpose(float2x%i(%s.%s, %s.%s));",
-                       numInputPoints, numInputPoints, proc.getAttrib(kAttribIdx_X).fName, swizzle,
-                       proc.getAttrib(kAttribIdx_Y).fName, swizzle);
+        v->codeAppendf("float%ix2 pts = transpose(float2x%i(%s, %s));",
+                       numInputPoints, numInputPoints, proc.getAttrib(kAttribIdx_X).fName,
+                       proc.getAttrib(kAttribIdx_Y).fName);
 
-        if (WindMethod::kCrossProduct == proc.fWindMethod) {
-            v->codeAppend ("float area_x2 = determinant(float2x2(pts[0] - pts[1], "
-                                                                "pts[0] - pts[2]));");
-            if (4 == numInputPoints) {
-                v->codeAppend ("area_x2 += determinant(float2x2(pts[0] - pts[2], "
-                                                               "pts[0] - pts[3]));");
-            }
-            v->codeAppend ("half wind = sign(area_x2);");
-        } else {
-            SkASSERT(WindMethod::kInstanceData == proc.fWindMethod);
-            SkASSERT(3 == numInputPoints);
-            SkASSERT(kFloat4_GrVertexAttribType == proc.getAttrib(kAttribIdx_X).fType);
-            v->codeAppendf("half wind = %s.w;", proc.getAttrib(kAttribIdx_X).fName);
+        v->codeAppend ("float area_x2 = determinant(float2x2(pts[0] - pts[1], pts[0] - pts[2]));");
+        if (4 == numInputPoints) {
+            v->codeAppend ("area_x2 += determinant(float2x2(pts[0] - pts[2], pts[0] - pts[3]));");
         }
+        v->codeAppend ("half wind = sign(area_x2);");
 
         float bloat = kAABloatRadius;
 #ifdef SK_DEBUG
@@ -350,9 +340,17 @@
     }
 };
 
-void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) {
+void GrCCCoverageProcessor::initVS(GrResourceProvider* rp, const GrCaps& caps) {
     SkASSERT(Impl::kVertexShader == fImpl);
-    const GrCaps& caps = *rp->caps();
+
+    GrVertexAttribType inputPtsType = RenderPassIsCubic(fRenderPass) ?
+                                      kFloat4_GrVertexAttribType : kFloat3_GrVertexAttribType;
+
+    SkASSERT(kAttribIdx_X == this->numAttribs());
+    this->addInstanceAttrib("X", inputPtsType);
+
+    SkASSERT(kAttribIdx_Y == this->numAttribs());
+    this->addInstanceAttrib("Y", inputPtsType);
 
     switch (fRenderPass) {
         case RenderPass::kTriangleHulls: {
@@ -375,6 +373,8 @@
                                                           gHull3AndEdgeIndexBufferKey);
                 fNumIndicesPerInstance = SK_ARRAY_COUNT(kHull3AndEdgeIndicesAsTris);
             }
+            SkASSERT(kAttribIdx_VertexData == this->numAttribs());
+            this->addVertexAttrib("vertexdata", kInt_GrVertexAttribType);
             break;
         }
         case RenderPass::kQuadraticHulls:
@@ -396,6 +396,8 @@
                                                           gHull4IndexBufferKey);
                 fNumIndicesPerInstance = SK_ARRAY_COUNT(kHull4IndicesAsTris);
             }
+            SkASSERT(kAttribIdx_VertexData == this->numAttribs());
+            this->addVertexAttrib("vertexdata", kInt_GrVertexAttribType);
             break;
         }
         case RenderPass::kTriangleEdges:
@@ -425,36 +427,20 @@
         }
     }
 
-    if (RenderPassIsCubic(fRenderPass) || WindMethod::kInstanceData == fWindMethod) {
-        SkASSERT(WindMethod::kCrossProduct == fWindMethod || 3 == this->numInputPoints());
-
-        SkASSERT(kAttribIdx_X == this->numAttribs());
-        this->addInstanceAttrib("X", kFloat4_GrVertexAttribType);
-
-        SkASSERT(kAttribIdx_Y == this->numAttribs());
-        this->addInstanceAttrib("Y", kFloat4_GrVertexAttribType);
-
-        SkASSERT(offsetof(QuadPointInstance, fX) == this->getAttrib(kAttribIdx_X).fOffsetInRecord);
-        SkASSERT(offsetof(QuadPointInstance, fY) == this->getAttrib(kAttribIdx_Y).fOffsetInRecord);
-        SkASSERT(sizeof(QuadPointInstance) == this->getInstanceStride());
+#ifdef SK_DEBUG
+    if (RenderPassIsCubic(fRenderPass)) {
+        SkASSERT(offsetof(CubicInstance, fX) == this->getAttrib(kAttribIdx_X).fOffsetInRecord);
+        SkASSERT(offsetof(CubicInstance, fY) == this->getAttrib(kAttribIdx_Y).fOffsetInRecord);
+        SkASSERT(sizeof(CubicInstance) == this->getInstanceStride());
     } else {
-        SkASSERT(kAttribIdx_X == this->numAttribs());
-        this->addInstanceAttrib("X", kFloat3_GrVertexAttribType);
-
-        SkASSERT(kAttribIdx_Y == this->numAttribs());
-        this->addInstanceAttrib("Y", kFloat3_GrVertexAttribType);
-
-        SkASSERT(offsetof(TriPointInstance, fX) == this->getAttrib(kAttribIdx_X).fOffsetInRecord);
-        SkASSERT(offsetof(TriPointInstance, fY) == this->getAttrib(kAttribIdx_Y).fOffsetInRecord);
-        SkASSERT(sizeof(TriPointInstance) == this->getInstanceStride());
+        SkASSERT(offsetof(TriangleInstance, fX) == this->getAttrib(kAttribIdx_X).fOffsetInRecord);
+        SkASSERT(offsetof(TriangleInstance, fY) == this->getAttrib(kAttribIdx_Y).fOffsetInRecord);
+        SkASSERT(sizeof(TriangleInstance) == this->getInstanceStride());
     }
-
     if (fVertexBuffer) {
-        SkASSERT(kAttribIdx_VertexData == this->numAttribs());
-        this->addVertexAttrib("vertexdata", kInt_GrVertexAttribType);
-
         SkASSERT(sizeof(int32_t) == this->getVertexStride());
     }
+#endif
 
     if (caps.usePrimitiveRestart()) {
         this->setWillUsePrimitiveRestart();
diff --git a/src/gpu/ccpr/GrCCGeometry.cpp b/src/gpu/ccpr/GrCCGeometry.cpp
index 481f4e4..19bc874 100644
--- a/src/gpu/ccpr/GrCCGeometry.cpp
+++ b/src/gpu/ccpr/GrCCGeometry.cpp
@@ -30,7 +30,7 @@
 
     // Store the current verb count in the fTriangles field for now. When we close the contour we
     // will use this value to calculate the actual number of triangles in its fan.
-    fCurrContourTallies = {fVerbs.count(), 0, 0, 0};
+    fCurrContourTallies = {fVerbs.count(), 0, 0};
 
     fPoints.push_back(devPt);
     fVerbs.push_back(Verb::kBeginContour);
diff --git a/src/gpu/ccpr/GrCCGeometry.h b/src/gpu/ccpr/GrCCGeometry.h
index 47b57c1..b50dd01 100644
--- a/src/gpu/ccpr/GrCCGeometry.h
+++ b/src/gpu/ccpr/GrCCGeometry.h
@@ -35,10 +35,9 @@
         kEndOpenContour // endPt != startPt.
     };
 
-    // These tallies track numbers of CCPR primitives that are required to draw a contour.
+    // These tallies track numbers of CCPR primitives are required to draw a contour.
     struct PrimitiveTallies {
         int fTriangles; // Number of triangles in the contour's fan.
-        int fWoundTriangles; // Triangles (from the tessellator) whose winding magnitude > 1.
         int fQuadratics;
         int fCubics;
 
@@ -116,11 +115,11 @@
                                   int maxSubdivisions = kMaxSubdivionsPerCubicSection);
 
     // Transient state used while building a contour.
-    SkPoint fCurrAnchorPoint;
-    SkPoint fCurrFanPoint;
-    PrimitiveTallies fCurrContourTallies;
-    SkCubicType fCurrCubicType;
-    SkDEBUGCODE(bool fBuildingContour = false);
+    SkPoint                         fCurrAnchorPoint;
+    SkPoint                         fCurrFanPoint;
+    PrimitiveTallies                fCurrContourTallies;
+    SkCubicType                     fCurrCubicType;
+    SkDEBUGCODE(bool                fBuildingContour = false);
 
     // TODO: These points could eventually be written directly to block-allocated GPU buffers.
     SkSTArray<128, SkPoint, true>   fPoints;
@@ -129,7 +128,6 @@
 
 inline void GrCCGeometry::PrimitiveTallies::operator+=(const PrimitiveTallies& b) {
     fTriangles += b.fTriangles;
-    fWoundTriangles += b.fWoundTriangles;
     fQuadratics += b.fQuadratics;
     fCubics += b.fCubics;
 }
@@ -137,14 +135,12 @@
 GrCCGeometry::PrimitiveTallies
 inline GrCCGeometry::PrimitiveTallies::operator-(const PrimitiveTallies& b) const {
     return {fTriangles - b.fTriangles,
-            fWoundTriangles - b.fWoundTriangles,
             fQuadratics - b.fQuadratics,
             fCubics - b.fCubics};
 }
 
 inline bool GrCCGeometry::PrimitiveTallies::operator==(const PrimitiveTallies& b) {
-    return fTriangles == b.fTriangles && fWoundTriangles == b.fWoundTriangles &&
-           fQuadratics == b.fQuadratics && fCubics == b.fCubics;
+    return fTriangles == b.fTriangles && fQuadratics == b.fQuadratics && fCubics == b.fCubics;
 }
 
 #endif
diff --git a/src/gpu/ccpr/GrCCPathParser.cpp b/src/gpu/ccpr/GrCCPathParser.cpp
index f729290..2a632d3 100644
--- a/src/gpu/ccpr/GrCCPathParser.cpp
+++ b/src/gpu/ccpr/GrCCPathParser.cpp
@@ -17,8 +17,8 @@
 #include "SkPoint.h"
 #include "ccpr/GrCCGeometry.h"
 
-using TriPointInstance = GrCCCoverageProcessor::TriPointInstance;
-using QuadPointInstance = GrCCCoverageProcessor::QuadPointInstance;
+using TriangleInstance = GrCCCoverageProcessor::TriangleInstance;
+using CubicInstance = GrCCCoverageProcessor::CubicInstance;
 
 GrCCPathParser::GrCCPathParser(int maxTotalPaths, int maxPathPoints, int numSkPoints,
                                int numSkVerbs)
@@ -32,8 +32,7 @@
     // that "end" at the beginning of the data. These will not be drawn, but will only be be read by
     // the first actual batch.
     fScissorSubBatches.push_back() = {PrimitiveTallies(), SkIRect::MakeEmpty()};
-    fCoverageCountBatches.push_back() = {PrimitiveTallies(), fScissorSubBatches.count(),
-                                         PrimitiveTallies()};
+    fCoverageCountBatches.push_back() = {PrimitiveTallies(), fScissorSubBatches.count()};
 }
 
 void GrCCPathParser::parsePath(const SkMatrix& m, const SkPath& path, SkRect* devBounds,
@@ -106,7 +105,6 @@
     fCurrPathPointsIdx = fGeometry.points().count();
     fCurrPathVerbsIdx = fGeometry.verbs().count();
     fCurrPathPrimitiveCounts = PrimitiveTallies();
-    fCurrPathFillType = path.getFillType();
 
     fGeometry.beginPath();
 
@@ -162,81 +160,7 @@
                                     int16_t atlasOffsetX, int16_t atlasOffsetY) {
     SkASSERT(fParsingPath);
 
-    fPathsInfo.emplace_back(scissorMode, atlasOffsetX, atlasOffsetY);
-
-    // Tessellate fans from very large and/or simple paths, in order to reduce overdraw.
-    int numVerbs = fGeometry.verbs().count() - fCurrPathVerbsIdx - 1;
-    int64_t tessellationWork = (int64_t)numVerbs * (32 - SkCLZ(numVerbs)); // N log N.
-    int64_t fanningWork = (int64_t)clippedDevIBounds.height() * clippedDevIBounds.width();
-    if (tessellationWork * (50*50) + (100*100) < fanningWork) { // Don't tessellate under 100x100.
-        fCurrPathPrimitiveCounts.fTriangles =
-                fCurrPathPrimitiveCounts.fWoundTriangles = 0;
-
-        const SkTArray<GrCCGeometry::Verb, true>& verbs = fGeometry.verbs();
-        const SkTArray<SkPoint, true>& pts = fGeometry.points();
-        int ptsIdx = fCurrPathPointsIdx;
-
-        // Build an SkPath of the Redbook fan.
-        SkPath fan;
-        fan.setFillType(fCurrPathFillType);
-        SkASSERT(GrCCGeometry::Verb::kBeginPath == verbs[fCurrPathVerbsIdx]);
-        for (int i = fCurrPathVerbsIdx + 1; i < fGeometry.verbs().count(); ++i) {
-            switch (verbs[i]) {
-                case GrCCGeometry::Verb::kBeginPath:
-                    SK_ABORT("Invalid GrCCGeometry");
-                    continue;
-
-                case GrCCGeometry::Verb::kBeginContour:
-                    fan.moveTo(pts[ptsIdx++]);
-                    continue;
-
-                case GrCCGeometry::Verb::kLineTo:
-                    fan.lineTo(pts[ptsIdx++]);
-                    continue;
-
-                case GrCCGeometry::Verb::kMonotonicQuadraticTo:
-                    fan.lineTo(pts[ptsIdx + 1]);
-                    ptsIdx += 2;
-                    continue;
-
-                case GrCCGeometry::Verb::kMonotonicCubicTo:
-                    fan.lineTo(pts[ptsIdx + 2]);
-                    ptsIdx += 3;
-                    continue;
-
-                case GrCCGeometry::Verb::kEndClosedContour:
-                case GrCCGeometry::Verb::kEndOpenContour:
-                    fan.close();
-                    continue;
-            }
-        }
-        GrTessellator::WindingVertex* vertices = nullptr;
-        int count = GrTessellator::PathToVertices(fan, std::numeric_limits<float>::infinity(),
-                                                  SkRect::Make(clippedDevIBounds), &vertices);
-        SkASSERT(0 == count % 3);
-        for (int i = 0; i < count; i += 3) {
-            SkASSERT(vertices[i].fWinding == vertices[i + 1].fWinding);
-            SkASSERT(vertices[i].fWinding == vertices[i + 2].fWinding);
-            if (1 == abs(vertices[i].fWinding)) {
-                // Ensure this triangle's points actually wind in the same direction as fWinding.
-                float ax = vertices[i].fPos.fX - vertices[i + 1].fPos.fX;
-                float ay = vertices[i].fPos.fY - vertices[i + 1].fPos.fY;
-                float bx = vertices[i].fPos.fX - vertices[i + 2].fPos.fX;
-                float by = vertices[i].fPos.fY - vertices[i + 2].fPos.fY;
-                float wind = ay*bx - ax*by;
-                if ((wind > 0) != (vertices[i].fWinding > 0)) {
-                    std::swap(vertices[i + 1].fPos, vertices[i + 2].fPos);
-                }
-                ++fCurrPathPrimitiveCounts.fTriangles;
-            } else {
-                ++fCurrPathPrimitiveCounts.fWoundTriangles;
-            }
-        }
-
-        fPathsInfo.back().fFanTessellation.reset(vertices);
-        fPathsInfo.back().fFanTessellationCount = count;
-    }
-
+    fPathsInfo.push_back() = {scissorMode, atlasOffsetX, atlasOffsetY};
     fTotalPrimitiveCounts[(int)scissorMode] += fCurrPathPrimitiveCounts;
 
     if (ScissorMode::kScissored == scissorMode) {
@@ -256,23 +180,15 @@
 GrCCPathParser::CoverageCountBatchID GrCCPathParser::closeCurrentBatch() {
     SkASSERT(!fInstanceBuffer);
     SkASSERT(!fCoverageCountBatches.empty());
-    const auto& lastBatch = fCoverageCountBatches.back();
-    const auto& lastScissorSubBatch = fScissorSubBatches[lastBatch.fEndScissorSubBatchIdx - 1];
 
-    PrimitiveTallies batchTotalCounts = fTotalPrimitiveCounts[(int)ScissorMode::kNonScissored] -
-                                        lastBatch.fEndNonScissorIndices;
-    batchTotalCounts += fTotalPrimitiveCounts[(int)ScissorMode::kScissored] -
-                        lastScissorSubBatch.fEndPrimitiveIndices;
+    int maxMeshes = 1 + fScissorSubBatches.count() -
+                        fCoverageCountBatches.back().fEndScissorSubBatchIdx;
+    fMaxMeshesPerDraw = SkTMax(fMaxMeshesPerDraw, maxMeshes);
 
     fCoverageCountBatches.push_back() = {
         fTotalPrimitiveCounts[(int)ScissorMode::kNonScissored],
-        fScissorSubBatches.count(),
-        batchTotalCounts
+        fScissorSubBatches.count()
     };
-
-    int maxMeshes = 1 + fScissorSubBatches.count() - lastBatch.fEndScissorSubBatchIdx;
-    fMaxMeshesPerDraw = SkTMax(fMaxMeshesPerDraw, maxMeshes);
-
     return fCoverageCountBatches.count() - 1;
 }
 
@@ -289,10 +205,10 @@
 // elements past the end for this method to use as scratch space.
 //
 // Returns the next triangle instance after the final one emitted.
-static TriPointInstance* emit_recursive_fan(const SkTArray<SkPoint, true>& pts,
+static TriangleInstance* emit_recursive_fan(const SkTArray<SkPoint, true>& pts,
                                             SkTArray<int32_t, true>& indices, int firstIndex,
                                             int indexCount, const Sk2f& atlasOffset,
-                                            TriPointInstance out[]) {
+                                            TriangleInstance out[]) {
     if (indexCount < 3) {
         return out;
     }
@@ -316,22 +232,6 @@
     return out;
 }
 
-static void emit_tessellated_fan(const GrTessellator::WindingVertex* vertices, int numVertices,
-                                 const Sk2f& atlasOffset, TriPointInstance* triPointInstanceData,
-                                 QuadPointInstance* quadPointInstanceData,
-                                 GrCCGeometry::PrimitiveTallies* indices) {
-    for (int i = 0; i < numVertices; i += 3) {
-        if (1 == abs(vertices[i].fWinding)) {
-            triPointInstanceData[indices->fTriangles++].set(vertices[i].fPos, vertices[i + 1].fPos,
-                                                            vertices[i + 2].fPos, atlasOffset);
-        } else {
-            quadPointInstanceData[indices->fWoundTriangles++].set(
-                    vertices[i].fPos, vertices[i+1].fPos, vertices[i + 2].fPos, atlasOffset,
-                    static_cast<float>(vertices[i].fWinding));
-        }
-    }
-}
-
 bool GrCCPathParser::finalize(GrOnFlushResourceProvider* onFlushRP) {
     SkASSERT(!fParsingPath); // Call saveParsedPath() or discardParsedPath().
     SkASSERT(fCoverageCountBatches.back().fEndNonScissorIndices == // Call closeCurrentBatch().
@@ -350,7 +250,7 @@
     //
     // We already know how big to make each of the 6 arrays from fTotalPrimitiveCounts, so layout is
     // straightforward. Start with triangles and quadratics. They both view the instance buffer as
-    // an array of TriPointInstance[], so we can begin at zero and lay them out one after the other.
+    // an array of TriangleInstance[], so we can begin at zero and lay them out one after the other.
     fBaseInstances[0].fTriangles = 0;
     fBaseInstances[1].fTriangles = fBaseInstances[0].fTriangles +
                                    fTotalPrimitiveCounts[0].fTriangles;
@@ -360,112 +260,85 @@
                                     fTotalPrimitiveCounts[0].fQuadratics;
     int triEndIdx = fBaseInstances[1].fQuadratics + fTotalPrimitiveCounts[1].fQuadratics;
 
-    // Wound triangles and cubics both view the same instance buffer as an array of
-    // QuadPointInstance[]. So, reinterpreting the instance data as QuadPointInstance[], we start
-    // them on the first index that will not overwrite previous TriPointInstance data.
-    int quadBaseIdx =
-            GR_CT_DIV_ROUND_UP(triEndIdx * sizeof(TriPointInstance), sizeof(QuadPointInstance));
-    fBaseInstances[0].fWoundTriangles = quadBaseIdx;
-    fBaseInstances[1].fWoundTriangles = fBaseInstances[0].fWoundTriangles +
-                                        fTotalPrimitiveCounts[0].fWoundTriangles;
-    fBaseInstances[0].fCubics = fBaseInstances[1].fWoundTriangles +
-                                fTotalPrimitiveCounts[1].fWoundTriangles;
+    // Cubics view the same instance buffer as an array of CubicInstance[]. So, reinterpreting the
+    // instance data as CubicInstance[], we start them on the first index that will not overwrite
+    // previous TriangleInstance data.
+    int cubicBaseIdx =
+            GR_CT_DIV_ROUND_UP(triEndIdx * sizeof(TriangleInstance), sizeof(CubicInstance));
+    fBaseInstances[0].fCubics = cubicBaseIdx;
     fBaseInstances[1].fCubics = fBaseInstances[0].fCubics + fTotalPrimitiveCounts[0].fCubics;
-    int quadEndIdx = fBaseInstances[1].fCubics + fTotalPrimitiveCounts[1].fCubics;
+    int cubicEndIdx = fBaseInstances[1].fCubics + fTotalPrimitiveCounts[1].fCubics;
 
     fInstanceBuffer = onFlushRP->makeBuffer(kVertex_GrBufferType,
-                                            quadEndIdx * sizeof(QuadPointInstance));
+                                            cubicEndIdx * sizeof(CubicInstance));
     if (!fInstanceBuffer) {
         return false;
     }
 
-    TriPointInstance* triPointInstanceData = static_cast<TriPointInstance*>(fInstanceBuffer->map());
-    QuadPointInstance* quadPointInstanceData =
-            reinterpret_cast<QuadPointInstance*>(triPointInstanceData);
-    SkASSERT(quadPointInstanceData);
+    TriangleInstance* triangleInstanceData = static_cast<TriangleInstance*>(fInstanceBuffer->map());
+    CubicInstance* cubicInstanceData = reinterpret_cast<CubicInstance*>(triangleInstanceData);
+    SkASSERT(cubicInstanceData);
 
-    PathInfo* nextPathInfo = fPathsInfo.begin();
+    PathInfo* currPathInfo = fPathsInfo.begin();
     float atlasOffsetX = 0.0, atlasOffsetY = 0.0;
     Sk2f atlasOffset;
+    int ptsIdx = -1;
     PrimitiveTallies instanceIndices[2] = {fBaseInstances[0], fBaseInstances[1]};
     PrimitiveTallies* currIndices = nullptr;
     SkSTArray<256, int32_t, true> currFan;
-    bool currFanIsTessellated = false;
 
     const SkTArray<SkPoint, true>& pts = fGeometry.points();
-    int ptsIdx = -1;
 
     // Expand the ccpr verbs into GPU instance buffers.
     for (GrCCGeometry::Verb verb : fGeometry.verbs()) {
         switch (verb) {
             case GrCCGeometry::Verb::kBeginPath:
                 SkASSERT(currFan.empty());
-                currIndices = &instanceIndices[(int)nextPathInfo->fScissorMode];
-                atlasOffsetX = static_cast<float>(nextPathInfo->fAtlasOffsetX);
-                atlasOffsetY = static_cast<float>(nextPathInfo->fAtlasOffsetY);
+                currIndices = &instanceIndices[(int)currPathInfo->fScissorMode];
+                atlasOffsetX = static_cast<float>(currPathInfo->fAtlasOffsetX);
+                atlasOffsetY = static_cast<float>(currPathInfo->fAtlasOffsetY);
                 atlasOffset = {atlasOffsetX, atlasOffsetY};
-                currFanIsTessellated = nextPathInfo->fFanTessellation.get();
-                if (currFanIsTessellated) {
-                    emit_tessellated_fan(nextPathInfo->fFanTessellation.get(),
-                                         nextPathInfo->fFanTessellationCount, atlasOffset,
-                                         triPointInstanceData, quadPointInstanceData, currIndices);
-                }
-                ++nextPathInfo;
+                ++currPathInfo;
                 continue;
 
             case GrCCGeometry::Verb::kBeginContour:
                 SkASSERT(currFan.empty());
-                ++ptsIdx;
-                if (!currFanIsTessellated) {
-                    currFan.push_back(ptsIdx);
-                }
+                currFan.push_back(++ptsIdx);
                 continue;
 
             case GrCCGeometry::Verb::kLineTo:
-                ++ptsIdx;
-                if (!currFanIsTessellated) {
-                    SkASSERT(!currFan.empty());
-                    currFan.push_back(ptsIdx);
-                }
+                SkASSERT(!currFan.empty());
+                currFan.push_back(++ptsIdx);
                 continue;
 
             case GrCCGeometry::Verb::kMonotonicQuadraticTo:
-                triPointInstanceData[currIndices->fQuadratics++].set(&pts[ptsIdx], atlasOffset);
-                ptsIdx += 2;
-                if (!currFanIsTessellated) {
-                    SkASSERT(!currFan.empty());
-                    currFan.push_back(ptsIdx);
-                }
+                SkASSERT(!currFan.empty());
+                triangleInstanceData[currIndices->fQuadratics++].set(&pts[ptsIdx], atlasOffset);
+                currFan.push_back(ptsIdx += 2);
                 continue;
 
             case GrCCGeometry::Verb::kMonotonicCubicTo:
-                quadPointInstanceData[currIndices->fCubics++].set(&pts[ptsIdx], atlasOffsetX,
-                                                                  atlasOffsetY);
-                ptsIdx += 3;
-                if (!currFanIsTessellated) {
-                    SkASSERT(!currFan.empty());
-                    currFan.push_back(ptsIdx);
-                }
+                SkASSERT(!currFan.empty());
+                cubicInstanceData[currIndices->fCubics++].set(&pts[ptsIdx], atlasOffsetX,
+                                                              atlasOffsetY);
+                currFan.push_back(ptsIdx += 3);
                 continue;
 
             case GrCCGeometry::Verb::kEndClosedContour:  // endPt == startPt.
-                if (!currFanIsTessellated) {
-                    SkASSERT(!currFan.empty());
-                    currFan.pop_back();
-                }
+                SkASSERT(!currFan.empty());
+                currFan.pop_back();
             // fallthru.
             case GrCCGeometry::Verb::kEndOpenContour:  // endPt != startPt.
-                SkASSERT(!currFanIsTessellated || currFan.empty());
-                if (!currFanIsTessellated && currFan.count() >= 3) {
+                if (currFan.count() >= 3) {
                     int fanSize = currFan.count();
                     // Reserve space for emit_recursive_fan. Technically this can grow to
                     // fanSize + log3(fanSize), but we approximate with log2.
                     currFan.push_back_n(SkNextLog2(fanSize));
-                    SkDEBUGCODE(TriPointInstance* end =)
+                    SkDEBUGCODE(TriangleInstance* end =)
                             emit_recursive_fan(pts, currFan, 0, fanSize, atlasOffset,
-                                               triPointInstanceData + currIndices->fTriangles);
+                                               triangleInstanceData + currIndices->fTriangles);
                     currIndices->fTriangles += fanSize - 2;
-                    SkASSERT(triPointInstanceData + currIndices->fTriangles == end);
+                    SkASSERT(triangleInstanceData + currIndices->fTriangles == end);
                 }
                 currFan.reset();
                 continue;
@@ -474,16 +347,14 @@
 
     fInstanceBuffer->unmap();
 
-    SkASSERT(nextPathInfo == fPathsInfo.end());
+    SkASSERT(currPathInfo == fPathsInfo.end());
     SkASSERT(ptsIdx == pts.count() - 1);
     SkASSERT(instanceIndices[0].fTriangles == fBaseInstances[1].fTriangles);
     SkASSERT(instanceIndices[1].fTriangles == fBaseInstances[0].fQuadratics);
     SkASSERT(instanceIndices[0].fQuadratics == fBaseInstances[1].fQuadratics);
     SkASSERT(instanceIndices[1].fQuadratics == triEndIdx);
-    SkASSERT(instanceIndices[0].fWoundTriangles == fBaseInstances[1].fWoundTriangles);
-    SkASSERT(instanceIndices[1].fWoundTriangles == fBaseInstances[0].fCubics);
     SkASSERT(instanceIndices[0].fCubics == fBaseInstances[1].fCubics);
-    SkASSERT(instanceIndices[1].fCubics == quadEndIdx);
+    SkASSERT(instanceIndices[1].fCubics == cubicEndIdx);
 
     fMeshesScratchBuffer.reserve(fMaxMeshesPerDraw);
     fDynamicStatesScratchBuffer.reserve(fMaxMeshesPerDraw);
@@ -494,56 +365,36 @@
 void GrCCPathParser::drawCoverageCount(GrOpFlushState* flushState, CoverageCountBatchID batchID,
                                        const SkIRect& drawBounds) const {
     using RenderPass = GrCCCoverageProcessor::RenderPass;
-    using WindMethod = GrCCCoverageProcessor::WindMethod;
 
     SkASSERT(fInstanceBuffer);
 
-    const PrimitiveTallies& batchTotalCounts = fCoverageCountBatches[batchID].fTotalPrimitiveCounts;
-
     GrPipeline pipeline(flushState->drawOpArgs().fProxy, GrPipeline::ScissorState::kEnabled,
                         SkBlendMode::kPlus);
 
-    if (batchTotalCounts.fTriangles) {
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleHulls,
-                             WindMethod::kCrossProduct, &PrimitiveTallies::fTriangles, drawBounds);
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleEdges,
-                             WindMethod::kCrossProduct, &PrimitiveTallies::fTriangles,
-                             drawBounds); // Might get skipped.
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleCorners,
-                             WindMethod::kCrossProduct, &PrimitiveTallies::fTriangles, drawBounds);
-    }
+    // Triangles.
+    this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleHulls,
+                         &PrimitiveTallies::fTriangles, drawBounds);
+    this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleEdges,
+                         &PrimitiveTallies::fTriangles, drawBounds);  // Might get skipped.
+    this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleCorners,
+                         &PrimitiveTallies::fTriangles, drawBounds);
 
-    if (batchTotalCounts.fWoundTriangles) {
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleHulls,
-                             WindMethod::kInstanceData, &PrimitiveTallies::fWoundTriangles,
-                             drawBounds);
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleEdges,
-                             WindMethod::kInstanceData, &PrimitiveTallies::fWoundTriangles,
-                             drawBounds); // Might get skipped.
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleCorners,
-                             WindMethod::kInstanceData, &PrimitiveTallies::fWoundTriangles,
-                             drawBounds);
-    }
+    // Quadratics.
+    this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kQuadraticHulls,
+                         &PrimitiveTallies::fQuadratics, drawBounds);
+    this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kQuadraticCorners,
+                         &PrimitiveTallies::fQuadratics, drawBounds);
 
-    if (batchTotalCounts.fQuadratics) {
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kQuadraticHulls,
-                             WindMethod::kCrossProduct, &PrimitiveTallies::fQuadratics, drawBounds);
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kQuadraticCorners,
-                             WindMethod::kCrossProduct, &PrimitiveTallies::fQuadratics, drawBounds);
-    }
-
-    if (batchTotalCounts.fCubics) {
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kCubicHulls,
-                             WindMethod::kCrossProduct, &PrimitiveTallies::fCubics, drawBounds);
-        this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kCubicCorners,
-                             WindMethod::kCrossProduct, &PrimitiveTallies::fCubics, drawBounds);
-    }
+    // Cubics.
+    this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kCubicHulls,
+                         &PrimitiveTallies::fCubics, drawBounds);
+    this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kCubicCorners,
+                         &PrimitiveTallies::fCubics, drawBounds);
 }
 
 void GrCCPathParser::drawRenderPass(GrOpFlushState* flushState, const GrPipeline& pipeline,
                                     CoverageCountBatchID batchID,
                                     GrCCCoverageProcessor::RenderPass renderPass,
-                                    GrCCCoverageProcessor::WindMethod windMethod,
                                     int PrimitiveTallies::*instanceType,
                                     const SkIRect& drawBounds) const {
     SkASSERT(pipeline.getScissorState().enabled());
@@ -556,13 +407,12 @@
     fMeshesScratchBuffer.pop_back_n(fMeshesScratchBuffer.count());
     fDynamicStatesScratchBuffer.pop_back_n(fDynamicStatesScratchBuffer.count());
 
-    GrCCCoverageProcessor proc(flushState->resourceProvider(), renderPass, windMethod);
+    GrCCCoverageProcessor proc(flushState->resourceProvider(), renderPass, flushState->caps());
 
     SkASSERT(batchID > 0);
     SkASSERT(batchID < fCoverageCountBatches.count());
     const CoverageCountBatch& previousBatch = fCoverageCountBatches[batchID - 1];
     const CoverageCountBatch& batch = fCoverageCountBatches[batchID];
-    SkDEBUGCODE(int totalInstanceCount = 0);
 
     if (int instanceCount = batch.fEndNonScissorIndices.*instanceType -
                             previousBatch.fEndNonScissorIndices.*instanceType) {
@@ -572,7 +422,6 @@
         proc.appendMesh(fInstanceBuffer.get(), instanceCount, baseInstance, &fMeshesScratchBuffer);
         fDynamicStatesScratchBuffer.push_back().fScissorRect.setXYWH(0, 0, drawBounds.width(),
                                                                      drawBounds.height());
-        SkDEBUGCODE(totalInstanceCount += instanceCount);
     }
 
     SkASSERT(previousBatch.fEndScissorSubBatchIdx > 0);
@@ -590,12 +439,10 @@
         proc.appendMesh(fInstanceBuffer.get(), instanceCount,
                         baseScissorInstance + startIndex, &fMeshesScratchBuffer);
         fDynamicStatesScratchBuffer.push_back().fScissorRect = scissorSubBatch.fScissor;
-        SkDEBUGCODE(totalInstanceCount += instanceCount);
     }
 
     SkASSERT(fMeshesScratchBuffer.count() == fDynamicStatesScratchBuffer.count());
     SkASSERT(fMeshesScratchBuffer.count() <= fMaxMeshesPerDraw);
-    SkASSERT(totalInstanceCount == batch.fTotalPrimitiveCounts.*instanceType);
 
     if (!fMeshesScratchBuffer.empty()) {
         SkASSERT(flushState->rtCommandBuffer());
diff --git a/src/gpu/ccpr/GrCCPathParser.h b/src/gpu/ccpr/GrCCPathParser.h
index f041610..aff6b10 100644
--- a/src/gpu/ccpr/GrCCPathParser.h
+++ b/src/gpu/ccpr/GrCCPathParser.h
@@ -10,7 +10,6 @@
 
 #include "GrMesh.h"
 #include "GrNonAtomicRef.h"
-#include "GrTessellator.h"
 #include "SkRect.h"
 #include "SkRefCnt.h"
 #include "ccpr/GrCCCoverageProcessor.h"
@@ -77,13 +76,8 @@
 
     // Every kBeginPath verb has a corresponding PathInfo entry.
     struct PathInfo {
-        PathInfo(ScissorMode scissorMode, int16_t offsetX, int16_t offsetY)
-                : fScissorMode(scissorMode), fAtlasOffsetX(offsetX), fAtlasOffsetY(offsetY) {}
-
         ScissorMode fScissorMode;
         int16_t fAtlasOffsetX, fAtlasOffsetY;
-        std::unique_ptr<GrTessellator::WindingVertex[]> fFanTessellation;
-        int fFanTessellationCount = 0;
     };
 
     // Defines a batch of CCPR primitives. Start indices are deduced by looking at the previous
@@ -91,7 +85,6 @@
     struct CoverageCountBatch {
         PrimitiveTallies fEndNonScissorIndices;
         int fEndScissorSubBatchIdx;
-        PrimitiveTallies fTotalPrimitiveCounts;
     };
 
     // Defines a sub-batch from CoverageCountBatch that will be drawn with the given scissor rect.
@@ -105,8 +98,8 @@
     void endContourIfNeeded(bool insideContour);
 
     void drawRenderPass(GrOpFlushState*, const GrPipeline&, CoverageCountBatchID,
-                        GrCCCoverageProcessor::RenderPass, GrCCCoverageProcessor::WindMethod,
-                        int PrimitiveTallies::*instanceType, const SkIRect& drawBounds) const;
+                        GrCCCoverageProcessor::RenderPass, int PrimitiveTallies::*instanceType,
+                        const SkIRect& drawBounds) const;
 
     // Staging area for the path being parsed.
     SkDEBUGCODE(int fParsingPath = false);
@@ -114,7 +107,6 @@
     int fCurrPathPointsIdx;
     int fCurrPathVerbsIdx;
     PrimitiveTallies fCurrPathPrimitiveCounts;
-    SkPath::FillType fCurrPathFillType;
 
     GrCCGeometry fGeometry;
     SkSTArray<32, PathInfo, true> fPathsInfo;