Add xp optimization for RGB coverage.
authoregdaniel <egdaniel@google.com>
Mon, 15 Dec 2014 20:38:53 +0000 (12:38 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 15 Dec 2014 20:38:53 +0000 (12:38 -0800)
This is needed since clearColorStages is being changed to ignore color input. For RGB coverage,
we want to clear all the color stages (since we know the final output color), but we don't want
to ignore the color input since it is needed.

In future we will change this so the XP stores the color internally and thus can tell the GP to
simiply ignore color.

BUG=skia:

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

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

index db0d6e8..40629ea 100644 (file)
@@ -66,9 +66,13 @@ public:
          */
         kClearCoverageStages_OptFlag      = 0x4,
         /**
+         * Clear color stages and override input color to that returned by getOptimizations
+         */
+        kOverrideColor_OptFlag            = 0x8,
+        /**
          * Set CoverageDrawing_StateBit
          */
-        kSetCoverageDrawing_OptFlag       = 0x8,
+        kSetCoverageDrawing_OptFlag       = 0x10,
     };
 
     GR_DECL_BITFIELD_OPS_FRIENDS(OptFlags);
@@ -76,10 +80,11 @@ 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. It will also set the output parameters,
-     * color and coverage, to specific values if it decides to remove all color or coverage stages.
+     * 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/coverage values for its draw.
+     * and color values for its draw.
      */
     // TODO: remove need for isCoverageDrawing once coverageDrawing is its own XP.
     // TODO: remove need for colorWriteDisabled once colorWriteDisabled is its own XP.
@@ -88,8 +93,8 @@ public:
                                       bool isCoverageDrawing,
                                       bool colorWriteDisabled,
                                       bool doesStencilWrite,
-                                      GrColor* color,
-                                      uint8_t* coverage,
+                                      GrColor* overrideColor,
+                                      uint8_t* overrideCoverage,
                                       const GrDrawTargetCaps& caps) = 0;
 
     struct BlendInfo {
index 60360d2..93184b4 100644 (file)
@@ -157,7 +157,8 @@ void GrOptDrawState::adjustProgramFromOptimizations(const GrDrawState& ds,
     fDescInfo.fReadsDst = false;
     fDescInfo.fReadsFragPosition = false;
 
-    if (flags & GrXferProcessor::kClearColorStages_OptFlag) {
+    if (flags & GrXferProcessor::kClearColorStages_OptFlag ||
+        flags & GrXferProcessor::kOverrideColor_OptFlag) {
         fDescInfo.fInputColorIsUsed = true;
         *firstColorStageIdx = ds.numColorStages();
         fDescInfo.fHasVertexColor = false;
index 6255e4a..b825916 100644 (file)
@@ -121,16 +121,28 @@ GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
                                             bool isCoverageDrawing,
                                             bool colorWriteDisabled,
                                             bool doesStencilWrite,
-                                            GrColor* color, uint8_t* coverage,
+                                            GrColor* overrideColor,
+                                            uint8_t* overrideCoverage,
                                             const GrDrawTargetCaps& caps) {
-    GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI,
-                                                                        coveragePOI,
-                                                                        isCoverageDrawing,
-                                                                        colorWriteDisabled,
-                                                                        doesStencilWrite,
-                                                                        color,
-                                                                        coverage);
-
+    GrXferProcessor::OptFlags optFlags;
+    // Optimizations when doing RGB Coverage
+    if (coveragePOI.isFourChannelOutput()) {
+        // 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.
+        uint8_t alpha = GrColorUnpackA(fBlendConstant);
+        *overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
+        optFlags = GrXferProcessor::kOverrideColor_OptFlag;
+    } else {
+        optFlags = this->internalGetOptimizations(colorPOI,
+                                                  coveragePOI,
+                                                  isCoverageDrawing,
+                                                  colorWriteDisabled,
+                                                  doesStencilWrite,
+                                                  overrideColor,
+                                                  overrideCoverage);
+    }
     this->calcOutputTypes(optFlags, caps, isCoverageDrawing || coveragePOI.isSolidWhite(),
                           colorPOI.readsDst() || coveragePOI.readsDst());
     return optFlags;
@@ -172,7 +184,8 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
                                                     bool isCoverageDrawing,
                                                     bool colorWriteDisabled,
                                                     bool doesStencilWrite,
-                                                    GrColor* color, uint8_t* coverage) {
+                                                    GrColor* overrideColor,
+                                                    uint8_t* overrideCoverage) {
     if (colorWriteDisabled) {
         fSrcBlend = kZero_GrBlendCoeff;
         fDstBlend = kOne_GrBlendCoeff;
@@ -193,23 +206,12 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
     bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend ||
                          (kISA_GrBlendCoeff == fDstBlend && srcAIsOne);
 
-    // Optimizations when doing RGB Coverage
-    if (coveragePOI.isFourChannelOutput()) {
-        // 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.
-        uint8_t alpha = GrColorUnpackA(fBlendConstant);
-        *color = GrColorPackRGBA(alpha, alpha, alpha, alpha);
-        return GrXferProcessor::kClearColorStages_OptFlag;
-    }
-
     // When coeffs are (0,1) there is no reason to draw at all, unless
     // stenciling is enabled. Having color writes disabled is effectively
     // (0,1).
     if ((kZero_GrBlendCoeff == fSrcBlend && dstCoeffIsOne)) {
         if (doesStencilWrite) {
-            *color = 0xffffffff;
+            *overrideColor = 0xffffffff;
             return GrXferProcessor::kClearColorStages_OptFlag |
                    GrXferProcessor::kSetCoverageDrawing_OptFlag;
         } else {
@@ -232,8 +234,8 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
                 // or blend, just write transparent black into the dst.
                 fSrcBlend = kOne_GrBlendCoeff;
                 fDstBlend = kZero_GrBlendCoeff;
-                *color = 0;
-                *coverage = 0xff;
+                *overrideColor = 0;
+                *overrideCoverage = 0xff;
                 return GrXferProcessor::kClearColorStages_OptFlag |
                        GrXferProcessor::kClearCoverageStages_OptFlag;
             }
@@ -253,7 +255,7 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
                 // the dst coeff is effectively zero so blend works out to:
                 // (c)(0)D + (1-c)D = (1-c)D.
                 fDstBlend = kISA_GrBlendCoeff;
-                *color = 0xffffffff;
+                *overrideColor = 0xffffffff;
                 return GrXferProcessor::kClearColorStages_OptFlag |
                        GrXferProcessor::kSetCoverageDrawing_OptFlag;
             } else if (srcAIsOne) {