Revert "CCPR: Initial semi-optimized vertex shader Impl"

This reverts commit e3877ce5ceb7842b61d54bebcc51864e5787a2bc.

Reason for revert: Intel crashing again

Original change's description:
> CCPR: Initial semi-optimized vertex shader Impl
> 
> TBR=bsalomon@google.com
> 
> Bug: skia:
> Change-Id: I24173e146d8c95cec5f29e8cb4fa5e2c28f9a33c
> Reviewed-on: https://skia-review.googlesource.com/89120
> Reviewed-by: Chris Dalton <csmartdalton@google.com>
> Commit-Queue: Chris Dalton <csmartdalton@google.com>

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

Change-Id: I2485db30397958722a07c5992c748ab69365ebb6
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/89300
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/gn/gpu.gni b/gn/gpu.gni
index f203437..fee613c 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -301,7 +301,6 @@
   "$_src/gpu/ccpr/GrCCPRCoverageOp.h",
   "$_src/gpu/ccpr/GrCCPRCoverageProcessor.cpp",
   "$_src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp",
-  "$_src/gpu/ccpr/GrCCPRCoverageProcessor_VSImpl.cpp",
   "$_src/gpu/ccpr/GrCCPRCoverageProcessor.h",
   "$_src/gpu/ccpr/GrCCPRCubicShader.cpp",
   "$_src/gpu/ccpr/GrCCPRCubicShader.h",
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index 2efb0e6..92892c2 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -236,10 +236,6 @@
                 GrCCPRGeometry::Verb::kEndClosedContour == verb) {
                 continue;
             }
-            if (GrCCPRGeometry::Verb::kLineTo == verb) {
-                ++ptsIdx;
-                continue;
-            }
             SkASSERT(GrCCPRGeometry::Verb::kMonotonicQuadraticTo == verb);
             fTriangleInstances.push_back().set(&geometry.points()[ptsIdx], Sk2f(0, 0));
             ptsIdx += 2;
@@ -255,14 +251,10 @@
     GrGLGpu* glGpu = kOpenGL_GrBackend == context->contextPriv().getBackend() ?
                      static_cast<GrGLGpu*>(state->gpu()) : nullptr;
 
-    if (!GrCCPRCoverageProcessor::DoesRenderPass(fView->fRenderPass, *state->caps().shaderCaps())) {
-        return;
-    }
-
-    GrCCPRCoverageProcessor proc(rp, fView->fRenderPass, *state->caps().shaderCaps());
+    GrCCPRCoverageProcessor proc(fView->fRenderPass);
     SkDEBUGCODE(proc.enableDebugVisualizations(kDebugBloat);)
 
-    SkSTArray<1, GrMesh> mesh;
+    SkSTArray<1, GrMesh, true> mesh;
     if (GrCCPRCoverageProcessor::RenderPassIsCubic(fView->fRenderPass)) {
         sk_sp<GrBuffer> instBuff(rp->createBuffer(fView->fCubicInstances.count() *
                                                   sizeof(CubicInstance), kVertex_GrBufferType,
diff --git a/src/gpu/ccpr/GrCCPRCoverageOp.cpp b/src/gpu/ccpr/GrCCPRCoverageOp.cpp
index 5cd35cd..57b73bf 100644
--- a/src/gpu/ccpr/GrCCPRCoverageOp.cpp
+++ b/src/gpu/ccpr/GrCCPRCoverageOp.cpp
@@ -7,7 +7,6 @@
 
 #include "GrCCPRCoverageOp.h"
 
-#include "GrCaps.h"
 #include "GrGpuCommandBuffer.h"
 #include "GrOnFlushResourceProvider.h"
 #include "GrOpFlushState.h"
@@ -397,7 +396,7 @@
     this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleHulls,
                              &PrimitiveTallies::fTriangles);
     this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleEdges,
-                             &PrimitiveTallies::fTriangles); // Might get skipped.
+                             &PrimitiveTallies::fTriangles);
     this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleCorners,
                              &PrimitiveTallies::fTriangles);
 
@@ -420,19 +419,14 @@
     using ScissorMode = GrCCPRCoverageOpsBuilder::ScissorMode;
     SkASSERT(pipeline.getScissorState().enabled());
 
-    if (!GrCCPRCoverageProcessor::DoesRenderPass(renderPass, *flushState->caps().shaderCaps())) {
-        return;
-    }
-
     fMeshesScratchBuffer.reset();
     fDynamicStatesScratchBuffer.reset();
 
-    GrCCPRCoverageProcessor proc(flushState->resourceProvider(), renderPass,
-                                 *flushState->caps().shaderCaps());
+    GrCCPRCoverageProcessor proc(renderPass);
 
-    if (int instanceCount = fInstanceCounts[(int)ScissorMode::kNonScissored].*instanceType) {
+    if (const int instanceCount = fInstanceCounts[(int)ScissorMode::kNonScissored].*instanceType) {
         SkASSERT(instanceCount > 0);
-        int baseInstance = fBaseInstances[(int)ScissorMode::kNonScissored].*instanceType;
+        const int baseInstance = fBaseInstances[(int)ScissorMode::kNonScissored].*instanceType;
         proc.appendMesh(fInstanceBuffer.get(), instanceCount, baseInstance, &fMeshesScratchBuffer);
         fDynamicStatesScratchBuffer.push_back().fScissorRect.setXYWH(0, 0, fDrawBounds.width(),
                                                                      fDrawBounds.height());
diff --git a/src/gpu/ccpr/GrCCPRCoverageOp.h b/src/gpu/ccpr/GrCCPRCoverageOp.h
index e3eee48..7957586 100644
--- a/src/gpu/ccpr/GrCCPRCoverageOp.h
+++ b/src/gpu/ccpr/GrCCPRCoverageOp.h
@@ -167,7 +167,7 @@
     const SkTArray<ScissorBatch, true> fScissorBatches;
     const SkISize fDrawBounds;
 
-    mutable SkTArray<GrMesh> fMeshesScratchBuffer;
+    mutable SkTArray<GrMesh, true> fMeshesScratchBuffer;
     mutable SkTArray<GrPipeline::DynamicState, true> fDynamicStatesScratchBuffer;
 
     friend class GrCCPRCoverageOpsBuilder;
diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
index 11e847f..3a456fd 100644
--- a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
@@ -11,21 +11,17 @@
 #include "ccpr/GrCCPRCubicShader.h"
 #include "ccpr/GrCCPRQuadraticShader.h"
 #include "ccpr/GrCCPRTriangleShader.h"
-#include "glsl/GrGLSLVertexGeoBuilder.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLVertexGeoBuilder.h"
 
 void GrCCPRCoverageProcessor::Shader::emitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                                   GrGLSLVarying::Scope scope, SkString* code,
-                                                   const char* position, const char* coverage,
-                                                   const char* wind) {
-    SkASSERT(GrGLSLVarying::Scope::kVertToGeo != scope);
-    WindHandling windHandling = this->onEmitVaryings(varyingHandler, scope, code, position,
-                                                     coverage, wind);
+                                                   SkString* code, const char* position,
+                                                   const char* coverage, const char* wind) {
+    WindHandling windHandling = this->onEmitVaryings(varyingHandler, code, position, coverage,
+                                                     wind);
     if (WindHandling::kNotHandled == windHandling) {
-        fWind.reset(kHalf_GrSLType, scope);
         varyingHandler->addFlatVarying("wind", &fWind);
-        code->appendf("%s = %s;", OutName(fWind), wind);
+        code->appendf("%s = %s;", fWind.gsOut(), wind);
     }
 }
 
@@ -84,16 +80,7 @@
 
 void GrCCPRCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&,
                                                   GrProcessorKeyBuilder* b) const {
-    int key = (int)fRenderPass << 1;
-    if (Impl::kGeometryShader == fImpl) {
-        key |= 1;
-    }
-#ifdef SK_DEBUG
-    uint32_t bloatBits;
-    memcpy(&bloatBits, &fDebugBloat, 4);
-    b->add32(bloatBits);
-#endif
-    b->add32(key);
+    b->add32((int)fRenderPass);
 }
 
 GrGLSLPrimitiveProcessor* GrCCPRCoverageProcessor::createGLSLInstance(const GrShaderCaps&) const {
@@ -119,6 +106,5 @@
             shader = skstd::make_unique<GrCCPRCubicCornerShader>();
             break;
     }
-    return Impl::kGeometryShader == fImpl ? this->createGSImpl(std::move(shader))
-                                          : this->createVSImpl(std::move(shader));
+    return this->createGSImpl(std::move(shader));
 }
diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.h b/src/gpu/ccpr/GrCCPRCoverageProcessor.h
index 3de36f1..7210d39 100644
--- a/src/gpu/ccpr/GrCCPRCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.h
@@ -9,7 +9,6 @@
 #define GrCCPRCoverageProcessor_DEFINED
 
 #include "GrGeometryProcessor.h"
-#include "GrShaderCaps.h"
 #include "SkNx.h"
 #include "glsl/GrGLSLGeometryProcessor.h"
 #include "glsl/GrGLSLVarying.h"
@@ -53,15 +52,14 @@
     // render pass. Here we enumerate every render pass needed in order to produce a complete
     // coverage count mask. This is an exhaustive list of all ccpr coverage shaders.
     //
-    // During a render pass, the "Impl" (GSImpl or VSimpl) generates conservative geometry for
+    // During a render pass, the "Impl" (currently only GSImpl) generates conservative geometry for
     // rasterization, and the Shader decides the coverage value at each pixel.
     enum class RenderPass {
         // For a Hull, the Impl generates a "conservative raster hull" around the input points. This
         // is the geometry that causes a pixel to be rasterized if it is touched anywhere by the
-        // input polygon. The initial coverage values sent to the Shader at each vertex are either
-        // null, or +1 all around if the Impl combines this pass with kTriangleEdges. Logically,
-        // the conservative raster hull is equivalent to the convex hull of pixel size boxes
-        // centered on each input point.
+        // input polygon. Initial coverage values sent to the Shader at each vertex will be null.
+        // Logically, the conservative raster hull is equivalent to the convex hull of pixel size
+        // boxes centered on each input point.
         kTriangleHulls,
         kQuadraticHulls,
         kCubicHulls,
@@ -72,9 +70,6 @@
         // edge geometry and 0 on the inside. This is the only geometry type that associates
         // coverage values with the output vertices. Interpolated, these coverage values convert
         // jagged conservative raster edges into a smooth antialiased edge.
-        //
-        // NOTE: The Impl may combine this pass with kTriangleHulls, in which case DoesRenderPass()
-        // will be false for kTriangleEdges and it must not be used.
         kTriangleEdges,
 
         // For Corners, the Impl Generates the conservative rasters of corner points (i.e.
@@ -87,20 +82,10 @@
     static bool RenderPassIsCubic(RenderPass);
     static const char* RenderPassName(RenderPass);
 
-    constexpr static bool DoesRenderPass(RenderPass renderPass, const GrShaderCaps& caps) {
-        return RenderPass::kTriangleEdges != renderPass || caps.geometryShaderSupport();
-    }
-
-    GrCCPRCoverageProcessor(GrResourceProvider* rp, RenderPass pass, const GrShaderCaps& caps)
+    GrCCPRCoverageProcessor(RenderPass pass)
             : INHERITED(kGrCCPRCoverageProcessor_ClassID)
-            , fRenderPass(pass)
-            , fImpl(caps.geometryShaderSupport() ?  Impl::kGeometryShader : Impl::kVertexShader) {
-        SkASSERT(DoesRenderPass(pass, caps));
-        if (Impl::kGeometryShader == fImpl) {
-            this->initGS();
-        } else {
-            this->initVS(rp);
-        }
+            , fRenderPass(pass) {
+        this->initGS();
     }
 
     // Appends a GrMesh that will draw the provided instances. The instanceBuffer must be an array
@@ -109,12 +94,8 @@
     //
     // NOTE: Quadratics use TriangleInstance since both have 3 points.
     void appendMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
-                    SkTArray<GrMesh>* out) {
-        if (Impl::kGeometryShader == fImpl) {
-            this->appendGSMesh(instanceBuffer, instanceCount, baseInstance, out);
-        } else {
-            this->appendVSMesh(instanceBuffer, instanceCount, baseInstance, out);
-        }
+                    SkTArray<GrMesh, true>* out) {
+        this->appendGSMesh(instanceBuffer, instanceCount, baseInstance, out);
     }
 
     // GrPrimitiveProcessor overrides.
@@ -159,8 +140,8 @@
                                    const char* repetitionID, const char* wind,
                                    GeometryVars*) const {}
 
-        void emitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
-                          const char* position, const char* coverage, const char* wind);
+        void emitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position,
+                          const char* coverage, const char* wind);
 
         void emitFragmentCode(const GrCCPRCoverageProcessor& proc, GrGLSLPPFragmentBuilder*,
                               const char* skOutputColor, const char* skOutputCoverage) const;
@@ -188,23 +169,15 @@
         //
         // NOTE: the coverage parameter is only relevant for edges (see comments in RenderPass).
         // Otherwise it is +1 all around.
-        virtual WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope,
-                                            SkString* code, const char* position,
-                                            const char* coverage, const char* wind) = 0;
+        virtual WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code,
+                                            const char* position, const char* coverage,
+                                            const char* wind) = 0;
 
         // Emits the fragment code that calculates a pixel's coverage value. If using
         // WindHandling::kHandled, this value must be signed appropriately.
         virtual void onEmitFragmentCode(GrGLSLPPFragmentBuilder*,
                                         const char* outputCoverage) const = 0;
 
-        // Returns the name of a Shader's internal varying at the point where where its value is
-        // assigned. This is intended to work whether called for a vertex or a geometry shader.
-        const char* OutName(const GrGLSLVarying& varying) const {
-            using Scope = GrGLSLVarying::Scope;
-            SkASSERT(Scope::kVertToGeo != varying.scope());
-            return Scope::kGeoToFrag == varying.scope() ? varying.gsOut() : varying.vsOut();
-        }
-
         // Defines a global float2 array that contains MSAA sample locations as offsets from pixel
         // center. Subclasses can use this for software multisampling.
         //
@@ -212,11 +185,10 @@
         static int DefineSoftSampleLocations(GrGLSLPPFragmentBuilder* f, const char* samplesName);
 
     private:
-        GrGLSLVarying fWind;
+        GrGLSLVarying fWind{kHalf_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
     };
 
     class GSImpl;
-    class VSImpl;
 
 private:
     // Slightly undershoot a bloat radius of 0.5 so vertices that fall on integer boundaries don't
@@ -226,26 +198,12 @@
     // Number of bezier points for curves, or 3 for triangles.
     int numInputPoints() const { return RenderPassIsCubic(fRenderPass) ? 4 : 3; }
 
-    enum class Impl : bool {
-        kGeometryShader,
-        kVertexShader
-    };
-
     void initGS();
-    void initVS(GrResourceProvider*);
-
     void appendGSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
-                      SkTArray<GrMesh>* out) const;
-    void appendVSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
-                      SkTArray<GrMesh>* out) const;
-
+                      SkTArray<GrMesh, true>* out) const;
     GrGLSLPrimitiveProcessor* createGSImpl(std::unique_ptr<Shader>) const;
-    GrGLSLPrimitiveProcessor* createVSImpl(std::unique_ptr<Shader>) const;
 
     const RenderPass fRenderPass;
-    const Impl fImpl;
-    sk_sp<const GrBuffer> fVertexBuffer; // Used by VSImpl.
-    sk_sp<const GrBuffer> fIndexBuffer; // Used by VSImpl.
     SkDEBUGCODE(float fDebugBloat = 0;)
 
     typedef GrGeometryProcessor INHERITED;
diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp
index 4d1df8c..5006ff5 100644
--- a/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp
+++ b/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp
@@ -72,8 +72,7 @@
         }
         g->emitFunction(kVoid_GrSLType, "emitVertex", emitArgs.count(), emitArgs.begin(), [&]() {
             SkString fnBody;
-            fShader->emitVaryings(varyingHandler, GrGLSLVarying::Scope::kGeoToFrag, &fnBody,
-                                  position, coverage, wind.c_str());
+            fShader->emitVaryings(varyingHandler, &fnBody, position, coverage, wind.c_str());
             g->emitVertex(&fnBody, position, rtAdjust);
             return fnBody;
         }().c_str(), &emitVertexFn);
@@ -293,7 +292,7 @@
 };
 
 /**
- * Generates conservative rasters around corners. (See comments for RenderPass)
+ * Generates conservatives around corners. (See comments for RenderPass)
  */
 class GSCornerImpl : public GrCCPRCoverageProcessor::GSImpl {
 public:
@@ -321,7 +320,6 @@
 };
 
 void GrCCPRCoverageProcessor::initGS() {
-    SkASSERT(Impl::kGeometryShader == fImpl);
     if (RenderPassIsCubic(fRenderPass)) {
         this->addVertexAttrib("x_or_y_values", kFloat4_GrVertexAttribType); // (See appendMesh.)
         SkASSERT(sizeof(CubicInstance) == this->getVertexStride() * 2);
@@ -333,12 +331,11 @@
 }
 
 void GrCCPRCoverageProcessor::appendGSMesh(GrBuffer* instanceBuffer, int instanceCount,
-                                           int baseInstance, SkTArray<GrMesh>* out) const {
+                                           int baseInstance, SkTArray<GrMesh, true>* out) const {
     // GSImpl doesn't actually make instanced draw calls. Instead, we feed transposed x,y point
     // values to the GPU in a regular vertex array and draw kLines (see initGS). Then, each vertex
     // invocation receives either the shape's x or y values as inputs, which it forwards to the
     // geometry shader.
-    SkASSERT(Impl::kGeometryShader == fImpl);
     GrMesh& mesh = out->emplace_back(GrPrimitiveType::kLines);
     mesh.setNonIndexedNonInstanced(instanceCount * 2);
     mesh.setVertexData(instanceBuffer, baseInstance * 2);
diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor_VSImpl.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor_VSImpl.cpp
deleted file mode 100644
index fdd304d..0000000
--- a/src/gpu/ccpr/GrCCPRCoverageProcessor_VSImpl.cpp
+++ /dev/null
@@ -1,441 +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 "GrCCPRCoverageProcessor.h"
-
-#include "GrMesh.h"
-#include "glsl/GrGLSLVertexGeoBuilder.h"
-
-using Shader = GrCCPRCoverageProcessor::Shader;
-
-static constexpr int kAttribIdx_X = 0;
-static constexpr int kAttribIdx_Y = 1;
-static constexpr int kAttribIdx_VertexData = 2;
-
-/**
- * This class and its subclasses implement the coverage processor with vertex shaders.
- */
-class GrCCPRCoverageProcessor::VSImpl : public GrGLSLGeometryProcessor {
-protected:
-    VSImpl(std::unique_ptr<Shader> shader) : fShader(std::move(shader)) {}
-
-    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
-                 FPCoordTransformIter&& transformIter) final {
-        this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
-    }
-
-    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
-        const GrCCPRCoverageProcessor& proc = args.fGP.cast<GrCCPRCoverageProcessor>();
-
-        // Vertex shader.
-        GrGLSLVertexBuilder* v = args.fVertBuilder;
-        int numInputPoints = proc.numInputPoints();
-
-        v->codeAppendf("float%ix2 pts = transpose(float2x%i(%s, %s));",
-                       numInputPoints, numInputPoints, proc.getAttrib(kAttribIdx_X).fName,
-                       proc.getAttrib(kAttribIdx_Y).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
-        if (proc.debugVisualizationsEnabled()) {
-            bloat *= proc.debugBloat();
-        }
-#endif
-        v->defineConstant("bloat", bloat);
-
-        const char* coverage = this->emitVertexPosition(proc, v, gpArgs);
-        SkASSERT(kFloat2_GrSLType == gpArgs->fPositionVar.getType());
-
-        GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
-        SkString varyingCode;
-        fShader->emitVaryings(varyingHandler, GrGLSLVarying::Scope::kVertToFrag, &varyingCode,
-                              gpArgs->fPositionVar.c_str(), coverage, "wind");
-        v->codeAppend(varyingCode.c_str());
-
-        varyingHandler->emitAttributes(proc);
-        SkASSERT(!args.fFPCoordTransformHandler->nextCoordTransform());
-
-        // Fragment shader.
-        fShader->emitFragmentCode(proc, args.fFragBuilder, args.fOutputColor, args.fOutputCoverage);
-    }
-
-    virtual const char* emitVertexPosition(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
-                                           GrGPArgs*) const = 0;
-
-    virtual ~VSImpl() {}
-
-    const std::unique_ptr<Shader> fShader;
-
-    typedef GrGLSLGeometryProcessor INHERITED;
-};
-
-/**
- * Vertex data tells the shader how to offset vertices for conservative raster, and how/whether to
- * calculate initial coverage values for edges. See VSHullAndEdgeImpl.
- */
-static constexpr int32_t pack_vertex_data(int32_t bloatIdx, int32_t edgeData,
-                                          int32_t cornerVertexID, int32_t cornerIdx) {
-    return (bloatIdx << 6) | (edgeData << 4) | (cornerVertexID << 2) | cornerIdx;
-}
-
-static constexpr int32_t hull_vertex_data(int32_t cornerIdx, int32_t cornerVertexID, int n) {
-    return pack_vertex_data((cornerIdx + (2 == cornerVertexID ? 1 : n - 1)) % n, 0, cornerVertexID,
-                            cornerIdx);
-}
-
-static constexpr int32_t edge_vertex_data(int32_t edgeID, int32_t endptIdx, int32_t endptVertexID,
-                                          int n) {
-    return pack_vertex_data(0 == endptIdx ? (edgeID + 1) % n : edgeID, (endptIdx << 1) | 1,
-                            endptVertexID, 0 == endptIdx ? edgeID : (edgeID + 1) % n);
-}
-
-static constexpr int32_t kHull3AndEdgeVertices[] = {
-    hull_vertex_data(0, 0, 3),
-    hull_vertex_data(0, 1, 3),
-    hull_vertex_data(0, 2, 3),
-    hull_vertex_data(1, 0, 3),
-    hull_vertex_data(1, 1, 3),
-    hull_vertex_data(1, 2, 3),
-    hull_vertex_data(2, 0, 3),
-    hull_vertex_data(2, 1, 3),
-    hull_vertex_data(2, 2, 3),
-
-    edge_vertex_data(0, 0, 0, 3),
-    edge_vertex_data(0, 0, 1, 3),
-    edge_vertex_data(0, 0, 2, 3),
-    edge_vertex_data(0, 1, 0, 3),
-    edge_vertex_data(0, 1, 1, 3),
-    edge_vertex_data(0, 1, 2, 3),
-
-    edge_vertex_data(1, 0, 0, 3),
-    edge_vertex_data(1, 0, 1, 3),
-    edge_vertex_data(1, 0, 2, 3),
-    edge_vertex_data(1, 1, 0, 3),
-    edge_vertex_data(1, 1, 1, 3),
-    edge_vertex_data(1, 1, 2, 3),
-
-    edge_vertex_data(2, 0, 0, 3),
-    edge_vertex_data(2, 0, 1, 3),
-    edge_vertex_data(2, 0, 2, 3),
-    edge_vertex_data(2, 1, 0, 3),
-    edge_vertex_data(2, 1, 1, 3),
-    edge_vertex_data(2, 1, 2, 3),
-};
-
-GR_DECLARE_STATIC_UNIQUE_KEY(gHull3AndEdgeVertexBufferKey);
-
-static constexpr uint16_t kHull3AndEdgeIndices[] =  {
-    // First corner and main body of the hull.
-    1, 2, 0,
-    2, 3, 0,
-    0, 3, 8, // Main body.
-
-    // Opposite side and corners of the hull.
-    4, 5, 3,
-    5, 6, 3,
-    3, 6, 8,
-    6, 7, 8,
-
-    // First edge.
-    10,  9, 11,
-     9, 14, 11,
-    11, 14, 12,
-    14, 13, 12,
-
-    // Second edge.
-    16, 15, 17,
-    15, 20, 17,
-    17, 20, 18,
-    20, 19, 18,
-
-    // Third edge.
-    22, 21, 23,
-    21, 26, 23,
-    23, 26, 24,
-    26, 25, 24,
-};
-
-GR_DECLARE_STATIC_UNIQUE_KEY(gHull3AndEdgeIndexBufferKey);
-
-static constexpr int32_t kHull4Vertices[] = {
-    hull_vertex_data(0, 0, 4),
-    hull_vertex_data(0, 1, 4),
-    hull_vertex_data(0, 2, 4),
-    hull_vertex_data(1, 0, 4),
-    hull_vertex_data(1, 1, 4),
-    hull_vertex_data(1, 2, 4),
-    hull_vertex_data(2, 0, 4),
-    hull_vertex_data(2, 1, 4),
-    hull_vertex_data(2, 2, 4),
-    hull_vertex_data(3, 0, 4),
-    hull_vertex_data(3, 1, 4),
-    hull_vertex_data(3, 2, 4),
-
-    // No edges for now (beziers don't use edges).
-};
-
-GR_DECLARE_STATIC_UNIQUE_KEY(gHull4VertexBufferKey);
-
-static constexpr uint16_t kHull4Indices[] =  {
-    // First half of the hull (split diagonally).
-     1,  0,  2,
-     0, 11,  2,
-     2, 11,  3,
-    11,  5,  3,
-     3,  5,  4,
-
-    // Second half of the hull.
-    7,  6,  8,
-    6,  5,  8,
-    8,  5,  9,
-    5, 11,  9,
-    9, 11, 10,
-};
-
-GR_DECLARE_STATIC_UNIQUE_KEY(gHull4IndexBufferKey);
-
-/**
- * Generates a conservative raster hull around a convex polygon. For triangles, we also generate
- * independent conservative rasters around each edge. (See comments for RenderPass)
- */
-class VSHullAndEdgeImpl : public GrCCPRCoverageProcessor::VSImpl {
-public:
-    VSHullAndEdgeImpl(std::unique_ptr<Shader> shader, int numSides)
-            : VSImpl(std::move(shader)), fNumSides(numSides) {}
-
-    const char* emitVertexPosition(const GrCCPRCoverageProcessor& proc, GrGLSLVertexBuilder* v,
-                                   GrGPArgs* gpArgs) const override {
-        Shader::GeometryVars vars;
-        fShader->emitSetupCode(v, "pts", nullptr, "wind", &vars);
-
-        const char* hullPts = vars.fHullVars.fAlternatePoints;
-        if (!hullPts) {
-            hullPts = "pts";
-        }
-
-        // Reverse all indices if the wind is counter-clockwise: [0, 1, 2] -> [2, 1, 0].
-        v->codeAppendf("int clockwise_indices = wind > 0 ? %s : 0x%x - %s;",
-                       proc.getAttrib(kAttribIdx_VertexData).fName,
-                       ((fNumSides - 1) << 6) | (0xf << 2) | (fNumSides - 1),
-                       proc.getAttrib(kAttribIdx_VertexData).fName);
-
-        // Here we generate conservative raster geometry for the input polygon. It is the convex
-        // hull of N pixel-size boxes, one centered on each the input points. Each corner has three
-        // vertices, where one or two may cause degenerate triangles. The vertex data tells us how
-        // to offset each vertex. Triangle edges are also handled here (see kHull3AndEdgeIndices).
-        // For more details on conservative raster, see:
-        // https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter42.html
-        v->codeAppendf("float2 corner = %s[clockwise_indices & 3];", hullPts);
-        v->codeAppendf("float2 bloatpoint = %s[clockwise_indices >> 6];", hullPts);
-        v->codeAppend ("float2 vertexbloat = float2(bloatpoint.y > corner.y ? -bloat : +bloat, "
-                                                   "bloatpoint.x > corner.x ? +bloat : -bloat);");
-
-        v->codeAppendf("if ((1 << 2) == (%s & (3 << 2))) {",
-                       proc.getAttrib(kAttribIdx_VertexData).fName);
-                           // We are the corner's middle vertex (of 3).
-        v->codeAppend (    "vertexbloat = float2(-vertexbloat.y, vertexbloat.x);");
-        v->codeAppend ("}");
-
-        v->codeAppendf("if ((2 << 2) == (%s & (3 << 2))) {",
-                       proc.getAttrib(kAttribIdx_VertexData).fName);
-                           // We are the corner's third vertex (of 3).
-        v->codeAppend (    "vertexbloat = -vertexbloat;");
-        v->codeAppend ("}");
-
-        v->codeAppend ("float2 vertex = corner + vertexbloat;");
-        gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertex");
-
-        if (4 == fNumSides) {
-            // We don't generate edges around 4-sided polygons.
-            return nullptr; // Known hull vertices don't need an initial coverage value.
-        }
-
-        // Find coverage for edge vertices.
-        Shader::EmitEdgeDistanceEquation(v, "bloatpoint", "corner",
-                                         "float3 edge_distance_equation");
-        v->codeAppend ("half coverage = dot(edge_distance_equation.xy, vertex) + "
-                                       "edge_distance_equation.z;");
-        v->codeAppendf("if (0 == (%s & (1 << 5))) {", proc.getAttrib(kAttribIdx_VertexData).fName);
-                           // We are the opposite endpoint. Invert coverage.
-        v->codeAppend (    "coverage = -1 - coverage;");
-        v->codeAppend ("}");
-        v->codeAppendf("if (0 == (%s & (1 << 4))) {", proc.getAttrib(kAttribIdx_VertexData).fName);
-                           // We are actually a hull vertex. Hull coverage is +1 all around.
-        v->codeAppend (    "coverage = +1;");
-        v->codeAppend ("}");
-
-        return "coverage";
-    }
-
-private:
-    const int fNumSides;
-};
-
-static constexpr uint16_t kCornerIndices[] =  {
-    // First corner.
-    0,  1,  2,
-    1,  3,  2,
-
-    // Second corner.
-    4,  5,  6,
-    5,  7,  6,
-
-    // Third corner.
-    8,  9, 10,
-    9, 11, 10,
-};
-
-GR_DECLARE_STATIC_UNIQUE_KEY(gCornerIndexBufferKey);
-
-/**
- * Generates conservative rasters around corners. (See comments for RenderPass)
- */
-class VSCornerImpl : public GrCCPRCoverageProcessor::VSImpl {
-public:
-    VSCornerImpl(std::unique_ptr<Shader> shader) : VSImpl(std::move(shader)) {}
-
-    const char* emitVertexPosition(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder* v,
-                                   GrGPArgs* gpArgs) const override {
-        Shader::GeometryVars vars;
-        v->codeAppend ("int corner_id = sk_VertexID / 4;");
-        fShader->emitSetupCode(v, "pts", "corner_id", "wind", &vars);
-
-        v->codeAppendf("float2 vertex = %s;", vars.fCornerVars.fPoint);
-        v->codeAppend ("vertex.x += (0 == (sk_VertexID & 2)) ? -bloat : +bloat;");
-        v->codeAppend ("vertex.y += (0 == (sk_VertexID & 1)) ? -bloat : +bloat;");
-
-        gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertex");
-        return nullptr; // Corner vertices don't have an initial coverage value.
-    }
-};
-
-void GrCCPRCoverageProcessor::initVS(GrResourceProvider* rp) {
-    SkASSERT(Impl::kVertexShader == fImpl);
-
-    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: {
-            GR_DEFINE_STATIC_UNIQUE_KEY(gHull3AndEdgeVertexBufferKey);
-            fVertexBuffer = rp->findOrMakeStaticBuffer(kVertex_GrBufferType,
-                                                       sizeof(kHull3AndEdgeVertices),
-                                                       kHull3AndEdgeVertices,
-                                                       gHull3AndEdgeVertexBufferKey);
-            GR_DEFINE_STATIC_UNIQUE_KEY(gHull3AndEdgeIndexBufferKey);
-            fIndexBuffer = rp->findOrMakeStaticBuffer(kIndex_GrBufferType,
-                                                      sizeof(kHull3AndEdgeIndices),
-                                                      kHull3AndEdgeIndices,
-                                                      gHull3AndEdgeIndexBufferKey);
-            SkASSERT(kAttribIdx_VertexData == this->numAttribs());
-            this->addVertexAttrib("vertexdata", kInt_GrVertexAttribType);
-            break;
-        }
-        case RenderPass::kQuadraticHulls:
-        case RenderPass::kCubicHulls: {
-            GR_DEFINE_STATIC_UNIQUE_KEY(gHull4VertexBufferKey);
-            fVertexBuffer = rp->findOrMakeStaticBuffer(kVertex_GrBufferType, sizeof(kHull4Vertices),
-                                                       kHull4Vertices, gHull4VertexBufferKey);
-            GR_DEFINE_STATIC_UNIQUE_KEY(gHull4IndexBufferKey);
-            fIndexBuffer = rp->findOrMakeStaticBuffer(kIndex_GrBufferType, sizeof(kHull4Indices),
-                                                      kHull4Indices, gHull4IndexBufferKey);
-            SkASSERT(kAttribIdx_VertexData == this->numAttribs());
-            this->addVertexAttrib("vertexdata", kInt_GrVertexAttribType);
-            break;
-        }
-        case RenderPass::kTriangleEdges:
-            SK_ABORT("kTriangleEdges RenderPass is not used by VSImpl.");
-            break;
-        case RenderPass::kTriangleCorners:
-        case RenderPass::kQuadraticCorners:
-        case RenderPass::kCubicCorners: {
-            GR_DEFINE_STATIC_UNIQUE_KEY(gCornerIndexBufferKey);
-            fIndexBuffer = rp->findOrMakeStaticBuffer(kIndex_GrBufferType, sizeof(kCornerIndices),
-                                                      kCornerIndices, gCornerIndexBufferKey);
-            break;
-        }
-    }
-
-#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(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(sizeof(int32_t) == this->getVertexStride());
-    }
-#endif
-}
-
-static int num_indices_per_instance(GrCCPRCoverageProcessor::RenderPass pass) {
-    switch (pass) {
-        using RenderPass = GrCCPRCoverageProcessor::RenderPass;
-        case RenderPass::kTriangleHulls:
-            return SK_ARRAY_COUNT(kHull3AndEdgeIndices);
-        case RenderPass::kQuadraticHulls:
-        case RenderPass::kCubicHulls:
-            return SK_ARRAY_COUNT(kHull4Indices);
-        case RenderPass::kTriangleEdges:
-            SK_ABORT("kTriangleEdges RenderPass is not used by VSImpl.");
-            return 0;
-        case RenderPass::kTriangleCorners:
-            return SK_ARRAY_COUNT(kCornerIndices);
-        case RenderPass::kQuadraticCorners:
-        case RenderPass::kCubicCorners:
-            return SK_ARRAY_COUNT(kCornerIndices) * 2/3;
-    }
-    SK_ABORT("Invalid RenderPass");
-    return 0;
-}
-
-void GrCCPRCoverageProcessor::appendVSMesh(GrBuffer* instanceBuffer, int instanceCount,
-                                           int baseInstance, SkTArray<GrMesh>* out) const {
-    SkASSERT(Impl::kVertexShader == fImpl);
-    GrMesh& mesh = out->emplace_back(GrPrimitiveType::kTriangles);
-    mesh.setIndexedInstanced(fIndexBuffer.get(), num_indices_per_instance(fRenderPass),
-                             instanceBuffer, instanceCount, baseInstance);
-    if (fVertexBuffer) {
-        mesh.setVertexData(fVertexBuffer.get(), 0);
-    }
-}
-
-GrGLSLPrimitiveProcessor*
-GrCCPRCoverageProcessor::createVSImpl(std::unique_ptr<Shader> shader) const {
-    switch (fRenderPass) {
-        case RenderPass::kTriangleHulls:
-            return new VSHullAndEdgeImpl(std::move(shader), 3);
-        case RenderPass::kQuadraticHulls:
-        case RenderPass::kCubicHulls:
-            return new VSHullAndEdgeImpl(std::move(shader), 4);
-        case RenderPass::kTriangleEdges:
-            SK_ABORT("kTriangleEdges RenderPass is not used by VSImpl.");
-            return nullptr;
-        case RenderPass::kTriangleCorners:
-        case RenderPass::kQuadraticCorners:
-        case RenderPass::kCubicCorners:
-            return new VSCornerImpl(std::move(shader));
-    }
-    SK_ABORT("Invalid RenderPass");
-    return nullptr;
-}
diff --git a/src/gpu/ccpr/GrCCPRCubicShader.cpp b/src/gpu/ccpr/GrCCPRCubicShader.cpp
index f2ef861..c9e546a 100644
--- a/src/gpu/ccpr/GrCCPRCubicShader.cpp
+++ b/src/gpu/ccpr/GrCCPRCubicShader.cpp
@@ -76,29 +76,25 @@
 }
 
 Shader::WindHandling GrCCPRCubicShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                                       GrGLSLVarying::Scope scope,
                                                        SkString* code, const char* position,
                                                        const char* coverage, const char* /*wind*/) {
     SkASSERT(!coverage);
 
-    fKLMD.reset(kFloat4_GrSLType, scope);
     varyingHandler->addVarying("klmd", &fKLMD);
     code->appendf("float3 klm = float3(%s, 1) * %s;", position, fKLMMatrix.c_str());
     code->appendf("float d = dot(float3(%s, 1), %s);", position, fEdgeDistanceEquation.c_str());
-    code->appendf("%s = float4(klm, d);", OutName(fKLMD));
+    code->appendf("%s = float4(klm, d);", fKLMD.gsOut());
 
-    this->onEmitVaryings(varyingHandler, scope, code);
+    this->onEmitVaryings(varyingHandler, code);
     return WindHandling::kNotHandled;
 }
 
-void GrCCPRCubicHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                           GrGLSLVarying::Scope scope, SkString* code) {
-    fGradMatrix.reset(kFloat2x2_GrSLType, scope);
-    varyingHandler->addVarying("grad_matrix", &fGradMatrix);
+void GrCCPRCubicHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler, SkString* code) {
     // "klm" was just defined by the base class.
-    code->appendf("%s[0] = 3 * klm[0] * %s[0].xy;", OutName(fGradMatrix), fKLMMatrix.c_str());
+    varyingHandler->addVarying("grad_matrix", &fGradMatrix);
+    code->appendf("%s[0] = 3 * klm[0] * %s[0].xy;", fGradMatrix.gsOut(), fKLMMatrix.c_str());
     code->appendf("%s[1] = -klm[1] * %s[2].xy - klm[2] * %s[1].xy;",
-                    OutName(fGradMatrix), fKLMMatrix.c_str(), fKLMMatrix.c_str());
+                    fGradMatrix.gsOut(), fKLMMatrix.c_str(), fKLMMatrix.c_str());
 }
 
 void GrCCPRCubicHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
@@ -117,18 +113,15 @@
     vars->fCornerVars.fPoint = "corner";
 }
 
-void GrCCPRCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                             GrGLSLVarying::Scope scope, SkString* code) {
-    fdKLMDdx.reset(kFloat4_GrSLType, scope);
+void GrCCPRCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler, SkString* code) {
     varyingHandler->addFlatVarying("dklmddx", &fdKLMDdx);
     code->appendf("%s = float4(%s[0].x, %s[1].x, %s[2].x, %s.x);",
-                  OutName(fdKLMDdx), fKLMMatrix.c_str(), fKLMMatrix.c_str(),
+                  fdKLMDdx.gsOut(), fKLMMatrix.c_str(), fKLMMatrix.c_str(),
                   fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str());
 
-    fdKLMDdy.reset(kFloat4_GrSLType, scope);
     varyingHandler->addFlatVarying("dklmddy", &fdKLMDdy);
     code->appendf("%s = float4(%s[0].y, %s[1].y, %s[2].y, %s.y);",
-                  OutName(fdKLMDdy), fKLMMatrix.c_str(), fKLMMatrix.c_str(),
+                  fdKLMDdy.gsOut(), fKLMMatrix.c_str(), fKLMMatrix.c_str(),
                   fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str());
 }
 
diff --git a/src/gpu/ccpr/GrCCPRCubicShader.h b/src/gpu/ccpr/GrCCPRCubicShader.h
index bb57878..10f4dff 100644
--- a/src/gpu/ccpr/GrCCPRCubicShader.h
+++ b/src/gpu/ccpr/GrCCPRCubicShader.h
@@ -29,31 +29,31 @@
     virtual void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
                                  GeometryVars*) const {}
 
-    WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
-                                const char* position, const char* coverage, const char* wind) final;
+    WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position,
+                                const char* coverage, const char* wind) final;
 
-    virtual void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) = 0;
+    virtual void onEmitVaryings(GrGLSLVaryingHandler*, SkString* code) = 0;
 
     GrShaderVar fKLMMatrix{"klm_matrix", kFloat3x3_GrSLType};
     GrShaderVar fEdgeDistanceEquation{"edge_distance_equation", kFloat3_GrSLType};
-    GrGLSLVarying fKLMD;
+    GrGLSLVarying fKLMD{kFloat4_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
 };
 
 class GrCCPRCubicHullShader : public GrCCPRCubicShader {
-    void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
+    void onEmitVaryings(GrGLSLVaryingHandler*, SkString* code) override;
     void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
 
-    GrGLSLVarying fGradMatrix;
+    GrGLSLVarying fGradMatrix{kFloat2x2_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
 };
 
 class GrCCPRCubicCornerShader : public GrCCPRCubicShader {
     void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
                          GeometryVars*) const override;
-    void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
+    void onEmitVaryings(GrGLSLVaryingHandler*, SkString* code) override;
     void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
 
-    GrGLSLVarying fdKLMDdx;
-    GrGLSLVarying fdKLMDdy;
+    GrGLSLVarying fdKLMDdx{kFloat4_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
+    GrGLSLVarying fdKLMDdy{kFloat4_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
 };
 
 #endif
diff --git a/src/gpu/ccpr/GrCCPRQuadraticShader.cpp b/src/gpu/ccpr/GrCCPRQuadraticShader.cpp
index 429cb4e..308e3ff 100644
--- a/src/gpu/ccpr/GrCCPRQuadraticShader.cpp
+++ b/src/gpu/ccpr/GrCCPRQuadraticShader.cpp
@@ -7,7 +7,6 @@
 
 #include "GrCCPRQuadraticShader.h"
 
-#include "glsl/GrGLSLVertexGeoBuilder.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLVertexGeoBuilder.h"
 
@@ -34,21 +33,19 @@
 }
 
 Shader::WindHandling GrCCPRQuadraticShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                                           GrGLSLVarying::Scope scope,
                                                            SkString* code, const char* position,
                                                            const char* coverage,
                                                            const char* /*wind*/) {
     SkASSERT(!coverage);
 
-    fXYD.reset(kFloat3_GrSLType, scope);
     varyingHandler->addVarying("xyd", &fXYD);
     code->appendf("%s.xy = (%s * float3(%s, 1)).xy;",
-                  OutName(fXYD), fCanonicalMatrix.c_str(), position);
+                  fXYD.gsOut(), fCanonicalMatrix.c_str(), position);
     code->appendf("%s.z = dot(%s.xy, %s) + %s.z;",
-                  OutName(fXYD), fEdgeDistanceEquation.c_str(), position,
+                  fXYD.gsOut(), fEdgeDistanceEquation.c_str(), position,
                   fEdgeDistanceEquation.c_str());
 
-    this->onEmitVaryings(varyingHandler, scope, code);
+    this->onEmitVaryings(varyingHandler, code);
     return WindHandling::kNotHandled;
 }
 
@@ -72,11 +69,10 @@
 }
 
 void GrCCPRQuadraticHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                               GrGLSLVarying::Scope scope, SkString* code) {
-    fGrad.reset(kFloat2_GrSLType, scope);
+                                               SkString* code) {
     varyingHandler->addVarying("grad", &fGrad);
     code->appendf("%s = float2(2 * %s.x, -1) * float2x2(%s);",
-                  OutName(fGrad), OutName(fXYD), fCanonicalMatrix.c_str());
+                  fGrad.gsOut(), fXYD.gsOut(), fCanonicalMatrix.c_str());
 }
 
 void GrCCPRQuadraticHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
@@ -95,17 +91,15 @@
 }
 
 void GrCCPRQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                                 GrGLSLVarying::Scope scope, SkString* code) {
-    fdXYDdx.reset(kFloat3_GrSLType, scope);
+                                                 SkString* code) {
     varyingHandler->addFlatVarying("dXYDdx", &fdXYDdx);
     code->appendf("%s = float3(%s[0].x, %s[0].y, %s.x);",
-                  OutName(fdXYDdx), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(),
+                  fdXYDdx.gsOut(), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(),
                   fEdgeDistanceEquation.c_str());
 
-    fdXYDdy.reset(kFloat3_GrSLType, scope);
     varyingHandler->addFlatVarying("dXYDdy", &fdXYDdy);
     code->appendf("%s = float3(%s[1].x, %s[1].y, %s.y);",
-                  OutName(fdXYDdy), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(),
+                  fdXYDdy.gsOut(), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(),
                   fEdgeDistanceEquation.c_str());
 }
 
diff --git a/src/gpu/ccpr/GrCCPRQuadraticShader.h b/src/gpu/ccpr/GrCCPRQuadraticShader.h
index 76b2563..14505c6 100644
--- a/src/gpu/ccpr/GrCCPRQuadraticShader.h
+++ b/src/gpu/ccpr/GrCCPRQuadraticShader.h
@@ -28,14 +28,14 @@
     virtual void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
                                  GeometryVars*) const = 0;
 
-    WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
-                                const char* position, const char* coverage, const char* wind) final;
+    WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position,
+                                const char* coverage, const char* wind) final;
 
-    virtual void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) {}
+    virtual void onEmitVaryings(GrGLSLVaryingHandler*, SkString* code) = 0;
 
     const GrShaderVar fCanonicalMatrix{"canonical_matrix", kFloat3x3_GrSLType};
     const GrShaderVar fEdgeDistanceEquation{"edge_distance_equation", kFloat3_GrSLType};
-    GrGLSLVarying fXYD;
+    GrGLSLVarying fXYD{kFloat3_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
 };
 
 /**
@@ -47,10 +47,10 @@
 class GrCCPRQuadraticHullShader : public GrCCPRQuadraticShader {
     void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
                          GeometryVars*) const override;
-    void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
+    void onEmitVaryings(GrGLSLVaryingHandler*, SkString* code) override;
     void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
 
-    GrGLSLVarying fGrad;
+    GrGLSLVarying fGrad{kFloat2_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
 };
 
 /**
@@ -59,11 +59,11 @@
 class GrCCPRQuadraticCornerShader : public GrCCPRQuadraticShader {
     void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
                          GeometryVars*) const override;
-    void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
+    void onEmitVaryings(GrGLSLVaryingHandler*, SkString* code) override;
     void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
 
-    GrGLSLVarying fdXYDdx;
-    GrGLSLVarying fdXYDdy;
+    GrGLSLVarying fdXYDdx{kFloat3_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
+    GrGLSLVarying fdXYDdy{kFloat3_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
 };
 
 #endif
diff --git a/src/gpu/ccpr/GrCCPRTriangleShader.cpp b/src/gpu/ccpr/GrCCPRTriangleShader.cpp
index 1305801..ce05697 100644
--- a/src/gpu/ccpr/GrCCPRTriangleShader.cpp
+++ b/src/gpu/ccpr/GrCCPRTriangleShader.cpp
@@ -13,16 +13,14 @@
 using Shader = GrCCPRCoverageProcessor::Shader;
 
 Shader::WindHandling GrCCPRTriangleShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                                          GrGLSLVarying::Scope scope,
                                                           SkString* code, const char* /*position*/,
                                                           const char* coverage, const char* wind) {
-    fCoverageTimesWind.reset(kHalf_GrSLType, scope);
     if (!coverage) {
         varyingHandler->addFlatVarying("wind", &fCoverageTimesWind);
-        code->appendf("%s = %s;", OutName(fCoverageTimesWind), wind);
+        code->appendf("%s = %s;", fCoverageTimesWind.gsOut(), wind);
     } else {
         varyingHandler->addVarying("coverage_times_wind", &fCoverageTimesWind);
-        code->appendf("%s = %s * %s;", OutName(fCoverageTimesWind), coverage, wind);
+        code->appendf("%s = %s * %s;", fCoverageTimesWind.gsOut(), coverage, wind);
     }
     return WindHandling::kHandled;
 }
@@ -87,23 +85,18 @@
 }
 
 Shader::WindHandling
-GrCCPRTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
-                                           GrGLSLVarying::Scope scope, SkString* code,
+GrCCPRTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler, SkString* code,
                                            const char* position, const char* coverage,
                                            const char* /*wind*/) {
     SkASSERT(!coverage);
 
-    fCornerLocationInAABoxes.reset(kFloat2x2_GrSLType, scope);
     varyingHandler->addVarying("corner_location_in_aa_boxes", &fCornerLocationInAABoxes);
-
-    fBisectInAABoxes.reset(kFloat2x2_GrSLType, scope);
     varyingHandler->addFlatVarying("bisect_in_aa_boxes", &fBisectInAABoxes);
-
     code->appendf("for (int i = 0; i < 2; ++i) {");
     code->appendf(    "%s[i] = %s * %s[i] + %s[i];",
-                      OutName(fCornerLocationInAABoxes), position, fAABoxMatrices.c_str(),
+                      fCornerLocationInAABoxes.gsOut(), position, fAABoxMatrices.c_str(),
                       fAABoxTranslates.c_str());
-    code->appendf(    "%s[i] = %s[i];", OutName(fBisectInAABoxes), fGeoShaderBisects.c_str());
+    code->appendf(    "%s[i] = %s[i];", fBisectInAABoxes.gsOut(), fGeoShaderBisects.c_str());
     code->appendf("}");
 
     return WindHandling::kNotHandled;
diff --git a/src/gpu/ccpr/GrCCPRTriangleShader.h b/src/gpu/ccpr/GrCCPRTriangleShader.h
index 02eb771..1f58e84 100644
--- a/src/gpu/ccpr/GrCCPRTriangleShader.h
+++ b/src/gpu/ccpr/GrCCPRTriangleShader.h
@@ -11,38 +11,35 @@
 #include "ccpr/GrCCPRCoverageProcessor.h"
 
 /**
- * Steps 1 & 2: Draw the triangle's conservative raster hull with a coverage of +1, then smooth the
- *              edges by drawing the conservative rasters of all 3 edges and interpolating from
- *              coverage=-1 on the outside to coverage=0 on the inside. The Impl may choose to
- *              implement these steps in either one or two actual render passes.
+ * Passes 1 & 2: Draw the triangle's conservative raster hull with a coverage of 1, then smooth the
+ *               edges by drawing the conservative rasters of all 3 edges and interpolating from
+ *               coverage=-1 on the outside to coverage=0 on the inside.
  */
 class GrCCPRTriangleShader : public GrCCPRCoverageProcessor::Shader {
-    WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
-                                const char* position, const char* coverage,
-                                const char* wind) override;
+    WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position,
+                                const char* coverage, const char* wind) override;
     void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
 
-    GrGLSLVarying fCoverageTimesWind;
+    GrGLSLVarying fCoverageTimesWind{kHalf_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
 };
 
 /**
- * Step 3: Touch up the corner pixels. Here we fix the simple distance-to-edge coverage analysis
+ * Pass 3: Touch up the corner pixels. Here we fix the simple distance-to-edge coverage analysis
  *         done previously so that it takes into account the region that is outside both edges at
  *         the same time.
  */
 class GrCCPRTriangleCornerShader : public GrCCPRCoverageProcessor::Shader {
     void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
                        const char* wind, GeometryVars*) const override;
-    WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
-                                const char* position, const char* coverage,
-                                const char* wind) override;
+    WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position,
+                                const char* coverage, const char* wind) override;
     void onEmitFragmentCode(GrGLSLPPFragmentBuilder* f, const char* outputCoverage) const override;
 
     GrShaderVar fAABoxMatrices{"aa_box_matrices", kFloat2x2_GrSLType, 2};
     GrShaderVar fAABoxTranslates{"aa_box_translates", kFloat2_GrSLType, 2};
     GrShaderVar fGeoShaderBisects{"bisects", kFloat2_GrSLType, 2};
-    GrGLSLVarying fCornerLocationInAABoxes;
-    GrGLSLVarying fBisectInAABoxes;
+    GrGLSLVarying fCornerLocationInAABoxes{kFloat2x2_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
+    GrGLSLVarying fBisectInAABoxes{kFloat2x2_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
 };
 
 #endif
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
index 6a38ee0..a239569 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
@@ -38,12 +38,14 @@
 
 bool GrCoverageCountingPathRenderer::IsSupported(const GrCaps& caps) {
     const GrShaderCaps& shaderCaps = *caps.shaderCaps();
-    return shaderCaps.integerSupport() &&
+    return shaderCaps.geometryShaderSupport() &&
+           shaderCaps.integerSupport() &&
            shaderCaps.flatInterpolationSupport() &&
            caps.instanceAttribSupport() &&
            GrCaps::kNone_MapFlags != caps.mapBufferFlags() &&
            caps.isConfigTexturable(kAlpha_half_GrPixelConfig) &&
            caps.isConfigRenderable(kAlpha_half_GrPixelConfig, /*withMSAA=*/false) &&
+           GrCaps::kNone_MapFlags != caps.mapBufferFlags() &&
            !caps.blacklistCoverageCounting();
 }
 
diff --git a/src/gpu/glsl/GrGLSLVarying.cpp b/src/gpu/glsl/GrGLSLVarying.cpp
index 5a57613..4bcce03 100644
--- a/src/gpu/glsl/GrGLSLVarying.cpp
+++ b/src/gpu/glsl/GrGLSLVarying.cpp
@@ -37,7 +37,6 @@
     VaryingInfo& v = fVaryings.push_back();
 
     SkASSERT(varying);
-    SkASSERT(kVoid_GrSLType != varying->fType);
     v.fType = varying->fType;
     v.fIsFlat = flat;
     fProgramBuilder->nameVariable(&v.fVsOut, 'v', name);
diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h
index dac9bb7..e6174a6 100644
--- a/src/gpu/glsl/GrGLSLVarying.h
+++ b/src/gpu/glsl/GrGLSLVarying.h
@@ -24,15 +24,8 @@
         kGeoToFrag
     };
 
-    GrGLSLVarying() = default;
     GrGLSLVarying(GrSLType type, Scope scope = Scope::kVertToFrag) : fType(type), fScope(scope) {}
 
-    void reset(GrSLType type, Scope scope = Scope::kVertToFrag) {
-        *this = GrGLSLVarying();
-        fType = type;
-        fScope = scope;
-    }
-
     GrSLType type() const { return fType; }
     Scope scope() const { return fScope; }
     bool isInVertexShader() const { return Scope::kGeoToFrag != fScope; }
@@ -44,8 +37,8 @@
     const char* fsIn() const { SkASSERT(this->isInFragmentShader()); return fFsIn; }
 
 private:
-    GrSLType fType = kVoid_GrSLType;
-    Scope fScope = Scope::kVertToFrag;
+    const GrSLType fType;
+    const Scope fScope;
     const char* fVsOut = nullptr;
     const char* fGsIn = nullptr;
     const char* fGsOut = nullptr;