Chromium Code Reviews| Index: src/gpu/GrInOrderDrawBuffer.cpp |
| diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp |
| index 5b1f00891e991dc4cccafa02d93a03672ebd6c80..f5bc236536ed1f8a66b831399ed0edba9f87bdd3 100644 |
| --- a/src/gpu/GrInOrderDrawBuffer.cpp |
| +++ b/src/gpu/GrInOrderDrawBuffer.cpp |
| @@ -20,7 +20,8 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, |
| : INHERITED(gpu, vertexPool, indexPool) |
| , fCmdBuffer(kCmdBufferInitialSizeInBytes) |
| , fPrevState(NULL) |
| - , fDrawID(0) { |
| + , fDrawID(0) |
| + , fBatchBuffer(gpu, vertexPool, indexPool) { |
| SkASSERT(vertexPool); |
| SkASSERT(indexPool); |
| @@ -208,6 +209,7 @@ int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds, const DrawIn |
| Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); |
| if (!draw->fInfo.isInstanced() || |
| + draw->fInfo.primitiveType() != info.primitiveType() || |
| draw->fInfo.verticesPerInstance() != info.verticesPerInstance() || |
| draw->fInfo.indicesPerInstance() != info.indicesPerInstance() || |
| draw->fInfo.vertexBuffer() != info.vertexBuffer() || |
| @@ -264,6 +266,30 @@ void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds, |
| this->recordTraceMarkersIfNecessary(); |
| } |
| +void GrInOrderDrawBuffer::onBatchDraw(GrBatch* batch, |
| + const GrDrawState& ds, |
| + GrPrimitiveType type, |
| + const GrScissorState& scissorState, |
| + const GrDeviceCoordTexture* dstCopy) { |
| + if (!this->recordStateAndShouldDraw(batch, ds, scissorState, dstCopy)) { |
| + return; |
| + } |
| + |
| + // Check if there is a Batch Draw we can batch with |
| + if (kBatchDraw != strip_trace_bit(fCmdBuffer.back().fType)) { |
| + GrNEW_APPEND_TO_RECORDER(fCmdBuffer, BatchDraw, (batch)); |
| + return; |
| + } |
| + |
| + BatchDraw* draw = static_cast<BatchDraw*>(&fCmdBuffer.back()); |
| + if (draw->fBatch->combineIfPossible(batch)) { |
| + return; |
| + } else { |
| + GrNEW_APPEND_TO_RECORDER(fCmdBuffer, BatchDraw, (batch)); |
| + } |
| + this->recordTraceMarkersIfNecessary(); |
| +} |
| + |
| void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, |
| const GrPathProcessor* pathProc, |
| const GrPath* path, |
| @@ -408,7 +434,6 @@ void GrInOrderDrawBuffer::onFlush() { |
| return; |
| } |
| - |
| CmdBuffer::Iter iter(fCmdBuffer); |
| int currCmdMarker = 0; |
| @@ -417,6 +442,10 @@ void GrInOrderDrawBuffer::onFlush() { |
| // stream. |
| SetState* currentState = NULL; |
| + // TODO to prevent flushing the batch buffer too much, we only flush when wasBatch && !isBatch |
| + // In the long term we can delete this and just flush once at the end of all geometry generation |
| + bool wasBatch = false; |
| + |
| while (iter.next()) { |
| GrGpuTraceMarker newMarker("", -1); |
| SkString traceString; |
| @@ -430,10 +459,22 @@ void GrInOrderDrawBuffer::onFlush() { |
| if (kSetState_Cmd == strip_trace_bit(iter->fType)) { |
| SetState* ss = reinterpret_cast<SetState*>(iter.get()); |
| - this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor, ss->fState, |
| - ss->fState.descInfo(), ss->fBatchTracker); |
| - currentState = ss; |
| - |
| + // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will |
| + // only have GrBatch and we can delete this |
| + if (ss->fPrimitiveProcessor) { |
| + // TODO see note above, this gets deleted once everyone uses batch drawing |
| + if (wasBatch) { |
| + wasBatch = false; |
| + fBatchBuffer.flush(); |
| + } |
| + |
| + this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor, ss->fState, |
| + ss->fState.descInfo(), |
| + ss->fBatchTracker); |
| + } else { |
| + wasBatch = true; |
| + } |
| + currentState = ss; |
|
bsalomon
2015/01/21 21:39:29
misaligned
joshualitt
2015/01/22 15:47:46
I'm sorry, maybe I'm just blind but was is misalig
bsalomon
2015/01/22 16:00:59
currentState = ss is tabbed in when it seems like
|
| } else { |
| iter->execute(this, currentState); |
| } |
| @@ -443,6 +484,11 @@ void GrInOrderDrawBuffer::onFlush() { |
| } |
| } |
| + // TODO see note above, one last catch |
| + if (wasBatch) { |
| + fBatchBuffer.flush(); |
| + } |
| + |
| SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); |
| ++fDrawID; |
| } |
| @@ -482,6 +528,12 @@ void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const Set |
| fCount, fStencilSettings); |
| } |
| +void GrInOrderDrawBuffer::BatchDraw::execute(GrInOrderDrawBuffer* buf, const SetState* state) { |
| + SkASSERT(state); |
| + fBatch->generateGeometry(buf->getBatchBuffer(), &state->fState); |
| + |
|
bsalomon
2015/01/21 21:39:29
extra \n
|
| +} |
| + |
| void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {} |
| void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const SetState*) { |
| @@ -529,7 +581,7 @@ bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrDrawState& ds, |
| ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker, |
| ss->fState.getInitBatchTracker()); |
| - if (fPrevState && |
| + if (fPrevState && fPrevState->fPrimitiveProcessor.get() && |
| fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker, |
| *ss->fPrimitiveProcessor, |
| ss->fBatchTracker) && |
| @@ -542,6 +594,33 @@ bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrDrawState& ds, |
| return true; |
| } |
| +bool GrInOrderDrawBuffer::recordStateAndShouldDraw(GrBatch* batch, |
| + const GrDrawState& ds, |
| + const GrScissorState& scissor, |
| + const GrDeviceCoordTexture* dstCopy) { |
| + // TODO this gets much simpler when we have batches everywhere. |
| + // If the previous command is also a set state, then we check to see if it has a Batch. If so, |
| + // and we can make the two batches equal, and we can combine the states, then we make them equal |
| + SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, |
| + (batch, ds, *this->getGpu()->caps(), scissor, |
| + dstCopy)); |
| + if (ss->fState.mustSkip()) { |
| + fCmdBuffer.pop_back(); |
| + return false; |
| + } |
| + |
| + batch->initBatchTracker(ss->fState.getInitBatchTracker()); |
| + |
| + if (fPrevState && !fPrevState->fPrimitiveProcessor.get() && |
| + fPrevState->fState.isEqual(ss->fState)) { |
| + fCmdBuffer.pop_back(); |
| + } else { |
| + fPrevState = ss; |
| + this->recordTraceMarkersIfNecessary(); |
| + } |
| + return true; |
| +} |
| + |
| void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { |
| SkASSERT(!fCmdBuffer.empty()); |
| SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); |