Index: src/gpu/batches/GrVertexBatch.cpp |
diff --git a/src/gpu/batches/GrVertexBatch.cpp b/src/gpu/batches/GrVertexBatch.cpp |
index fc7a1e4fae227279592a62e69a02f5bd16e9c969..8a5dd6289bb30ad7427ea4b8ff5671ed3cfbb981 100644 |
--- a/src/gpu/batches/GrVertexBatch.cpp |
+++ b/src/gpu/batches/GrVertexBatch.cpp |
@@ -9,7 +9,10 @@ |
#include "GrBatchFlushState.h" |
#include "GrResourceProvider.h" |
-GrVertexBatch::GrVertexBatch(uint32_t classID) : INHERITED(classID) {} |
+GrVertexBatch::GrVertexBatch(uint32_t classID) |
+ : INHERITED(classID) |
+ , fBaseDrawToken(GrBatchDrawToken::AlreadyFlushedToken()) { |
+} |
void GrVertexBatch::onPrepare(GrBatchFlushState* state) { |
Target target(state, this); |
@@ -42,9 +45,9 @@ void* GrVertexBatch::InstancedHelper::init(Target* target, GrPrimitiveType primT |
return vertices; |
} |
-void GrVertexBatch::InstancedHelper::recordDraw(Target* target) { |
+void GrVertexBatch::InstancedHelper::recordDraw(Target* target, const GrGeometryProcessor* gp) { |
SkASSERT(fMesh.instanceCount()); |
- target->draw(fMesh); |
+ target->draw(gp, fMesh); |
} |
void* GrVertexBatch::QuadHelper::init(Target* target, size_t vertexStride, |
@@ -60,22 +63,50 @@ void* GrVertexBatch::QuadHelper::init(Target* target, size_t vertexStride, |
} |
void GrVertexBatch::onDraw(GrBatchFlushState* state) { |
- int uploadCnt = fInlineUploads.count(); |
- int currUpload = 0; |
+ int currUploadIdx = 0; |
+ int currMeshIdx = 0; |
+ |
+ SkASSERT(fQueuedDraws.empty() || fBaseDrawToken == state->nextTokenToFlush()); |
- // Iterate of all the drawArrays. Before issuing the draws in each array, perform any inline |
- // uploads. |
- for (DrawArrayList::Iter da(fDrawArrays); da.get(); da.next()) { |
- state->advanceLastFlushedToken(); |
- while (currUpload < uploadCnt && |
- fInlineUploads[currUpload]->lastUploadToken() <= state->lastFlushedToken()) { |
- fInlineUploads[currUpload++]->upload(state->uploader()); |
+ for (int currDrawIdx = 0; currDrawIdx < fQueuedDraws.count(); ++currDrawIdx) { |
+ GrBatchDrawToken drawToken = state->nextTokenToFlush(); |
+ while (currUploadIdx < fInlineUploads.count() && |
+ fInlineUploads[currUploadIdx].fUploadBeforeToken == drawToken) { |
+ state->doUpload(fInlineUploads[currUploadIdx++].fUpload); |
} |
- const GrVertexBatch::DrawArray& drawArray = *da.get(); |
+ const QueuedDraw &draw = fQueuedDraws[currDrawIdx]; |
+ state->gpu()->draw(*this->pipeline(), *draw.fGeometryProcessor.get(), |
+ fMeshes.begin() + currMeshIdx, draw.fMeshCnt); |
+ currMeshIdx += draw.fMeshCnt; |
+ state->flushToken(); |
+ } |
+ SkASSERT(currUploadIdx == fInlineUploads.count()); |
+ SkASSERT(currMeshIdx == fMeshes.count()); |
+ fQueuedDraws.reset(); |
+ fInlineUploads.reset(); |
+} |
- state->gpu()->draw(*this->pipeline(), |
- *drawArray.fPrimitiveProcessor.get(), |
- drawArray.fDraws.begin(), |
- drawArray.fDraws.count()); |
+////////////////////////////////////////////////////////////////////////////// |
+ |
+void GrVertexBatch::Target::draw(const GrGeometryProcessor* gp, const GrMesh& mesh) { |
+ GrVertexBatch* batch = this->vertexBatch(); |
+ batch->fMeshes.push_back(mesh); |
+ if (!batch->fQueuedDraws.empty()) { |
+ // If the last draw shares a geometry processor and there are no intervening uploads, |
+ // add this mesh to it. |
+ GrVertexBatch::QueuedDraw& lastDraw = this->vertexBatch()->fQueuedDraws.back(); |
+ if (lastDraw.fGeometryProcessor == gp && |
+ (batch->fInlineUploads.empty() || |
+ batch->fInlineUploads.back().fUploadBeforeToken != this->nextDrawToken())) { |
+ ++lastDraw.fMeshCnt; |
+ return; |
+ } |
+ } |
+ GrVertexBatch::QueuedDraw& draw = this->vertexBatch()->fQueuedDraws.push_back(); |
+ GrBatchDrawToken token = this->state()->issueDrawToken(); |
+ draw.fGeometryProcessor.reset(gp); |
+ draw.fMeshCnt = 1; |
+ if (batch->fQueuedDraws.count() == 1) { |
+ batch->fBaseDrawToken = token; |
} |
} |