Make GrColorFragmentProcessorAnalysis do all analysis in constructor.

We no longer do piecemeal analysis. This simplifies the change to make FPs have unique ownership.

Change-Id: I4e6b2c23b4277b612dedfc466cee74630a30e997
Reviewed-on: https://skia-review.googlesource.com/25362
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 63dc3a3..f9f42f9 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -505,8 +505,10 @@
         return series[0];
     }
     // Run the through the series, do the invariant output processing, and look for eliminations.
-    GrColorFragmentProcessorAnalysis info;
-    info.analyzeProcessors(sk_sp_address_as_pointer_address(series), cnt);
+    GrProcessorAnalysisColor inputColor;
+    inputColor.setToUnknown();
+    GrColorFragmentProcessorAnalysis info(inputColor, sk_sp_address_as_pointer_address(series),
+                                          cnt);
     SkTArray<sk_sp<GrFragmentProcessor>> replacementSeries;
     GrColor4f knownColor;
     int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
diff --git a/src/gpu/GrProcessorAnalysis.cpp b/src/gpu/GrProcessorAnalysis.cpp
index 118e93d..2bbb546 100644
--- a/src/gpu/GrProcessorAnalysis.cpp
+++ b/src/gpu/GrProcessorAnalysis.cpp
@@ -9,36 +9,43 @@
 #include "GrGeometryProcessor.h"
 #include "ops/GrDrawOp.h"
 
-void GrColorFragmentProcessorAnalysis::analyzeProcessors(
-        const GrFragmentProcessor* const* processors, int cnt) {
+GrColorFragmentProcessorAnalysis::GrColorFragmentProcessorAnalysis(
+        const GrProcessorAnalysisColor& input,
+        const GrFragmentProcessor* const* processors,
+        int cnt) {
+    fCompatibleWithCoverageAsAlpha = true;
+    fIsOpaque = input.isOpaque();
+    fUsesLocalCoords = false;
+    fProcessorsToEliminate = 0;
+    GrColor color;
+    if ((fKnowOutputColor = input.isConstant(&color))) {
+        fLastKnownOutputColor = GrColor4f::FromGrColor(color);
+    }
     for (int i = 0; i < cnt; ++i) {
-        bool knowCurrentOutput = fProcessorsVisitedWithKnownOutput == fTotalProcessorsVisited;
-        if (fUsesLocalCoords && !knowCurrentOutput &&
-            !fAllProcessorsCompatibleWithCoverageAsAlpha && !fIsOpaque) {
-            fTotalProcessorsVisited += cnt - i;
-            return;
+        if (fUsesLocalCoords && !fKnowOutputColor && !fCompatibleWithCoverageAsAlpha &&
+            !fIsOpaque) {
+            break;
         }
         const GrFragmentProcessor* fp = processors[i];
-        if (knowCurrentOutput &&
+        if (fKnowOutputColor &&
             fp->hasConstantOutputForConstantInput(fLastKnownOutputColor, &fLastKnownOutputColor)) {
-            ++fProcessorsVisitedWithKnownOutput;
+            ++fProcessorsToEliminate;
             fIsOpaque = fLastKnownOutputColor.isOpaque();
             // We reset these since the caller is expected to not use the earlier fragment
             // processors.
-            fAllProcessorsCompatibleWithCoverageAsAlpha = true;
+            fCompatibleWithCoverageAsAlpha = true;
             fUsesLocalCoords = false;
         } else {
+            fKnowOutputColor = false;
             if (fIsOpaque && !fp->preservesOpaqueInput()) {
                 fIsOpaque = false;
             }
-            if (fAllProcessorsCompatibleWithCoverageAsAlpha &&
-                !fp->compatibleWithCoverageAsAlpha()) {
-                fAllProcessorsCompatibleWithCoverageAsAlpha = false;
+            if (fCompatibleWithCoverageAsAlpha && !fp->compatibleWithCoverageAsAlpha()) {
+                fCompatibleWithCoverageAsAlpha = false;
             }
             if (fp->usesLocalCoords()) {
                 fUsesLocalCoords = true;
             }
         }
-        ++fTotalProcessorsVisited;
     }
 }
diff --git a/src/gpu/GrProcessorAnalysis.h b/src/gpu/GrProcessorAnalysis.h
index a635e65..4175b5e 100644
--- a/src/gpu/GrProcessorAnalysis.h
+++ b/src/gpu/GrProcessorAnalysis.h
@@ -90,28 +90,11 @@
  */
 class GrColorFragmentProcessorAnalysis {
 public:
-    GrColorFragmentProcessorAnalysis() = default;
+    GrColorFragmentProcessorAnalysis() = delete;
 
-    GrColorFragmentProcessorAnalysis(const GrProcessorAnalysisColor& input)
-            : GrColorFragmentProcessorAnalysis() {
-        fAllProcessorsCompatibleWithCoverageAsAlpha = true;
-        fIsOpaque = input.isOpaque();
-        GrColor color;
-        if (input.isConstant(&color)) {
-            fLastKnownOutputColor = GrColor4f::FromGrColor(color);
-            fProcessorsVisitedWithKnownOutput = 0;
-        }
-    }
-
-    void reset(const GrProcessorAnalysisColor& input) {
-        *this = GrColorFragmentProcessorAnalysis(input);
-    }
-
-    /**
-     * 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 analyzeProcessors(const GrFragmentProcessor* const* processors, int cnt);
+    GrColorFragmentProcessorAnalysis(const GrProcessorAnalysisColor& input,
+                                     const GrFragmentProcessor* const* processors,
+                                     int cnt);
 
     bool isOpaque() const { return fIsOpaque; }
 
@@ -121,7 +104,7 @@
      * as indicated by initialProcessorsToEliminate() are in fact eliminated.
      */
     bool allProcessorsCompatibleWithCoverageAsAlpha() const {
-        return fAllProcessorsCompatibleWithCoverageAsAlpha;
+        return fCompatibleWithCoverageAsAlpha;
     }
 
     /**
@@ -139,34 +122,36 @@
      * processors to eliminate.
      */
     int initialProcessorsToEliminate(GrColor* newPipelineInputColor) const {
-        if (fProcessorsVisitedWithKnownOutput > 0) {
+        if (fProcessorsToEliminate > 0) {
             *newPipelineInputColor = fLastKnownOutputColor.toGrColor();
         }
-        return SkTMax(0, fProcessorsVisitedWithKnownOutput);
+        return fProcessorsToEliminate;
     }
 
     int initialProcessorsToEliminate(GrColor4f* newPipelineInputColor) const {
-        if (fProcessorsVisitedWithKnownOutput > 0) {
+        if (fProcessorsToEliminate > 0) {
             *newPipelineInputColor = fLastKnownOutputColor;
         }
-        return SkTMax(0, fProcessorsVisitedWithKnownOutput);
+        return fProcessorsToEliminate;
     }
 
+    /**
+     * Provides known information about the last processor's output color.
+     */
     GrProcessorAnalysisColor outputColor() const {
-        if (fProcessorsVisitedWithKnownOutput != fTotalProcessorsVisited) {
-            return GrProcessorAnalysisColor(fIsOpaque ? GrProcessorAnalysisColor::Opaque::kYes
-                                                      : GrProcessorAnalysisColor::Opaque::kNo);
+        if (fKnowOutputColor) {
+            return fLastKnownOutputColor.toGrColor();
         }
-        return GrProcessorAnalysisColor(fLastKnownOutputColor.toGrColor());
+        return fIsOpaque ? GrProcessorAnalysisColor::Opaque::kYes
+                         : GrProcessorAnalysisColor::Opaque::kNo;
     }
 
 private:
-    int fTotalProcessorsVisited = 0;
-    // negative one means even the color is unknown before adding the first processor.
-    int fProcessorsVisitedWithKnownOutput = -1;
-    bool fIsOpaque = false;
-    bool fAllProcessorsCompatibleWithCoverageAsAlpha = true;
-    bool fUsesLocalCoords = false;
+    bool fIsOpaque;
+    bool fCompatibleWithCoverageAsAlpha;
+    bool fUsesLocalCoords;
+    bool fKnowOutputColor;
+    int fProcessorsToEliminate;
     GrColor4f fLastKnownOutputColor;
 };
 
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index c476f64..21e5fc3 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -153,13 +153,11 @@
     SkASSERT(!fFragmentProcessorOffset);
 
     GrProcessorSet::Analysis analysis;
-
-    const GrFragmentProcessor* clipFP = clip ? clip->clipCoverageFragmentProcessor() : nullptr;
-    GrColorFragmentProcessorAnalysis colorAnalysis(colorInput);
     analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput;
 
+    const GrFragmentProcessor* clipFP = clip ? clip->clipCoverageFragmentProcessor() : nullptr;
     const GrFragmentProcessor* const* fps = fFragmentProcessors.get() + fFragmentProcessorOffset;
-    colorAnalysis.analyzeProcessors(fps, fColorFragmentProcessorCnt);
+    GrColorFragmentProcessorAnalysis colorAnalysis(colorInput, fps, fColorFragmentProcessorCnt);
     analysis.fCompatibleWithCoverageAsAlpha &=
             colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha();
     fps += fColorFragmentProcessorCnt;