Clarify when tweak alpha for coverage optimizaton can occur.

Also refer to it directly rather than using the term "modulate"

Change-Id: Ifa44a4d46e1be11b567943f58ead24e38f10d03b
Reviewed-on: https://skia-review.googlesource.com/8488
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h
index 96ca1c8..55dc08f 100644
--- a/include/gpu/GrFragmentProcessor.h
+++ b/include/gpu/GrFragmentProcessor.h
@@ -99,11 +99,20 @@
     }
 
     /**
-     * True if the processor's output is a modulation of its input color or alpha with a computed
-     * premultiplied color or alpha in the 0..1 range. If true and the blend mode allows it we may
-     * fold coverage into the first color fragment processor's input.
+     * A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color
+     * output under the following scenario:
+     *   * all the color fragment processors report true to this query,
+     *   * all the coverage fragment processors report true to this query,
+     *   * the blend mode arithmetic allows for it it.
+     * To be compatible a fragment processor's output must be a modulation of its input color or
+     * alpha with a computed premultiplied color or alpha that is in 0..1 range. The computed color
+     * or alpha that is modulated against the input cannot depend on the input's alpha. The computed
+     * value cannot depend on the input's color channels unless it unpremultiplies the input color
+     * channels by the input alpha.
      */
-    bool modulatesInput() const { return SkToBool(fFlags & kModulatesInput_OptimizationFlag); }
+    bool compatibleWithCoverageAsAlpha() const {
+        return SkToBool(fFlags & kCompatibleWithCoverageAsAlpha_OptimizationFlag);
+    }
 
     /**
      * If this is true then all opaque input colors to the processor produce opaque output colors.
@@ -207,10 +216,10 @@
 protected:
     enum OptimizationFlags : uint32_t {
         kNone_OptimizationFlags,
-        kModulatesInput_OptimizationFlag = 0x1,
+        kCompatibleWithCoverageAsAlpha_OptimizationFlag = 0x1,
         kPreservesOpaqueInput_OptimizationFlag = 0x2,
         kConstantOutputForConstantInput_OptimizationFlag = 0x4,
-        kAll_OptimizationFlags = kModulatesInput_OptimizationFlag |
+        kAll_OptimizationFlags = kCompatibleWithCoverageAsAlpha_OptimizationFlag |
                                  kPreservesOpaqueInput_OptimizationFlag |
                                  kConstantOutputForConstantInput_OptimizationFlag
     };
diff --git a/include/gpu/effects/GrConstColorProcessor.h b/include/gpu/effects/GrConstColorProcessor.h
index 44e8cb1..b543aa5 100644
--- a/include/gpu/effects/GrConstColorProcessor.h
+++ b/include/gpu/effects/GrConstColorProcessor.h
@@ -46,7 +46,7 @@
     static OptimizationFlags OptFlags(GrColor4f color, InputMode mode) {
         OptimizationFlags flags = kConstantOutputForConstantInput_OptimizationFlag;
         if (mode != kIgnore_InputMode) {
-            flags |= kModulatesInput_OptimizationFlag;
+            flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
         }
         if (color.isOpaque()) {
             flags |= kPreservesOpaqueInput_OptimizationFlag;
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
index f0338a6..3d0defb 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
@@ -32,9 +32,10 @@
 
 inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::OptFlags(float outerThreshold) {
     if (outerThreshold >= 1.f) {
-        return kPreservesOpaqueInput_OptimizationFlag | kModulatesInput_OptimizationFlag;
+        return kPreservesOpaqueInput_OptimizationFlag |
+               kCompatibleWithCoverageAsAlpha_OptimizationFlag;
     } else {
-        return kModulatesInput_OptimizationFlag;
+        return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
     }
 }
 
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp
index 70c4247..c95b41e 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.cpp
+++ b/src/effects/GrCircleBlurFragmentProcessor.cpp
@@ -86,7 +86,7 @@
                                                              float textureRadius,
                                                              float solidRadius,
                                                              GrTexture* blurProfile)
-        : INHERITED(kModulatesInput_OptimizationFlag)
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
         , fCircle(circle)
         , fSolidRadius(solidRadius)
         , fTextureRadius(textureRadius)
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index c070ccf..5249696 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -973,7 +973,7 @@
 
 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture* blurProfile,
                                    GrSLPrecision precision)
-        : INHERITED(kModulatesInput_OptimizationFlag)
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
         , fRect(rect)
         , fSigma(sigma)
         , fBlurProfileSampler(blurProfile)
@@ -1197,7 +1197,7 @@
 }
 
 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture* ninePatchTexture)
-        : INHERITED(kModulatesInput_OptimizationFlag)
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
         , fRRect(rrect)
         , fSigma(sigma)
         , fNinePatchSampler(ninePatchTexture) {
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index a3efbcf..e3f0f3a 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -1691,7 +1691,7 @@
                                    const SkMatrix& matrix,
                                    BoundaryMode boundaryMode,
                                    const SkIRect* srcBounds)
-        // Perhaps this could advertise the opaque or modulating optimizations?
+        // Perhaps this could advertise the opaque or coverage-as-alpha optimizations?
         : INHERITED(texture, nullptr, SkMatrix::I(), kNone_OptimizationFlags)
         , fLight(light)
         , fSurfaceScale(surfaceScale)
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 03f0cbc..23efdd3 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -1584,8 +1584,10 @@
 /////////////////////////////////////////////////////////////////////
 
 inline GrFragmentProcessor::OptimizationFlags GrGradientEffect::OptFlags(bool isOpaque) {
-    return isOpaque ? kPreservesOpaqueInput_OptimizationFlag | kModulatesInput_OptimizationFlag
-                    : kModulatesInput_OptimizationFlag;
+    return isOpaque
+                   ? kPreservesOpaqueInput_OptimizationFlag |
+                             kCompatibleWithCoverageAsAlpha_OptimizationFlag
+                   : kCompatibleWithCoverageAsAlpha_OptimizationFlag;
 }
 
 GrGradientEffect::GrGradientEffect(const CreateArgs& args, bool isOpaque)
diff --git a/src/gpu/GrProcOptInfo.cpp b/src/gpu/GrProcOptInfo.cpp
index 92e6838..9eda9bb 100644
--- a/src/gpu/GrProcOptInfo.cpp
+++ b/src/gpu/GrProcOptInfo.cpp
@@ -12,7 +12,7 @@
 void GrProcOptInfo::analyzeProcessors(const GrFragmentProcessor* const* processors, int cnt) {
     for (int i = 0; i < cnt; ++i) {
         bool knowCurrentOutput = fProcessorsVisitedWithKnownOutput == fTotalProcessorsVisited;
-        if (!knowCurrentOutput && !fAllProcessorsModulatePremul && !fIsOpaque) {
+        if (!knowCurrentOutput && !fAllProcessorsCompatibleWithCoverageAsAlpha && !fIsOpaque) {
             fTotalProcessorsVisited += cnt - i;
             return;
         }
@@ -24,8 +24,8 @@
         } else if (fIsOpaque && !fp->preservesOpaqueInput()) {
             fIsOpaque = false;
         }
-        if (fAllProcessorsModulatePremul && !fp->modulatesInput()) {
-            fAllProcessorsModulatePremul = false;
+        if (fAllProcessorsCompatibleWithCoverageAsAlpha && !fp->compatibleWithCoverageAsAlpha()) {
+            fAllProcessorsCompatibleWithCoverageAsAlpha = false;
         }
         ++fTotalProcessorsVisited;
     }
diff --git a/src/gpu/GrProcOptInfo.h b/src/gpu/GrProcOptInfo.h
index 2c55233..1a85789 100644
--- a/src/gpu/GrProcOptInfo.h
+++ b/src/gpu/GrProcOptInfo.h
@@ -52,7 +52,9 @@
                fLastKnownOutputColor == GrColor4f::OpaqueWhite();
     }
     bool isOpaque() const { return fIsOpaque; }
-    bool allProcessorsModulateByPremul() const { return fAllProcessorsModulatePremul; }
+    bool allProcessorsCompatibleWithCoverageAsAlpha() const {
+        return fAllProcessorsCompatibleWithCoverageAsAlpha;
+    }
     bool isLCDCoverage() const { return fIsLCDCoverage; }
 
     /**
@@ -91,7 +93,7 @@
     int fProcessorsVisitedWithKnownOutput = -1;
     bool fIsLCDCoverage = false;
     bool fIsOpaque = false;
-    bool fAllProcessorsModulatePremul = true;
+    bool fAllProcessorsCompatibleWithCoverageAsAlpha = true;
     GrColor4f fLastKnownOutputColor;
 };
 
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index 907a9e5..0248beb 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -31,7 +31,9 @@
 
 private:
     AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect)
-            : INHERITED(kModulatesInput_OptimizationFlag), fRect(rect), fEdgeType(edgeType) {
+            : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+            , fRect(rect)
+            , fEdgeType(edgeType) {
         this->initClassID<AARectEffect>();
     }
 
@@ -327,7 +329,9 @@
 }
 
 GrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[])
-        : INHERITED(kModulatesInput_OptimizationFlag), fEdgeType(edgeType), fEdgeCount(n) {
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+        , fEdgeType(edgeType)
+        , fEdgeCount(n) {
     this->initClassID<GrConvexPolyEffect>();
     // Factory function should have already ensured this.
     SkASSERT(n <= kMaxEdges);
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index bc11d7e..d733069 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -300,7 +300,7 @@
      */
 
     OptFlags flags = kNone_OptFlags;
-    if (analysis.fColorPOI.allProcessorsModulateByPremul()) {
+    if (analysis.fColorPOI.allProcessorsCompatibleWithCoverageAsAlpha()) {
         flags |= kCanTweakAlphaForCoverage_OptFlag;
     }
     return flags;
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index fc8add8..0cae0ba 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -159,7 +159,8 @@
                                                      GrTextureDomain::Mode tileMode,
                                                      bool convolveAlpha)
         // To advertise the preserves opaqueness optimization we'd have to examine the parameters.
-        : INHERITED(texture, nullptr, SkMatrix::I(), kModulatesInput_OptimizationFlag)
+        : INHERITED(texture, nullptr, SkMatrix::I(),
+                    kCompatibleWithCoverageAsAlpha_OptimizationFlag)
         , fKernelSize(kernelSize)
         , fGain(SkScalarToFloat(gain))
         , fBias(SkScalarToFloat(bias) / 255.0f)
diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
index 36db836..62b1c52 100644
--- a/src/gpu/effects/GrOvalEffect.cpp
+++ b/src/gpu/effects/GrOvalEffect.cpp
@@ -57,7 +57,10 @@
 }
 
 CircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r)
-        : INHERITED(kModulatesInput_OptimizationFlag), fCenter(c), fRadius(r), fEdgeType(edgeType) {
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+        , fCenter(c)
+        , fRadius(r)
+        , fEdgeType(edgeType) {
     this->initClassID<CircleEffect>();
 }
 
@@ -219,7 +222,7 @@
 
 EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx,
                              SkScalar ry)
-        : INHERITED(kModulatesInput_OptimizationFlag)
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
         , fCenter(c)
         , fRadii(SkVector::Make(rx, ry))
         , fEdgeType(edgeType) {
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index a04bb5b..ead4ed6 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -465,7 +465,7 @@
         if (!fBlendFormula.usesInputColor()) {
             optFlags |= GrXferProcessor::kIgnoreColor_OptFlag;
         }
-        if (analysis.fColorPOI.allProcessorsModulateByPremul() &&
+        if (analysis.fColorPOI.allProcessorsCompatibleWithCoverageAsAlpha() &&
             fBlendFormula.canTweakAlphaForCoverage() && !analysis.fCoveragePOI.isLCDCoverage()) {
             optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag;
         }
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 29d3d3d..7253de8 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -88,7 +88,7 @@
 
 CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t circularCornerFlags,
                                          const SkRRect& rrect)
-        : INHERITED(kModulatesInput_OptimizationFlag)
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
         , fRRect(rrect)
         , fEdgeType(edgeType)
         , fCircularCornerFlags(circularCornerFlags) {
@@ -421,7 +421,9 @@
 }
 
 EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect)
-        : INHERITED(kModulatesInput_OptimizationFlag), fRRect(rrect), fEdgeType(edgeType) {
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+        , fRRect(rrect)
+        , fEdgeType(edgeType) {
     this->initClassID<EllipticalRRectEffect>();
 }
 
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
index 894334b..74b25c7 100644
--- a/src/gpu/effects/GrSingleTextureEffect.h
+++ b/src/gpu/effects/GrSingleTextureEffect.h
@@ -54,15 +54,17 @@
                           sk_sp<GrColorSpaceXform>, const SkMatrix&, const GrSamplerParams&);
 
     /**
-     * Can be used as a helper to implement subclass onOptimizationFlags(). It assumes that
-     * the subclass output color will be a modulation of the input color with a value read from the
-     * texture.
+     * Can be used as a helper to decide which fragment processor OptimizationFlags should be set.
+     * This assumes that the subclass output color will be a modulation of the input color with a
+     * value read from the texture and that the texture contains premultiplied color or alpha values
+     * that are in range.
      */
     static OptimizationFlags ModulationFlags(GrPixelConfig config) {
         if (GrPixelConfigIsOpaque(config)) {
-            return kModulatesInput_OptimizationFlag | kPreservesOpaqueInput_OptimizationFlag;
+            return kCompatibleWithCoverageAsAlpha_OptimizationFlag |
+                   kPreservesOpaqueInput_OptimizationFlag;
         } else {
-            return kModulatesInput_OptimizationFlag;
+            return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
         }
     }
 
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 142cd1d..39bc3cc 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -251,9 +251,9 @@
 inline GrFragmentProcessor::OptimizationFlags GrTextureDomainEffect::OptFlags(
         GrPixelConfig config, GrTextureDomain::Mode mode) {
     if (mode == GrTextureDomain::kDecal_Mode || !GrPixelConfigIsOpaque(config)) {
-        return GrFragmentProcessor::kModulatesInput_OptimizationFlag;
+        return GrFragmentProcessor::kCompatibleWithCoverageAsAlpha_OptimizationFlag;
     } else {
-        return GrFragmentProcessor::kModulatesInput_OptimizationFlag |
+        return GrFragmentProcessor::kCompatibleWithCoverageAsAlpha_OptimizationFlag |
                GrFragmentProcessor::kPreservesOpaqueInput_OptimizationFlag;
     }
 }
@@ -398,7 +398,7 @@
 
 GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor(
         GrTexture* texture, const SkIRect& subset, const SkIPoint& deviceSpaceOffset)
-        : INHERITED(kModulatesInput_OptimizationFlag)
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
         , fTextureSampler(texture, GrSamplerParams::ClampNoFilter())
         , fTextureDomain(texture, GrTextureDomain::MakeTexelDomain(subset),
                          GrTextureDomain::kDecal_Mode) {
@@ -422,7 +422,7 @@
         sk_sp<GrTextureProxy> proxy,
         const SkIRect& subset,
         const SkIPoint& deviceSpaceOffset)
-        : INHERITED(kModulatesInput_OptimizationFlag)
+        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
         , fTextureSampler(context->textureProvider(), proxy, GrSamplerParams::ClampNoFilter())
         , fTextureDomain(proxy.get(), GrTextureDomain::MakeTexelDomain(subset),
                          GrTextureDomain::kDecal_Mode) {
diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
index 5433b67..8488fec 100644
--- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
+++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
@@ -289,9 +289,12 @@
             case SkBlendMode::kSrcIn:
             case SkBlendMode::kDstIn:
             case SkBlendMode::kModulate:
-                flags = fp->preservesOpaqueInput()
-                        ? kPreservesOpaqueInput_OptimizationFlag | kModulatesInput_OptimizationFlag
-                        : kModulatesInput_OptimizationFlag;
+                if (fp->preservesOpaqueInput()) {
+                    flags = kPreservesOpaqueInput_OptimizationFlag |
+                            kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+                } else {
+                    flags = kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+                }
                 break;
 
             // Produces zero when both are opaque, indeterminate if one is opaque.
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index a69371d..8801a34 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -316,7 +316,7 @@
         for (int j = 0; j < timesToInvokeFactory; ++j) {
             fp = FPFactory::MakeIdx(i, &testData);
             if (!fp->hasConstantOutputForConstantInput() && !fp->preservesOpaqueInput() &&
-                !fp->modulatesInput()) {
+                !fp->compatibleWithCoverageAsAlpha()) {
                 continue;
             }
             test_draw_op(rtc.get(), fp, dataTexture.get());
@@ -340,7 +340,7 @@
                 for (int x = 0; x < 256 && passing; ++x) {
                     GrColor input = texel_color(x, y);
                     GrColor output = rgbaData.get()[y * 256 + x];
-                    if (fp->modulatesInput()) {
+                    if (fp->compatibleWithCoverageAsAlpha()) {
                         // A modulating processor is allowed to modulate either the input color or
                         // just the input alpha.
                         bool legalColorModulation =