Revert of Start on simplifying generateGeometry() overrides (patchset #10 id:160001...
authorbsalomon <bsalomon@google.com>
Mon, 4 May 2015 18:41:41 +0000 (11:41 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 4 May 2015 18:41:42 +0000 (11:41 -0700)
Reason for revert:
Breaking bots

Original issue's description:
> Start on simplifying generateGeometry() overrides
>
> Committed: https://skia.googlesource.com/skia/+/f28381c6866cad92af8ebe5b9d2db074613b1963

TBR=joshualitt@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

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

17 files changed:
gm/beziereffects.cpp
gm/convexpolyeffect.cpp
src/gpu/GrAAConvexPathRenderer.cpp
src/gpu/GrAADistanceFieldPathRenderer.cpp
src/gpu/GrAAHairLinePathRenderer.cpp
src/gpu/GrAARectRenderer.cpp
src/gpu/GrAtlasTextContext.cpp
src/gpu/GrBatch.cpp
src/gpu/GrBatch.h
src/gpu/GrContext.cpp
src/gpu/GrDefaultPathRenderer.cpp
src/gpu/GrDrawTarget.cpp
src/gpu/GrDrawTarget.h
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrOvalRenderer.cpp
src/gpu/GrTessellatingPathRenderer.cpp
src/gpu/effects/GrDashingEffect.cpp

index d543c14..6568422 100644 (file)
@@ -16,6 +16,7 @@
 #include "GrBufferAllocPool.h"
 #include "GrContext.h"
 #include "GrPathUtils.h"
+#include "GrResourceProvider.h"
 #include "GrTest.h"
 #include "GrTestBatch.h"
 #include "SkColorPriv.h"
@@ -66,14 +67,25 @@ private:
     }
 
     void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
-        QuadHelper helper;
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
+
         size_t vertexStride = this->geometryProcessor()->getVertexStride();
-        SkASSERT(vertexStride == sizeof(Vertex));
-        Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1));
-        if (!verts) {
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              kVertsPerCubic,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
+
+        if (!vertices || !indexBuffer) {
+            SkDebugf("Could not allocate buffers\n");
             return;
         }
 
+        SkASSERT(vertexStride == sizeof(Vertex));
+        Vertex* verts = reinterpret_cast<Vertex*>(vertices);
+
         verts[0].fPosition.setRectFan(fGeometry.fBounds.fLeft, fGeometry.fBounds.fTop,
                                       fGeometry.fBounds.fRight, fGeometry.fBounds.fBottom,
                                       sizeof(Vertex));
@@ -82,7 +94,16 @@ private:
             verts[v].fKLM[1] = eval_line(verts[v].fPosition, fKlmEqs + 3, fSign);
             verts[v].fKLM[2] = eval_line(verts[v].fPosition, fKlmEqs + 6, 1.f);
         }
-        helper.issueDraws(batchTarget);
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangleFan_GrPrimitiveType);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setStartVertex(firstVertex);
+        drawInfo.setVertexCount(kVertsPerCubic);
+        drawInfo.setStartIndex(0);
+        drawInfo.setIndexCount(kIndicesPerCubic);
+        drawInfo.setIndexBuffer(indexBuffer);
+        batchTarget->draw(drawInfo);
     }
 
     Geometry fGeometry;
@@ -454,19 +475,42 @@ private:
     }
 
     void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
-        QuadHelper helper;
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
+
         size_t vertexStride = this->geometryProcessor()->getVertexStride();
-        SkASSERT(vertexStride == sizeof(Vertex));
-        GrDrawTarget::DrawInfo drawInfo;
-        Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1));
-        if (!verts) {
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+
+        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              kVertsPerCubic,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
+
+        if (!vertices || !indexBuffer) {
+            SkDebugf("Could not allocate buffers\n");
             return;
         }
+
+        SkASSERT(vertexStride == sizeof(Vertex));
+        Vertex* verts = reinterpret_cast<Vertex*>(vertices);
+
         verts[0].fPosition.setRectFan(fGeometry.fBounds.fLeft, fGeometry.fBounds.fTop,
                                       fGeometry.fBounds.fRight, fGeometry.fBounds.fBottom,
                                       sizeof(Vertex));
+
         fDevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
-        helper.issueDraws(batchTarget);
+
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setStartVertex(firstVertex);
+        drawInfo.setVertexCount(kVertsPerCubic);
+        drawInfo.setStartIndex(0);
+        drawInfo.setIndexCount(kIndicesPerCubic);
+        drawInfo.setIndexBuffer(indexBuffer);
+        batchTarget->draw(drawInfo);
     }
 
     Geometry fGeometry;
index cd9b3d1..60b73c5 100644 (file)
@@ -17,6 +17,7 @@
 #include "GrContext.h"
 #include "GrDefaultGeoProcFactory.h"
 #include "GrPathUtils.h"
+#include "GrResourceProvider.h"
 #include "GrTest.h"
 #include "GrTestBatch.h"
 #include "SkColorPriv.h"
@@ -52,24 +53,47 @@ private:
     }
 
     void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
+
         size_t vertexStride = this->geometryProcessor()->getVertexStride();
-        SkASSERT(vertexStride == sizeof(SkPoint));
-        QuadHelper helper;
-        SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(batchTarget, vertexStride, 1));
-        if (!verts) {
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+
+        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              kVertsPerCubic,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
+
+        if (!vertices || !indexBuffer) {
+            SkDebugf("Could not allocate buffers\n");
             return;
         }
 
+        SkASSERT(vertexStride == sizeof(SkPoint));
+        SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
+
         // Make sure any artifacts around the exterior of path are visible by using overly
         // conservative bounding geometry.
         fGeometry.fBounds.outset(5.f, 5.f);
         fGeometry.fBounds.toQuad(verts);
 
-        helper.issueDraws(batchTarget);
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangleFan_GrPrimitiveType);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setStartVertex(firstVertex);
+        drawInfo.setVertexCount(kVertsPerCubic);
+        drawInfo.setStartIndex(0);
+        drawInfo.setIndexCount(kIndicesPerCubic);
+        drawInfo.setIndexBuffer(indexBuffer);
+        batchTarget->draw(drawInfo);
     }
 
     Geometry fGeometry;
 
+    static const int kVertsPerCubic = 4;
+    static const int kIndicesPerCubic = 6;
+
     typedef GrTestBatch INHERITED;
 };
 
index f203064..3a548aa 100644 (file)
@@ -824,14 +824,19 @@ public:
             create_vertices(segments, fanPt, &draws, verts, idxs);
 
             GrDrawTarget::DrawInfo info;
+            info.setVertexBuffer(vertexBuffer);
+            info.setIndexBuffer(indexBuffer);
+            info.setPrimitiveType(kTriangles_GrPrimitiveType);
+            info.setStartIndex(firstIndex);
 
+            int vOffset = 0;
             for (int i = 0; i < draws.count(); ++i) {
                 const Draw& draw = draws[i];
-                info.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
-                                 firstIndex, draw.fVertexCnt, draw.fIndexCnt);
+                info.setStartVertex(vOffset + firstVertex);
+                info.setVertexCount(draw.fVertexCnt);
+                info.setIndexCount(draw.fIndexCnt);
                 batchTarget->draw(info);
-                firstVertex += draw.fVertexCnt;
-                firstIndex += draw.fIndexCnt;
+                vOffset += draw.fVertexCnt;
             }
         }
     }
index 312b731..ca8c52f 100755 (executable)
@@ -13,9 +13,9 @@
 #include "GrBufferAllocPool.h"
 #include "GrContext.h"
 #include "GrPipelineBuilder.h"
-#include "GrResourceProvider.h"
 #include "GrSurfacePriv.h"
 #include "GrSWMaskHelper.h"
+#include "GrResourceProvider.h"
 #include "GrTexturePriv.h"
 #include "GrVertexBuffer.h"
 #include "effects/GrDistanceFieldGeoProc.h"
@@ -169,13 +169,6 @@ public:
         fBatch.fCoverageIgnored = init.fCoverageIgnored;
     }
 
-    struct FlushInfo {
-        SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
-        SkAutoTUnref<const GrIndexBuffer>  fIndexBuffer;
-        int fVertexOffset;
-        int fInstancesToFlush;
-    };
-
     void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
         int instanceCount = fGeoData.count();
 
@@ -202,25 +195,43 @@ public:
 
         this->initDraw(batchTarget, dfProcessor, pipeline);
 
-        FlushInfo flushInfo;
+        static const int kVertsPerQuad = 4;
+        static const int kIndicesPerQuad = 6;
+
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
 
         // allocate vertices
         size_t vertexStride = dfProcessor->getVertexStride();
         SkASSERT(vertexStride == 2 * sizeof(SkPoint));
-
         const GrVertexBuffer* vertexBuffer;
+        int vertexCount = kVertsPerQuad * instanceCount;
+        int firstVertex;
+
         void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
-                                                              kVerticesPerQuad * instanceCount,
+                                                              vertexCount,
                                                               &vertexBuffer,
-                                                              &flushInfo.fVertexOffset);
-        flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
-        flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadIndexBuffer());
-        if (!vertices || !flushInfo.fIndexBuffer) {
+                                                              &firstVertex);
+
+        if (!vertices || !indexBuffer) {
             SkDebugf("Could not allocate vertices\n");
             return;
         }
 
-        flushInfo.fInstancesToFlush = 0;
+        // We may have to flush while uploading path data to the atlas, so we set up the draw here
+        int maxInstancesPerDraw = indexBuffer->maxQuads();
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerQuad);
+        drawInfo.setIndicesPerInstance(kIndicesPerQuad);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int instancesToFlush = 0;
         for (int i = 0; i < instanceCount; i++) {
             Geometry& args = fGeoData[i];
 
@@ -254,7 +265,9 @@ public:
                 if (!this->addPathToAtlas(batchTarget,
                                           dfProcessor,
                                           pipeline,
-                                          &flushInfo,
+                                          &drawInfo,
+                                          &instancesToFlush,
+                                          maxInstancesPerDraw,
                                           atlas,
                                           args.fPathData,
                                           args.fPath,
@@ -271,21 +284,21 @@ public:
 
             // Now set vertices
             intptr_t offset = reinterpret_cast<intptr_t>(vertices);
-            offset += i * kVerticesPerQuad * vertexStride;
+            offset += i * kVertsPerQuad * vertexStride;
             SkPoint* positions = reinterpret_cast<SkPoint*>(offset);
-            this->writePathVertices(batchTarget,
-                                    atlas,
-                                    pipeline,
-                                    dfProcessor,
-                                    positions,
-                                    vertexStride,
-                                    this->viewMatrix(),
-                                    args.fPath,
-                                    args.fPathData);
-            flushInfo.fInstancesToFlush++;
+            this->drawPath(batchTarget,
+                           atlas,
+                           pipeline,
+                           dfProcessor,
+                           positions,
+                           vertexStride,
+                           this->viewMatrix(),
+                           args.fPath,
+                           args.fPathData);
+            instancesToFlush++;
         }
 
-        this->flush(batchTarget, &flushInfo);
+        this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw);
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -312,7 +325,9 @@ private:
     bool addPathToAtlas(GrBatchTarget* batchTarget,
                         const GrGeometryProcessor* dfProcessor,
                         const GrPipeline* pipeline,
-                        FlushInfo* flushInfo,
+                        GrDrawTarget::DrawInfo* drawInfo,
+                        int* instancesToFlush,
+                        int maxInstancesPerDraw,
                         GrBatchAtlas* atlas,
                         PathData* pathData,
                         const SkPath& path,
@@ -414,8 +429,9 @@ private:
         bool success = atlas->addToAtlas(&id, batchTarget, width, height, dfStorage.get(),
                                          &atlasLocation);
         if (!success) {
-            this->flush(batchTarget, flushInfo);
+            this->flush(batchTarget, drawInfo, *instancesToFlush, maxInstancesPerDraw);
             this->initDraw(batchTarget, dfProcessor, pipeline);
+            *instancesToFlush = 0;
 
             SkDEBUGCODE(success =) atlas->addToAtlas(&id, batchTarget, width, height,
                                                      dfStorage.get(), &atlasLocation);
@@ -451,15 +467,15 @@ private:
         return true;
     }
 
-    void writePathVertices(GrBatchTarget* target,
-                           GrBatchAtlas* atlas,
-                           const GrPipeline* pipeline,
-                           const GrGeometryProcessor* gp,
-                           SkPoint* positions,
-                           size_t vertexStride,
-                           const SkMatrix& viewMatrix,
-                           const SkPath& path,
-                           const PathData* pathData) {
+    void drawPath(GrBatchTarget* target,
+                  GrBatchAtlas* atlas,
+                  const GrPipeline* pipeline,
+                  const GrGeometryProcessor* gp,
+                  SkPoint* positions,
+                  size_t vertexStride,
+                  const SkMatrix& viewMatrix,
+                  const SkPath& path,
+                  const PathData* pathData) {
         GrTexture* texture = atlas->getTexture();
 
         SkScalar dx = pathData->fBounds.fLeft;
@@ -506,18 +522,20 @@ private:
         dfProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init);
     }
 
-    void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
-        GrDrawTarget::DrawInfo drawInfo;
-        int instancesToFlush = flushInfo->fInstancesToFlush;
-        int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads();
-        drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
-            flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad,
-            kIndicesPerQuad, &instancesToFlush, maxInstancesPerDraw);
-        do {
-            batchTarget->draw(drawInfo);
-        } while (drawInfo.nextInstances(&instancesToFlush, maxInstancesPerDraw));
-        flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;
-        flushInfo->fInstancesToFlush = 0;
+    void flush(GrBatchTarget* batchTarget,
+               GrDrawTarget::DrawInfo* drawInfo,
+               int instanceCount,
+               int maxInstancesPerDraw) {
+        while (instanceCount) {
+            drawInfo->setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo->setVertexCount(drawInfo->instanceCount() * drawInfo->verticesPerInstance());
+            drawInfo->setIndexCount(drawInfo->instanceCount() * drawInfo->indicesPerInstance());
+
+            batchTarget->draw(*drawInfo);
+
+            drawInfo->setStartVertex(drawInfo->startVertex() + drawInfo->vertexCount());
+            instanceCount -= drawInfo->instanceCount();
+       }
     }
 
     GrColor color() const { return fBatch.fColor; }
index ba6dcec..f046af8 100644 (file)
@@ -888,14 +888,23 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
         }
 
         {
-            int linesLeft = lineCount;
             GrDrawTarget::DrawInfo info;
-            info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer,
-                               firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, &linesLeft,
-                               kLineSegsNumInIdxBuffer);
-            do {
+            info.setVertexBuffer(vertexBuffer);
+            info.setIndexBuffer(linesIndexBuffer);
+            info.setPrimitiveType(kTriangles_GrPrimitiveType);
+            info.setStartIndex(0);
+
+            int lines = 0;
+            while (lines < lineCount) {
+                int n = SkTMin(lineCount - lines, kLineSegsNumInIdxBuffer);
+
+                info.setStartVertex(kLineSegNumVertices*lines + firstVertex);
+                info.setVertexCount(kLineSegNumVertices*n);
+                info.setIndexCount(kIdxsPerLineSeg*n);
                 batchTarget->draw(info);
-            } while (info.nextInstances(&linesLeft, kLineSegsNumInIdxBuffer));
+
+                lines += n;
+            }
         }
     }
 
@@ -944,15 +953,23 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
             quadGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
             {
-                int quadsLeft = quadCount;
-                GrDrawTarget::DrawInfo info;
-                info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
-                                   firstVertex, kQuadNumVertices, kIdxsPerQuad, &quadsLeft,
-                                   kQuadsNumInIdxBuffer);
-               do {
+               GrDrawTarget::DrawInfo info;
+               info.setVertexBuffer(vertexBuffer);
+               info.setIndexBuffer(quadsIndexBuffer);
+               info.setPrimitiveType(kTriangles_GrPrimitiveType);
+               info.setStartIndex(0);
+
+               int quads = 0;
+               while (quads < quadCount) {
+                   int n = SkTMin(quadCount - quads, kQuadsNumInIdxBuffer);
+
+                   info.setStartVertex(kQuadNumVertices*quads + firstVertex);
+                   info.setVertexCount(kQuadNumVertices*n);
+                   info.setIndexCount(kIdxsPerQuad*n);
                    batchTarget->draw(info);
-               } while (info.nextInstances(&quadsLeft, kQuadsNumInIdxBuffer));
-               firstVertex += quadCount * kQuadNumVertices;
+
+                   quads += n;
+               }
            }
         }
 
@@ -968,14 +985,23 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
             conicGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
             {
-                int conicsLeft = conicCount;
                 GrDrawTarget::DrawInfo info;
-                info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
-                                  firstVertex, kQuadNumVertices, kIdxsPerQuad, &conicsLeft,
-                                  kQuadsNumInIdxBuffer);
-                do {
+                info.setVertexBuffer(vertexBuffer);
+                info.setIndexBuffer(quadsIndexBuffer);
+                info.setPrimitiveType(kTriangles_GrPrimitiveType);
+                info.setStartIndex(0);
+
+                int conics = 0;
+                while (conics < conicCount) {
+                    int n = SkTMin(conicCount - conics, kQuadsNumInIdxBuffer);
+
+                    info.setStartVertex(kQuadNumVertices*(quadCount + conics) + firstVertex);
+                    info.setVertexCount(kQuadNumVertices*n);
+                    info.setIndexCount(kIdxsPerQuad*n);
                     batchTarget->draw(info);
-                } while (info.nextInstances(&conicsLeft, kQuadsNumInIdxBuffer));
+
+                    conics += n;
+                }
             }
         }
     }
index 267d970..d1c377a 100644 (file)
@@ -112,17 +112,22 @@ public:
         init.fUsesLocalCoords = this->usesLocalCoords();
         gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer(
+            batchTarget->resourceProvider()));
+
         size_t vertexStride = gp->getVertexStride();
         SkASSERT(canTweakAlphaForCoverage ?
                  vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) :
                  vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
         int instanceCount = fGeoData.count();
+        int vertexCount = kVertsPerAAFillRect * instanceCount;
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              vertexCount,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
 
-        SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer(
-            batchTarget->resourceProvider()));
-        InstancedHelper helper;
-        void* vertices = helper.init(batchTarget, vertexStride, indexBuffer, kVertsPerAAFillRect,
-                                     kIndicesPerAAFillRect, instanceCount);
         if (!vertices || !indexBuffer) {
             SkDebugf("Could not allocate vertices\n");
             return;
@@ -140,7 +145,28 @@ public:
                                              canTweakAlphaForCoverage);
         }
 
-        helper.issueDraws(batchTarget);
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerAAFillRect);
+        drawInfo.setIndicesPerInstance(kIndicesPerAAFillRect);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = kNumAAFillRectsInIndexBuffer;
+
+        while (instanceCount) {
+            drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            instanceCount -= drawInfo.instanceCount();
+        }
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -459,6 +485,9 @@ public:
 
         batchTarget->initDraw(gp, pipeline);
 
+        const SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            GetIndexBuffer(batchTarget->resourceProvider(), this->miterStroke()));
+
         // TODO this is hacky, but the only way we have to initialize the GP is to use the
         // GrPipelineInfo struct so we can generate the correct shader.  Once we have GrBatch
         // everywhere we can remove this nastiness
@@ -476,24 +505,28 @@ public:
                  vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
         int innerVertexNum = 4;
         int outerVertexNum = this->miterStroke() ? 4 : 8;
-        int verticesPerInstance = (outerVertexNum + innerVertexNum) * 2;
-        int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt;
+        int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
+
         int instanceCount = fGeoData.count();
+        int vertexCount = totalVertexNum * instanceCount;
+
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+
+        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              vertexCount,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
 
-        const SkAutoTUnref<const GrIndexBuffer> indexBuffer(
-            GetIndexBuffer(batchTarget->resourceProvider(), this->miterStroke()));
-        InstancedHelper helper;
-        void* vertices = helper.init(batchTarget, vertexStride, indexBuffer, verticesPerInstance, 
-                                     indicesPerInstance, instanceCount);
         if (!vertices || !indexBuffer) {
-             SkDebugf("Could not allocate vertices\n");
-             return;
-         }
+            SkDebugf("Could not allocate vertices\n");
+            return;
+        }
 
         for (int i = 0; i < instanceCount; i++) {
             const Geometry& args = fGeoData[i];
             this->generateAAStrokeRectGeometry(vertices,
-                                               i * verticesPerInstance * vertexStride,
+                                               i * totalVertexNum * vertexStride,
                                                vertexStride,
                                                outerVertexNum,
                                                innerVertexNum,
@@ -504,7 +537,30 @@ public:
                                                args.fMiterStroke,
                                                canTweakAlphaForCoverage);
         }
-        helper.issueDraws(batchTarget);
+        int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt;
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(totalVertexNum);
+        drawInfo.setIndicesPerInstance(indicesPerInstance);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = this->miterStroke() ? kNumMiterRectsInIndexBuffer :
+                                                        kNumBevelRectsInIndexBuffer;
+
+        while (instanceCount) {
+            drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            instanceCount -= drawInfo.instanceCount();
+        }
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
index c8688b0..33e4f7e 100644 (file)
@@ -1474,13 +1474,6 @@ public:
         fBatch.fCoverageIgnored = init.fCoverageIgnored;
     }
 
-    struct FlushInfo {
-        SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
-        SkAutoTUnref<const GrIndexBuffer> fIndexBuffer;
-        int fGlyphsToFlush;
-        int fVertexOffset;
-    };
-
     void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
         // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix.
         // TODO actually only invert if we don't have RGBA
@@ -1513,8 +1506,6 @@ public:
                                                  localMatrix));
         }
 
-        FlushInfo flushInfo;
-        flushInfo.fGlyphsToFlush = 0;
         size_t vertexStride = gp->getVertexStride();
         SkASSERT(vertexStride == (fUseDistanceFields ?
                                   get_vertex_stride_df(fMaskFormat, fUseLCDText) :
@@ -1524,21 +1515,35 @@ public:
 
         int glyphCount = this->numGlyphs();
         int instanceCount = fInstanceCount;
-        const GrVertexBuffer* vertexBuffer;
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
 
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
         void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
                                                               glyphCount * kVerticesPerGlyph,
                                                               &vertexBuffer,
-                                                              &flushInfo.fVertexOffset);
-        flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
-        flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadIndexBuffer());
-        if (!vertices || !flushInfo.fVertexBuffer) {
+                                                              &firstVertex);
+        if (!vertices || !indexBuffer) {
             SkDebugf("Could not allocate vertices\n");
             return;
         }
 
         unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices);
 
+        // setup drawinfo
+        int maxInstancesPerDraw = indexBuffer->maxQuads();
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVerticesPerGlyph);
+        drawInfo.setIndicesPerInstance(kIndicesPerGlyph);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
         // We cache some values to avoid going to the glyphcache for the same fontScaler twice
         // in a row
         const SkDescriptor* desc = NULL;
@@ -1546,6 +1551,7 @@ public:
         GrFontScaler* scaler = NULL;
         SkTypeface* typeface = NULL;
 
+        int instancesToFlush = 0;
         for (int i = 0; i < instanceCount; i++) {
             Geometry& args = fGeoData[i];
             Blob* blob = args.fBlob;
@@ -1629,8 +1635,10 @@ public:
 
                         if (!fFontCache->hasGlyph(glyph) &&
                             !strike->addGlyphToAtlas(batchTarget, glyph, scaler)) {
-                            this->flush(batchTarget, &flushInfo);
+                            this->flush(batchTarget, &drawInfo, instancesToFlush,
+                                        maxInstancesPerDraw);
                             this->initDraw(batchTarget, gp, pipeline);
+                            instancesToFlush = 0;
                             brokenRun = glyphIdx > 0;
 
                             SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(batchTarget,
@@ -1666,7 +1674,7 @@ public:
                         SkScalar transY = args.fTransY;
                         this->regeneratePositions(vertex, vertexStride, transX, transY);
                     }
-                    flushInfo.fGlyphsToFlush++;
+                    instancesToFlush++;
                 }
 
                 // We my have changed the color so update it here
@@ -1679,7 +1687,7 @@ public:
                                                         fFontCache->atlasGeneration(fMaskFormat);
                 }
             } else {
-                flushInfo.fGlyphsToFlush += glyphCount;
+                instancesToFlush += glyphCount;
 
                 // set use tokens for all of the glyphs in our subrun.  This is only valid if we
                 // have a valid atlas generation
@@ -1698,7 +1706,7 @@ public:
         if (cache) {
             SkGlyphCache::AttachCache(cache);
         }
-        this->flush(batchTarget, &flushInfo);
+        this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw);
     }
 
     // The minimum number of Geometry we will try to allocate.
@@ -1825,19 +1833,20 @@ private:
         gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
     }
 
-    void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
-        GrDrawTarget::DrawInfo drawInfo;
-        int glyphsToFlush = flushInfo->fGlyphsToFlush;
-        int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
-        drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
-                               flushInfo->fIndexBuffer, flushInfo->fVertexOffset,
-                               kVerticesPerGlyph, kIndicesPerGlyph, &glyphsToFlush,
-                               maxGlyphsPerDraw);
-        do {
-            batchTarget->draw(drawInfo);
-        } while (drawInfo.nextInstances(&glyphsToFlush, maxGlyphsPerDraw));
-        flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
-        flushInfo->fGlyphsToFlush = 0;
+    void flush(GrBatchTarget* batchTarget,
+               GrDrawTarget::DrawInfo* drawInfo,
+               int instanceCount,
+               int maxInstancesPerDraw) {
+        while (instanceCount) {
+            drawInfo->setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo->setVertexCount(drawInfo->instanceCount() * drawInfo->verticesPerInstance());
+            drawInfo->setIndexCount(drawInfo->instanceCount() * drawInfo->indicesPerInstance());
+
+            batchTarget->draw(*drawInfo);
+
+            drawInfo->setStartVertex(drawInfo->startVertex() + drawInfo->vertexCount());
+            instanceCount -= drawInfo->instanceCount();
+       }
     }
 
     GrColor color() const { return fBatch.fColor; }
index 1ef6c97..ce30499 100644 (file)
@@ -6,8 +6,6 @@
  */
 
 #include "GrBatch.h"
-#include "GrBatchTarget.h"
-#include "GrResourceProvider.h"
 
 #include "GrMemoryPool.h"
 #include "SkSpinlock.h"
@@ -45,43 +43,3 @@ void* GrBatch::operator new(size_t size) {
 void GrBatch::operator delete(void* target) {
     return MemoryPoolAccessor().pool()->release(target);
 }
-
-void* GrBatch::InstancedHelper::init(GrBatchTarget* batchTarget, size_t vertexStride,
-                                     const GrIndexBuffer* indexBuffer, int verticesPerInstance,
-                                     int indicesPerInstance, int instancesToDraw) {
-    SkASSERT(!fInstancesRemaining);
-    SkASSERT(batchTarget);
-    if (!indexBuffer) {
-        return NULL;
-    }
-    const GrVertexBuffer* vertexBuffer;
-    int firstVertex;
-    int vertexCount = verticesPerInstance * instancesToDraw;
-    void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, vertexCount, &vertexBuffer,
-                                                          &firstVertex);
-    if (!vertices) {
-        SkDebugf("Vertices could not be allocated for instanced rendering.");
-        return NULL;
-    }
-    SkASSERT(vertexBuffer);
-    fInstancesRemaining = instancesToDraw;
-
-    fDrawInfo.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer,
-        firstVertex, verticesPerInstance, indicesPerInstance, &fInstancesRemaining,
-        indexBuffer->maxQuads());
-    size_t ibSize = fDrawInfo.indexBuffer()->gpuMemorySize();
-    fMaxInstancesPerDraw = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerInstance));
-    SkASSERT(fMaxInstancesPerDraw > 0);
-    return vertices;
-}
-
-void* GrBatch::QuadHelper::init(GrBatchTarget* batchTarget, size_t vertexStride, int quadsToDraw) {
-    SkAutoTUnref<const GrIndexBuffer> quadIndexBuffer(
-        batchTarget->resourceProvider()->refQuadIndexBuffer());
-    if (!quadIndexBuffer) {
-        SkDebugf("Could not get quad index buffer.");
-        return NULL;
-    }
-    return this->INHERITED::init(batchTarget, vertexStride, quadIndexBuffer, kVerticesPerQuad,
-                                 kIndicesPerQuad, quadsToDraw);
-}
index 38316ce..7b5c888 100644 (file)
 #include <new>
 // TODO remove this header when we move entirely to batch
 #include "GrDrawTarget.h"
-#include "GrBatchTarget.h"
 #include "GrGeometryProcessor.h"
 #include "SkRefCnt.h"
 #include "SkThread.h"
 #include "SkTypes.h"
 
+class GrBatchTarget;
 class GrGpu;
 class GrIndexBufferAllocPool;
 class GrPipeline;
@@ -113,48 +113,6 @@ protected:
         return fBounds.joinPossiblyEmptyRect(otherBounds);
     }
 
-    /** Helper for rendering instances using an instanced index index buffer. This class creates the
-        space for the vertices and flushes the draws to the batch target.*/
-   class InstancedHelper {
-   public:
-        InstancedHelper() : fInstancesRemaining(0) {}
-        /** Returns the allocated storage for the vertices. The caller should populate the before
-            vertices before calling issueDraws(). */
-        void* init(GrBatchTarget* batchTarget, size_t vertexStride,
-                   const GrIndexBuffer* indexBuffer, int verticesPerInstance,
-                   int indicesPerInstance, int instancesToDraw);
-
-        /** Call after init() to issue draws to the batch target.*/
-        void issueDraws(GrBatchTarget* batchTarget) {
-            SkASSERT(fDrawInfo.instanceCount());
-            do {
-                batchTarget->draw(fDrawInfo);
-            } while (fDrawInfo.nextInstances(&fInstancesRemaining, fMaxInstancesPerDraw));
-        }
-    private:
-        int                     fInstancesRemaining;
-        int                     fMaxInstancesPerDraw;
-        GrDrawTarget::DrawInfo  fDrawInfo;
-    };
-
-    static const int kVerticesPerQuad = 4;
-    static const int kIndicesPerQuad = 6;
-
-    /** A specialization of InstanceHelper for quad rendering. */
-    class QuadHelper : private InstancedHelper {
-    public:
-        QuadHelper() : INHERITED() {}
-        /** Finds the cached quad index buffer and reserves vertex space. Returns NULL on failure
-            and on sucess a pointer to the vertex data that the caller should populate before
-            calling issueDraws(). */
-        void* init(GrBatchTarget* batchTarget, size_t vertexStride, int quadsToDraw);
-
-        using InstancedHelper::issueDraws;
-
-    private:
-        typedef InstancedHelper INHERITED;
-    };
-
     SkRect fBounds;
 
 private:
index a9c6ce0..819774a 100755 (executable)
@@ -502,7 +502,15 @@ public:
         }
 
         GrDrawTarget::DrawInfo drawInfo;
-        drawInfo.init(primType, vertexBuffer, firstVertex, vertexCount);
+        drawInfo.setPrimitiveType(primType);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setStartVertex(firstVertex);
+        drawInfo.setVertexCount(vertexCount);
+        drawInfo.setStartIndex(0);
+        drawInfo.setIndexCount(0);
+        drawInfo.setInstanceCount(0);
+        drawInfo.setVerticesPerInstance(0);
+        drawInfo.setIndicesPerInstance(0);
         batchTarget->draw(drawInfo);
     }
 
@@ -821,8 +829,8 @@ public:
             return;
         }
 
-        const GrIndexBuffer* indexBuffer = NULL;
-        int firstIndex = 0;
+        const GrIndexBuffer* indexBuffer;
+        int firstIndex;
 
         void* indices = NULL;
         if (this->hasIndices()) {
@@ -862,12 +870,17 @@ public:
         }
 
         GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(this->primitiveType());
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setStartVertex(firstVertex);
+        drawInfo.setVertexCount(this->vertexCount());
         if (this->hasIndices()) {
-            drawInfo.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
-                                 firstIndex, this->vertexCount(), this->indexCount());
-
+            drawInfo.setIndexBuffer(indexBuffer);
+            drawInfo.setStartIndex(firstIndex);
+            drawInfo.setIndexCount(this->indexCount());
         } else {
-            drawInfo.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount());
+            drawInfo.setStartIndex(0);
+            drawInfo.setIndexCount(0);
         }
         batchTarget->draw(drawInfo);
     }
index a86d117..93d64ab 100644 (file)
@@ -329,8 +329,8 @@ public:
             return;
         }
 
-        const GrIndexBuffer* indexBuffer = NULL;
-        int firstIndex = 0;
+        const GrIndexBuffer* indexBuffer;
+        int firstIndex;
 
         void* indices = NULL;
         if (isIndexed) {
@@ -370,11 +370,17 @@ public:
         }
 
         GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(primitiveType);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setStartVertex(firstVertex);
+        drawInfo.setVertexCount(vertexOffset);
         if (isIndexed) {
-            drawInfo.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
-                                 vertexOffset, indexOffset);
+            drawInfo.setIndexBuffer(indexBuffer);
+            drawInfo.setStartIndex(firstIndex);
+            drawInfo.setIndexCount(indexOffset);
         } else {
-            drawInfo.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
+            drawInfo.setStartIndex(0);
+            drawInfo.setIndexCount(0);
         }
         batchTarget->draw(drawInfo);
 
index 7ae2c99..8503097 100644 (file)
@@ -37,8 +37,16 @@ GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
     fVerticesPerInstance    = di.fVerticesPerInstance;
     fIndicesPerInstance     = di.fIndicesPerInstance;
 
-    fVertexBuffer.reset(di.vertexBuffer());
-    fIndexBuffer.reset(di.indexBuffer());
+    if (di.fDevBounds) {
+        SkASSERT(di.fDevBounds == &di.fDevBoundsStorage);
+        fDevBoundsStorage = di.fDevBoundsStorage;
+        fDevBounds = &fDevBoundsStorage;
+    } else {
+        fDevBounds = NULL;
+    }
+
+    this->setVertexBuffer(di.vertexBuffer());
+    this->setIndexBuffer(di.indexBuffer());
 
     return *this;
 }
index c584181..0dca57a 100644 (file)
@@ -225,132 +225,65 @@ public:
     virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
 
     /**
-     * Used to communicate draw index vertex offsets and counts toto GPUs / subclasses
+     * Used to communicate drawto GPUs / subclasses
      */
     class DrawInfo {
     public:
-        DrawInfo() {}
+        DrawInfo() { fDevBounds = NULL; }
         DrawInfo(const DrawInfo& di) { (*this) = di; }
         DrawInfo& operator =(const DrawInfo& di);
 
-        void init(GrPrimitiveType primType, const GrVertexBuffer* vertexBuffer, int startVertex,
-                  int vertexCount) {
-            SkASSERT(vertexBuffer);
-            SkASSERT(vertexCount);
-            SkASSERT(startVertex >= 0);
-            fPrimitiveType = primType;
-            fVertexBuffer.reset(SkRef(vertexBuffer));
-            fIndexBuffer.reset(NULL);
-            fStartVertex = startVertex;
-            fStartIndex = 0;
-            fVertexCount = vertexCount;
-            fIndexCount = 0;
-            fInstanceCount = 0;
-            fVerticesPerInstance = 0;
-            fIndicesPerInstance = 0;
-        }
-
-        void initIndexed(GrPrimitiveType primType,
-                         const GrVertexBuffer* vertexBuffer,
-                         const GrIndexBuffer* indexBuffer,
-                         int startVertex,
-                         int startIndex,
-                         int vertexCount,
-                         int indexCount) {
-            SkASSERT(indexBuffer);
-            SkASSERT(vertexBuffer);
-            SkASSERT(indexCount);
-            SkASSERT(vertexCount);
-            SkASSERT(startIndex >= 0);
-            SkASSERT(startVertex >= 0);
-            fPrimitiveType = primType;
-            fVertexBuffer.reset(SkRef(vertexBuffer));
-            fIndexBuffer.reset(SkRef(indexBuffer));
-            fStartVertex = startVertex;
-            fStartIndex = startIndex;
-            fVertexCount = vertexCount;
-            fIndexCount = indexCount;
-            fInstanceCount = 0;
-            fVerticesPerInstance = 0;
-            fIndicesPerInstance = 0;
-        }
-
-        void initInstanced(GrPrimitiveType primType,
-                           const GrVertexBuffer* vertexBuffer,
-                           const GrIndexBuffer* indexBuffer,
-                           int startVertex,
-                           int verticesPerInstance,
-                           int indicesPerInstance,
-                           int instanceCount) {
-            SkASSERT(vertexBuffer);
-            SkASSERT(indexBuffer);
-            SkASSERT(instanceCount);
-            SkASSERT(verticesPerInstance);
-            SkASSERT(indicesPerInstance);
-            SkASSERT(startVertex >= 0);
-            fPrimitiveType = primType;
-            fVertexBuffer.reset(SkRef(vertexBuffer));
-            fIndexBuffer.reset(SkRef(indexBuffer));
-            fStartVertex = startVertex;
-            fStartIndex = 0;
-            fVerticesPerInstance = verticesPerInstance;
-            fIndicesPerInstance = indicesPerInstance;
-            fInstanceCount = instanceCount;
-            fVertexCount = instanceCount * fVerticesPerInstance;
-            fIndexCount = instanceCount * fIndicesPerInstance;
-        }
-
-        /** Variation of the above that may be used when the total number of instances may exceed
-            the number of instances supported by the index buffer. To be used with
-            nextInstances() to draw in max-sized batches.*/
-        void initInstanced(GrPrimitiveType primType,
-                           const GrVertexBuffer* vertexBuffer,
-                           const GrIndexBuffer* indexBuffer,
-                           int startVertex,
-                           int verticesPerInstance,
-                           int indicesPerInstance,
-                           int* instancesRemaining,
-                           int maxInstancesPerDraw) {
-            int instanceCount = SkTMin(*instancesRemaining, maxInstancesPerDraw);
-            *instancesRemaining -= instanceCount;
-            this->initInstanced(primType, vertexBuffer, indexBuffer, startVertex,
-                                verticesPerInstance, indicesPerInstance, instanceCount);
-        }
-
         GrPrimitiveType primitiveType() const { return fPrimitiveType; }
         int startVertex() const { return fStartVertex; }
         int startIndex() const { return fStartIndex; }
         int vertexCount() const { return fVertexCount; }
         int indexCount() const { return fIndexCount; }
-
-        /** These return 0 if initInstanced was not used to initialize the DrawInfo. */
         int verticesPerInstance() const { return fVerticesPerInstance; }
         int indicesPerInstance() const { return fIndicesPerInstance; }
         int instanceCount() const { return fInstanceCount; }
 
+        void setPrimitiveType(GrPrimitiveType type) { fPrimitiveType = type; }
+        void setStartVertex(int startVertex) { fStartVertex = startVertex; }
+        void setStartIndex(int startIndex) { fStartIndex = startIndex; }
+        void setVertexCount(int vertexCount) { fVertexCount = vertexCount; }
+        void setIndexCount(int indexCount) { fIndexCount = indexCount; }
+        void setVerticesPerInstance(int verticesPerI) { fVerticesPerInstance = verticesPerI; }
+        void setIndicesPerInstance(int indicesPerI) { fIndicesPerInstance = indicesPerI; }
+        void setInstanceCount(int instanceCount) { fInstanceCount = instanceCount; }
+
         bool isIndexed() const { return fIndexCount > 0; }
+#ifdef SK_DEBUG
+        bool isInstanced() const; // this version is longer because of asserts
+#else
         bool isInstanced() const { return fInstanceCount > 0; }
+#endif
 
-        /** Called after using this draw info to draw the next set of instances.
-            The vertex offset is advanced while the index buffer is reused at the same
-            position. instancesRemaining is number of instances that remain, maxInstances is
-            the most number of instances that can be used with the index buffer. If there
-            are no instances remaining, the DrawInfo is unmodified and false is returned.*/
-        bool nextInstances(int* instancesRemaining, int maxInstances) {
-            SkASSERT(this->isInstanced());
-            if (!*instancesRemaining) {
-                return false;
-            }
-            fStartVertex += fVertexCount;
-            fInstanceCount = SkTMin(*instancesRemaining, maxInstances);
-            fVertexCount = fInstanceCount * fVerticesPerInstance;
-            fIndexCount = fInstanceCount * fIndicesPerInstance;
-            *instancesRemaining -= fInstanceCount;
-            return true;
+        // adds or remove instances
+        void adjustInstanceCount(int instanceOffset);
+        // shifts the start vertex
+        void adjustStartVertex(int vertexOffset) {
+            fStartVertex += vertexOffset;
+            SkASSERT(fStartVertex >= 0);
+        }
+        // shifts the start index
+        void adjustStartIndex(int indexOffset) {
+            SkASSERT(this->isIndexed());
+            fStartIndex += indexOffset;
+            SkASSERT(fStartIndex >= 0);
+        }
+        void setDevBounds(const SkRect& bounds) {
+            fDevBoundsStorage = bounds;
+            fDevBounds = &fDevBoundsStorage;
         }
-
         const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
         const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
+        void setVertexBuffer(const GrVertexBuffer* vb) {
+            fVertexBuffer.reset(vb);
+        }
+        void setIndexBuffer(const GrIndexBuffer* ib) {
+            fIndexBuffer.reset(ib);
+        }
+        const SkRect* getDevBounds() const { return fDevBounds; }
 
     private:
         friend class GrDrawTarget;
@@ -366,6 +299,9 @@ public:
         int                     fVerticesPerInstance;
         int                     fIndicesPerInstance;
 
+        SkRect                  fDevBoundsStorage;
+        SkRect*                 fDevBounds;
+
         GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer;
         GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType>  fIndexBuffer;
     };
index a766af2..bf78a90 100644 (file)
@@ -8,6 +8,7 @@
 #include "GrInOrderDrawBuffer.h"
 
 #include "GrDefaultGeoProcFactory.h"
+#include "GrResourceProvider.h"
 #include "GrTemplates.h"
 
 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context,
@@ -131,49 +132,79 @@ public:
         init.fUsesLocalCoords = this->usesLocalCoords();
         gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
-        int instanceCount = fGeoData.count();
         size_t vertexStride = gp->getVertexStride();
+
         SkASSERT(hasExplicitLocalCoords ?
                  vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
                  vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
-        QuadHelper helper;
-        void* vertices = helper.init(batchTarget, vertexStride, instanceCount);
 
-        if (!vertices) {
+        int instanceCount = fGeoData.count();
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
+
+        int vertexCount = kVertsPerRect * instanceCount;
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              vertexCount,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
+
+        if (!vertices || !indexBuffer) {
+            SkDebugf("Could not allocate buffers\n");
             return;
         }
 
-
         for (int i = 0; i < instanceCount; i++) {
-            const Geometry& geom = fGeoData[i];
+            const Geometry& args = fGeoData[i];
 
-            intptr_t offset = GrTCast<intptr_t>(vertices) + kVerticesPerQuad * i * vertexStride;
+            intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
             SkPoint* positions = GrTCast<SkPoint*>(offset);
 
-            positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop,
-                                  geom.fRect.fRight, geom.fRect.fBottom, vertexStride);
-            geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerticesPerQuad);
+            positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
+                                  args.fRect.fRight, args.fRect.fBottom, vertexStride);
+            args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
 
-            if (geom.fHasLocalRect) {
+            if (args.fHasLocalRect) {
                 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
                 SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
-                coords->setRectFan(geom.fLocalRect.fLeft, geom.fLocalRect.fTop,
-                                   geom.fLocalRect.fRight, geom.fLocalRect.fBottom,
+                coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
+                                   args.fLocalRect.fRight, args.fLocalRect.fBottom,
                                    vertexStride);
-                if (geom.fHasLocalMatrix) {
-                    geom.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPerQuad);
+                if (args.fHasLocalMatrix) {
+                    args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
                 }
             }
 
             static const int kColorOffset = sizeof(SkPoint);
             GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
             for (int j = 0; j < 4; ++j) {
-                *vertColor = geom.fColor;
+                *vertColor = args.fColor;
                 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
             }
         }
 
-        helper.issueDraws(batchTarget);
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerRect);
+        drawInfo.setIndicesPerInstance(kIndicesPerRect);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = indexBuffer->maxQuads();
+        while (instanceCount) {
+            drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            instanceCount -= drawInfo.instanceCount();
+       }
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -232,6 +263,9 @@ private:
         bool fCoverageIgnored;
     };
 
+    const static int kVertsPerRect = 4;
+    const static int kIndicesPerRect = 6;
+
     BatchTracker fBatch;
     SkSTArray<1, Geometry, true> fGeoData;
 };
index a5dc991..38efefa 100644 (file)
@@ -744,22 +744,34 @@ public:
         gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
         int instanceCount = fGeoData.count();
+        int vertexCount = kVertsPerCircle * instanceCount;
         size_t vertexStride = gp->getVertexStride();
         SkASSERT(vertexStride == sizeof(CircleVertex));
-        QuadHelper helper;
-        CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget, vertexStride,
-                                                                          instanceCount));
-        if (!verts) {
+
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+
+        void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              vertexCount,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
+
+        if (!vertices || !indexBuffer) {
+            SkDebugf("Could not allocate buffers\n");
             return;
         }
 
+        CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices);
+
         for (int i = 0; i < instanceCount; i++) {
-            Geometry& geom = fGeoData[i];
+            Geometry& args = fGeoData[i];
 
-            SkScalar innerRadius = geom.fInnerRadius;
-            SkScalar outerRadius = geom.fOuterRadius;
+            SkScalar innerRadius = args.fInnerRadius;
+            SkScalar outerRadius = args.fOuterRadius;
 
-            const SkRect& bounds = geom.fDevBounds;
+            const SkRect& bounds = args.fDevBounds;
 
             // The inner radius in the vertex data must be specified in normalized space.
             innerRadius = innerRadius / outerRadius;
@@ -783,9 +795,31 @@ public:
             verts[3].fOuterRadius = outerRadius;
             verts[3].fInnerRadius = innerRadius;
 
-            verts += kVerticesPerQuad;
+            verts += kVertsPerCircle;
+        }
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerCircle);
+        drawInfo.setIndicesPerInstance(kIndicesPerCircle);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = indexBuffer->maxQuads();
+
+        while (instanceCount) {
+            drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            instanceCount -= drawInfo.instanceCount();
         }
-        helper.issueDraws(batchTarget);
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -833,6 +867,9 @@ private:
         bool fCoverageIgnored;
     };
 
+    static const int kVertsPerCircle = 4;
+    static const int kIndicesPerCircle = 6;
+
     BatchTracker fBatch;
     SkSTArray<1, Geometry, true> fGeoData;
 };
@@ -972,28 +1009,40 @@ public:
         gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
         int instanceCount = fGeoData.count();
-        QuadHelper helper;
+        int vertexCount = kVertsPerEllipse * instanceCount;
         size_t vertexStride = gp->getVertexStride();
         SkASSERT(vertexStride == sizeof(EllipseVertex));
-        EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
-            helper.init(batchTarget, vertexStride, instanceCount));
-        if (!verts) {
+
+        const GrVertexBuffer* vertexBuffer;
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
+        int firstVertex;
+
+        void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              vertexCount,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
+
+        if (!vertices || !indexBuffer) {
+            SkDebugf("Could not allocate buffers\n");
             return;
         }
 
+        EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices);
+
         for (int i = 0; i < instanceCount; i++) {
-            Geometry& geom = fGeoData[i];
+            Geometry& args = fGeoData[i];
 
-            SkScalar xRadius = geom.fXRadius;
-            SkScalar yRadius = geom.fYRadius;
+            SkScalar xRadius = args.fXRadius;
+            SkScalar yRadius = args.fYRadius;
 
             // Compute the reciprocals of the radii here to save time in the shader
             SkScalar xRadRecip = SkScalarInvert(xRadius);
             SkScalar yRadRecip = SkScalarInvert(yRadius);
-            SkScalar xInnerRadRecip = SkScalarInvert(geom.fInnerXRadius);
-            SkScalar yInnerRadRecip = SkScalarInvert(geom.fInnerYRadius);
+            SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius);
+            SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius);
 
-            const SkRect& bounds = geom.fDevBounds;
+            const SkRect& bounds = args.fDevBounds;
 
             // The inner radius in the vertex data must be specified in normalized space.
             verts[0].fPos = SkPoint::Make(bounds.fLeft,  bounds.fTop);
@@ -1016,9 +1065,31 @@ public:
             verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
             verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
 
-            verts += kVerticesPerQuad;
+            verts += kVertsPerEllipse;
+        }
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerEllipse);
+        drawInfo.setIndicesPerInstance(kIndicesPerEllipse);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = indexBuffer->maxQuads();
+
+        while (instanceCount) {
+            drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            instanceCount -= drawInfo.instanceCount();
         }
-        helper.issueDraws(batchTarget);
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1066,6 +1137,9 @@ private:
         bool fCoverageIgnored;
     };
 
+    static const int kVertsPerEllipse = 4;
+    static const int kIndicesPerEllipse = 6;
+
     BatchTracker fBatch;
     SkSTArray<1, Geometry, true> fGeoData;
 };
@@ -1243,30 +1317,41 @@ public:
         init.fUsesLocalCoords = this->usesLocalCoords();
         gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
+
         int instanceCount = fGeoData.count();
+        int vertexCount = kVertsPerEllipse * instanceCount;
         size_t vertexStride = gp->getVertexStride();
         SkASSERT(vertexStride == sizeof(DIEllipseVertex));
-        QuadHelper helper;
-        DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(
-            helper.init(batchTarget, vertexStride, instanceCount));
-        if (!verts) {
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+        void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              vertexCount,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
+
+        if (!vertices || !indexBuffer) {
+            SkDebugf("Could not allocate buffers\n");
             return;
         }
 
+        DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(vertices);
+
         for (int i = 0; i < instanceCount; i++) {
-            Geometry& geom = fGeoData[i];
+            Geometry& args = fGeoData[i];
 
-            SkScalar xRadius = geom.fXRadius;
-            SkScalar yRadius = geom.fYRadius;
+            SkScalar xRadius = args.fXRadius;
+            SkScalar yRadius = args.fYRadius;
 
-            const SkRect& bounds = geom.fBounds;
+            const SkRect& bounds = args.fBounds;
 
             // This adjusts the "radius" to include the half-pixel border
-            SkScalar offsetDx = SkScalarDiv(geom.fGeoDx, xRadius);
-            SkScalar offsetDy = SkScalarDiv(geom.fGeoDy, yRadius);
+            SkScalar offsetDx = SkScalarDiv(args.fGeoDx, xRadius);
+            SkScalar offsetDy = SkScalarDiv(args.fGeoDy, yRadius);
 
-            SkScalar innerRatioX = SkScalarDiv(xRadius, geom.fInnerXRadius);
-            SkScalar innerRatioY = SkScalarDiv(yRadius, geom.fInnerYRadius);
+            SkScalar innerRatioX = SkScalarDiv(xRadius, args.fInnerXRadius);
+            SkScalar innerRatioY = SkScalarDiv(yRadius, args.fInnerYRadius);
 
             verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop);
             verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy);
@@ -1284,9 +1369,31 @@ public:
             verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy);
             verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
 
-            verts += kVerticesPerQuad;
+            verts += kVertsPerEllipse;
+        }
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerEllipse);
+        drawInfo.setIndicesPerInstance(kIndicesPerEllipse);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = indexBuffer->maxQuads();
+
+        while (instanceCount) {
+            drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            instanceCount -= drawInfo.instanceCount();
         }
-        helper.issueDraws(batchTarget);
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1334,6 +1441,9 @@ private:
         bool fCoverageIgnored;
     };
 
+    static const int kVertsPerEllipse = 4;
+    static const int kIndicesPerEllipse = 6;
+
     BatchTracker fBatch;
     SkSTArray<1, Geometry, true> fGeoData;
 };
@@ -1612,22 +1722,27 @@ public:
         gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
         int instanceCount = fGeoData.count();
+        int vertexCount = kVertsPerRRect * instanceCount;
         size_t vertexStride = gp->getVertexStride();
         SkASSERT(vertexStride == sizeof(CircleVertex));
 
-        // drop out the middle quad if we're stroked
-        int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect;
+        const GrVertexBuffer* vertexBuffer;
         SkAutoTUnref<const GrIndexBuffer> indexBuffer(
             ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
+        int firstVertex;
+
+        void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              vertexCount,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
 
-        InstancedHelper helper;
-        CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget,
-            vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance, instanceCount));
-        if (!verts || !indexBuffer) {
+        if (!vertices || !indexBuffer) {
             SkDebugf("Could not allocate vertices\n");
             return;
         }
 
+        CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices);
+
         for (int i = 0; i < instanceCount; i++) {
             Geometry& args = fGeoData[i];
 
@@ -1672,7 +1787,32 @@ public:
             }
         }
 
-        helper.issueDraws(batchTarget);
+        // drop out the middle quad if we're stroked
+        int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
+                                        SK_ARRAY_COUNT(gRRectIndices);
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerRRect);
+        drawInfo.setIndicesPerInstance(indexCnt);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = kNumRRectsInIndexBuffer;
+
+        while (instanceCount) {
+            drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            instanceCount -= drawInfo.instanceCount();
+        }
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1793,23 +1933,27 @@ public:
         gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
 
         int instanceCount = fGeoData.count();
+        int vertexCount = kVertsPerRRect * instanceCount;
         size_t vertexStride = gp->getVertexStride();
         SkASSERT(vertexStride == sizeof(EllipseVertex));
 
-        // drop out the middle quad if we're stroked
-        int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect;
+        const GrVertexBuffer* vertexBuffer;
         SkAutoTUnref<const GrIndexBuffer> indexBuffer(
             ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
+        int firstVertex;
+
+        void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              vertexCount,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
 
-        InstancedHelper helper;
-        EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
-            helper.init(batchTarget, vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance,
-            instanceCount));
-        if (!verts || !indexBuffer) {
+        if (!vertices || !indexBuffer) {
             SkDebugf("Could not allocate vertices\n");
             return;
         }
 
+        EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices);
+
         for (int i = 0; i < instanceCount; i++) {
             Geometry& args = fGeoData[i];
 
@@ -1864,7 +2008,33 @@ public:
                 verts++;
             }
         }
-        helper.issueDraws(batchTarget);
+
+        // drop out the middle quad if we're stroked
+        int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
+                                        SK_ARRAY_COUNT(gRRectIndices);
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerRRect);
+        drawInfo.setIndicesPerInstance(indexCnt);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = kNumRRectsInIndexBuffer;
+
+        while (instanceCount) {
+            drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            instanceCount -= drawInfo.instanceCount();
+        }
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
index 5fd1bcd..7a9c5a7 100644 (file)
@@ -1459,7 +1459,12 @@ public:
         GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType
                                                   : kTriangles_GrPrimitiveType;
         GrDrawTarget::DrawInfo drawInfo;
-        drawInfo.init(primitiveType, vertexBuffer, firstVertex, actualCount);
+        drawInfo.setPrimitiveType(primitiveType);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setStartVertex(firstVertex);
+        drawInfo.setVertexCount(actualCount);
+        drawInfo.setStartIndex(0);
+        drawInfo.setIndexCount(0);
         batchTarget->draw(drawInfo);
 
         batchTarget->putBackVertices((size_t)(count - actualCount), stride);
index b941d8b..fa8b3a2 100644 (file)
@@ -19,6 +19,7 @@
 #include "GrDrawTargetCaps.h"
 #include "GrInvariantOutput.h"
 #include "GrProcessor.h"
+#include "GrResourceProvider.h"
 #include "GrStrokeInfo.h"
 #include "GrVertexBuffer.h"
 #include "SkGr.h"
@@ -535,29 +536,38 @@ public:
             draw.fHasEndRect = hasEndRect;
         }
 
-        QuadHelper helper;
-        void* vertices = helper.init(batchTarget, gp->getVertexStride(), instanceCount);
-        if (!vertices) {
+        SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+            batchTarget->resourceProvider()->refQuadIndexBuffer());
+
+        const GrVertexBuffer* vertexBuffer;
+        int firstVertex;
+        size_t vertexStride = gp->getVertexStride();
+        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                              totalRectCount * kVertsPerDash,
+                                                              &vertexBuffer,
+                                                              &firstVertex);
+        if (!vertices || !indexBuffer) {
+            SkDebugf("Could not allocate buffers\n");
             return;
         }
 
         int curVIdx = 0;
         int rectIndex = 0;
         for (int i = 0; i < instanceCount; i++) {
-            Geometry& geom = fGeoData[i];
+            Geometry& args = fGeoData[i];
 
             if (!draws[i].fLineDone) {
                 if (fullDash) {
-                    setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+                    setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
                                       draws[i].fStartOffset, draws[i].fDevBloatX,
                                       draws[i].fDevBloatY, draws[i].fLineLength,
-                                      draws[i].fHalfDevStroke, geom.fIntervals[0],
-                                      geom.fIntervals[1], draws[i].fStrokeWidth,
+                                      draws[i].fHalfDevStroke, args.fIntervals[0],
+                                      args.fIntervals[1], draws[i].fStrokeWidth,
                                       capType, gp->getVertexStride());
                 } else {
                     SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
                     SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
-                    setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
+                    setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
                 }
                 curVIdx += 4;
             }
@@ -565,16 +575,16 @@ public:
 
             if (draws[i].fHasStartRect) {
                 if (fullDash) {
-                    setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+                    setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
                                       draws[i].fStartOffset, draws[i].fDevBloatX,
-                                      draws[i].fDevBloatY, geom.fIntervals[0],
-                                      draws[i].fHalfDevStroke, geom.fIntervals[0],
-                                      geom.fIntervals[1], draws[i].fStrokeWidth, capType,
+                                      draws[i].fDevBloatY, args.fIntervals[0],
+                                      draws[i].fHalfDevStroke, args.fIntervals[0],
+                                      args.fIntervals[1], draws[i].fStrokeWidth, capType,
                                       gp->getVertexStride());
                 } else {
                     SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
                     SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
-                    setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
+                    setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
                 }
 
                 curVIdx += 4;
@@ -583,22 +593,43 @@ public:
 
             if (draws[i].fHasEndRect) {
                 if (fullDash) {
-                    setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+                    setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
                                       draws[i].fStartOffset, draws[i].fDevBloatX,
-                                      draws[i].fDevBloatY, geom.fIntervals[0],
-                                      draws[i].fHalfDevStroke, geom.fIntervals[0],
-                                      geom.fIntervals[1], draws[i].fStrokeWidth, capType,
+                                      draws[i].fDevBloatY, args.fIntervals[0],
+                                      draws[i].fHalfDevStroke, args.fIntervals[0],
+                                      args.fIntervals[1], draws[i].fStrokeWidth, capType,
                                       gp->getVertexStride());
                 } else {
                     SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
                     SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
-                    setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
+                    setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
                 }
                 curVIdx += 4;
             }
             rectIndex++;
         }
-        helper.issueDraws(batchTarget);
+
+        GrDrawTarget::DrawInfo drawInfo;
+        drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
+        drawInfo.setStartVertex(0);
+        drawInfo.setStartIndex(0);
+        drawInfo.setVerticesPerInstance(kVertsPerDash);
+        drawInfo.setIndicesPerInstance(kIndicesPerDash);
+        drawInfo.adjustStartVertex(firstVertex);
+        drawInfo.setVertexBuffer(vertexBuffer);
+        drawInfo.setIndexBuffer(indexBuffer);
+
+        int maxInstancesPerDraw = indexBuffer->maxQuads();
+        while (totalRectCount) {
+            drawInfo.setInstanceCount(SkTMin(totalRectCount, maxInstancesPerDraw));
+            drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
+            drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
+
+            batchTarget->draw(drawInfo);
+
+            drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
+            totalRectCount -= drawInfo.instanceCount();
+       }
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }