| Index: src/gpu/GrInOrderDrawBuffer.cpp
|
| diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
|
| index e298be6c8bffb575798ae14250512495626e0fe5..fbe48a9b52ee33caa70186fec93df8cbb14e8c7e 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(primProc);
|
| + 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;
|
| +}
|
|
|