Move DrawInfo out from GrDrawTarget and rename to GrVertices.

Review URL: https://codereview.chromium.org/1124733004
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index f203064..7e98994 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -823,7 +823,7 @@
             SkSTArray<kPreallocDrawCnt, Draw, true> draws;
             create_vertices(segments, fanPt, &draws, verts, idxs);
 
-            GrDrawTarget::DrawInfo info;
+            GrVertices info;
 
             for (int i = 0; i < draws.count(); ++i) {
                 const Draw& draw = draws[i];
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp
index 312b731..7c0468d 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp
@@ -507,15 +507,15 @@
     }
 
     void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
-        GrDrawTarget::DrawInfo drawInfo;
+        GrVertices vertices;
         int instancesToFlush = flushInfo->fInstancesToFlush;
         int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads();
-        drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
+        vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
             flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad,
             kIndicesPerQuad, &instancesToFlush, maxInstancesPerDraw);
         do {
-            batchTarget->draw(drawInfo);
-        } while (drawInfo.nextInstances(&instancesToFlush, maxInstancesPerDraw));
+            batchTarget->draw(vertices);
+        } while (vertices.nextInstances(&instancesToFlush, maxInstancesPerDraw));
         flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;
         flushInfo->fInstancesToFlush = 0;
     }
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 2749e4d..f9b0c5a 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -889,7 +889,7 @@
 
         {
             int linesLeft = lineCount;
-            GrDrawTarget::DrawInfo info;
+            GrVertices info;
             info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer,
                                firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, &linesLeft,
                                kLineSegsNumInIdxBuffer);
@@ -945,7 +945,7 @@
 
             {
                 int quadsLeft = quadCount;
-                GrDrawTarget::DrawInfo info;
+                GrVertices info;
                 info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
                                    firstVertex, kQuadNumVertices, kIdxsPerQuad, &quadsLeft,
                                    kQuadsNumInIdxBuffer);
@@ -969,7 +969,7 @@
 
             {
                 int conicsLeft = conicCount;
-                GrDrawTarget::DrawInfo info;
+                GrVertices info;
                 info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
                                   firstVertex, kQuadNumVertices, kIdxsPerQuad, &conicsLeft,
                                   kQuadsNumInIdxBuffer);
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index c8688b0..e5fd8e6 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -1826,16 +1826,16 @@
     }
 
     void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
-        GrDrawTarget::DrawInfo drawInfo;
+        GrVertices vertices;
         int glyphsToFlush = flushInfo->fGlyphsToFlush;
         int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
-        drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
+        vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
                                flushInfo->fIndexBuffer, flushInfo->fVertexOffset,
                                kVerticesPerGlyph, kIndicesPerGlyph, &glyphsToFlush,
                                maxGlyphsPerDraw);
         do {
-            batchTarget->draw(drawInfo);
-        } while (drawInfo.nextInstances(&glyphsToFlush, maxGlyphsPerDraw));
+            batchTarget->draw(vertices);
+        } while (vertices.nextInstances(&glyphsToFlush, maxGlyphsPerDraw));
         flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
         flushInfo->fGlyphsToFlush = 0;
     }
diff --git a/src/gpu/GrBatch.cpp b/src/gpu/GrBatch.cpp
index 38ab142..7d1c0ae 100644
--- a/src/gpu/GrBatch.cpp
+++ b/src/gpu/GrBatch.cpp
@@ -69,7 +69,7 @@
     size_t ibSize = indexBuffer->gpuMemorySize();
     fMaxInstancesPerDraw = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerInstance));
 
-    fDrawInfo.initInstanced(primType, vertexBuffer, indexBuffer,
+    fVertices.initInstanced(primType, vertexBuffer, indexBuffer,
         firstVertex, verticesPerInstance, indicesPerInstance, &fInstancesRemaining,
         fMaxInstancesPerDraw);
     SkASSERT(fMaxInstancesPerDraw > 0);
diff --git a/src/gpu/GrBatch.h b/src/gpu/GrBatch.h
index d03fa67..dc01db4 100644
--- a/src/gpu/GrBatch.h
+++ b/src/gpu/GrBatch.h
@@ -9,10 +9,9 @@
 #define GrBatch_DEFINED
 
 #include <new>
-// TODO remove this header when we move entirely to batch
-#include "GrDrawTarget.h"
 #include "GrBatchTarget.h"
 #include "GrGeometryProcessor.h"
+#include "GrVertices.h"
 #include "SkRefCnt.h"
 #include "SkThread.h"
 #include "SkTypes.h"
@@ -126,15 +125,15 @@
 
         /** Call after init() to issue draws to the batch target.*/
         void issueDraws(GrBatchTarget* batchTarget) {
-            SkASSERT(fDrawInfo.instanceCount());
+            SkASSERT(fVertices.instanceCount());
             do {
-                batchTarget->draw(fDrawInfo);
-            } while (fDrawInfo.nextInstances(&fInstancesRemaining, fMaxInstancesPerDraw));
+                batchTarget->draw(fVertices);
+            } while (fVertices.nextInstances(&fInstancesRemaining, fMaxInstancesPerDraw));
         }
     private:
-        int                     fInstancesRemaining;
-        int                     fMaxInstancesPerDraw;
-        GrDrawTarget::DrawInfo  fDrawInfo;
+        int         fInstancesRemaining;
+        int         fMaxInstancesPerDraw;
+        GrVertices  fVertices;
     };
 
     static const int kVerticesPerQuad = 4;
diff --git a/src/gpu/GrBatchTarget.cpp b/src/gpu/GrBatchTarget.cpp
index 4c24a80..b5293d7 100644
--- a/src/gpu/GrBatchTarget.cpp
+++ b/src/gpu/GrBatchTarget.cpp
@@ -46,10 +46,10 @@
 
         GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker);
 
-        int drawCount = bf->fDraws.count();
-        const SkSTArray<1, DrawInfo, true>& draws = bf->fDraws;
+        int drawCount = bf->fVertexDraws.count();
+        const SkSTArray<1, GrVertices, true>& vertexDraws = bf->fVertexDraws;
         for (int i = 0; i < drawCount; i++) {
-            fGpu->draw(args, draws[i]);
+            fGpu->draw(args, vertexDraws[i]);
         }
     }
 }
diff --git a/src/gpu/GrBatchTarget.h b/src/gpu/GrBatchTarget.h
index 97cd2ed..91726e5 100644
--- a/src/gpu/GrBatchTarget.h
+++ b/src/gpu/GrBatchTarget.h
@@ -12,8 +12,8 @@
 #include "GrBufferAllocPool.h"
 #include "GrPendingProgramElement.h"
 #include "GrPipeline.h"
-#include "GrGpu.h"
 #include "GrTRecorder.h"
+#include "GrVertices.h"
 
 /*
  * GrBatch instances use this object to allocate space for their geometry and to issue the draws
@@ -30,7 +30,6 @@
                   GrVertexBufferAllocPool* vpool,
                   GrIndexBufferAllocPool* ipool);
 
-    typedef GrDrawTarget::DrawInfo DrawInfo;
     void initDraw(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline) {
         GrNEW_APPEND_TO_RECORDER(fFlushBuffer, BufferedFlush, (primProc, pipeline));
         fNumberOfDraws++;
@@ -83,8 +82,8 @@
         }
     }
 
-    void draw(const GrDrawTarget::DrawInfo& draw) {
-        fFlushBuffer.back().fDraws.push_back(draw);
+    void draw(const GrVertices& vertices) {
+        fFlushBuffer.back().fVertexDraws.push_back(vertices);
     }
 
     bool isIssued(BatchToken token) const { return fLastFlushedToken >= token; }
@@ -145,7 +144,7 @@
         ProgramPrimitiveProcessor fPrimitiveProcessor;
         const GrPipeline* fPipeline;
         GrBatchTracker fBatchTracker;
-        SkSTArray<1, DrawInfo, true> fDraws;
+        SkSTArray<1, GrVertices, true> fVertexDraws;
     };
 
     enum {
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 37886f0..8bdfa7f 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -36,6 +36,7 @@
 #include "GrTexturePriv.h"
 #include "GrTraceMarker.h"
 #include "GrTracing.h"
+#include "GrVertices.h"
 #include "SkDashPathPriv.h"
 #include "SkConfig8888.h"
 #include "SkGr.h"
@@ -473,17 +474,17 @@
         const GrVertexBuffer* vertexBuffer;
         int firstVertex;
 
-        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
-                                                              vertexCount,
-                                                              &vertexBuffer,
-                                                              &firstVertex);
+        void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                           vertexCount,
+                                                           &vertexBuffer,
+                                                           &firstVertex);
 
-        if (!vertices) {
+        if (!verts) {
             SkDebugf("Could not allocate vertices\n");
             return;
         }
 
-        SkPoint* vertex = reinterpret_cast<SkPoint*>(vertices);
+        SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
 
         GrPrimitiveType primType;
 
@@ -501,9 +502,9 @@
             vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
         }
 
-        GrDrawTarget::DrawInfo drawInfo;
-        drawInfo.init(primType, vertexBuffer, firstVertex, vertexCount);
-        batchTarget->draw(drawInfo);
+        GrVertices vertices;
+        vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
+        batchTarget->draw(vertices);
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -811,12 +812,12 @@
         const GrVertexBuffer* vertexBuffer;
         int firstVertex;
 
-        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
-                                                              this->vertexCount(),
-                                                              &vertexBuffer,
+        void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                           this->vertexCount(),
+                                                           &vertexBuffer,
                                                               &firstVertex);
 
-        if (!vertices) {
+        if (!verts) {
             SkDebugf("Could not allocate vertices\n");
             return;
         }
@@ -849,27 +850,27 @@
             }
 
             for (int j = 0; j < args.fPositions.count(); ++j) {
-                *((SkPoint*)vertices) = args.fPositions[j];
+                *((SkPoint*)verts) = args.fPositions[j];
                 if (this->hasColors()) {
-                    *(GrColor*)((intptr_t)vertices + colorOffset) = args.fColors[j];
+                    *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j];
                 }
                 if (this->hasLocalCoords()) {
-                    *(SkPoint*)((intptr_t)vertices + texOffset) = args.fLocalCoords[j];
+                    *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j];
                 }
-                vertices = (void*)((intptr_t)vertices + vertexStride);
+                verts = (void*)((intptr_t)verts + vertexStride);
                 vertexOffset++;
             }
         }
 
-        GrDrawTarget::DrawInfo drawInfo;
+        GrVertices vertices;
         if (this->hasIndices()) {
-            drawInfo.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
+            vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
                                  firstIndex, this->vertexCount(), this->indexCount());
 
         } else {
-            drawInfo.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount());
+            vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount());
         }
-        batchTarget->draw(drawInfo);
+        batchTarget->draw(vertices);
     }
 
     SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index a86d117..e1ba1c8 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -14,7 +14,7 @@
 #include "GrDefaultGeoProcFactory.h"
 #include "GrPathUtils.h"
 #include "GrPipelineBuilder.h"
-#include "GrVertexBuffer.h"
+#include "GrVertices.h"
 #include "SkGeometry.h"
 #include "SkString.h"
 #include "SkStrokeRec.h"
@@ -319,12 +319,12 @@
         const GrVertexBuffer* vertexBuffer;
         int firstVertex;
 
-        void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
-                                                              maxVertices,
-                                                              &vertexBuffer,
-                                                              &firstVertex);
+        void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
+                                                           maxVertices,
+                                                           &vertexBuffer,
+                                                           &firstVertex);
 
-        if (!vertices) {
+        if (!verts) {
             SkDebugf("Could not allocate vertices\n");
             return;
         }
@@ -352,7 +352,7 @@
 
             int vertexCnt = 0;
             int indexCnt = 0;
-            if (!this->createGeom(vertices,
+            if (!this->createGeom(verts,
                                   vertexOffset,
                                   indices,
                                   indexOffset,
@@ -369,14 +369,14 @@
             SkASSERT(vertexOffset <= maxVertices && indexOffset <= maxIndices);
         }
 
-        GrDrawTarget::DrawInfo drawInfo;
+        GrVertices vertices;
         if (isIndexed) {
-            drawInfo.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
+            vertices.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
                                  vertexOffset, indexOffset);
         } else {
-            drawInfo.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
+            vertices.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
         }
-        batchTarget->draw(drawInfo);
+        batchTarget->draw(vertices);
 
         // put back reserves
         batchTarget->putBackIndices((size_t)(maxIndices - indexOffset));
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 7ae2c99..a45aca8 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -26,25 +26,6 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
-    fPrimitiveType  = di.fPrimitiveType;
-    fStartVertex    = di.fStartVertex;
-    fStartIndex     = di.fStartIndex;
-    fVertexCount    = di.fVertexCount;
-    fIndexCount     = di.fIndexCount;
-
-    fInstanceCount          = di.fInstanceCount;
-    fVerticesPerInstance    = di.fVerticesPerInstance;
-    fIndicesPerInstance     = di.fIndicesPerInstance;
-
-    fVertexBuffer.reset(di.vertexBuffer());
-    fIndexBuffer.reset(di.indexBuffer());
-
-    return *this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 #define DEBUG_INVAL_BUFFER 0xdeadcafe
 #define DEBUG_INVAL_START_IDX -1
 
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 458e6e1..5871abf 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -224,152 +224,6 @@
 
     virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
 
-    /**
-     * Used to communicate draw index vertex offsets and counts toto GPUs / subclasses
-     */
-    class DrawInfo {
-    public:
-        DrawInfo() {}
-        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; }
-
-        bool isIndexed() const { return fIndexCount > 0; }
-        bool isInstanced() const { return fInstanceCount > 0; }
-
-        /** 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;
-        }
-
-        const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
-        const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
-
-    private:
-        friend class GrDrawTarget;
-
-        GrPrimitiveType         fPrimitiveType;
-
-        int                     fStartVertex;
-        int                     fStartIndex;
-        int                     fVertexCount;
-        int                     fIndexCount;
-
-        int                     fInstanceCount;
-        int                     fVerticesPerInstance;
-        int                     fIndicesPerInstance;
-
-        GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer;
-        GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType>  fIndexBuffer;
-    };
-
     bool programUnitTest(int maxStages);
 
 protected:
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index cdf5226..d98b3ce 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -18,6 +18,24 @@
 #include "GrRenderTargetPriv.h"
 #include "GrStencilAttachment.h"
 #include "GrVertexBuffer.h"
+#include "GrVertices.h"
+
+GrVertices& GrVertices::operator =(const GrVertices& di) {
+    fPrimitiveType  = di.fPrimitiveType;
+    fStartVertex    = di.fStartVertex;
+    fStartIndex     = di.fStartIndex;
+    fVertexCount    = di.fVertexCount;
+    fIndexCount     = di.fIndexCount;
+
+    fInstanceCount          = di.fInstanceCount;
+    fVerticesPerInstance    = di.fVerticesPerInstance;
+    fIndicesPerInstance     = di.fIndicesPerInstance;
+
+    fVertexBuffer.reset(di.vertexBuffer());
+    fIndexBuffer.reset(di.indexBuffer());
+
+    return *this;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -269,9 +287,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrGpu::draw(const DrawArgs& args, const GrDrawTarget::DrawInfo& info) {
+void GrGpu::draw(const DrawArgs& args, const GrVertices& vertices) {
     this->handleDirtyContext();
-    this->onDraw(args, info);
+    this->onDraw(args, vertices);
 }
 
 void GrGpu::stencilPath(const GrPath* path, const StencilPathState& state) {
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 3903af6..d89d371 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -23,6 +23,7 @@
 class GrPrimitiveProcessor;
 class GrStencilAttachment;
 class GrVertexBufferAllocPool;
+class GrVertices;
 
 class GrGpu : public SkRefCnt {
 public:
@@ -280,7 +281,6 @@
     virtual void xferBarrier(GrXferBarrierType) = 0;
 
     struct DrawArgs {
-        typedef GrDrawTarget::DrawInfo DrawInfo;
         DrawArgs(const GrPrimitiveProcessor* primProc,
                  const GrPipeline* pipeline,
                  const GrProgramDesc* desc,
@@ -297,7 +297,7 @@
         const GrBatchTracker* fBatchTracker;
     };
 
-    void draw(const DrawArgs&, const GrDrawTarget::DrawInfo&);
+    void draw(const DrawArgs&, const GrVertices&);
 
     /** None of these params are optional, pointers used just to avoid making copies. */
     struct StencilPathState {
@@ -435,7 +435,7 @@
     virtual void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) = 0;
 
     // overridden by backend-specific derived class to perform the draw call.
-    virtual void onDraw(const DrawArgs&, const GrDrawTarget::DrawInfo&) = 0;
+    virtual void onDraw(const DrawArgs&, const GrVertices&) = 0;
     virtual void onStencilPath(const GrPath*, const StencilPathState&) = 0;
 
     virtual void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) = 0;
diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp
index 5fd1bcd..262cce3 100644
--- a/src/gpu/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/GrTessellatingPathRenderer.cpp
@@ -11,7 +11,7 @@
 #include "GrBatchTarget.h"
 #include "GrDefaultGeoProcFactory.h"
 #include "GrPathUtils.h"
-#include "GrVertexBuffer.h"
+#include "GrVertices.h"
 #include "SkChunkAlloc.h"
 #include "SkGeometry.h"
 
@@ -1439,28 +1439,28 @@
         size_t stride = gp->getVertexStride();
         const GrVertexBuffer* vertexBuffer;
         int firstVertex;
-        void* vertices = batchTarget->vertexPool()->makeSpace(stride,
-                                                              count,
-                                                              &vertexBuffer,
-                                                              &firstVertex);
+        void* verts = batchTarget->vertexPool()->makeSpace(stride,
+                                                           count,
+                                                           &vertexBuffer,
+                                                           &firstVertex);
 
-        if (!vertices) {
+        if (!verts) {
             SkDebugf("Could not allocate vertices\n");
             return;
         }
 
         LOG("emitting %d verts\n", count);
-        void* end = polys_to_triangles(polys, fillType, vertices);
+        void* end = polys_to_triangles(polys, fillType, verts);
         int actualCount = static_cast<int>(
-            (static_cast<char*>(end) - static_cast<char*>(vertices)) / stride);
+            (static_cast<char*>(end) - static_cast<char*>(verts)) / stride);
         LOG("actual count: %d\n", actualCount);
         SkASSERT(actualCount <= count);
 
         GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType
                                                   : kTriangles_GrPrimitiveType;
-        GrDrawTarget::DrawInfo drawInfo;
-        drawInfo.init(primitiveType, vertexBuffer, firstVertex, actualCount);
-        batchTarget->draw(drawInfo);
+        GrVertices vertices;
+        vertices.init(primitiveType, vertexBuffer, firstVertex, actualCount);
+        batchTarget->draw(vertices);
 
         batchTarget->putBackVertices((size_t)(count - actualCount), stride);
         return;
diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp
index 23739f2..dfec048 100644
--- a/src/gpu/GrTest.cpp
+++ b/src/gpu/GrTest.cpp
@@ -200,7 +200,7 @@
 
     void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override {}
 
-    void onDraw(const DrawArgs&, const GrDrawTarget::DrawInfo&) override {}
+    void onDraw(const DrawArgs&, const GrVertices&) override {}
 
     void onStencilPath(const GrPath* path, const StencilPathState& state) override {}
 
diff --git a/src/gpu/GrVertices.h b/src/gpu/GrVertices.h
new file mode 100644
index 0000000..cce5627
--- /dev/null
+++ b/src/gpu/GrVertices.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrVertices_DEFINED
+#define GrVertices_DEFINED
+
+#include "GrIndexBuffer.h"
+#include "GrVertexBuffer.h"
+
+/**
+ * Used to communicate index and vertex buffers, counts, and offsets for a draw from GrBatch to
+ * GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this
+ * and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there
+ * already (stride, attribute mappings).
+ */
+class GrVertices {
+public:
+    GrVertices() {}
+    GrVertices(const GrVertices& di) { (*this) = di; }
+    GrVertices& operator =(const GrVertices& 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 GrVertices. */
+    int verticesPerInstance() const { return fVerticesPerInstance; }
+    int indicesPerInstance() const { return fIndicesPerInstance; }
+    int instanceCount() const { return fInstanceCount; }
+
+    bool isIndexed() const { return fIndexCount > 0; }
+    bool isInstanced() const { return fInstanceCount > 0; }
+
+    /** 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 GrVertices 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;
+    }
+
+    const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
+    const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
+
+private:
+    GrPrimitiveType         fPrimitiveType;
+
+    int                     fStartVertex;
+    int                     fStartIndex;
+    int                     fVertexCount;
+    int                     fIndexCount;
+
+    int                     fInstanceCount;
+    int                     fVerticesPerInstance;
+    int                     fIndicesPerInstance;
+
+    GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer;
+    GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType>  fIndexBuffer;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 4421b3c..540072f 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -16,6 +16,7 @@
 #include "GrTemplates.h"
 #include "GrTexturePriv.h"
 #include "GrTypes.h"
+#include "GrVertices.h"
 #include "SkStrokeRec.h"
 #include "SkTemplates.h"
 
@@ -1408,7 +1409,7 @@
 }
 
 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
-                            const GrDrawTarget::DrawInfo& info,
+                            const GrVertices& info,
                             size_t* indexOffsetInBytes) {
     GrGLVertexBuffer* vbuf;
     vbuf = (GrGLVertexBuffer*) info.vertexBuffer();
@@ -1851,29 +1852,31 @@
     #endif
 #endif
 
-void GrGLGpu::onDraw(const DrawArgs& args, const GrDrawTarget::DrawInfo& info) {
+void GrGLGpu::onDraw(const DrawArgs& args, const GrVertices& vertices) {
     if (!this->flushGLState(args)) {
         return;
     }
 
     size_t indexOffsetInBytes = 0;
-    this->setupGeometry(*args.fPrimitiveProcessor, info, &indexOffsetInBytes);
+    this->setupGeometry(*args.fPrimitiveProcessor, vertices, &indexOffsetInBytes);
 
-    SkASSERT((size_t)info.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GLMode));
+    SkASSERT((size_t)vertices.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GLMode));
 
-    if (info.isIndexed()) {
+    if (vertices.isIndexed()) {
         GrGLvoid* indices =
-            reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) * info.startIndex());
+            reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) *
+                                        vertices.startIndex());
         // info.startVertex() was accounted for by setupGeometry.
-        GL_CALL(DrawElements(gPrimitiveType2GLMode[info.primitiveType()],
-                             info.indexCount(),
+        GL_CALL(DrawElements(gPrimitiveType2GLMode[vertices.primitiveType()],
+                             vertices.indexCount(),
                              GR_GL_UNSIGNED_SHORT,
                              indices));
     } else {
         // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account for
         // startVertex in the DrawElements case. So we always rely on setupGeometry to have
         // accounted for startVertex.
-        GL_CALL(DrawArrays(gPrimitiveType2GLMode[info.primitiveType()], 0, info.vertexCount()));
+        GL_CALL(DrawArrays(gPrimitiveType2GLMode[vertices.primitiveType()], 0,
+                           vertices.vertexCount()));
     }
 #if SWAP_PER_DRAW
     glFlush();
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 5357142..5c8eea5 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -24,6 +24,7 @@
 #include "SkTypes.h"
 
 class GrPipeline;
+class GrVertices;
 
 #ifdef SK_DEVELOPER
 #define PROGRAM_CACHE_STATS
@@ -148,7 +149,7 @@
 
     void onResolveRenderTarget(GrRenderTarget* target) override;
 
-    void onDraw(const DrawArgs&, const GrDrawTarget::DrawInfo&) override;
+    void onDraw(const DrawArgs&, const GrVertices&) override;
     void onStencilPath(const GrPath*, const StencilPathState&) override;
     void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) override;
     void onDrawPaths(const DrawArgs&,
@@ -173,10 +174,10 @@
     bool flushGLState(const DrawArgs&);
 
     // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
-    // an into the index buffer. It does not account for drawInfo.startIndex() but rather the start
+    // an into the index buffer. It does not account for vertices.startIndex() but rather the start
     // index is relative to the returned offset.
     void setupGeometry(const GrPrimitiveProcessor&,
-                       const GrDrawTarget::DrawInfo& info,
+                       const GrVertices& vertices,
                        size_t* indexOffsetInBytes);
 
     // Subclasses should call this to flush the blend state.