Adds ability to draw rects using a unit square vertex buffer. Useful when matrix/uniform changes are less expensive than sending new verts. 

Adds optional matrix parameters to GrContext drawRect and drawRectToRect so that non-axis-aligned matrices can be drawn using these functions.

codereview Issue 4105049

git-svn-id: http://skia.googlecode.com/svn/trunk@749 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index d8bbcd2..3624747 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -21,6 +21,7 @@
 #include "GrTextureCache.h"
 #include "GrClipIterator.h"
 #include "GrIndexBuffer.h"
+#include "GrVertexBuffer.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -57,7 +58,8 @@
 
 GrGpu::GrGpu() : f8bitPaletteSupport(false),
                  fNPOTTextureSupport(kNone_NPOTTextureType),
-                 fQuadIndexBuffer(NULL) {
+                 fQuadIndexBuffer(NULL),
+                 fUnitSquareVertexBuffer(NULL) {
 #if GR_DEBUG
 //    gr_run_unittests();
 #endif
@@ -65,9 +67,8 @@
 }
 
 GrGpu::~GrGpu() {
-    if (NULL != fQuadIndexBuffer) {
-        fQuadIndexBuffer->unref();
-    }
+    GrSafeUnref(fQuadIndexBuffer);
+    GrSafeUnref(fUnitSquareVertexBuffer);
 }
 
 void GrGpu::resetContext() {
@@ -155,7 +156,7 @@
                 if (!fQuadIndexBuffer->updateData(indices, SIZE)) {
                     fQuadIndexBuffer->unref();
                     fQuadIndexBuffer = NULL;
-                    GrAssert(!"Can't get indices into buffer!");
+                    GrCrash("Can't get indices into buffer!");
                 }
                 GrFree(indices);
             }
@@ -165,6 +166,31 @@
     return fQuadIndexBuffer;
 }
 
+const GrVertexBuffer* GrGpu::unitSquareVertexBuffer() const {
+    if (NULL == fUnitSquareVertexBuffer) {
+
+        static const GrPoint DATA[] = {
+            GrPoint(0,         0),
+            GrPoint(GR_Scalar1,0),
+            GrPoint(GR_Scalar1,GR_Scalar1),
+            GrPoint(0,         GR_Scalar1)
+        };
+        static const size_t SIZE = sizeof(DATA);
+
+        GrGpu* me = const_cast<GrGpu*>(this);
+        fUnitSquareVertexBuffer = me->createVertexBuffer(SIZE, false);
+        if (NULL != fUnitSquareVertexBuffer) {
+            if (!fUnitSquareVertexBuffer->updateData(DATA, SIZE)) {
+                fUnitSquareVertexBuffer->unref();
+                fUnitSquareVertexBuffer = NULL;
+                GrCrash("Can't get vertices into buffer!");
+            }
+        }
+    }
+
+    return fUnitSquareVertexBuffer;
+}
+
 int GrGpu::maxQuadsInIndexBuffer() const {
     return (NULL == this->quadIndexBuffer()) ? 0 : MAX_QUADS;
 }