Gpu blend optimizations, handle more xfer modes with fractional pixel coverage

Review URL: http://codereview.appspot.com/5237062/



git-svn-id: http://skia.googlecode.com/svn/trunk@2464 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrDrawTarget.h b/gpu/src/GrDrawTarget.h
index e411338..10633f5 100644
--- a/gpu/src/GrDrawTarget.h
+++ b/gpu/src/GrDrawTarget.h
@@ -131,7 +131,6 @@
                                         //   pairs for convexity while 
                                         //   rasterizing.  Set this if the
                                         //   source polygon is non-convex.
-
         // subclass may use additional bits internally
         kDummyStateBit,
         kLastPublicStateBit = kDummyStateBit-1
@@ -524,13 +523,13 @@
     GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
 
     /**
-     * Determines if blend is effectively disabled.
+     * Determines if blending will require a read of a dst given the current
+     * state set on the draw target
      *
-     * @return true if blend can be disabled without changing the rendering
-     *  result given the current state including the vertex layout specified
-     *  with the vertex source.
+     * @return true if the dst surface will be read at each pixel hit by the
+     *         a draw operation.
      */
-    bool canDisableBlend() const;
+    bool drawWillReadDst() const;
 
     /**
      * Color alpha and coverage are two inputs to the drawing pipeline. For some
@@ -550,9 +549,7 @@
      * color specified by setColor or per-vertex colors will give the right
      * blending result.
      */
-    bool canTweakAlphaForCoverage() const {
-        return CanTweakAlphaForCoverage(fCurrDrawState.fDstBlend);
-    }
+    bool canTweakAlphaForCoverage() const;
 
      /**
       * Determines the interpretation per-vertex edge data when the
@@ -568,7 +565,7 @@
      * lines be used (if line primitive type is drawn)? (Note that lines are
      * always 1 pixel wide)
      */
-    virtual bool willUseHWAALines() const = 0;
+     bool willUseHWAALines() const;
 
     /**
      * Sets the edge data required for edge antialiasing.
@@ -653,6 +650,7 @@
 
 private:
     static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
+
 public:
     /**
      * Generates a bit indicating that a texture stage uses the position
@@ -1299,15 +1297,57 @@
 
 protected:
 
-    // Determines whether it is correct to apply partial pixel coverage
-    // by multiplying the src color by the fractional coverage.
-    static bool CanTweakAlphaForCoverage(GrBlendCoeff dstCoeff);
-    
-    // determines whether HW blending can be disabled or not
-    static bool CanDisableBlend(GrVertexLayout layout, const DrState& state);
+    /**
+     * Optimizations for blending / coverage to be applied based on the current
+     * state.
+     * Subclasses that actually draw (as opposed to those that just buffer for
+     * playback) must implement the flags that replace the output color.
+     */
+    enum BlendOptFlags {
+        /**
+         * No optimization
+         */
+        kNone_BlendOpt = 0,
+        /**
+         * Don't draw at all
+         */
+        kSkipDraw_BlendOptFlag = 0x2,
+        /**
+         * Emit the src color, disable HW blending (replace dst with src)
+         */
+        kDisableBlend_BlendOptFlag = 0x4,
+        /**
+         * The coverage value does not have to be computed separately from
+         * alpha, the the output color can be the modulation of the two.
+         */
+        kCoverageAsAlpha_BlendOptFlag = 0x1,
+        /**
+         * Instead of emitting a src color, emit coverage in the alpha channel
+         * and r,g,b are "don't cares".
+         */
+        kEmitCoverage_BlendOptFlag = 0x10,
+        /**
+         * Emit transparent black instead of the src color, no need to compute
+         * coverage.
+         */
+        kEmitTransBlack_BlendOptFlag = 0x8,
+    };
+    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
 
-    // determines whether HW AA lines can be used or not
-    static bool CanUseHWAALines(GrVertexLayout layout, const DrState& state);
+    // Determines what optimizations can be applied based on the blend.
+    // The coeffecients may have to be tweaked in order for the optimization
+    // to work. srcCoeff and dstCoeff are optional params that receive the
+    // tweaked coeffecients.
+    // Normally the function looks at the current state to see if coverage
+    // is enabled. By setting forceCoverage the caller can speculatively
+    // determine the blend optimizations that would be used if there was
+    // partial pixel coverage
+    BlendOptFlags getBlendOpts(bool forceCoverage = false,
+                               GrBlendCoeff* srcCoeff = NULL,
+                               GrBlendCoeff* dstCoeff = NULL) const;
+
+    // determine if src alpha is guaranteed to be one for all src pixels
+    bool srcAlphaWillBeOne() const;
 
     enum GeometrySrcType {
         kNone_GeometrySrcType,     //<! src has not been specified
@@ -1431,4 +1471,6 @@
     
 };
 
+GR_MAKE_BITFIELD_OPS(GrDrawTarget::BlendOptFlags);
+
 #endif