Remove XP override color.

The only use case for this was using the blend constant for LCD text. Now instead of overriding the op's color with an alpha we upload the alpha as a uniform.

This also removes two unused parameters from GrXferProcessor::getOptimizations.

Change-Id: I8268da9904a5d26649c6ae81a5705b0930893904
Reviewed-on: https://skia-review.googlesource.com/9221
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 60f80f8..e1cbd65 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -68,9 +68,7 @@
 
     const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
                                                        &GrPorterDuffXPFactory::SimpleSrcOverXP();
-    optFlags = xpForOpts->getOptimizations(
-            *args.fAnalysis, args.fUserStencil->doesWrite(args.fAppliedClip->hasStencilClip()),
-            &overrideColor, *args.fCaps);
+    optFlags = xpForOpts->getOptimizations(*args.fAnalysis);
 
     // No need to have an override color if it isn't even going to be used.
     if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
@@ -79,8 +77,7 @@
 
     fXferProcessor.reset(xferProcessor.get());
 
-    if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag) ||
-        (optFlags & GrXferProcessor::kOverrideColor_OptFlag)) {
+    if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
         colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors();
     }
 
diff --git a/src/gpu/GrUserStencilSettings.h b/src/gpu/GrUserStencilSettings.h
index 3cbadfd..2549c44 100644
--- a/src/gpu/GrUserStencilSettings.h
+++ b/src/gpu/GrUserStencilSettings.h
@@ -188,9 +188,6 @@
     bool isDisabled(bool hasStencilClip) const {
         return this->flags(hasStencilClip) & kDisabled_StencilFlag;
     }
-    bool doesWrite(bool hasStencilClip) const {
-        return !(this->flags(hasStencilClip) & kNoModifyStencil_StencilFlag);
-    }
     bool isTwoSided(bool hasStencilClip) const {
         return !(this->flags(hasStencilClip) & kSingleSided_StencilFlag);
     }
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index 56653b5..a926812 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -31,13 +31,8 @@
 }
 
 GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(
-        const FragmentProcessorAnalysis& analysis,
-        bool doesStencilWrite,
-        GrColor* overrideColor,
-        const GrCaps& caps) const {
-    GrXferProcessor::OptFlags flags =
-            this->onGetOptimizations(analysis, doesStencilWrite, overrideColor, caps);
-    return flags;
+        const FragmentProcessorAnalysis& analysis) const {
+    return this->onGetOptimizations(analysis);
 }
 
 bool GrXferProcessor::hasSecondaryOutput() const {
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index e837ed0..c00bcbe 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -111,13 +111,9 @@
          */
         kIgnoreColor_OptFlag = 0x1,
         /**
-         * Clear color stages and override input color to that returned by getOptimizations
+         * Can tweak alpha for coverage.
          */
-        kOverrideColor_OptFlag = 0x2,
-        /**
-         * Can tweak alpha for coverage. Currently this flag should only be used by a GrDrawOp.
-         */
-        kCanTweakAlphaForCoverage_OptFlag = 0x4,
+        kCanTweakAlphaForCoverage_OptFlag = 0x2,
     };
 
     static const OptFlags kNone_OptFlags = (OptFlags)0;
@@ -127,16 +123,10 @@
     /**
      * Determines which optimizations (as described by the ptFlags above) can be performed by
      * the draw with this xfer processor. If this function is called, the xfer processor may change
-     * its state to reflected the given blend optimizations. If the XP needs to see a specific input
-     * color to blend correctly, it will set the OverrideColor flag and the output parameter
-     * overrideColor will be the required value that should be passed into the XP.
-     * A caller who calls this function on a XP is required to honor the returned OptFlags
-     * and color values for its draw.
+     * its state to reflected the given blend optimizations. Callers are required to honor the
+     * returned OptFlags.
      */
-    OptFlags getOptimizations(const FragmentProcessorAnalysis&,
-                              bool doesStencilWrite,
-                              GrColor* overrideColor,
-                              const GrCaps& caps) const;
+    OptFlags getOptimizations(const FragmentProcessorAnalysis&) const;
 
     /**
      * Returns whether this XP will require an Xfer barrier on the given rt. If true, outBarrierType
@@ -229,10 +219,7 @@
 private:
     void notifyRefCntIsZero() const final {}
 
-    virtual OptFlags onGetOptimizations(const FragmentProcessorAnalysis&,
-                                        bool doesStencilWrite,
-                                        GrColor* overrideColor,
-                                        const GrCaps& caps) const = 0;
+    virtual OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const = 0;
 
     /**
      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index d8eb0d9..d86467e 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -34,10 +34,7 @@
 private:
     CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage);
 
-    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis& analysis,
-                                                 bool doesStencilWrite,
-                                                 GrColor* color,
-                                                 const GrCaps& caps) const override;
+    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override;
 
     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
 
@@ -108,10 +105,7 @@
 }
 
 GrXferProcessor::OptFlags CoverageSetOpXP::onGetOptimizations(
-        const FragmentProcessorAnalysis& analysis,
-        bool doesStencilWrite,
-        GrColor* color,
-        const GrCaps& caps) const {
+        const FragmentProcessorAnalysis&) const {
     // We never look at the color input
     return GrXferProcessor::kIgnoreColor_OptFlag;
 }
@@ -168,8 +162,7 @@
     bool invertCoverage() const { return fInvertCoverage; }
 
 private:
-    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool, GrColor*,
-                                                 const GrCaps&) const override {
+    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override {
         // We never look at the color input
         return GrXferProcessor::kIgnoreColor_OptFlag;
     }
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index a33d292..ccbab73 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -103,10 +103,7 @@
     }
 
 private:
-    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&,
-                                                 bool doesStencilWrite,
-                                                 GrColor* overrideColor,
-                                                 const GrCaps& caps) const override;
+    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override;
 
     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
 
@@ -197,10 +194,8 @@
     return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation;
 }
 
-GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const FragmentProcessorAnalysis& analysis,
-                                                       bool doesStencilWrite,
-                                                       GrColor* overrideColor,
-                                                       const GrCaps& caps) const {
+GrXferProcessor::OptFlags CustomXP::onGetOptimizations(
+        const FragmentProcessorAnalysis& analysis) const {
     /*
       Most the optimizations we do here are based on tweaking alpha for coverage.
 
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index 9c0228f..6bdf188 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -29,10 +29,7 @@
 private:
     DisableColorXP();
 
-    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&,
-                                                 bool doesStencilWrite,
-                                                 GrColor* color,
-                                                 const GrCaps& caps) const override {
+    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override {
         return GrXferProcessor::kIgnoreColor_OptFlag;
     }
 
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 7dd7be6..7378874 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -350,10 +350,7 @@
     BlendFormula getBlendFormula() const { return fBlendFormula; }
 
 private:
-    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&,
-                                                 bool doesStencilWrite,
-                                                 GrColor* overrideColor,
-                                                 const GrCaps&) const override;
+    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override;
 
     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
 
@@ -450,10 +447,7 @@
 }
 
 GrXferProcessor::OptFlags PorterDuffXferProcessor::onGetOptimizations(
-        const FragmentProcessorAnalysis& analysis,
-        bool doesStencilWrite,
-        GrColor* overrideColor,
-        const GrCaps& caps) const {
+        const FragmentProcessorAnalysis& analysis) const {
     GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
     if (!fBlendFormula.modifiesDst()) {
         optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag |
@@ -489,8 +483,7 @@
     SkBlendMode getXfermode() const { return fXfermode; }
 
 private:
-    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool, GrColor*,
-                                                 const GrCaps&) const override {
+    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override {
         return kNone_OptFlags;
     }
 
@@ -561,13 +554,12 @@
 
     GrGLSLXferProcessor* createGLSLInstance() const override;
 
+    uint8_t alpha() const { return fAlpha; }
+
 private:
     PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha);
 
-    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&,
-                                                 bool doesStencilWrite,
-                                                 GrColor* overrideColor,
-                                                 const GrCaps&) const override;
+    GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override;
 
     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
 
@@ -579,15 +571,14 @@
 
     bool onIsEqual(const GrXferProcessor& xpBase) const override {
         const PDLCDXferProcessor& xp = xpBase.cast<PDLCDXferProcessor>();
-        if (fBlendConstant != xp.fBlendConstant ||
-            fAlpha != xp.fAlpha) {
+        if (fBlendConstant != xp.fBlendConstant || fAlpha != xp.fAlpha) {
             return false;
         }
         return true;
     }
 
-    GrColor      fBlendConstant;
-    uint8_t      fAlpha;
+    GrColor fBlendConstant;
+    uint8_t fAlpha;
 
     typedef GrXferProcessor INHERITED;
 };
@@ -596,7 +587,7 @@
 
 class GLPDLCDXferProcessor : public GrGLSLXferProcessor {
 public:
-    GLPDLCDXferProcessor(const GrProcessor&) {}
+    GLPDLCDXferProcessor(const GrProcessor&) : fLastAlpha(SK_MaxU32) {}
 
     virtual ~GLPDLCDXferProcessor() {}
 
@@ -605,14 +596,28 @@
 
 private:
     void emitOutputsForBlendState(const EmitArgs& args) override {
+        const char* alpha;
+        fAlphaUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType,
+                                                         kDefault_GrSLPrecision, "alpha", &alpha);
         GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
+        // We want to force our primary output to be alpha * Coverage, where alpha is the alpha
+        // value of the src color. We know that there are no color stages (or we wouldn't have
+        // created this xp) and the r,g, and b channels of the op's input color are baked into the
+        // blend constant.
         SkASSERT(args.fInputCoverage);
-        fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
-                                 args.fInputCoverage);
+        fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, alpha, args.fInputCoverage);
     }
 
-    void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
+    void onSetData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) override {
+        uint32_t alpha = SkToU32(xp.cast<PDLCDXferProcessor>().alpha());
+        if (fLastAlpha != alpha) {
+            pdm.set1f(fAlphaUniform, alpha / 255.f);
+            fLastAlpha = alpha;
+        }
+    }
 
+    GrGLSLUniformHandler::UniformHandle fAlphaUniform;
+    uint32_t fLastAlpha;
     typedef GrGLSLXferProcessor INHERITED;
 };
 
@@ -651,16 +656,9 @@
     return new GLPDLCDXferProcessor(*this);
 }
 
-GrXferProcessor::OptFlags PDLCDXferProcessor::onGetOptimizations(const FragmentProcessorAnalysis&,
-                                                                 bool doesStencilWrite,
-                                                                 GrColor* overrideColor,
-                                                                 const GrCaps& caps) const {
-    // We want to force our primary output to be alpha * Coverage, where alpha is the alpha
-    // value of the blend the constant. We should already have valid blend coeff's if we are at
-    // a point where we have RGB coverage. We don't need any color stages since the known color
-    // output is already baked into the blendConstant.
-    *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha);
-    return GrXferProcessor::kOverrideColor_OptFlag;
+GrXferProcessor::OptFlags PDLCDXferProcessor::onGetOptimizations(
+        const FragmentProcessorAnalysis&) const {
+    return GrXferProcessor::kIgnoreColor_OptFlag;
 }
 
 ///////////////////////////////////////////////////////////////////////////////