diff options
Diffstat (limited to 'src/gpu/GrInOrderDrawBuffer.cpp')
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 93 |
1 files changed, 82 insertions, 11 deletions
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index e298be6c8b..76e085dffa 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -17,6 +17,7 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context, , fCommands(context->getGpu(), vertexPool, indexPool) , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4) , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4) + , fPipelineBuffer(kPipelineBufferMinReserve) , fDrawID(0) { SkASSERT(vertexPool); @@ -300,7 +301,12 @@ void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder, void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch, const PipelineInfo& pipelineInfo) { - GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(this, batch, pipelineInfo); + State* state = this->setupPipelineAndShouldDraw(batch, pipelineInfo); + if (!state) { + return; + } + + GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(state, batch); this->recordTraceMarkersIfNecessary(cmd); } @@ -309,7 +315,7 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder const GrPath* path, const GrScissorState& scissorState, const GrStencilSettings& stencilSettings) { - GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(this, pipelineBuilder, + GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(pipelineBuilder, pathProc, path, scissorState, stencilSettings); this->recordTraceMarkersIfNecessary(cmd); @@ -319,9 +325,11 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc, const GrPath* path, const GrStencilSettings& stencilSettings, const PipelineInfo& pipelineInfo) { - GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(this, pathProc, - path, stencilSettings, - pipelineInfo); + State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo); + if (!state) { + return; + } + GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(state, pathProc, path, stencilSettings); this->recordTraceMarkersIfNecessary(cmd); } @@ -334,7 +342,11 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc, int count, const GrStencilSettings& stencilSettings, const PipelineInfo& pipelineInfo) { - GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(this, pathProc, pathRange, + State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo); + if (!state) { + return; + } + GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(state, this, pathProc, pathRange, indices, indexType, transformValues, transformType, count, stencilSettings, pipelineInfo); @@ -343,16 +355,14 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc, void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, GrRenderTarget* renderTarget) { - GrTargetCommands::Cmd* cmd = fCommands.recordClear(this, rect, color, - canIgnoreRect, renderTarget); + GrTargetCommands::Cmd* cmd = fCommands.recordClear(rect, color, canIgnoreRect, renderTarget); this->recordTraceMarkersIfNecessary(cmd); } void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* renderTarget) { - GrTargetCommands::Cmd* cmd = fCommands.recordClearStencilClip(this, rect, - insideClip, renderTarget); + GrTargetCommands::Cmd* cmd = fCommands.recordClearStencilClip(rect, insideClip, renderTarget); this->recordTraceMarkersIfNecessary(cmd); } @@ -361,7 +371,7 @@ void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { return; } - GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(this, renderTarget); + GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(renderTarget); this->recordTraceMarkersIfNecessary(cmd); } @@ -370,6 +380,15 @@ void GrInOrderDrawBuffer::onReset() { fPathIndexBuffer.rewind(); fPathTransformBuffer.rewind(); fGpuCmdMarkers.reset(); + + fPrevState.reset(NULL); + // Note, fPrevState points into fPipelineBuffer's allocation, so we have to reset first. + // Furthermore, we have to reset fCommands before fPipelineBuffer too. + if (fDrawID % kPipelineBufferHighWaterMark) { + fPipelineBuffer.rewind(); + } else { + fPipelineBuffer.reset(); + } } void GrInOrderDrawBuffer::onFlush() { @@ -400,3 +419,55 @@ void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* c } } } + +GrTargetCommands::State* +GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc, + const GrDrawTarget::PipelineInfo& pipelineInfo) { + State* state = this->allocState(); + this->setupPipeline(pipelineInfo, state->pipelineLocation()); + + if (state->getPipeline()->mustSkip()) { + this->unallocState(state); + return NULL; + } + + state->fPrimitiveProcessor->initBatchTracker(&state->fBatchTracker, + state->getPipeline()->getInitBatchTracker()); + + if (fPrevState && fPrevState->fPrimitiveProcessor.get() && + fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker, + *state->fPrimitiveProcessor, + state->fBatchTracker) && + fPrevState->getPipeline()->isEqual(*state->getPipeline())) { + this->unallocState(state); + } else { + fPrevState.reset(state); + } + + fCommands.recordXferBarrierIfNecessary(*fPrevState->getPipeline(), this); + return fPrevState; +} + +GrTargetCommands::State* +GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch, + const GrDrawTarget::PipelineInfo& pipelineInfo) { + State* state = this->allocState(); + this->setupPipeline(pipelineInfo, state->pipelineLocation()); + + if (state->getPipeline()->mustSkip()) { + this->unallocState(state); + return NULL; + } + + batch->initBatchTracker(state->getPipeline()->getInitBatchTracker()); + + if (fPrevState && !fPrevState->fPrimitiveProcessor.get() && + fPrevState->getPipeline()->isEqual(*state->getPipeline())) { + this->unallocState(state); + } else { + fPrevState.reset(state); + } + + fCommands.recordXferBarrierIfNecessary(*fPrevState->getPipeline(), this); + return fPrevState; +} |