Remove XP override color.
authorBrian Salomon <bsalomon@google.com>
Fri, 3 Mar 2017 19:30:15 +0000 (14:30 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 6 Mar 2017 13:39:09 +0000 (13:39 +0000)
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>
src/gpu/GrPipeline.cpp
src/gpu/GrUserStencilSettings.h
src/gpu/GrXferProcessor.cpp
src/gpu/GrXferProcessor.h
src/gpu/effects/GrCoverageSetOpXP.cpp
src/gpu/effects/GrCustomXfermode.cpp
src/gpu/effects/GrDisableColorXP.cpp
src/gpu/effects/GrPorterDuffXferProcessor.cpp
tests/GrPorterDuffTest.cpp

index 60f80f8..e1cbd65 100644 (file)
@@ -68,9 +68,7 @@ GrPipelineOptimizations GrPipeline::init(const InitArgs& args) {
 
     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 @@ GrPipelineOptimizations GrPipeline::init(const InitArgs& args) {
 
     fXferProcessor.reset(xferProcessor.get());
 
-    if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag) ||
-        (optFlags & GrXferProcessor::kOverrideColor_OptFlag)) {
+    if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
         colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors();
     }
 
index 3cbadfd..2549c44 100644 (file)
@@ -188,9 +188,6 @@ struct GrUserStencilSettings {
     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);
     }
index 56653b5..a926812 100644 (file)
@@ -31,13 +31,8 @@ GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture,
 }
 
 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 {
index e837ed0..c00bcbe 100644 (file)
@@ -111,13 +111,9 @@ public:
          */
         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 @@ public:
     /**
      * 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 @@ protected:
 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
index d8eb0d9..d86467e 100644 (file)
@@ -34,10 +34,7 @@ public:
 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 @@ GrGLSLXferProcessor* CoverageSetOpXP::createGLSLInstance() const {
 }
 
 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 @@ public:
     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;
     }
index a33d292..ccbab73 100644 (file)
@@ -103,10 +103,7 @@ public:
     }
 
 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 @@ bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
     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.
 
index 9c0228f..6bdf188 100644 (file)
@@ -29,10 +29,7 @@ public:
 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;
     }
 
index 7dd7be6..7378874 100644 (file)
@@ -350,10 +350,7 @@ public:
     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 @@ GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const {
 }
 
 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 @@ public:
     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 @@ public:
 
     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 @@ private:
 
     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 @@ private:
 
 class GLPDLCDXferProcessor : public GrGLSLXferProcessor {
 public:
-    GLPDLCDXferProcessor(const GrProcessor&) {}
+    GLPDLCDXferProcessor(const GrProcessor&) : fLastAlpha(SK_MaxU32) {}
 
     virtual ~GLPDLCDXferProcessor() {}
 
@@ -605,14 +596,28 @@ public:
 
 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 @@ GrGLSLXferProcessor* PDLCDXferProcessor::createGLSLInstance() const {
     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;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
index c1d73ef..89067cf 100644 (file)
@@ -71,8 +71,7 @@ public:
             fReadsDst = GrXPFactory::WillReadDst(xpf, analysis);
             sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps));
             TEST_ASSERT(!GrXPFactory::WillNeedDstTexture(xpf, caps, analysis));
-            GrColor ignoredOverrideColor;
-            fOptFlags = xp->getOptimizations(analysis, false, &ignoredOverrideColor, caps);
+            fOptFlags = xp->getOptimizations(analysis);
             GetXPOutputTypes(xp.get(), &fPrimaryOutputType, &fSecondaryOutputType);
             xp->getBlendInfo(&fBlendInfo);
             TEST_ASSERT(!xp->willReadDstColor());
@@ -986,8 +985,7 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const
 
     TEST_ASSERT(GrXPFactory::WillReadDst(xpf, analysis));
 
-    GrColor overrideColor;
-    xp->getOptimizations(analysis, false, &overrideColor, caps);
+    xp->getOptimizations(analysis);
 
     GrXferProcessor::BlendInfo blendInfo;
     xp->getBlendInfo(&blendInfo);
@@ -1047,8 +1045,7 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) {
                     return;
                 }
                 TEST_ASSERT(!xp->hasSecondaryOutput());
-                GrColor ignoredOverrideColor;
-                xp->getOptimizations(analysis, false, &ignoredOverrideColor, caps);
+                xp->getOptimizations(analysis);
                 TEST_ASSERT(!xp->hasSecondaryOutput());
             }
         }