From 7539856c1b9cbb1886a6a498cc534b77fc83ddb2 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Mon, 17 Aug 2015 12:55:38 -0700 Subject: Make GrVertexBatch objects hold their own draws during GrDrawTarget flush NO_MERGE_BUILDS Review URL: https://codereview.chromium.org/1286043004 --- src/gpu/batches/GrAAFillRectBatch.cpp | 12 +++---- src/gpu/batches/GrAAStrokeRectBatch.cpp | 11 +++--- src/gpu/batches/GrAAStrokeRectBatch.h | 6 ++-- src/gpu/batches/GrBWFillRectBatch.cpp | 12 +++---- src/gpu/batches/GrDrawAtlasBatch.cpp | 9 ++--- src/gpu/batches/GrDrawAtlasBatch.h | 3 +- src/gpu/batches/GrDrawBatch.h | 30 +++++++++++++++-- src/gpu/batches/GrDrawVerticesBatch.cpp | 14 ++++---- src/gpu/batches/GrDrawVerticesBatch.h | 6 ++-- src/gpu/batches/GrStrokeRectBatch.cpp | 11 +++--- src/gpu/batches/GrStrokeRectBatch.h | 4 +-- src/gpu/batches/GrTestBatch.h | 15 ++++----- src/gpu/batches/GrVertexBatch.cpp | 59 ++++++++++++++++++++++++++------- src/gpu/batches/GrVertexBatch.h | 47 +++++++++++++++++--------- 14 files changed, 160 insertions(+), 79 deletions(-) (limited to 'src/gpu/batches') diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp index d8ef3d3152..098c6bdae4 100644 --- a/src/gpu/batches/GrAAFillRectBatch.cpp +++ b/src/gpu/batches/GrAAFillRectBatch.cpp @@ -7,6 +7,7 @@ #include "GrAAFillRectBatch.h" +#include "GrBatchFlushState.h" #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" #include "GrResourceKey.h" @@ -96,7 +97,7 @@ public: fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); } - void generateGeometry(GrBatchTarget* batchTarget) override { + void onPrepareDraws(Target* target) override { bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); SkAutoTUnref gp(CreateFillRectGP(canTweakAlphaForCoverage, @@ -109,17 +110,16 @@ public: return; } - batchTarget->initDraw(gp, this->pipeline()); + target->initDraw(gp, this->pipeline()); size_t vertexStride = gp->getVertexStride(); SkASSERT(Base::StrideCheck(vertexStride, canTweakAlphaForCoverage, this->usesLocalCoords())); int instanceCount = fGeoData.count(); - SkAutoTUnref indexBuffer(get_index_buffer( - batchTarget->resourceProvider())); + SkAutoTUnref indexBuffer(get_index_buffer(target->resourceProvider())); InstancedHelper helper; - void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, vertexStride, + void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer, kVertsPerAAFillRect, kIndicesPerAAFillRect, instanceCount); if (!vertices || !indexBuffer) { @@ -134,7 +134,7 @@ public: fGeoData[i], canTweakAlphaForCoverage); } - helper.issueDraw(batchTarget); + helper.recordDraw(target); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } diff --git a/src/gpu/batches/GrAAStrokeRectBatch.cpp b/src/gpu/batches/GrAAStrokeRectBatch.cpp index 91ff230f0d..bab5f02580 100644 --- a/src/gpu/batches/GrAAStrokeRectBatch.cpp +++ b/src/gpu/batches/GrAAStrokeRectBatch.cpp @@ -7,6 +7,7 @@ #include "GrAAStrokeRectBatch.h" +#include "GrBatchFlushState.h" #include "GrDefaultGeoProcFactory.h" #include "GrResourceKey.h" #include "GrResourceProvider.h" @@ -59,7 +60,7 @@ void GrAAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) { fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); } -void GrAAStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget) { +void GrAAStrokeRectBatch::onPrepareDraws(Target* target) { bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); SkAutoTUnref gp(create_stroke_rect_gp(canTweakAlphaForCoverage, @@ -71,7 +72,7 @@ void GrAAStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget) { return; } - batchTarget->initDraw(gp, this->pipeline()); + target->initDraw(gp, this->pipeline()); size_t vertexStride = gp->getVertexStride(); @@ -85,9 +86,9 @@ void GrAAStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget) { int instanceCount = fGeoData.count(); const SkAutoTUnref indexBuffer( - GetIndexBuffer(batchTarget->resourceProvider(), this->miterStroke())); + GetIndexBuffer(target->resourceProvider(), this->miterStroke())); InstancedHelper helper; - void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, vertexStride, + void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer, verticesPerInstance, indicesPerInstance, instanceCount); if (!vertices || !indexBuffer) { @@ -109,7 +110,7 @@ void GrAAStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget) { args.fMiterStroke, canTweakAlphaForCoverage); } - helper.issueDraw(batchTarget); + helper.recordDraw(target); } const GrIndexBuffer* GrAAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resourceProvider, diff --git a/src/gpu/batches/GrAAStrokeRectBatch.h b/src/gpu/batches/GrAAStrokeRectBatch.h index f9c4f3ed9d..2c6b0dbcf0 100644 --- a/src/gpu/batches/GrAAStrokeRectBatch.h +++ b/src/gpu/batches/GrAAStrokeRectBatch.h @@ -14,6 +14,8 @@ #include "SkMatrix.h" #include "SkRect.h" +class GrResourceProvider; + class GrAAStrokeRectBatch : public GrVertexBatch { public: // TODO support AA rotated stroke rects by copying around view matrices @@ -42,11 +44,11 @@ public: void initBatchTracker(const GrPipelineOptimizations&) override; - void generateGeometry(GrBatchTarget* batchTarget) override; - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } private: + void onPrepareDraws(Target*) override; + GrAAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix) { this->initClassID(); fBatch.fViewMatrix = viewMatrix; diff --git a/src/gpu/batches/GrBWFillRectBatch.cpp b/src/gpu/batches/GrBWFillRectBatch.cpp index c0c93c7614..f797e9ef4d 100644 --- a/src/gpu/batches/GrBWFillRectBatch.cpp +++ b/src/gpu/batches/GrBWFillRectBatch.cpp @@ -7,13 +7,13 @@ #include "GrBWFillRectBatch.h" -#include "GrBatchTarget.h" +#include "GrBatchFlushState.h" #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" #include "GrPrimitiveProcessor.h" #include "GrVertexBatch.h" -class GrBatchTarget; +class GrBatchFlushState; class SkMatrix; struct SkRect; @@ -58,14 +58,14 @@ public: fBatch.fCoverageIgnored = !init.readsCoverage(); } - void generateGeometry(GrBatchTarget* batchTarget) override { + void onPrepareDraws(Target* target) override { SkAutoTUnref gp(this->createRectGP()); if (!gp) { SkDebugf("Could not create GrGeometryProcessor\n"); return; } - batchTarget->initDraw(gp, this->pipeline()); + target->initDraw(gp, this->pipeline()); int instanceCount = fGeoData.count(); size_t vertexStride = gp->getVertexStride(); @@ -73,7 +73,7 @@ public: vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)); QuadHelper helper; - void* vertices = helper.init(batchTarget, vertexStride, instanceCount); + void* vertices = helper.init(target, vertexStride, instanceCount); if (!vertices) { return; @@ -110,7 +110,7 @@ public: } } - helper.issueDraw(batchTarget); + helper.recordDraw(target); } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } diff --git a/src/gpu/batches/GrDrawAtlasBatch.cpp b/src/gpu/batches/GrDrawAtlasBatch.cpp index 487580c39d..3596e16861 100644 --- a/src/gpu/batches/GrDrawAtlasBatch.cpp +++ b/src/gpu/batches/GrDrawAtlasBatch.cpp @@ -6,6 +6,7 @@ */ #include "GrDrawAtlasBatch.h" +#include "GrBatchFlushState.h" #include "GrBatchTest.h" #include "SkGr.h" #include "SkRandom.h" @@ -41,14 +42,14 @@ static const GrGeometryProcessor* set_vertex_attributes(bool hasColors, return GrDefaultGeoProcFactory::Create(gpColor, coverage, localCoords, viewMatrix); } -void GrDrawAtlasBatch::generateGeometry(GrBatchTarget* batchTarget) { +void GrDrawAtlasBatch::onPrepareDraws(Target* target) { // Setup geometry processor SkAutoTUnref gp(set_vertex_attributes(this->hasColors(), this->color(), this->viewMatrix(), this->coverageIgnored())); - batchTarget->initDraw(gp, this->pipeline()); + target->initDraw(gp, this->pipeline()); int instanceCount = fGeoData.count(); size_t vertexStride = gp->getVertexStride(); @@ -57,7 +58,7 @@ void GrDrawAtlasBatch::generateGeometry(GrBatchTarget* batchTarget) { QuadHelper helper; int numQuads = this->quadCount(); - void* verts = helper.init(batchTarget, vertexStride, numQuads); + void* verts = helper.init(target, vertexStride, numQuads); if (!verts) { SkDebugf("Could not allocate vertices\n"); return; @@ -71,7 +72,7 @@ void GrDrawAtlasBatch::generateGeometry(GrBatchTarget* batchTarget) { memcpy(vertPtr, args.fVerts.begin(), allocSize); vertPtr += allocSize; } - helper.issueDraw(batchTarget); + helper.recordDraw(target); } GrDrawAtlasBatch::GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& viewMatrix, diff --git a/src/gpu/batches/GrDrawAtlasBatch.h b/src/gpu/batches/GrDrawAtlasBatch.h index 6e353ef647..c7ee9f3e37 100644 --- a/src/gpu/batches/GrDrawAtlasBatch.h +++ b/src/gpu/batches/GrDrawAtlasBatch.h @@ -42,11 +42,12 @@ public: } void initBatchTracker(const GrPipelineOptimizations&) override; - void generateGeometry(GrBatchTarget* batchTarget) override; SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } private: + void onPrepareDraws(Target*) override; + GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& viewMatrix, int spriteCount, const SkRSXform* xforms, const SkRect* rects, const SkColor* colors); diff --git a/src/gpu/batches/GrDrawBatch.h b/src/gpu/batches/GrDrawBatch.h index 8ac758eca0..bbebe5b98c 100644 --- a/src/gpu/batches/GrDrawBatch.h +++ b/src/gpu/batches/GrDrawBatch.h @@ -13,11 +13,33 @@ struct GrInitInvariantOutput; +/** + * GrDrawBatches are flushed in two phases (preDraw, and draw). In preDraw uploads to GrGpuResources + * and draws are determined and scheduled. They are issued in the draw phase. GrBatchToken is used + * to sequence the uploads relative to each other and to draws. + **/ + +typedef uint64_t GrBatchToken; + +class GrBatchUploader : public SkRefCnt { +public: + class TextureUploader; + + GrBatchUploader(GrBatchToken lastUploadToken) : fLastUploadToken(lastUploadToken) {} + GrBatchToken lastUploadToken() const { return fLastUploadToken; } + virtual void upload(TextureUploader*)=0; + +private: + GrBatchToken fLastUploadToken; +}; + /** * Base class for GrBatches that draw. These batches have a GrPipeline installed by GrDrawTarget. */ class GrDrawBatch : public GrBatch { public: + class Target; + GrDrawBatch(); ~GrDrawBatch() override; @@ -41,8 +63,12 @@ private: */ virtual void initBatchTracker(const GrPipelineOptimizations&) = 0; - SkAlignedSTStorage<1, GrPipeline> fPipelineStorage; - bool fPipelineInstalled; +protected: + SkTArray, true> fInlineUploads; + +private: + SkAlignedSTStorage<1, GrPipeline> fPipelineStorage; + bool fPipelineInstalled; typedef GrBatch INHERITED; }; diff --git a/src/gpu/batches/GrDrawVerticesBatch.cpp b/src/gpu/batches/GrDrawVerticesBatch.cpp index ebfda36296..bca7d230bc 100644 --- a/src/gpu/batches/GrDrawVerticesBatch.cpp +++ b/src/gpu/batches/GrDrawVerticesBatch.cpp @@ -7,7 +7,7 @@ #include "GrDrawVerticesBatch.h" -#include "GrBatchTarget.h" +#include "GrBatchFlushState.h" #include "GrInvariantOutput.h" #include "GrDefaultGeoProcFactory.h" @@ -107,14 +107,14 @@ void GrDrawVerticesBatch::initBatchTracker(const GrPipelineOptimizations& opt) { fBatch.fCoverageIgnored = !opt.readsCoverage(); } -void GrDrawVerticesBatch::generateGeometry(GrBatchTarget* batchTarget) { +void GrDrawVerticesBatch::onPrepareDraws(Target* target) { int colorOffset = -1, texOffset = -1; SkAutoTUnref gp( set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset, &texOffset, this->color(), this->viewMatrix(), this->coverageIgnored())); - batchTarget->initDraw(gp, this->pipeline()); + target->initDraw(gp, this->pipeline()); size_t vertexStride = gp->getVertexStride(); @@ -126,8 +126,8 @@ void GrDrawVerticesBatch::generateGeometry(GrBatchTarget* batchTarget) { const GrVertexBuffer* vertexBuffer; int firstVertex; - void* verts = batchTarget->makeVertSpace(vertexStride, this->vertexCount(), - &vertexBuffer, &firstVertex); + void* verts = target->makeVertexSpace(vertexStride, this->vertexCount(), + &vertexBuffer, &firstVertex); if (!verts) { SkDebugf("Could not allocate vertices\n"); @@ -139,7 +139,7 @@ void GrDrawVerticesBatch::generateGeometry(GrBatchTarget* batchTarget) { uint16_t* indices = NULL; if (this->hasIndices()) { - indices = batchTarget->makeIndexSpace(this->indexCount(), &indexBuffer, &firstIndex); + indices = target->makeIndexSpace(this->indexCount(), &indexBuffer, &firstIndex); if (!indices) { SkDebugf("Could not allocate indices\n"); @@ -180,7 +180,7 @@ void GrDrawVerticesBatch::generateGeometry(GrBatchTarget* batchTarget) { } else { vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount()); } - batchTarget->draw(vertices); + target->draw(vertices); } bool GrDrawVerticesBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) { diff --git a/src/gpu/batches/GrDrawVerticesBatch.h b/src/gpu/batches/GrDrawVerticesBatch.h index 5e9628bc16..8864b16898 100644 --- a/src/gpu/batches/GrDrawVerticesBatch.h +++ b/src/gpu/batches/GrDrawVerticesBatch.h @@ -15,7 +15,7 @@ #include "SkRect.h" #include "SkTDArray.h" -class GrBatchTarget; +class GrBatchFlushState; struct GrInitInvariantOutput; class GrDrawVerticesBatch : public GrVertexBatch { @@ -47,11 +47,11 @@ public: void initBatchTracker(const GrPipelineOptimizations&) override; - void generateGeometry(GrBatchTarget* batchTarget) override; - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } private: + void onPrepareDraws(Target*) override; + GrDrawVerticesBatch(const Geometry& geometry, GrPrimitiveType primitiveType, const SkMatrix& viewMatrix, const SkPoint* positions, int vertexCount, diff --git a/src/gpu/batches/GrStrokeRectBatch.cpp b/src/gpu/batches/GrStrokeRectBatch.cpp index 649ba01ddd..766302bf5b 100644 --- a/src/gpu/batches/GrStrokeRectBatch.cpp +++ b/src/gpu/batches/GrStrokeRectBatch.cpp @@ -7,6 +7,7 @@ #include "GrStrokeRectBatch.h" #include "GrBatchTest.h" +#include "GrBatchFlushState.h" #include "SkRandom.h" GrStrokeRectBatch::GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) { @@ -65,8 +66,7 @@ static void init_stroke_rect_strip(SkPoint verts[10], const SkRect& rect, SkScal verts[9] = verts[1]; } - -void GrStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget) { +void GrStrokeRectBatch::onPrepareDraws(Target* target) { SkAutoTUnref gp; { using namespace GrDefaultGeoProcFactory; @@ -79,7 +79,7 @@ void GrStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget) { this->viewMatrix())); } - batchTarget->initDraw(gp, this->pipeline()); + target->initDraw(gp, this->pipeline()); size_t vertexStride = gp->getVertexStride(); @@ -95,8 +95,7 @@ void GrStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget) { const GrVertexBuffer* vertexBuffer; int firstVertex; - void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount, - &vertexBuffer, &firstVertex); + void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex); if (!verts) { SkDebugf("Could not allocate vertices\n"); @@ -123,7 +122,7 @@ void GrStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget) { GrVertices vertices; vertices.init(primType, vertexBuffer, firstVertex, vertexCount); - batchTarget->draw(vertices); + target->draw(vertices); } #ifdef GR_TEST_UTILS diff --git a/src/gpu/batches/GrStrokeRectBatch.h b/src/gpu/batches/GrStrokeRectBatch.h index 31b11d9c32..2e81cc237f 100644 --- a/src/gpu/batches/GrStrokeRectBatch.h +++ b/src/gpu/batches/GrStrokeRectBatch.h @@ -38,9 +38,9 @@ public: void initBatchTracker(const GrPipelineOptimizations&) override; - void generateGeometry(GrBatchTarget* batchTarget) override; - private: + void onPrepareDraws(Target*) override; + GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters); GrColor color() const { return fBatch.fColor; } diff --git a/src/gpu/batches/GrTestBatch.h b/src/gpu/batches/GrTestBatch.h index f72ea6143d..085b184a28 100644 --- a/src/gpu/batches/GrTestBatch.h +++ b/src/gpu/batches/GrTestBatch.h @@ -8,7 +8,7 @@ #ifndef GrTestBatch_DEFINED #define GrTestBatch_DEFINED -#include "GrBatchTarget.h" +#include "GrBatchFlushState.h" #include "GrGeometryProcessor.h" #include "GrVertexBuffer.h" @@ -49,12 +49,6 @@ public: fBatch.fCoverageIgnored = !opt.readsCoverage(); } - void generateGeometry(GrBatchTarget* batchTarget) override { - batchTarget->initDraw(fGeometryProcessor, this->pipeline()); - - this->onGenerateGeometry(batchTarget); - } - protected: GrTestBatch(const GrGeometryProcessor* gp, const SkRect& bounds) { fGeometryProcessor.reset(SkRef(gp)); @@ -65,6 +59,11 @@ protected: const GrGeometryProcessor* geometryProcessor() const { return fGeometryProcessor; } private: + void onPrepareDraws(Target* target) override { + target->initDraw(fGeometryProcessor, this->pipeline()); + this->generateGeometry(target); + } + virtual Geometry* geoData(int index) = 0; virtual const Geometry* geoData(int index) const = 0; @@ -72,7 +71,7 @@ private: return false; } - virtual void onGenerateGeometry(GrBatchTarget* batchTarget) = 0; + virtual void generateGeometry(Target*) = 0; struct BatchTracker { GrColor fColor; diff --git a/src/gpu/batches/GrVertexBatch.cpp b/src/gpu/batches/GrVertexBatch.cpp index e800422818..6081e26371 100644 --- a/src/gpu/batches/GrVertexBatch.cpp +++ b/src/gpu/batches/GrVertexBatch.cpp @@ -6,24 +6,28 @@ */ #include "GrVertexBatch.h" -#include "GrBatchTarget.h" +#include "GrBatchFlushState.h" #include "GrResourceProvider.h" -GrVertexBatch::GrVertexBatch() : fNumberOfDraws(0) {} +GrVertexBatch::GrVertexBatch() : fDrawArrays(1) {} -void* GrVertexBatch::InstancedHelper::init(GrBatchTarget* batchTarget, GrPrimitiveType primType, - size_t vertexStride, const GrIndexBuffer* indexBuffer, - int verticesPerInstance, int indicesPerInstance, - int instancesToDraw) { - SkASSERT(batchTarget); +void GrVertexBatch::prepareDraws(GrBatchFlushState* state) { + Target target(state, this); + this->onPrepareDraws(&target); +} + +void* GrVertexBatch::InstancedHelper::init(Target* target, GrPrimitiveType primType, + size_t vertexStride, const GrIndexBuffer* indexBuffer, + int verticesPerInstance, int indicesPerInstance, + int instancesToDraw) { + SkASSERT(target); if (!indexBuffer) { return NULL; } const GrVertexBuffer* vertexBuffer; int firstVertex; int vertexCount = verticesPerInstance * instancesToDraw; - void* vertices = batchTarget->makeVertSpace(vertexStride, vertexCount, - &vertexBuffer, &firstVertex); + void* vertices = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex); if (!vertices) { SkDebugf("Vertices could not be allocated for instanced rendering."); return NULL; @@ -38,14 +42,45 @@ void* GrVertexBatch::InstancedHelper::init(GrBatchTarget* batchTarget, GrPrimiti return vertices; } -void* GrVertexBatch::QuadHelper::init(GrBatchTarget* batchTarget, size_t vertexStride, +void GrVertexBatch::InstancedHelper::recordDraw(Target* target) { + SkASSERT(fVertices.instanceCount()); + target->draw(fVertices); +} + +void* GrVertexBatch::QuadHelper::init(Target* target, size_t vertexStride, int quadsToDraw) { SkAutoTUnref quadIndexBuffer( - batchTarget->resourceProvider()->refQuadIndexBuffer()); + target->resourceProvider()->refQuadIndexBuffer()); if (!quadIndexBuffer) { SkDebugf("Could not get quad index buffer."); return NULL; } - return this->INHERITED::init(batchTarget, kTriangles_GrPrimitiveType, vertexStride, + return this->INHERITED::init(target, kTriangles_GrPrimitiveType, vertexStride, quadIndexBuffer, kVerticesPerQuad, kIndicesPerQuad, quadsToDraw); } + +void GrVertexBatch::issueDraws(GrBatchFlushState* state) { + int uploadCnt = fInlineUploads.count(); + int currUpload = 0; + + // Iterate of all the drawArrays. Before issuing the draws in each array, perform any inline + // uploads. + for (SkTLList::Iter da(fDrawArrays); da.get(); da.next()) { + state->advanceLastFlushedToken(); + while (currUpload < uploadCnt && + fInlineUploads[currUpload]->lastUploadToken() <= state->lastFlushedToken()) { + fInlineUploads[currUpload++]->upload(state->uploader()); + } + const GrVertexBatch::DrawArray& drawArray = *da.get(); + GrProgramDesc desc; + const GrPipeline* pipeline = this->pipeline(); + const GrPrimitiveProcessor* primProc = drawArray.fPrimitiveProcessor.get(); + state->gpu()->buildProgramDesc(&desc, *primProc, *pipeline, fBatchTracker); + GrGpu::DrawArgs args(primProc, pipeline, &desc, &fBatchTracker); + + int drawCount = drawArray.fDraws.count(); + for (int i = 0; i < drawCount; i++) { + state->gpu()->draw(args, drawArray.fDraws[i]); + } + } +} diff --git a/src/gpu/batches/GrVertexBatch.h b/src/gpu/batches/GrVertexBatch.h index 882cfa0c8d..b868962411 100644 --- a/src/gpu/batches/GrVertexBatch.h +++ b/src/gpu/batches/GrVertexBatch.h @@ -9,20 +9,25 @@ #define GrVertexBatch_DEFINED #include "GrDrawBatch.h" -#include "GrBatchTarget.h" +#include "GrPrimitiveProcessor.h" +#include "GrPendingProgramElement.h" +#include "GrVertices.h" + +#include "SkTLList.h" + +class GrBatchFlushState; /** * Base class for vertex-based GrBatches. */ class GrVertexBatch : public GrDrawBatch { public: - GrVertexBatch(); + class Target; - virtual void generateGeometry(GrBatchTarget*) = 0; + GrVertexBatch(); - // TODO this goes away when batches are everywhere - void setNumberOfDraws(int numberOfDraws) { fNumberOfDraws = numberOfDraws; } - int numberOfDraws() const { return fNumberOfDraws; } + void prepareDraws(GrBatchFlushState* state); + void issueDraws(GrBatchFlushState* state); protected: /** Helper for rendering instances using an instanced index index buffer. This class creates the @@ -32,15 +37,12 @@ protected: InstancedHelper() {} /** Returns the allocated storage for the vertices. The caller should populate the before vertices before calling issueDraws(). */ - void* init(GrBatchTarget* batchTarget, GrPrimitiveType, size_t vertexStride, + void* init(Target*, GrPrimitiveType, size_t vertexStride, const GrIndexBuffer*, int verticesPerInstance, int indicesPerInstance, int instancesToDraw); /** Call after init() to issue draws to the batch target.*/ - void issueDraw(GrBatchTarget* batchTarget) { - SkASSERT(fVertices.instanceCount()); - batchTarget->draw(fVertices); - } + void recordDraw(Target* target); private: GrVertices fVertices; }; @@ -55,16 +57,31 @@ protected: /** 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::issueDraw; + void* init(Target* batchTarget, size_t vertexStride, int quadsToDraw); + using InstancedHelper::recordDraw; private: typedef InstancedHelper INHERITED; }; private: - int fNumberOfDraws; + virtual void onPrepareDraws(Target*) = 0; + + // A set of contiguous draws with no inline uploads between them that all use the same + // primitive processor. All the draws in a DrawArray share a primitive processor and use the + // the batch's GrPipeline. + struct DrawArray { + SkSTArray<1, GrVertices, true> fDraws; + GrPendingProgramElement fPrimitiveProcessor; + }; + + // Array of DrawArray. There may be inline uploads between each DrawArray and each DrawArray + // may use a different primitive processor. + SkTLList fDrawArrays; + + // What is this? + GrBatchTracker fBatchTracker; + typedef GrDrawBatch INHERITED; }; -- cgit v1.2.3