aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrInOrderDrawBuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrInOrderDrawBuffer.cpp')
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp93
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;
+}