Accelerate AA filled rect drawing using drawIndexedInstances

https://codereview.appspot.com/6947078/



git-svn-id: http://skia.googlecode.com/svn/trunk@6889 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrAARectRenderer.h b/include/gpu/GrAARectRenderer.h
index e8b9f15..0cf7faa 100644
--- a/include/gpu/GrAARectRenderer.h
+++ b/include/gpu/GrAARectRenderer.h
@@ -54,10 +54,6 @@
     GrIndexBuffer*              fAAFillRectIndexBuffer;
     GrIndexBuffer*              fAAStrokeRectIndexBuffer;
 
-    static const uint16_t       gFillAARectIdx[];
-    static const uint16_t       gStrokeAARectIdx[];
-
-    static int aaFillRectIndexCount();
     GrIndexBuffer* aaFillRectIndexBuffer(GrGpu* gpu);
 
     static int aaStrokeRectIndexCount();
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index c62eeb7..b9d17f8 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -36,7 +36,7 @@
     GrSafeSetNull(fAAStrokeRectIndexBuffer);
 }
 
-const uint16_t GrAARectRenderer::gFillAARectIdx[] = {
+static const uint16_t gFillAARectIdx[] = {
     0, 1, 5, 5, 4, 0,
     1, 2, 6, 6, 5, 1,
     2, 3, 7, 7, 6, 2,
@@ -44,27 +44,47 @@
     4, 5, 6, 6, 7, 4,
 };
 
-int GrAARectRenderer::aaFillRectIndexCount() {
-    return GR_ARRAY_COUNT(gFillAARectIdx);
-}
+static const int kIndicesPerAAFillRect = GR_ARRAY_COUNT(gFillAARectIdx);
+static const int kVertsPerAAFillRect = 8;
+static const int kNumAAFillRectsInIndexBuffer = 256;
 
 GrIndexBuffer* GrAARectRenderer::aaFillRectIndexBuffer(GrGpu* gpu) {
+    static const size_t kAAFillRectIndexBufferSize = kIndicesPerAAFillRect *
+                                                     sizeof(uint16_t) *
+                                                     kNumAAFillRectsInIndexBuffer;
+
     if (NULL == fAAFillRectIndexBuffer) {
-        fAAFillRectIndexBuffer = gpu->createIndexBuffer(sizeof(gFillAARectIdx),
-                                                         false);
+        fAAFillRectIndexBuffer = gpu->createIndexBuffer(kAAFillRectIndexBufferSize, false);
         if (NULL != fAAFillRectIndexBuffer) {
-#if GR_DEBUG
-            bool updated =
-#endif
-            fAAFillRectIndexBuffer->updateData(gFillAARectIdx,
-                                               sizeof(gFillAARectIdx));
-            GR_DEBUGASSERT(updated);
+            uint16_t* data = (uint16_t*) fAAFillRectIndexBuffer->lock();
+            bool useTempData = (NULL == data);
+            if (useTempData) {
+                data = SkNEW_ARRAY(uint16_t, kNumAAFillRectsInIndexBuffer * kIndicesPerAAFillRect);
+            }
+            for (int i = 0; i < kNumAAFillRectsInIndexBuffer; ++i) {
+                // Each AA filled rect is drawn with 8 vertices and 10 triangles (8 around
+                // the inner rect (for AA) and 2 for the inner rect.
+                int baseIdx = i * kIndicesPerAAFillRect;
+                uint16_t baseVert = (uint16_t)(i * kVertsPerAAFillRect);
+                for (int j = 0; j < kIndicesPerAAFillRect; ++j) {
+                    data[baseIdx+j] = baseVert + gFillAARectIdx[j];
+                }
+            }
+            if (useTempData) {
+                if (!fAAFillRectIndexBuffer->updateData(data, kAAFillRectIndexBufferSize)) {
+                    GrCrash("Can't get AA Fill Rect indices into buffer!");
+                }
+                SkDELETE_ARRAY(data);
+            } else {
+                fAAFillRectIndexBuffer->unlock();
+            }
         }
     }
+
     return fAAFillRectIndexBuffer;
 }
 
-const uint16_t GrAARectRenderer::gStrokeAARectIdx[] = {
+static const uint16_t gStrokeAARectIdx[] = {
     0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0,
     1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0,
     2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0,
@@ -114,6 +134,7 @@
         GrPrintf("Failed to get space for vertices!\n");
         return;
     }
+
     GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(gpu);
     if (NULL == indexBuffer) {
         GrPrintf("Failed to create index buffer!\n");
@@ -146,9 +167,9 @@
     }
 
     target->setIndexSourceToBuffer(indexBuffer);
-
-    target->drawIndexed(kTriangles_GrPrimitiveType, 0,
-                        0, 8, this->aaFillRectIndexCount());
+    target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
+                                 kVertsPerAAFillRect,
+                                 kIndicesPerAAFillRect);
 }
 
 void GrAARectRenderer::strokeAARect(GrGpu* gpu,
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 51546e7..d51dca4 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -300,16 +300,16 @@
             draw->fVertexBuffer != vertexBuffer) {
 
             draw = this->recordDraw();
-            draw->fIndexBuffer = geomSrc.fIndexBuffer;
-            geomSrc.fIndexBuffer->ref();
+            draw->fPrimitiveType = type;
+            draw->fStartVertex = poolState.fPoolStartVertex;
+            draw->fStartIndex = 0;
+            draw->fVertexCount = 0;
+            draw->fIndexCount = 0;
+            draw->fVertexLayout = geomSrc.fVertexLayout;
             draw->fVertexBuffer = vertexBuffer;
             vertexBuffer->ref();
-            draw->fPrimitiveType = type;
-            draw->fStartIndex = 0;
-            draw->fIndexCount = 0;
-            draw->fStartVertex = poolState.fPoolStartVertex;
-            draw->fVertexCount = 0;
-            draw->fVertexLayout = geomSrc.fVertexLayout;
+            draw->fIndexBuffer = geomSrc.fIndexBuffer;
+            geomSrc.fIndexBuffer->ref();
         } else {
             GrAssert(!(draw->fIndexCount % indicesPerInstance));
             GrAssert(!(draw->fVertexCount % verticesPerInstance));
@@ -343,15 +343,16 @@
             if (!instancesToConcat) {
                 int startVertex = draw->fStartVertex + draw->fVertexCount;
                 draw = this->recordDraw();
-                draw->fIndexBuffer = geomSrc.fIndexBuffer;
-                geomSrc.fIndexBuffer->ref();
+                draw->fPrimitiveType = type;
+                draw->fStartVertex = startVertex;
+                draw->fStartIndex = 0;
+                draw->fVertexCount = 0;
+                draw->fIndexCount = 0;
+                draw->fVertexLayout = geomSrc.fVertexLayout;
                 draw->fVertexBuffer = vertexBuffer;
                 vertexBuffer->ref();
-                draw->fPrimitiveType = type;
-                draw->fStartIndex = 0;
-                draw->fStartVertex = startVertex;
-                draw->fVertexCount = 0;
-                draw->fVertexLayout = geomSrc.fVertexLayout;
+                draw->fIndexBuffer = geomSrc.fIndexBuffer;
+                geomSrc.fIndexBuffer->ref();
                 instancesToConcat = maxInstancesPerDraw;
             }
             draw->fVertexCount += instancesToConcat * verticesPerInstance;