Avoid special shader for opaque alpha when drawing simple rectangles.

It's a wasted shader compiler and also seems to cause a rendering bug
in Windows Chrome on ANGLE.

Bug: chromium:942565
Change-Id: I56373ac596d4d1548d6c86cda7127bf12190a0ae
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/203383
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index 099c05e..94dd240 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -235,6 +235,7 @@
     }
     fFragmentProcessorOffset = colorFPsToEliminate;
     fColorFragmentProcessorCnt -= colorFPsToEliminate;
+    analysis.fHasColorFragmentProcessor = (fColorFragmentProcessorCnt != 0);
 
     bool hasMixedSampledCoverage = (GrFSAAType::kMixedSamples == fsaaType)
             && !userStencil->testAlwaysPasses((clip) ? clip->hasStencilClip() : false);
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index b7b7ae0..ec550ee 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -84,6 +84,8 @@
         bool requiresDstTexture() const { return fRequiresDstTexture; }
         bool requiresNonOverlappingDraws() const { return fRequiresNonOverlappingDraws; }
         bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
+        // Indicates whether all color fragment processors were eliminated in the analysis.
+        bool hasColorFragmentProcessor() const { return fHasColorFragmentProcessor; }
 
         bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
         bool inputColorIsOverridden() const {
@@ -96,6 +98,7 @@
                 , fCompatibleWithCoverageAsAlpha(true)
                 , fRequiresDstTexture(false)
                 , fRequiresNonOverlappingDraws(false)
+                , fHasColorFragmentProcessor(false)
                 , fIsInitialized(true)
                 , fInputColorType(kOriginal_InputColorType) {}
         enum InputColorType : uint32_t {
@@ -112,6 +115,7 @@
         PackedBool fCompatibleWithCoverageAsAlpha : 1;
         PackedBool fRequiresDstTexture : 1;
         PackedBool fRequiresNonOverlappingDraws : 1;
+        PackedBool fHasColorFragmentProcessor : 1;
         PackedBool fIsInitialized : 1;
         PackedInputColorType fInputColorType : 2;
 
diff --git a/src/gpu/ops/GrFillRectOp.cpp b/src/gpu/ops/GrFillRectOp.cpp
index 84dda90..59b5b62 100644
--- a/src/gpu/ops/GrFillRectOp.cpp
+++ b/src/gpu/ops/GrFillRectOp.cpp
@@ -162,6 +162,14 @@
                                     GrQuadPerEdgeAA::MinColorType(*color, clampType, caps));
             }
         }
+        // Most SkShaders' FPs multiply their calculated color by the paint color or alpha. We want
+        // to use ColorType::kNone to optimize out that multiply. However, if there are no color
+        // FPs then were really writing a special shader for white rectangles and not saving any
+        // multiples. So in that case use bytes to avoid the extra shader (and possibly work around
+        // an ANGLE issue: crbug.com/942565).
+        if (fColorType == ColorType::kNone && !result.hasColorFragmentProcessor()) {
+            fColorType = ColorType::kByte;
+        }
 
         return result;
     }