Add blend optimization helpers and use to convert rect draws to clears.

R=robertphillips@google.com, jvanverth@google.com, reed@google.com

Author: bsalomon@google.com

Review URL: https://chromiumcodereview.appspot.com/21877006

git-svn-id: http://skia.googlecode.com/svn/trunk/include@10537 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkMatrix.h b/core/SkMatrix.h
index f148e39..71e6b97 100644
--- a/core/SkMatrix.h
+++ b/core/SkMatrix.h
@@ -470,6 +470,18 @@
         return this->mapRect(rect, *rect);
     }
 
+    /** Apply this matrix to the src rectangle, and write the four transformed
+        points into dst. The points written to dst will be the original top-left, top-right,
+        bottom-right, and bottom-left points transformed by the matrix.
+        @param dst  Where the transformed quad is written.
+        @param rect The original rectangle to be transformed.
+    */
+    void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const {
+        // This could potentially be faster if we only transformed each x and y of the rect once.
+        rect.toQuad(dst);
+        this->mapPoints(dst, 4);
+    }
+
     /** Return the mean radius of a circle after it has been mapped by
         this matrix. NOTE: in perspective this value assumes the circle
         has its center at the origin.
diff --git a/core/SkRect.h b/core/SkRect.h
index 9f3b59a..d0eaac4 100644
--- a/core/SkRect.h
+++ b/core/SkRect.h
@@ -466,8 +466,9 @@
         return !SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4);
     }
 
-    /** return the 4 points that enclose the rectangle
-    */
+    /** return the 4 points that enclose the rectangle (top-left, top-right, bottom-right,
+        bottom-left). TODO: Consider adding param to control whether quad is CW or CCW.
+     */
     void toQuad(SkPoint quad[4]) const;
 
     /** Set this rectangle to the empty rectangle (0,0,0,0)
diff --git a/gpu/GrPaint.h b/gpu/GrPaint.h
index 9e326f0..59343e7 100644
--- a/gpu/GrPaint.h
+++ b/gpu/GrPaint.h
@@ -174,7 +174,28 @@
         this->resetColorFilter();
     }
 
+    /**
+     * Determines whether the drawing with this paint is opaque with respect to both color blending
+     * and fractional coverage. It does not consider whether AA has been enabled on the paint or
+     * not. Depending upon whether multisampling or coverage-based AA is in use, AA may make the
+     * result only apply to the interior of primitives.
+     *
+     */
+    bool isOpaque() const;
+
+    /**
+     * Returns true if isOpaque would return true and the paint represents a solid constant color
+     * draw. If the result is true, constantColor will be updated to contain the constant color.
+     */
+    bool isOpaqueAndConstantColor(GrColor* constantColor) const;
+
 private:
+
+    /**
+     * Helper for isOpaque and isOpaqueAndConstantColor.
+     */
+    bool getOpaqueAndKnownColor(GrColor* solidColor, uint32_t* solidColorKnownComponents) const;
+
     /**
      * Called when the source coord system from which geometry is rendered changes. It ensures that
      * the local coordinates seen by effects remains unchanged. oldToNew gives the transformation
diff --git a/gpu/GrSurface.h b/gpu/GrSurface.h
index 52a5665..eeb63ad 100644
--- a/gpu/GrSurface.h
+++ b/gpu/GrSurface.h
@@ -11,6 +11,7 @@
 
 #include "GrTypes.h"
 #include "GrResource.h"
+#include "SkRect.h"
 
 class GrTexture;
 class GrRenderTarget;
@@ -33,6 +34,12 @@
      */
     int height() const { return fDesc.fHeight; }
 
+    /**
+     * Helper that gets the width and height of the surface as a bounding rectangle.
+     */
+    void getBoundsRect(SkRect* rect) const { rect->setWH(SkIntToScalar(this->width()),
+                                                         SkIntToScalar(this->height())); }
+
     GrSurfaceOrigin origin() const {
         GrAssert(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin || kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
         return fDesc.fOrigin;