Fix to set correct output type when blending when we've read dst
authoregdaniel <egdaniel@google.com>
Wed, 10 Dec 2014 20:45:20 +0000 (12:45 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 10 Dec 2014 20:45:20 +0000 (12:45 -0800)
BUG=skia:

Review URL: https://codereview.chromium.org/791143002

include/gpu/effects/GrPorterDuffXferProcessor.h
src/gpu/effects/GrPorterDuffXferProcessor.cpp

index 26800c7..695d305 100644 (file)
@@ -36,6 +36,14 @@ public:
     /// @name Stage Output Types
     ////
 
+    enum PrimaryOutputType {
+        // Modulate color and coverage, write result as the color output.
+        kModulate_PrimaryOutputType,
+        // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
+        // can only be set if fDstReadKey is non-zero.
+        kCombineWithDst_PrimaryOutputType,
+    };
+
     enum SecondaryOutputType {
         // There is no secondary output
         kNone_SecondaryOutputType,
@@ -52,6 +60,7 @@ public:
         kSecondaryOutputTypeCnt,
     };
 
+    PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; }
     SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; }
 
     GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
@@ -77,6 +86,7 @@ private:
         if (fSrcBlend != xp.fSrcBlend ||
             fDstBlend != xp.fDstBlend ||
             fBlendConstant != xp.fBlendConstant ||
+            fPrimaryOutputType != xp.fPrimaryOutputType || 
             fSecondaryOutputType != xp.fSecondaryOutputType) {
             return false;
         }
@@ -99,6 +109,7 @@ private:
     GrBlendCoeff fSrcBlend;
     GrBlendCoeff fDstBlend;
     GrColor      fBlendConstant;
+    PrimaryOutputType fPrimaryOutputType;
     SecondaryOutputType fSecondaryOutputType;
 
     typedef GrXferProcessor INHERITED;
index 0978546..f27b16c 100644 (file)
@@ -68,6 +68,10 @@ public:
         
         fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
                                args.fInputCoverage);
+        if (GrPorterDuffXferProcessor::kCombineWithDst_PrimaryOutputType == xp.primaryOutputType()){
+            fsBuilder->codeAppendf("%s += (vec4(1.0) - %s) * %s;", args.fOutputPrimary,
+                                   args.fInputCoverage, fsBuilder->dstColor());
+        }
     }
 
     virtual void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
@@ -75,6 +79,7 @@ public:
     static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
                        GrProcessorKeyBuilder* b) {
         const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>();
+        b->add32(xp.primaryOutputType());
         b->add32(xp.secondaryOutputType());
     };
 
@@ -89,6 +94,7 @@ GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBl
     : fSrcBlend(srcBlend)
     , fDstBlend(dstBlend)
     , fBlendConstant(constant)
+    , fPrimaryOutputType(kModulate_PrimaryOutputType) 
     , fSecondaryOutputType(kNone_SecondaryOutputType) {
     this->initClassID<GrPorterDuffXferProcessor>();
 }
@@ -152,6 +158,10 @@ void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFla
                 fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
                 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
             }
+        } else if (readsDst &&
+                   kOne_GrBlendCoeff == fSrcBlend &&
+                   kZero_GrBlendCoeff == fDstBlend) {
+            fPrimaryOutputType = kCombineWithDst_PrimaryOutputType;
         }
     }
 }