diff options
author | bsalomon <bsalomon@google.com> | 2015-05-04 11:41:41 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-04 11:41:42 -0700 |
commit | 8415abe44cf205ac214b7793c076fd8c13272240 (patch) | |
tree | c527e81183de555849faf4f6bc83c9db0cad7a87 /src | |
parent | f28381c6866cad92af8ebe5b9d2db074613b1963 (diff) |
Revert of Start on simplifying generateGeometry() overrides (patchset #10 id:160001 of https://codereview.chromium.org/1122673002/)
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
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 13 | ||||
-rwxr-xr-x | src/gpu/GrAADistanceFieldPathRenderer.cpp | 122 | ||||
-rw-r--r-- | src/gpu/GrAAHairLinePathRenderer.cpp | 66 | ||||
-rw-r--r-- | src/gpu/GrAARectRenderer.cpp | 92 | ||||
-rw-r--r-- | src/gpu/GrAtlasTextContext.cpp | 71 | ||||
-rw-r--r-- | src/gpu/GrBatch.cpp | 42 | ||||
-rw-r--r-- | src/gpu/GrBatch.h | 44 | ||||
-rwxr-xr-x | src/gpu/GrContext.cpp | 27 | ||||
-rw-r--r-- | src/gpu/GrDefaultPathRenderer.cpp | 16 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 12 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 146 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 68 | ||||
-rw-r--r-- | src/gpu/GrOvalRenderer.cpp | 272 | ||||
-rw-r--r-- | src/gpu/GrTessellatingPathRenderer.cpp | 7 | ||||
-rw-r--r-- | src/gpu/effects/GrDashingEffect.cpp | 69 |
15 files changed, 650 insertions, 417 deletions
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index f20306404a..3a548aa60a 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -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; } } } diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp index 312b731fd7..ca8c52fa34 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp @@ -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; } diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index ba6dcecd43..f046af871f 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -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; + } } } } diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 267d970c62..d1c377aa53 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -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; } diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index c8688b0adc..33e4f7ed86 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -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; } diff --git a/src/gpu/GrBatch.cpp b/src/gpu/GrBatch.cpp index 1ef6c9797c..ce30499ff8 100644 --- a/src/gpu/GrBatch.cpp +++ b/src/gpu/GrBatch.cpp @@ -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); -} diff --git a/src/gpu/GrBatch.h b/src/gpu/GrBatch.h index 38316cebad..7b5c888a70 100644 --- a/src/gpu/GrBatch.h +++ b/src/gpu/GrBatch.h @@ -11,12 +11,12 @@ #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: diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index a9c6ce0b5a..819774a076 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -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); } diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index a86d117f59..93d64abab2 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -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); diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 7ae2c99825..850309797c 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -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; } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index c584181396..0dca57a9db 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -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 draws to 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; }; diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index a766af2c7e..bf78a90743 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -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; }; diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index a5dc991e70..38efefa857 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -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; } diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp index 5fd1bcd479..7a9c5a7751 100644 --- a/src/gpu/GrTessellatingPathRenderer.cpp +++ b/src/gpu/GrTessellatingPathRenderer.cpp @@ -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); diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index b941d8be7d..fa8b3a2dcf 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -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; } |