Simplify GrProcOptInfo initialization.

Removes unused single channel tracking.

Makes it so that only the op/gp can initiate lcd coverage.

Makes GrProcOptInfo fragment processor analysis continuable.

Change-Id: I003a8aa3836bb64d04b230ddee581dc500e613a9
Reviewed-on: https://skia-review.googlesource.com/7039
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/gn/gpu.gni b/gn/gpu.gni
index eebbd74..61dea74 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -114,7 +114,6 @@
   "$_src/gpu/GrGpuFactory.h",
   "$_src/gpu/GrImageTextureMaker.cpp",
   "$_src/gpu/GrImageTextureMaker.h",
-  "$_src/gpu/GrInvariantOutput.cpp",
   "$_src/gpu/GrMemoryPool.cpp",
   "$_src/gpu/GrMemoryPool.h",
   "$_src/gpu/GrMesh.h",
diff --git a/include/gpu/GrInvariantOutput.h b/include/gpu/GrInvariantOutput.h
index af75a40..61ec77d 100644
--- a/include/gpu/GrInvariantOutput.h
+++ b/include/gpu/GrInvariantOutput.h
@@ -18,42 +18,35 @@
     GrPipelineInput()
             : fValidFlags(kNone_GrColorComponentFlags)
             , fColor(0)
-            , fIsSingleComponent(false)
             , fIsLCDCoverage(false) {}
 
     void setKnownFourComponents(GrColor color) {
         fColor = color;
         fValidFlags = kRGBA_GrColorComponentFlags;
-        fIsSingleComponent = false;
     }
 
     void setUnknownFourComponents() {
         fValidFlags = kNone_GrColorComponentFlags;
-        fIsSingleComponent = false;
     }
 
     void setUnknownOpaqueFourComponents() {
         fColor = 0xffU << GrColor_SHIFT_A;
         fValidFlags = kA_GrColorComponentFlag;
-        fIsSingleComponent = false;
     }
 
     void setKnownSingleComponent(uint8_t alpha) {
         fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
         fValidFlags = kRGBA_GrColorComponentFlags;
-        fIsSingleComponent = true;
     }
 
     void setUnknownSingleComponent() {
         fValidFlags = kNone_GrColorComponentFlags;
-        fIsSingleComponent = true;
     }
 
     void setUsingLCDCoverage() { fIsLCDCoverage = true; }
 
     GrColorComponentFlags   fValidFlags;
     GrColor                 fColor;
-    bool                    fIsSingleComponent;
     bool                    fIsLCDCoverage; // Temorary data member until texture pixel configs are
                                             // updated
 };
@@ -61,21 +54,17 @@
 /** This describes the output of a GrFragmentProcessor in a GrPipeline. */
 class GrInvariantOutput {
 public:
-    GrInvariantOutput(GrColor color, GrColorComponentFlags flags, bool isSingleComponent)
-        : fColor(color)
-        , fValidFlags(flags)
-        , fIsSingleComponent(isSingleComponent)
-        , fNonMulStageFound(false)
-        , fWillUseInputColor(true)
-        , fIsLCDCoverage(false) {}
+    GrInvariantOutput(GrColor color, GrColorComponentFlags flags)
+            : fColor(color)
+            , fValidFlags(flags)
+            , fNonMulStageFound(false)
+            , fWillUseInputColor(true) {}
 
     GrInvariantOutput(const GrPipelineInput& input)
             : fColor(input.fColor)
             , fValidFlags(input.fValidFlags)
-            , fIsSingleComponent(input.fIsSingleComponent)
             , fNonMulStageFound(false)
-            , fWillUseInputColor(false)
-            , fIsLCDCoverage(input.fIsLCDCoverage) {}
+            , fWillUseInputColor(false) {}
 
     virtual ~GrInvariantOutput() {}
 
@@ -88,7 +77,6 @@
         SkDEBUGCODE(this->validate());
         if (this->isOpaque()) {
             fValidFlags = kA_GrColorComponentFlag;
-            fIsSingleComponent = false;
         } else {
             // Since the current state is not opaque we no longer care if the color being
             // multiplied is opaque.
@@ -147,9 +135,6 @@
                     SkMulDiv255Round(GrColorUnpackG(fColor), GrColorUnpackG(color)),
                     SkMulDiv255Round(GrColorUnpackB(fColor), GrColorUnpackB(color)),
                     SkMulDiv255Round(GrColorUnpackA(fColor), a));
-                if (kRGBA_GrColorComponentFlags == fValidFlags) {
-                    fIsSingleComponent = GetAlphaAndCheckSingleChannel(fColor, &a);
-                }
             }
         }
         SkDEBUGCODE(this->validate());
@@ -167,7 +152,6 @@
                 this->internalSetToTransparentBlack();
             } else {
                 // We know that color has different component values
-                fIsSingleComponent = false;
                 fColor = GrColorPackRGBA(
                     SkMulDiv255Round(preAlpha, GrColorUnpackR(color)),
                     SkMulDiv255Round(preAlpha, GrColorUnpackG(color)),
@@ -176,7 +160,6 @@
                 fValidFlags = kRGBA_GrColorComponentFlags;
             }
         } else {
-            fIsSingleComponent = false;
             fValidFlags = kNone_GrColorComponentFlags;
         }
         SkDEBUGCODE(this->validate());
@@ -197,14 +180,12 @@
             } else {
                 fValidFlags = kNone_GrColorComponentFlags;
             }
-            fIsSingleComponent = true;
         }
         SkDEBUGCODE(this->validate());
     }
 
     void premulFourChannelColor() {
         SkDEBUGCODE(this->validate());
-        SkASSERT(!fIsSingleComponent);
         fNonMulStageFound = true;
         if (!(fValidFlags & kA_GrColorComponentFlag)) {
             fValidFlags = kNone_GrColorComponentFlags;
@@ -217,7 +198,6 @@
     void invalidateComponents(GrColorComponentFlags invalidateFlags, ReadInput readsInput) {
         SkDEBUGCODE(this->validate());
         fValidFlags = (fValidFlags & ~invalidateFlags);
-        fIsSingleComponent = false;
         fNonMulStageFound = true;
         if (kWillNot_ReadInput == readsInput) {
             fWillUseInputColor = false;
@@ -229,16 +209,11 @@
         SkDEBUGCODE(this->validate());
         fValidFlags = validFlags;
         fColor = color;
-        fIsSingleComponent = false;
         fNonMulStageFound = true;
         if (kWillNot_ReadInput == readsInput) {
             fWillUseInputColor = false;
         }
         if (kRGBA_GrColorComponentFlags == fValidFlags) {
-            uint32_t a;
-            if (GetAlphaAndCheckSingleChannel(color, &a)) {
-                fIsSingleComponent = true;
-            }
         }
         SkDEBUGCODE(this->validate());
     }
@@ -253,21 +228,16 @@
         SkDEBUGCODE(this->validate());
     }
 
-    // Temporary setter to handle LCD text correctly until we improve texture pixel config queries
-    // and thus can rely solely on number of coverage components for RGA vs single channel coverage.
-    void setUsingLCDCoverage() {
-        fIsLCDCoverage = true;
-    }
-
     GrColor color() const { return fColor; }
     GrColorComponentFlags validFlags() const { return fValidFlags; }
     bool willUseInputColor() const { return fWillUseInputColor; }
 
-    /**
-     * If isSingleComponent is true, then the flag values for r, g, b, and a must all be the
-     * same. If the flags are all set then all color components must be equal.
-     */
-    SkDEBUGCODE(void validate() const;)
+#ifdef SK_DEBUG
+    void validate() const {
+        // If we claim that we are not using the input color we must not be modulating the input.
+        SkASSERT(fNonMulStageFound || fWillUseInputColor);
+    }
+#endif
 
 private:
     friend class GrProcOptInfo;
@@ -279,10 +249,9 @@
                *alpha == GrColorUnpackB(color);
     }
 
-    void reset(GrColor color, GrColorComponentFlags flags, bool isSingleComponent) {
+    void reset(GrColor color, GrColorComponentFlags flags) {
         fColor = color;
         fValidFlags = flags;
-        fIsSingleComponent = isSingleComponent;
         fNonMulStageFound = false;
         fWillUseInputColor = true;
     }
@@ -290,21 +259,17 @@
     void reset(const GrPipelineInput& input) {
         fColor = input.fColor;
         fValidFlags = input.fValidFlags;
-        fIsSingleComponent = input.fIsSingleComponent;
         fNonMulStageFound = false;
         fWillUseInputColor = true;
-        fIsLCDCoverage = input.fIsLCDCoverage;
     }
 
     void internalSetToTransparentBlack() {
         fValidFlags = kRGBA_GrColorComponentFlags;
         fColor = 0;
-        fIsSingleComponent = true;
     }
 
     void internalSetToUnknown() {
         fValidFlags = kNone_GrColorComponentFlags;
-        fIsSingleComponent = false;
     }
 
     bool hasZeroAlpha() const {
@@ -319,16 +284,11 @@
         return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor);
     }
 
-    bool isSingleComponent() const { return fIsSingleComponent; }
-
     void resetWillUseInputColor() { fWillUseInputColor = true; }
 
     bool allStagesMulInput() const { return !fNonMulStageFound; }
     void resetNonMulStageFound() { fNonMulStageFound = false; }
 
-    bool isLCDCoverage() const { return fIsLCDCoverage; }
-
-    SkDEBUGCODE(bool colorComponentsAllEqual() const;)
     /**
      * If alpha is valid, check that any valid R,G,B values are <= A
      */
@@ -336,11 +296,8 @@
 
     GrColor fColor;
     GrColorComponentFlags fValidFlags;
-    bool fIsSingleComponent;
     bool fNonMulStageFound;
     bool fWillUseInputColor;
-    bool fIsLCDCoverage; // Temorary data member until texture pixel configs are updated
-
 };
 
 #endif
diff --git a/src/core/SkModeColorFilter.cpp b/src/core/SkModeColorFilter.cpp
index fb09c27..58127d3 100644
--- a/src/core/SkModeColorFilter.cpp
+++ b/src/core/SkModeColorFilter.cpp
@@ -129,8 +129,7 @@
     // (at least for coeff modes)
     if ((unsigned)fMode <= (unsigned)SkBlendMode::kLastCoeffMode) {
         static SkRandom gRand;
-        GrInvariantOutput io(GrPremulColor(gRand.nextU()), kRGBA_GrColorComponentFlags,
-                                false);
+        GrInvariantOutput io(GrPremulColor(gRand.nextU()), kRGBA_GrColorComponentFlags);
         fp->computeInvariantOutput(&io);
         SkASSERT(io.validFlags() == kRGBA_GrColorComponentFlags);
     }
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 75b6af7..977974d 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -185,7 +185,7 @@
                 return;
             }
 
-            GrInvariantOutput childOutput(GrColor_WHITE, kRGBA_GrColorComponentFlags, false);
+            GrInvariantOutput childOutput(GrColor_WHITE, kRGBA_GrColorComponentFlags);
             this->childProcessor(0).computeInvariantOutput(&childOutput);
 
             if (0 == GrColorUnpackA(inout->color()) || 0 == GrColorUnpackA(childOutput.color())) {
@@ -280,7 +280,7 @@
         GrColor4f fColor;
     };
 
-    GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags, false);
+    GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags);
     fp->computeInvariantOutput(&childOut);
     if (childOut.willUseInputColor()) {
         return sk_sp<GrFragmentProcessor>(new ReplaceInputFragmentProcessor(std::move(fp), color));
@@ -329,9 +329,6 @@
         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
 
         void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
-            GrProcOptInfo info;
-            info.calcWithInitialValues(fChildProcessors.begin(), fChildProcessors.count(),
-                                       inout->color(), inout->validFlags(), false, false);
             for (int i = 0; i < this->numChildProcessors(); ++i) {
                 this->childProcessor(i).computeInvariantOutput(inout);
             }
@@ -343,9 +340,8 @@
     }
 
     // Run the through the series, do the invariant output processing, and look for eliminations.
-    GrProcOptInfo info;
-    info.calcWithInitialValues(sk_sp_address_as_pointer_address(series), cnt,
-                               0x0, kNone_GrColorComponentFlags, false, false);
+    GrProcOptInfo info(0x0, kNone_GrColorComponentFlags);
+    info.addProcessors(sk_sp_address_as_pointer_address(series), cnt);
     if (kRGBA_GrColorComponentFlags == info.validFlags()) {
         // TODO: We need to preserve 4f and color spaces during invariant processing. This color
         // has definitely lost precision, and could easily be in the wrong gamut (or have been
diff --git a/src/gpu/GrInvariantOutput.cpp b/src/gpu/GrInvariantOutput.cpp
deleted file mode 100644
index ee64d33..0000000
--- a/src/gpu/GrInvariantOutput.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrInvariantOutput.h"
-
-#ifdef SK_DEBUG
-
-void GrInvariantOutput::validate() const {
-    if (fIsSingleComponent) {
-        SkASSERT(0 == fValidFlags || kRGBA_GrColorComponentFlags == fValidFlags);
-        if (kRGBA_GrColorComponentFlags == fValidFlags) {
-            SkASSERT(this->colorComponentsAllEqual());
-        }
-    }
-
-    // If we claim that we are not using the input color we must not be modulating the input.
-    SkASSERT(fNonMulStageFound || fWillUseInputColor);
-}
-
-bool GrInvariantOutput::colorComponentsAllEqual() const {
-    unsigned colorA = GrColorUnpackA(fColor);
-    return(GrColorUnpackR(fColor) == colorA &&
-           GrColorUnpackG(fColor) == colorA &&
-           GrColorUnpackB(fColor) == colorA);
-}
-
-#endif // end DEBUG
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index 122d87e..7143b46 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -45,10 +45,9 @@
 }
 
 bool GrPaint::internalIsConstantBlendedColor(GrColor paintColor, GrColor* color) const {
-    GrProcOptInfo colorProcInfo;
-    colorProcInfo.calcWithInitialValues(
-        sk_sp_address_as_pointer_address(fColorFragmentProcessors.begin()),
-        this->numColorFragmentProcessors(), paintColor, kRGBA_GrColorComponentFlags, false);
+    GrProcOptInfo colorProcInfo(paintColor, kRGBA_GrColorComponentFlags);
+    colorProcInfo.addProcessors(sk_sp_address_as_pointer_address(fColorFragmentProcessors.begin()),
+                                this->numColorFragmentProcessors());
 
     GrXPFactory::InvariantBlendedColor blendedColor;
     if (fXPFactory) {
diff --git a/src/gpu/GrProcOptInfo.cpp b/src/gpu/GrProcOptInfo.cpp
index 5e61254..1493206 100644
--- a/src/gpu/GrProcOptInfo.cpp
+++ b/src/gpu/GrProcOptInfo.cpp
@@ -6,35 +6,10 @@
  */
 
 #include "GrProcOptInfo.h"
-
 #include "GrGeometryProcessor.h"
-
 #include "ops/GrDrawOp.h"
 
-void GrProcOptInfo::calcWithInitialValues(const GrFragmentProcessor * const processors[],
-                                          int cnt,
-                                          GrColor startColor,
-                                          GrColorComponentFlags flags,
-                                          bool areCoverageStages,
-                                          bool isLCD) {
-    GrPipelineInput out;
-    out.fIsSingleComponent = areCoverageStages;
-    out.fColor = startColor;
-    out.fValidFlags = flags;
-    out.fIsLCDCoverage = isLCD;
-    fInOut.reset(out);
-    this->internalCalc(processors, cnt);
-}
-
-void GrProcOptInfo::completeCalculations(const GrFragmentProcessor * const processors[], int cnt) {
-    this->internalCalc(processors, cnt);
-}
-
-void GrProcOptInfo::internalCalc(const GrFragmentProcessor* const processors[], int cnt) {
-    fFirstEffectiveProcessorIndex = 0;
-    fInputColorIsUsed = true;
-    fInputColor = fInOut.color();
-
+void GrProcOptInfo::addProcessors(const GrFragmentProcessor* const* processors, int cnt) {
     for (int i = 0; i < cnt; ++i) {
         const GrFragmentProcessor* processor = processors[i];
         fInOut.resetWillUseInputColor();
diff --git a/src/gpu/GrProcOptInfo.h b/src/gpu/GrProcOptInfo.h
index d70ec46..8149f2c 100644
--- a/src/gpu/GrProcOptInfo.h
+++ b/src/gpu/GrProcOptInfo.h
@@ -22,33 +22,35 @@
  */
 class GrProcOptInfo {
 public:
-    GrProcOptInfo()
-        : fInOut(0, static_cast<GrColorComponentFlags>(0), false)
-        , fFirstEffectiveProcessorIndex(0)
-        , fInputColorIsUsed(true)
-        , fInputColor(0) {}
+    GrProcOptInfo() : fInOut(0, static_cast<GrColorComponentFlags>(0)) {}
 
-    void calcWithInitialValues(const GrFragmentProcessor* const *, int cnt, GrColor startColor,
-                               GrColorComponentFlags, bool areCoverageStages, bool isLCD = false);
-    void initFromPipelineInput(const GrPipelineInput& input) { fInOut.reset(input); }
-    void completeCalculations(const GrFragmentProcessor * const processors[], int cnt);
+    GrProcOptInfo(GrColor color, GrColorComponentFlags colorFlags)
+            : fInOut(color, colorFlags), fInputColor(color) {}
+
+    void resetToLCDCoverage(GrColor color, GrColorComponentFlags colorFlags) {
+        this->internalReset(color, colorFlags, true);
+    }
+
+    void reset(GrColor color, GrColorComponentFlags colorFlags) {
+        this->internalReset(color, colorFlags, false);
+    }
+
+    void reset(const GrPipelineInput& input) {
+        this->internalReset(input.fColor, input.fValidFlags, input.fIsLCDCoverage);
+    }
+
+    /**
+     * Runs through a series of processors and updates calculated values. This can be called
+     * repeatedly for cases when the sequence of processors is not in a contiguous array.
+     */
+    void addProcessors(const GrFragmentProcessor* const* processors, int cnt);
 
     bool isSolidWhite() const { return fInOut.isSolidWhite(); }
     bool isOpaque() const { return fInOut.isOpaque(); }
-    bool isSingleComponent() const { return fInOut.isSingleComponent(); }
     bool allStagesMultiplyInput() const { return fInOut.allStagesMulInput(); }
-
-    // TODO: Once texture pixel configs quaries are updated, we no longer need this function.
-    // For now this function will correctly tell us if we are using LCD text or not and should only
-    // be called when looking at the coverage output.
-    bool isFourChannelOutput() const { return !fInOut.isSingleComponent() &&
-                                               fInOut.isLCDCoverage(); }
-
+    bool isLCDCoverage() const { return fIsLCDCoverage; }
     GrColor color() const { return fInOut.color(); }
-
-    GrColorComponentFlags validFlags() const {
-        return fInOut.validFlags();
-    }
+    GrColorComponentFlags validFlags() const { return fInOut.validFlags(); }
 
     /**
      * Returns the index of the first effective color processor. If an intermediate processor
@@ -74,12 +76,21 @@
     GrColor inputColorToFirstEffectiveProccesor() const { return fInputColor; }
 
 private:
+    void internalReset(GrColor color, GrColorComponentFlags colorFlags, bool isLCDCoverage) {
+        fInOut.reset(color, colorFlags);
+        fFirstEffectiveProcessorIndex = 0;
+        fInputColorIsUsed = true;
+        fInputColor = color;
+        fIsLCDCoverage = isLCDCoverage;
+    }
+
     void internalCalc(const GrFragmentProcessor* const[], int cnt);
 
     GrInvariantOutput fInOut;
-    int fFirstEffectiveProcessorIndex;
-    bool fInputColorIsUsed;
-    GrColor fInputColor;
+    int fFirstEffectiveProcessorIndex = 0;
+    bool fInputColorIsUsed = true;
+    bool fIsLCDCoverage = false;
+    GrColor fInputColor = 0;
 };
 
 #endif
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 9fb2dcb..780e13b 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -318,10 +318,10 @@
             return;
         }
     }
-    args.fAnalysis.fColorPOI.completeCalculations(
+    args.fAnalysis.fColorPOI.addProcessors(
             sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()),
             pipelineBuilder.numColorFragmentProcessors());
-    args.fAnalysis.fCoveragePOI.completeCalculations(
+    args.fAnalysis.fCoveragePOI.addProcessors(
             sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()),
             pipelineBuilder.numCoverageFragmentProcessors());
     args.fScissor = &appliedClip.scissorState();
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index d96ab94..070fa2f 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -62,7 +62,7 @@
     if (analysis.fUsesPLSDstRead) {
         return false;
     }
-    if (analysis.fCoveragePOI.isFourChannelOutput()) {
+    if (analysis.fCoveragePOI.isLCDCoverage()) {
         return false; // LCD coverage must be applied after the blend equation.
     }
     if (caps.canUseAdvancedBlendEquation(equation)) {
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index a813a53..7f40906 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -325,7 +325,7 @@
                                       bool hasMixedSamples,
                                       SkBlendMode xfermode) {
     SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode);
-    SkASSERT(!coveragePOI.isFourChannelOutput());
+    SkASSERT(!coveragePOI.isLCDCoverage());
 
     bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples;
     return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][(int)xfermode];
@@ -334,7 +334,7 @@
 static BlendFormula get_lcd_blend_formula(const GrProcOptInfo& coveragePOI,
                                           SkBlendMode xfermode) {
     SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode);
-    SkASSERT(coveragePOI.isFourChannelOutput());
+    SkASSERT(coveragePOI.isLCDCoverage());
 
     return gLCDBlendTable[(int)xfermode];
 }
@@ -470,8 +470,7 @@
             optFlags |= GrXferProcessor::kIgnoreColor_OptFlag;
         }
         if (analysis.fColorPOI.allStagesMultiplyInput() &&
-            fBlendFormula.canTweakAlphaForCoverage() &&
-            !analysis.fCoveragePOI.isFourChannelOutput()) {
+            fBlendFormula.canTweakAlphaForCoverage() && !analysis.fCoveragePOI.isLCDCoverage()) {
             optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag;
         }
     }
@@ -750,7 +749,7 @@
         return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fBlendMode);
     }
     BlendFormula blendFormula;
-    if (analysis.fCoveragePOI.isFourChannelOutput()) {
+    if (analysis.fCoveragePOI.isLCDCoverage()) {
         if (SkBlendMode::kSrcOver == fBlendMode &&
             kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() &&
             !caps.shaderCaps()->dualSourceBlendingSupport() &&
@@ -814,7 +813,7 @@
     // When we have four channel coverage we always need to read the dst in order to correctly
     // blend. The one exception is when we are using srcover mode and we know the input color into
     // the XP.
-    if (analysis.fCoveragePOI.isFourChannelOutput()) {
+    if (analysis.fCoveragePOI.isLCDCoverage()) {
         if (SkBlendMode::kSrcOver == fBlendMode &&
             kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() &&
             !caps.shaderCaps()->dstReadInShaderSupport()) {
@@ -875,7 +874,7 @@
     // doing lcd blending we will just use our global SimpleSrcOverXP. This slightly differs from
     // the general case where we convert a src-over blend that has solid coverage and an opaque
     // color to src-mode, which allows disabling of blending.
-    if (!analysis.fCoveragePOI.isFourChannelOutput()) {
+    if (!analysis.fCoveragePOI.isLCDCoverage()) {
         // We return nullptr here, which our caller interprets as meaning "use SimpleSrcOverXP".
         // We don't simply return the address of that XP here because our caller would have to unref
         // it and since it is a global object and GrProgramElement's ref-cnting system is not thread
@@ -913,7 +912,7 @@
     // When we have four channel coverage we always need to read the dst in order to correctly
     // blend. The one exception is when we are using srcover mode and we know the input color
     // into the XP.
-    if (analysis.fCoveragePOI.isFourChannelOutput()) {
+    if (analysis.fCoveragePOI.isLCDCoverage()) {
         if (kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() &&
             !caps.shaderCaps()->dstReadInShaderSupport()) {
             return false;
diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
index 2954170..d3eaee3 100644
--- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
+++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
@@ -182,7 +182,7 @@
         if (SkXfermode::ModeAsCoeff(fMode, &skSrcCoeff, &skDstCoeff)) {
             GrBlendCoeff srcCoeff = SkXfermodeCoeffToGrBlendCoeff(skSrcCoeff);
             GrBlendCoeff dstCoeff = SkXfermodeCoeffToGrBlendCoeff(skDstCoeff);
-            GrInvariantOutput childOutput(0xFFFFFFFF, kRGBA_GrColorComponentFlags, false);
+            GrInvariantOutput childOutput(0xFFFFFFFF, kRGBA_GrColorComponentFlags);
             this->childProcessor(0).computeInvariantOutput(&childOutput);
             GrColor blendColor;
             GrColorComponentFlags blendFlags;
diff --git a/src/gpu/ops/GrDrawOp.cpp b/src/gpu/ops/GrDrawOp.cpp
index f778601..1fd2182 100644
--- a/src/gpu/ops/GrDrawOp.cpp
+++ b/src/gpu/ops/GrDrawOp.cpp
@@ -20,8 +20,8 @@
     GrPipelineInput coverage;
     GrPipelineAnalysisDrawOpInput input(&color, &coverage);
     this->getPipelineAnalysisInput(&input);
-    analysis->fColorPOI.initFromPipelineInput(color);
-    analysis->fCoveragePOI.initFromPipelineInput(coverage);
+    analysis->fColorPOI.reset(color);
+    analysis->fCoveragePOI.reset(coverage);
     analysis->fUsesPLSDstRead = input.usesPLSDstRead();
 }
 
diff --git a/tests/GpuColorFilterTest.cpp b/tests/GpuColorFilterTest.cpp
index d93f1b7..5d45141 100644
--- a/tests/GpuColorFilterTest.cpp
+++ b/tests/GpuColorFilterTest.cpp
@@ -103,8 +103,7 @@
         sk_sp<GrFragmentProcessor> fp(cf->asFragmentProcessor(ctxInfo.grContext(), nullptr));
         REPORTER_ASSERT(reporter, fp);
         GrInvariantOutput inout(test.inputColor,
-                                static_cast<GrColorComponentFlags>(test.inputComponents),
-                                false);
+                                static_cast<GrColorComponentFlags>(test.inputComponents));
         fp->computeInvariantOutput(&inout);
         REPORTER_ASSERT(reporter, filterColor(inout.color(), inout.validFlags()) ==
                                   test.outputColor);
diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp
index 3132fee..6ef05d9 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -93,15 +93,14 @@
 
 static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
     GrPipelineAnalysis analysis;
-    analysis.fColorPOI.calcWithInitialValues(NULL, 0, 0, kNone_GrColorComponentFlags, false);
-    // Setting 2nd to last value to false and last to true will force covPOI to LCD coverage.
-    analysis.fCoveragePOI.calcWithInitialValues(NULL, 0, 0, kNone_GrColorComponentFlags, false,
-                                                true);
+    analysis.fColorPOI.reset(0, kNone_GrColorComponentFlags);
+    // Setting the last argument to true will force covPOI to LCD coverage.
+    analysis.fCoveragePOI.resetToLCDCoverage(0, kNone_GrColorComponentFlags);
 
     SkASSERT(!analysis.fColorPOI.isOpaque());
     SkASSERT(!analysis.fColorPOI.isSolidWhite());
     SkASSERT(!analysis.fCoveragePOI.isSolidWhite());
-    SkASSERT(analysis.fCoveragePOI.isFourChannelOutput());
+    SkASSERT(analysis.fCoveragePOI.isLCDCoverage());
 
     for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
         SkBlendMode xfermode = static_cast<SkBlendMode>(m);
@@ -284,13 +283,13 @@
 }
 static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
     GrPipelineAnalysis analysis;
-    analysis.fColorPOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags, false);
-    analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags, true);
+    analysis.fColorPOI.reset(0, kNone_GrColorComponentFlags);
+    analysis.fCoveragePOI.reset(0, kNone_GrColorComponentFlags);
 
     SkASSERT(!analysis.fColorPOI.isOpaque());
     SkASSERT(!analysis.fColorPOI.isSolidWhite());
     SkASSERT(!analysis.fCoveragePOI.isSolidWhite());
-    SkASSERT(!analysis.fCoveragePOI.isFourChannelOutput());
+    SkASSERT(!analysis.fCoveragePOI.isLCDCoverage());
 
     for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
         SkBlendMode xfermode = static_cast<SkBlendMode>(m);
@@ -474,16 +473,14 @@
 
 static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
     GrPipelineAnalysis analysis;
-    analysis.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackRGBA(229, 0, 154, 0),
-                                             kR_GrColorComponentFlag | kB_GrColorComponentFlag,
-                                             false);
-    analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
-                                                kRGBA_GrColorComponentFlags, true);
+    analysis.fColorPOI.reset(GrColorPackRGBA(229, 0, 154, 0),
+                             kR_GrColorComponentFlag | kB_GrColorComponentFlag);
+    analysis.fCoveragePOI.reset(GrColorPackA4(255), kRGBA_GrColorComponentFlags);
 
     SkASSERT(!analysis.fColorPOI.isOpaque());
     SkASSERT(!analysis.fColorPOI.isSolidWhite());
     SkASSERT(analysis.fCoveragePOI.isSolidWhite());
-    SkASSERT(!analysis.fCoveragePOI.isFourChannelOutput());
+    SkASSERT(!analysis.fCoveragePOI.isLCDCoverage());
 
     for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
         SkBlendMode xfermode = static_cast<SkBlendMode>(m);
@@ -670,14 +667,13 @@
 
 static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
     GrPipelineAnalysis analysis;
-    analysis.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
-                                             kA_GrColorComponentFlag, false);
-    analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags, true);
+    analysis.fColorPOI.reset(GrColorPackA4(255), kA_GrColorComponentFlag);
+    analysis.fCoveragePOI.reset(0, kNone_GrColorComponentFlags);
 
     SkASSERT(analysis.fColorPOI.isOpaque());
     SkASSERT(!analysis.fColorPOI.isSolidWhite());
     SkASSERT(!analysis.fCoveragePOI.isSolidWhite());
-    SkASSERT(!analysis.fCoveragePOI.isFourChannelOutput());
+    SkASSERT(!analysis.fCoveragePOI.isLCDCoverage());
 
     for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
         SkBlendMode xfermode = static_cast<SkBlendMode>(m);
@@ -866,16 +862,14 @@
 
 static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
     GrPipelineAnalysis analysis;
-    analysis.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackRGBA(0, 82, 0, 255),
-                                             kG_GrColorComponentFlag | kA_GrColorComponentFlag,
-                                             false);
-    analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
-                                                kRGBA_GrColorComponentFlags, true);
+    analysis.fColorPOI.reset(GrColorPackRGBA(0, 82, 0, 255),
+                             kG_GrColorComponentFlag | kA_GrColorComponentFlag);
+    analysis.fCoveragePOI.reset(GrColorPackA4(255), kRGBA_GrColorComponentFlags);
 
     SkASSERT(analysis.fColorPOI.isOpaque());
     SkASSERT(!analysis.fColorPOI.isSolidWhite());
     SkASSERT(analysis.fCoveragePOI.isSolidWhite());
-    SkASSERT(!analysis.fCoveragePOI.isFourChannelOutput());
+    SkASSERT(!analysis.fCoveragePOI.isLCDCoverage());
 
     for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
         SkBlendMode xfermode = static_cast<SkBlendMode>(m);
@@ -1095,7 +1089,7 @@
     GrProcOptInfo covPOI = analysis.fCoveragePOI;
 
     SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags());
-    SkASSERT(covPOI.isFourChannelOutput());
+    SkASSERT(covPOI.isLCDCoverage());
 
     const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(SkBlendMode::kSrcOver);
     TEST_ASSERT(!xpf->willNeedDstTexture(caps, analysis));
@@ -1159,15 +1153,12 @@
 
     for (size_t c = 0; c < SK_ARRAY_COUNT(testColors); c++) {
         GrPipelineAnalysis analysis;
-        analysis.fColorPOI.calcWithInitialValues(nullptr, 0, testColors[c], testColorFlags[c],
-                                                 false);
+        analysis.fColorPOI.reset(testColors[c], testColorFlags[c]);
         for (int f = 0; f <= 1; f++) {
             if (!f) {
-                analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0,
-                                                            kNone_GrColorComponentFlags, true);
+                analysis.fCoveragePOI.reset(0, kNone_GrColorComponentFlags);
             } else {
-                analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
-                                                            kRGBA_GrColorComponentFlags, true);
+                analysis.fCoveragePOI.reset(GrColorPackA4(255), kRGBA_GrColorComponentFlags);
             }
             for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
                 SkBlendMode xfermode = static_cast<SkBlendMode>(m);