ccpr: Don't do coverage count transformations on literal coverage atlases

Previously we would just run coverage count transformations on
everything, including cached literal coverage atlases. This was
wasteful since it isn't necessary if the atlas already has literal
coverage. MSAA mode will introduce even more atlases that don't need
coverage count transformations, so it's definitely time to clean this
up.

Bug: skia:
Change-Id: Ifc72eaa7cbd4ab5e4ef4acb5610117ae9f54e4c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/227144
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
index b1e5ab8..ed9a004 100644
--- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp
+++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
@@ -357,7 +357,9 @@
                               == fCacheEntry->cachedAtlas()->coverageType())
                     ? SkPMColor4f{0,0,.25,.25} : SkPMColor4f{0,.25,0,.25};
 #endif
-            op->recordInstance(fCacheEntry->cachedAtlas()->getOnFlushProxy(),
+            auto coverageMode = GrCCPathProcessor::GetCoverageMode(
+                    fCacheEntry->cachedAtlas()->coverageType());
+            op->recordInstance(coverageMode, fCacheEntry->cachedAtlas()->getOnFlushProxy(),
                                resources->nextPathInstanceIdx());
             resources->appendDrawPathInstance().set(
                     *fCacheEntry, fCachedMaskShift, SkPMColor4f_toFP16(fColor), doEvenOddFill);
@@ -375,7 +377,8 @@
     if (auto atlas = resources->renderShapeInAtlas(
                 fMaskDevIBounds, fMatrix, fShape, fStrokeDevWidth, &octoBounds, &devIBounds,
                 &devToAtlasOffset)) {
-        op->recordInstance(atlas->textureProxy(), resources->nextPathInstanceIdx());
+        op->recordInstance(GrCCPathProcessor::CoverageMode::kCoverageCount, atlas->textureProxy(),
+                           resources->nextPathInstanceIdx());
         resources->appendDrawPathInstance().set(
                 octoBounds, devToAtlasOffset, SkPMColor4f_toFP16(fColor), doEvenOddFill);
 
@@ -389,16 +392,16 @@
     }
 }
 
-inline void GrCCDrawPathsOp::recordInstance(GrTextureProxy* atlasProxy, int instanceIdx) {
+inline void GrCCDrawPathsOp::recordInstance(
+        GrCCPathProcessor::CoverageMode coverageMode, GrTextureProxy* atlasProxy, int instanceIdx) {
     if (fInstanceRanges.empty()) {
-        fInstanceRanges.push_back({atlasProxy, instanceIdx});
-        return;
-    }
-    if (fInstanceRanges.back().fAtlasProxy != atlasProxy) {
+        fInstanceRanges.push_back({coverageMode, atlasProxy, instanceIdx});
+    } else if (fInstanceRanges.back().fAtlasProxy != atlasProxy) {
         fInstanceRanges.back().fEndInstanceIdx = instanceIdx;
-        fInstanceRanges.push_back({atlasProxy, instanceIdx});
-        return;
+        fInstanceRanges.push_back({coverageMode, atlasProxy, instanceIdx});
     }
+    SkASSERT(fInstanceRanges.back().fCoverageMode == coverageMode);
+    SkASSERT(fInstanceRanges.back().fAtlasProxy == atlasProxy);
 }
 
 void GrCCDrawPathsOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
@@ -427,7 +430,7 @@
         SkASSERT(atlas->isInstantiated());
 
         GrCCPathProcessor pathProc(
-                atlas->peekTexture(), atlas->textureSwizzle(), atlas->origin(),
+                range.fCoverageMode, atlas->peekTexture(), atlas->textureSwizzle(), atlas->origin(),
                 fViewMatrixIfUsingLocalCoords);
         GrTextureProxy* atlasProxy = range.fAtlasProxy;
         fixedDynamicState.fPrimitiveProcessorTextures = &atlasProxy;
diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.h b/src/gpu/ccpr/GrCCDrawPathsOp.h
index 1f95138..2b607e1 100644
--- a/src/gpu/ccpr/GrCCDrawPathsOp.h
+++ b/src/gpu/ccpr/GrCCDrawPathsOp.h
@@ -84,7 +84,8 @@
                     const SkIRect& shapeConservativeIBounds, const SkIRect& maskDevIBounds,
                     const SkRect& conservativeDevBounds, GrPaint&&);
 
-    void recordInstance(GrTextureProxy* atlasProxy, int instanceIdx);
+    void recordInstance(
+            GrCCPathProcessor::CoverageMode, GrTextureProxy* atlasProxy, int instanceIdx);
 
     const SkMatrix fViewMatrixIfUsingLocalCoords;
 
@@ -133,6 +134,7 @@
     GrProcessorSet fProcessors;
 
     struct InstanceRange {
+        GrCCPathProcessor::CoverageMode fCoverageMode;
         GrTextureProxy* fAtlasProxy;
         int fEndInstanceIdx;
     };
diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp
index 72a0932..8b8af8a 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPathProcessor.cpp
@@ -79,10 +79,11 @@
     }
 }
 
-GrCCPathProcessor::GrCCPathProcessor(const GrTexture* atlasTexture, const GrSwizzle& swizzle,
-                                     GrSurfaceOrigin atlasOrigin,
+GrCCPathProcessor::GrCCPathProcessor(CoverageMode coverageMode, const GrTexture* atlasTexture,
+                                     const GrSwizzle& swizzle, GrSurfaceOrigin atlasOrigin,
                                      const SkMatrix& viewMatrixIfUsingLocalCoords)
         : INHERITED(kGrCCPathProcessor_ClassID)
+        , fCoverageMode(coverageMode)
         , fAtlasAccess(atlasTexture->texturePriv().textureType(), atlasTexture->config(),
                        GrSamplerState::Filter::kNearest, GrSamplerState::WrapMode::kClamp, swizzle)
         , fAtlasSize(SkISize::Make(atlasTexture->width(), atlasTexture->height()))
@@ -150,6 +151,7 @@
     const GrCCPathProcessor& proc = args.fGP.cast<GrCCPathProcessor>();
     GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
     GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
+    bool isCoverageCount = (CoverageMode::kCoverageCount == proc.fCoverageMode);
 
     const char* atlasAdjust;
     fAtlasAdjustUniform = uniHandler->addUniform(
@@ -157,9 +159,10 @@
 
     varyingHandler->emitAttributes(proc);
 
-    GrGLSLVarying texcoord(kFloat3_GrSLType);
-    GrGLSLVarying color(kHalf4_GrSLType);
+    GrGLSLVarying texcoord((isCoverageCount) ? kFloat3_GrSLType : kFloat2_GrSLType);
     varyingHandler->addVarying("texcoord", &texcoord);
+
+    GrGLSLVarying color(kHalf4_GrSLType);
     varyingHandler->addPassThroughAttribute(
             kInstanceAttribs[kColorAttribIdx], args.fOutputColor, Interpolation::kCanBeFlat);
 
@@ -197,9 +200,9 @@
                            "? float2(N[0].x, N[1].y)"
                            ": float2(N[1].x, N[0].y);");
     v->codeAppendf("octocoord = (ceil(octocoord * bloatdir - 1e-4) + 0.25) * bloatdir;");
+    v->codeAppendf("float2 atlascoord = octocoord + float2(dev_to_atlas_offset);");
 
     // Convert to atlas coordinates in order to do our texture lookup.
-    v->codeAppendf("float2 atlascoord = octocoord + float2(dev_to_atlas_offset);");
     if (kTopLeft_GrSurfaceOrigin == proc.fAtlasOrigin) {
         v->codeAppendf("%s.xy = atlascoord * %s;", texcoord.vsOut(), atlasAdjust);
     } else {
@@ -207,7 +210,9 @@
         v->codeAppendf("%s.xy = float2(atlascoord.x * %s.x, 1 - atlascoord.y * %s.y);",
                        texcoord.vsOut(), atlasAdjust, atlasAdjust);
     }
-    v->codeAppendf("%s.z = wind * .5;", texcoord.vsOut());
+    if (isCoverageCount) {
+        v->codeAppendf("%s.z = wind * .5;", texcoord.vsOut());
+    }
 
     gpArgs->fPositionVar.set(kFloat2_GrSLType, "octocoord");
     this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, proc.fLocalMatrix,
@@ -216,19 +221,24 @@
     // Fragment shader.
     GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
 
-    // Look up coverage count in the atlas.
-    f->codeAppend ("half coverage = ");
+    // Look up coverage in the atlas.
+    f->codeAppendf("half coverage = ");
     f->appendTextureLookup(args.fTexSamplers[0], SkStringPrintf("%s.xy", texcoord.fsIn()).c_str(),
                            kFloat2_GrSLType);
-    f->codeAppend (".a;");
+    f->codeAppendf(".a;");
 
-    // Scale coverage count by .5. Make it negative for even-odd paths and positive for winding
-    // ones. Clamp winding coverage counts at 1.0 (i.e. min(coverage/2, .5)).
-    f->codeAppendf("coverage = min(abs(coverage) * half(%s.z), .5);", texcoord.fsIn());
+    if (isCoverageCount) {
+        f->codeAppendf("coverage = abs(coverage);");
 
-    // For negative values, this finishes the even-odd sawtooth function. Since positive (winding)
-    // values were clamped at "coverage/2 = .5", this only undoes the previous multiply by .5.
-    f->codeAppend ("coverage = 1 - abs(fract(coverage) * 2 - 1);");
+        // Scale coverage count by .5. Make it negative for even-odd paths and positive for
+        // winding ones. Clamp winding coverage counts at 1.0 (i.e. min(coverage/2, .5)).
+        f->codeAppendf("coverage = min(abs(coverage) * half(%s.z), .5);", texcoord.fsIn());
+
+        // For negative values, this finishes the even-odd sawtooth function. Since positive
+        // (winding) values were clamped at "coverage/2 = .5", this only undoes the previous
+        // multiply by .5.
+        f->codeAppend ("coverage = 1 - abs(fract(coverage) * 2 - 1);");
+    }
 
     f->codeAppendf("%s = half4(coverage);", args.fOutputCoverage);
 }
diff --git a/src/gpu/ccpr/GrCCPathProcessor.h b/src/gpu/ccpr/GrCCPathProcessor.h
index 7a5d8f6..ac97fd8 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.h
+++ b/src/gpu/ccpr/GrCCPathProcessor.h
@@ -13,6 +13,7 @@
 #include "src/gpu/GrCaps.h"
 #include "src/gpu/GrGeometryProcessor.h"
 #include "src/gpu/GrPipeline.h"
+#include "src/gpu/ccpr/GrCCAtlas.h"
 #include "src/gpu/ccpr/GrOctoBounds.h"
 
 class GrCCPathCacheEntry;
@@ -53,11 +54,26 @@
     static sk_sp<const GrGpuBuffer> FindVertexBuffer(GrOnFlushResourceProvider*);
     static sk_sp<const GrGpuBuffer> FindIndexBuffer(GrOnFlushResourceProvider*);
 
-    GrCCPathProcessor(const GrTexture* atlasTexture, const GrSwizzle&, GrSurfaceOrigin atlasOrigin,
-                      const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I());
+    enum class CoverageMode : bool {
+        kCoverageCount,
+        kLiteral
+    };
+
+    static CoverageMode GetCoverageMode(GrCCAtlas::CoverageType coverageType) {
+        return (GrCCAtlas::CoverageType::kFP16_CoverageCount == coverageType)
+                ? CoverageMode::kCoverageCount
+                : CoverageMode::kLiteral;
+    }
+
+    GrCCPathProcessor(
+            CoverageMode, const GrTexture* atlasTexture, const GrSwizzle&,
+            GrSurfaceOrigin atlasOrigin,
+            const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I());
 
     const char* name() const override { return "GrCCPathProcessor"; }
-    void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
+    void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
+        b->add32((uint32_t)fCoverageMode);
+    }
     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
 
     void drawPaths(GrOpFlushState*, const GrPipeline&, const GrPipeline::FixedDynamicState*,
@@ -67,6 +83,7 @@
 private:
     const TextureSampler& onTextureSampler(int) const override { return fAtlasAccess; }
 
+    const CoverageMode fCoverageMode;
     const TextureSampler fAtlasAccess;
     SkISize fAtlasSize;
     GrSurfaceOrigin fAtlasOrigin;
diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp
index 33ac61b..2f7ac99 100644
--- a/src/gpu/ccpr/GrCCPerFlushResources.cpp
+++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp
@@ -82,8 +82,9 @@
         auto srcProxy = fSrcProxy.get();
         SkASSERT(srcProxy->isInstantiated());
 
-        GrCCPathProcessor pathProc(srcProxy->peekTexture(), srcProxy->textureSwizzle(),
-                                   srcProxy->origin());
+        GrCCPathProcessor pathProc(
+                GrCCPathProcessor::CoverageMode::kCoverageCount, srcProxy->peekTexture(),
+                srcProxy->textureSwizzle(), srcProxy->origin());
 
         GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kSrc,
                             flushState->drawOpArgs().fOutputSwizzle);