diff options
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, 417 insertions, 650 deletions
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 3a548aa60a..f20306404a 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -824,19 +824,14 @@ 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.setStartVertex(vOffset + firstVertex); - info.setVertexCount(draw.fVertexCnt); - info.setIndexCount(draw.fIndexCnt); + info.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex, + firstIndex, draw.fVertexCnt, draw.fIndexCnt); batchTarget->draw(info); - vOffset += draw.fVertexCnt; + firstVertex += draw.fVertexCnt; + firstIndex += draw.fIndexCnt; } } } diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp index ca8c52fa34..312b731fd7 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,6 +169,13 @@ 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(); @@ -195,43 +202,25 @@ public: this->initDraw(batchTarget, dfProcessor, pipeline); - static const int kVertsPerQuad = 4; - static const int kIndicesPerQuad = 6; - - SkAutoTUnref<const GrIndexBuffer> indexBuffer( - batchTarget->resourceProvider()->refQuadIndexBuffer()); + FlushInfo flushInfo; // allocate vertices size_t vertexStride = dfProcessor->getVertexStride(); SkASSERT(vertexStride == 2 * sizeof(SkPoint)); - const GrVertexBuffer* vertexBuffer; - int vertexCount = kVertsPerQuad * instanceCount; - int firstVertex; + const GrVertexBuffer* vertexBuffer; void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, - vertexCount, + kVerticesPerQuad * instanceCount, &vertexBuffer, - &firstVertex); - - if (!vertices || !indexBuffer) { + &flushInfo.fVertexOffset); + flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); + flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadIndexBuffer()); + if (!vertices || !flushInfo.fIndexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } - // 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; + flushInfo.fInstancesToFlush = 0; for (int i = 0; i < instanceCount; i++) { Geometry& args = fGeoData[i]; @@ -265,9 +254,7 @@ public: if (!this->addPathToAtlas(batchTarget, dfProcessor, pipeline, - &drawInfo, - &instancesToFlush, - maxInstancesPerDraw, + &flushInfo, atlas, args.fPathData, args.fPath, @@ -284,21 +271,21 @@ public: // Now set vertices intptr_t offset = reinterpret_cast<intptr_t>(vertices); - offset += i * kVertsPerQuad * vertexStride; + offset += i * kVerticesPerQuad * vertexStride; SkPoint* positions = reinterpret_cast<SkPoint*>(offset); - this->drawPath(batchTarget, - atlas, - pipeline, - dfProcessor, - positions, - vertexStride, - this->viewMatrix(), - args.fPath, - args.fPathData); - instancesToFlush++; + this->writePathVertices(batchTarget, + atlas, + pipeline, + dfProcessor, + positions, + vertexStride, + this->viewMatrix(), + args.fPath, + args.fPathData); + flushInfo.fInstancesToFlush++; } - this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw); + this->flush(batchTarget, &flushInfo); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } @@ -325,9 +312,7 @@ private: bool addPathToAtlas(GrBatchTarget* batchTarget, const GrGeometryProcessor* dfProcessor, const GrPipeline* pipeline, - GrDrawTarget::DrawInfo* drawInfo, - int* instancesToFlush, - int maxInstancesPerDraw, + FlushInfo* flushInfo, GrBatchAtlas* atlas, PathData* pathData, const SkPath& path, @@ -429,9 +414,8 @@ private: bool success = atlas->addToAtlas(&id, batchTarget, width, height, dfStorage.get(), &atlasLocation); if (!success) { - this->flush(batchTarget, drawInfo, *instancesToFlush, maxInstancesPerDraw); + this->flush(batchTarget, flushInfo); this->initDraw(batchTarget, dfProcessor, pipeline); - *instancesToFlush = 0; SkDEBUGCODE(success =) atlas->addToAtlas(&id, batchTarget, width, height, dfStorage.get(), &atlasLocation); @@ -467,15 +451,15 @@ private: return true; } - 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) { + 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) { GrTexture* texture = atlas->getTexture(); SkScalar dx = pathData->fBounds.fLeft; @@ -522,20 +506,18 @@ private: dfProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init); } - 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(); - } + 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; } GrColor color() const { return fBatch.fColor; } diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index f046af871f..ba6dcecd43 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -888,23 +888,14 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel } { + int linesLeft = lineCount; GrDrawTarget::DrawInfo info; - 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); + info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer, + firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, &linesLeft, + kLineSegsNumInIdxBuffer); + do { batchTarget->draw(info); - - lines += n; - } + } while (info.nextInstances(&linesLeft, kLineSegsNumInIdxBuffer)); } } @@ -953,23 +944,15 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel quadGP->initBatchTracker(batchTarget->currentBatchTracker(), init); { - 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); + int quadsLeft = quadCount; + GrDrawTarget::DrawInfo info; + info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer, + firstVertex, kQuadNumVertices, kIdxsPerQuad, &quadsLeft, + kQuadsNumInIdxBuffer); + do { batchTarget->draw(info); - - quads += n; - } + } while (info.nextInstances(&quadsLeft, kQuadsNumInIdxBuffer)); + firstVertex += quadCount * kQuadNumVertices; } } @@ -985,23 +968,14 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel conicGP->initBatchTracker(batchTarget->currentBatchTracker(), init); { + int conicsLeft = conicCount; GrDrawTarget::DrawInfo info; - 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); + info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer, + firstVertex, kQuadNumVertices, kIdxsPerQuad, &conicsLeft, + kQuadsNumInIdxBuffer); + do { batchTarget->draw(info); - - conics += n; - } + } while (info.nextInstances(&conicsLeft, kQuadsNumInIdxBuffer)); } } } diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index d1c377aa53..267d970c62 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -112,22 +112,17 @@ 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; @@ -145,28 +140,7 @@ public: canTweakAlphaForCoverage); } - 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(); - } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } @@ -485,9 +459,6 @@ 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 @@ -505,28 +476,24 @@ public: vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); int innerVertexNum = 4; int outerVertexNum = this->miterStroke() ? 4 : 8; - int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; - + int verticesPerInstance = (outerVertexNum + innerVertexNum) * 2; + int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt; 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 * totalVertexNum * vertexStride, + i * verticesPerInstance * vertexStride, vertexStride, outerVertexNum, innerVertexNum, @@ -537,30 +504,7 @@ public: args.fMiterStroke, canTweakAlphaForCoverage); } - 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(); - } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index 33e4f7ed86..c8688b0adc 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -1474,6 +1474,13 @@ 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 @@ -1506,6 +1513,8 @@ public: localMatrix)); } + FlushInfo flushInfo; + flushInfo.fGlyphsToFlush = 0; size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == (fUseDistanceFields ? get_vertex_stride_df(fMaskFormat, fUseLCDText) : @@ -1515,35 +1524,21 @@ public: int glyphCount = this->numGlyphs(); int instanceCount = fInstanceCount; - SkAutoTUnref<const GrIndexBuffer> indexBuffer( - batchTarget->resourceProvider()->refQuadIndexBuffer()); - const GrVertexBuffer* vertexBuffer; - int firstVertex; + void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, glyphCount * kVerticesPerGlyph, &vertexBuffer, - &firstVertex); - if (!vertices || !indexBuffer) { + &flushInfo.fVertexOffset); + flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); + flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadIndexBuffer()); + if (!vertices || !flushInfo.fVertexBuffer) { 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; @@ -1551,7 +1546,6 @@ 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; @@ -1635,10 +1629,8 @@ public: if (!fFontCache->hasGlyph(glyph) && !strike->addGlyphToAtlas(batchTarget, glyph, scaler)) { - this->flush(batchTarget, &drawInfo, instancesToFlush, - maxInstancesPerDraw); + this->flush(batchTarget, &flushInfo); this->initDraw(batchTarget, gp, pipeline); - instancesToFlush = 0; brokenRun = glyphIdx > 0; SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(batchTarget, @@ -1674,7 +1666,7 @@ public: SkScalar transY = args.fTransY; this->regeneratePositions(vertex, vertexStride, transX, transY); } - instancesToFlush++; + flushInfo.fGlyphsToFlush++; } // We my have changed the color so update it here @@ -1687,7 +1679,7 @@ public: fFontCache->atlasGeneration(fMaskFormat); } } else { - instancesToFlush += glyphCount; + flushInfo.fGlyphsToFlush += glyphCount; // set use tokens for all of the glyphs in our subrun. This is only valid if we // have a valid atlas generation @@ -1706,7 +1698,7 @@ public: if (cache) { SkGlyphCache::AttachCache(cache); } - this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw); + this->flush(batchTarget, &flushInfo); } // The minimum number of Geometry we will try to allocate. @@ -1833,20 +1825,19 @@ private: gp->initBatchTracker(batchTarget->currentBatchTracker(), init); } - 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(); - } + 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; } GrColor color() const { return fBatch.fColor; } diff --git a/src/gpu/GrBatch.cpp b/src/gpu/GrBatch.cpp index ce30499ff8..1ef6c9797c 100644 --- a/src/gpu/GrBatch.cpp +++ b/src/gpu/GrBatch.cpp @@ -6,6 +6,8 @@ */ #include "GrBatch.h" +#include "GrBatchTarget.h" +#include "GrResourceProvider.h" #include "GrMemoryPool.h" #include "SkSpinlock.h" @@ -43,3 +45,43 @@ 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 7b5c888a70..38316cebad 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,6 +113,48 @@ 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 819774a076..a9c6ce0b5a 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -502,15 +502,7 @@ public: } GrDrawTarget::DrawInfo drawInfo; - 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); + drawInfo.init(primType, vertexBuffer, firstVertex, vertexCount); batchTarget->draw(drawInfo); } @@ -829,8 +821,8 @@ public: return; } - const GrIndexBuffer* indexBuffer; - int firstIndex; + const GrIndexBuffer* indexBuffer = NULL; + int firstIndex = 0; void* indices = NULL; if (this->hasIndices()) { @@ -870,17 +862,12 @@ public: } GrDrawTarget::DrawInfo drawInfo; - drawInfo.setPrimitiveType(this->primitiveType()); - drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setStartVertex(firstVertex); - drawInfo.setVertexCount(this->vertexCount()); if (this->hasIndices()) { - drawInfo.setIndexBuffer(indexBuffer); - drawInfo.setStartIndex(firstIndex); - drawInfo.setIndexCount(this->indexCount()); + drawInfo.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex, + firstIndex, this->vertexCount(), this->indexCount()); + } else { - drawInfo.setStartIndex(0); - drawInfo.setIndexCount(0); + drawInfo.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount()); } batchTarget->draw(drawInfo); } diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index 93d64abab2..a86d117f59 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -329,8 +329,8 @@ public: return; } - const GrIndexBuffer* indexBuffer; - int firstIndex; + const GrIndexBuffer* indexBuffer = NULL; + int firstIndex = 0; void* indices = NULL; if (isIndexed) { @@ -370,17 +370,11 @@ public: } GrDrawTarget::DrawInfo drawInfo; - drawInfo.setPrimitiveType(primitiveType); - drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setStartVertex(firstVertex); - drawInfo.setVertexCount(vertexOffset); if (isIndexed) { - drawInfo.setIndexBuffer(indexBuffer); - drawInfo.setStartIndex(firstIndex); - drawInfo.setIndexCount(indexOffset); + drawInfo.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex, + vertexOffset, indexOffset); } else { - drawInfo.setStartIndex(0); - drawInfo.setIndexCount(0); + drawInfo.init(primitiveType, vertexBuffer, firstVertex, vertexOffset); } batchTarget->draw(drawInfo); diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 850309797c..7ae2c99825 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -37,16 +37,8 @@ GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) { fVerticesPerInstance = di.fVerticesPerInstance; fIndicesPerInstance = di.fIndicesPerInstance; - if (di.fDevBounds) { - SkASSERT(di.fDevBounds == &di.fDevBoundsStorage); - fDevBoundsStorage = di.fDevBoundsStorage; - fDevBounds = &fDevBoundsStorage; - } else { - fDevBounds = NULL; - } - - this->setVertexBuffer(di.vertexBuffer()); - this->setIndexBuffer(di.indexBuffer()); + fVertexBuffer.reset(di.vertexBuffer()); + fIndexBuffer.reset(di.indexBuffer()); return *this; } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 0dca57a9db..c584181396 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -225,65 +225,132 @@ public: virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); } /** - * Used to communicate draws to GPUs / subclasses + * Used to communicate draw index vertex offsets and counts toto GPUs / subclasses */ class DrawInfo { public: - DrawInfo() { fDevBounds = NULL; } + 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; } - 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 - // 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; + /** 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(); } - 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; @@ -299,9 +366,6 @@ 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 bf78a90743..a766af2c7e 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -8,7 +8,6 @@ #include "GrInOrderDrawBuffer.h" #include "GrDefaultGeoProcFactory.h" -#include "GrResourceProvider.h" #include "GrTemplates.h" GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context, @@ -132,79 +131,49 @@ 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); - 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"); + if (!vertices) { return; } + for (int i = 0; i < instanceCount; i++) { - const Geometry& args = fGeoData[i]; + const Geometry& geom = fGeoData[i]; - intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride; + intptr_t offset = GrTCast<intptr_t>(vertices) + kVerticesPerQuad * i * vertexStride; SkPoint* positions = GrTCast<SkPoint*>(offset); - positions->setRectFan(args.fRect.fLeft, args.fRect.fTop, - args.fRect.fRight, args.fRect.fBottom, vertexStride); - args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect); + positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop, + geom.fRect.fRight, geom.fRect.fBottom, vertexStride); + geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerticesPerQuad); - if (args.fHasLocalRect) { + if (geom.fHasLocalRect) { static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset); - coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop, - args.fLocalRect.fRight, args.fLocalRect.fBottom, + coords->setRectFan(geom.fLocalRect.fLeft, geom.fLocalRect.fTop, + geom.fLocalRect.fRight, geom.fLocalRect.fBottom, vertexStride); - if (args.fHasLocalMatrix) { - args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect); + if (geom.fHasLocalMatrix) { + geom.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPerQuad); } } static const int kColorOffset = sizeof(SkPoint); GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset); for (int j = 0; j < 4; ++j) { - *vertColor = args.fColor; + *vertColor = geom.fColor; vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); } } - 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(); - } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } @@ -263,9 +232,6 @@ 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 38efefa857..a5dc991e70 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -744,34 +744,22 @@ public: gp->initBatchTracker(batchTarget->currentBatchTracker(), init); int instanceCount = fGeoData.count(); - int vertexCount = kVertsPerCircle * instanceCount; size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(CircleVertex)); - - 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"); + QuadHelper helper; + CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget, vertexStride, + instanceCount)); + if (!verts) { return; } - CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices); - for (int i = 0; i < instanceCount; i++) { - Geometry& args = fGeoData[i]; + Geometry& geom = fGeoData[i]; - SkScalar innerRadius = args.fInnerRadius; - SkScalar outerRadius = args.fOuterRadius; + SkScalar innerRadius = geom.fInnerRadius; + SkScalar outerRadius = geom.fOuterRadius; - const SkRect& bounds = args.fDevBounds; + const SkRect& bounds = geom.fDevBounds; // The inner radius in the vertex data must be specified in normalized space. innerRadius = innerRadius / outerRadius; @@ -795,31 +783,9 @@ public: verts[3].fOuterRadius = outerRadius; verts[3].fInnerRadius = innerRadius; - 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(); + verts += kVerticesPerQuad; } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } @@ -867,9 +833,6 @@ private: bool fCoverageIgnored; }; - static const int kVertsPerCircle = 4; - static const int kIndicesPerCircle = 6; - BatchTracker fBatch; SkSTArray<1, Geometry, true> fGeoData; }; @@ -1009,40 +972,28 @@ public: gp->initBatchTracker(batchTarget->currentBatchTracker(), init); int instanceCount = fGeoData.count(); - int vertexCount = kVertsPerEllipse * instanceCount; + QuadHelper helper; size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(EllipseVertex)); - - 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"); + EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( + helper.init(batchTarget, vertexStride, instanceCount)); + if (!verts) { return; } - EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices); - for (int i = 0; i < instanceCount; i++) { - Geometry& args = fGeoData[i]; + Geometry& geom = fGeoData[i]; - SkScalar xRadius = args.fXRadius; - SkScalar yRadius = args.fYRadius; + SkScalar xRadius = geom.fXRadius; + SkScalar yRadius = geom.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(args.fInnerXRadius); - SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius); + SkScalar xInnerRadRecip = SkScalarInvert(geom.fInnerXRadius); + SkScalar yInnerRadRecip = SkScalarInvert(geom.fInnerYRadius); - const SkRect& bounds = args.fDevBounds; + const SkRect& bounds = geom.fDevBounds; // The inner radius in the vertex data must be specified in normalized space. verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); @@ -1065,31 +1016,9 @@ public: verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); - 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(); + verts += kVerticesPerQuad; } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } @@ -1137,9 +1066,6 @@ private: bool fCoverageIgnored; }; - static const int kVertsPerEllipse = 4; - static const int kIndicesPerEllipse = 6; - BatchTracker fBatch; SkSTArray<1, Geometry, true> fGeoData; }; @@ -1317,41 +1243,30 @@ 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)); - const GrVertexBuffer* vertexBuffer; - int firstVertex; - void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, - vertexCount, - &vertexBuffer, - &firstVertex); - - if (!vertices || !indexBuffer) { - SkDebugf("Could not allocate buffers\n"); + QuadHelper helper; + DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>( + helper.init(batchTarget, vertexStride, instanceCount)); + if (!verts) { return; } - DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(vertices); - for (int i = 0; i < instanceCount; i++) { - Geometry& args = fGeoData[i]; + Geometry& geom = fGeoData[i]; - SkScalar xRadius = args.fXRadius; - SkScalar yRadius = args.fYRadius; + SkScalar xRadius = geom.fXRadius; + SkScalar yRadius = geom.fYRadius; - const SkRect& bounds = args.fBounds; + const SkRect& bounds = geom.fBounds; // This adjusts the "radius" to include the half-pixel border - SkScalar offsetDx = SkScalarDiv(args.fGeoDx, xRadius); - SkScalar offsetDy = SkScalarDiv(args.fGeoDy, yRadius); + SkScalar offsetDx = SkScalarDiv(geom.fGeoDx, xRadius); + SkScalar offsetDy = SkScalarDiv(geom.fGeoDy, yRadius); - SkScalar innerRatioX = SkScalarDiv(xRadius, args.fInnerXRadius); - SkScalar innerRatioY = SkScalarDiv(yRadius, args.fInnerYRadius); + SkScalar innerRatioX = SkScalarDiv(xRadius, geom.fInnerXRadius); + SkScalar innerRatioY = SkScalarDiv(yRadius, geom.fInnerYRadius); verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy); @@ -1369,31 +1284,9 @@ public: verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy); verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy); - 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(); + verts += kVerticesPerQuad; } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } @@ -1441,9 +1334,6 @@ private: bool fCoverageIgnored; }; - static const int kVertsPerEllipse = 4; - static const int kIndicesPerEllipse = 6; - BatchTracker fBatch; SkSTArray<1, Geometry, true> fGeoData; }; @@ -1722,27 +1612,22 @@ public: gp->initBatchTracker(batchTarget->currentBatchTracker(), init); int instanceCount = fGeoData.count(); - int vertexCount = kVertsPerRRect * instanceCount; size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(CircleVertex)); - const GrVertexBuffer* vertexBuffer; + // drop out the middle quad if we're stroked + int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect; SkAutoTUnref<const GrIndexBuffer> indexBuffer( ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider())); - int firstVertex; - - void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, - vertexCount, - &vertexBuffer, - &firstVertex); - if (!vertices || !indexBuffer) { + InstancedHelper helper; + CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget, + vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance, instanceCount)); + if (!verts || !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]; @@ -1787,32 +1672,7 @@ public: } } - // 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(); - } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } @@ -1933,27 +1793,23 @@ public: gp->initBatchTracker(batchTarget->currentBatchTracker(), init); int instanceCount = fGeoData.count(); - int vertexCount = kVertsPerRRect * instanceCount; size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(EllipseVertex)); - const GrVertexBuffer* vertexBuffer; + // drop out the middle quad if we're stroked + int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect; SkAutoTUnref<const GrIndexBuffer> indexBuffer( ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider())); - int firstVertex; - - void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, - vertexCount, - &vertexBuffer, - &firstVertex); - if (!vertices || !indexBuffer) { + InstancedHelper helper; + EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( + helper.init(batchTarget, vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance, + instanceCount)); + if (!verts || !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]; @@ -2008,33 +1864,7 @@ public: verts++; } } - - // 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(); - } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp index 7a9c5a7751..5fd1bcd479 100644 --- a/src/gpu/GrTessellatingPathRenderer.cpp +++ b/src/gpu/GrTessellatingPathRenderer.cpp @@ -1459,12 +1459,7 @@ public: GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType : kTriangles_GrPrimitiveType; GrDrawTarget::DrawInfo drawInfo; - drawInfo.setPrimitiveType(primitiveType); - drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setStartVertex(firstVertex); - drawInfo.setVertexCount(actualCount); - drawInfo.setStartIndex(0); - drawInfo.setIndexCount(0); + drawInfo.init(primitiveType, vertexBuffer, firstVertex, actualCount); 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 fa8b3a2dcf..b941d8be7d 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -19,7 +19,6 @@ #include "GrDrawTargetCaps.h" #include "GrInvariantOutput.h" #include "GrProcessor.h" -#include "GrResourceProvider.h" #include "GrStrokeInfo.h" #include "GrVertexBuffer.h" #include "SkGr.h" @@ -536,38 +535,29 @@ public: draw.fHasEndRect = hasEndRect; } - 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"); + QuadHelper helper; + void* vertices = helper.init(batchTarget, gp->getVertexStride(), instanceCount); + if (!vertices) { return; } int curVIdx = 0; int rectIndex = 0; for (int i = 0; i < instanceCount; i++) { - Geometry& args = fGeoData[i]; + Geometry& geom = fGeoData[i]; if (!draws[i].fLineDone) { if (fullDash) { - setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv, + setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv, draws[i].fStartOffset, draws[i].fDevBloatX, draws[i].fDevBloatY, draws[i].fLineLength, - draws[i].fHalfDevStroke, args.fIntervals[0], - args.fIntervals[1], draws[i].fStrokeWidth, + draws[i].fHalfDevStroke, geom.fIntervals[0], + geom.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, args.fSrcRotInv, verts); + setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts); } curVIdx += 4; } @@ -575,16 +565,16 @@ public: if (draws[i].fHasStartRect) { if (fullDash) { - setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv, + setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv, draws[i].fStartOffset, draws[i].fDevBloatX, - draws[i].fDevBloatY, args.fIntervals[0], - draws[i].fHalfDevStroke, args.fIntervals[0], - args.fIntervals[1], draws[i].fStrokeWidth, capType, + draws[i].fDevBloatY, geom.fIntervals[0], + draws[i].fHalfDevStroke, geom.fIntervals[0], + geom.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, args.fSrcRotInv, verts); + setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts); } curVIdx += 4; @@ -593,43 +583,22 @@ public: if (draws[i].fHasEndRect) { if (fullDash) { - setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv, + setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv, draws[i].fStartOffset, draws[i].fDevBloatX, - draws[i].fDevBloatY, args.fIntervals[0], - draws[i].fHalfDevStroke, args.fIntervals[0], - args.fIntervals[1], draws[i].fStrokeWidth, capType, + draws[i].fDevBloatY, geom.fIntervals[0], + draws[i].fHalfDevStroke, geom.fIntervals[0], + geom.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, args.fSrcRotInv, verts); + setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts); } curVIdx += 4; } rectIndex++; } - - 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(); - } + helper.issueDraws(batchTarget); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |