| Index: src/gpu/GrTargetCommands.cpp
|
| diff --git a/src/gpu/GrTargetCommands.cpp b/src/gpu/GrTargetCommands.cpp
|
| index a6d31481413b0d29005013b1a975ad3f13a69459..d68a24292e54e9150382e8e30a561f29096b5fa5 100644
|
| --- a/src/gpu/GrTargetCommands.cpp
|
| +++ b/src/gpu/GrTargetCommands.cpp
|
| @@ -26,27 +26,19 @@ static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
|
| return isWinding;
|
| }
|
|
|
| -GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(
|
| - GrInOrderDrawBuffer* iodb,
|
| - GrBatch* batch,
|
| - const GrDrawTarget::PipelineInfo& pipelineInfo) {
|
| - if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) {
|
| - return NULL;
|
| - }
|
| -
|
| +GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(State* state, GrBatch* batch) {
|
| // Check if there is a Batch Draw we can batch with
|
| - if (Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) {
|
| + if (!fCmdBuffer.empty() && Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) {
|
| DrawBatch* previous = static_cast<DrawBatch*>(&fCmdBuffer.back());
|
| - if (previous->fBatch->combineIfPossible(batch)) {
|
| + if (previous->fState == state && previous->fBatch->combineIfPossible(batch)) {
|
| return NULL;
|
| }
|
| }
|
|
|
| - return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
|
| + return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (state, batch, &fBatchTarget));
|
| }
|
|
|
| GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath(
|
| - GrInOrderDrawBuffer* iodb,
|
| const GrPipelineBuilder& pipelineBuilder,
|
| const GrPathProcessor* pathProc,
|
| const GrPath* path,
|
| @@ -63,21 +55,17 @@ GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath(
|
| }
|
|
|
| GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath(
|
| - GrInOrderDrawBuffer* iodb,
|
| + State* state,
|
| const GrPathProcessor* pathProc,
|
| const GrPath* path,
|
| - const GrStencilSettings& stencilSettings,
|
| - const GrDrawTarget::PipelineInfo& pipelineInfo) {
|
| - // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
|
| - if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
|
| - return NULL;
|
| - }
|
| - DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
|
| + const GrStencilSettings& stencilSettings) {
|
| + DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (state, path));
|
| dp->fStencilSettings = stencilSettings;
|
| return dp;
|
| }
|
|
|
| GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
|
| + State* state,
|
| GrInOrderDrawBuffer* iodb,
|
| const GrPathProcessor* pathProc,
|
| const GrPathRange* pathRange,
|
| @@ -92,10 +80,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
|
| SkASSERT(indexValues);
|
| SkASSERT(transformValues);
|
|
|
| - if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
|
| - return NULL;
|
| - }
|
| -
|
| char* savedIndices;
|
| float* savedTransforms;
|
|
|
| @@ -103,7 +87,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
|
| transformValues, transformType,
|
| count, &savedIndices, &savedTransforms);
|
|
|
| - if (Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) {
|
| + if (!fCmdBuffer.empty() && Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) {
|
| // The previous command was also DrawPaths. Try to collapse this call into the one
|
| // before. Note that stenciling all the paths at once, then covering, may not be
|
| // equivalent to two separate draw calls if there is overlap. Blending won't work,
|
| @@ -117,7 +101,8 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
|
| transformType == previous->fTransformType &&
|
| stencilSettings == previous->fStencilSettings &&
|
| path_fill_type_is_winding(stencilSettings) &&
|
| - !pipelineInfo.willBlendWithDst(pathProc)) {
|
| + !pipelineInfo.willBlendWithDst(pathProc) &&
|
| + previous->fState == state) {
|
| const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
|
| const int xformSize = GrPathRendering::PathTransformSize(transformType);
|
| if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices &&
|
| @@ -130,7 +115,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
|
| }
|
| }
|
|
|
| - DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
|
| + DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (state, pathRange));
|
| dp->fIndices = savedIndices;
|
| dp->fIndexType = indexType;
|
| dp->fTransforms = savedTransforms;
|
| @@ -140,8 +125,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
|
| return dp;
|
| }
|
|
|
| -GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb,
|
| - const SkIRect* rect,
|
| +GrTargetCommands::Cmd* GrTargetCommands::recordClear(const SkIRect* rect,
|
| GrColor color,
|
| bool canIgnoreRect,
|
| GrRenderTarget* renderTarget) {
|
| @@ -163,8 +147,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb,
|
| return clr;
|
| }
|
|
|
| -GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuffer* iodb,
|
| - const SkIRect& rect,
|
| +GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(const SkIRect& rect,
|
| bool insideClip,
|
| GrRenderTarget* renderTarget) {
|
| SkASSERT(renderTarget);
|
| @@ -175,8 +158,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuf
|
| return clr;
|
| }
|
|
|
| -GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb,
|
| - GrRenderTarget* renderTarget) {
|
| +GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrRenderTarget* renderTarget) {
|
| SkASSERT(renderTarget);
|
|
|
| Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
|
| @@ -186,7 +168,6 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb
|
|
|
| void GrTargetCommands::reset() {
|
| fCmdBuffer.reset();
|
| - fPrevState = NULL;
|
| }
|
|
|
| void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
|
| @@ -194,10 +175,6 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
|
| return;
|
| }
|
|
|
| - // Updated every time we find a set state cmd to reflect the current state in the playback
|
| - // stream.
|
| - SetState* currentState = NULL;
|
| -
|
| GrGpu* gpu = iodb->getGpu();
|
|
|
| // Loop over all batches and generate geometry
|
| @@ -206,13 +183,8 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
|
| if (Cmd::kDrawBatch_CmdType == genIter->type()) {
|
| DrawBatch* db = reinterpret_cast<DrawBatch*>(genIter.get());
|
| fBatchTarget.resetNumberOfDraws();
|
| - db->execute(NULL, currentState);
|
| + db->fBatch->generateGeometry(&fBatchTarget, db->fState->getPipeline());
|
| db->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws());
|
| - } else if (Cmd::kSetState_CmdType == genIter->type()) {
|
| - SetState* ss = reinterpret_cast<SetState*>(genIter.get());
|
| -
|
| - ss->execute(gpu, currentState);
|
| - currentState = ss;
|
| }
|
| }
|
|
|
| @@ -231,29 +203,7 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
|
| gpu->addGpuTraceMarker(&newMarker);
|
| }
|
|
|
| - if (Cmd::kDrawBatch_CmdType == iter->type()) {
|
| - DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
|
| - fBatchTarget.flushNext(db->fBatch->numberOfDraws());
|
| -
|
| - if (iter->isTraced()) {
|
| - gpu->removeGpuTraceMarker(&newMarker);
|
| - }
|
| - continue;
|
| - }
|
| -
|
| - if (Cmd::kSetState_CmdType == iter->type()) {
|
| - // TODO this is just until NVPR is in batch
|
| - SetState* ss = reinterpret_cast<SetState*>(iter.get());
|
| -
|
| - if (ss->fPrimitiveProcessor) {
|
| - ss->execute(gpu, currentState);
|
| - }
|
| - currentState = ss;
|
| -
|
| - } else {
|
| - iter->execute(gpu, currentState);
|
| - }
|
| -
|
| + iter->execute(gpu);
|
| if (iter->isTraced()) {
|
| gpu->removeGpuTraceMarker(&newMarker);
|
| }
|
| @@ -262,7 +212,7 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
|
| fBatchTarget.postFlush();
|
| }
|
|
|
| -void GrTargetCommands::StencilPath::execute(GrGpu* gpu, const SetState*) {
|
| +void GrTargetCommands::StencilPath::execute(GrGpu* gpu) {
|
| GrGpu::StencilPathState state;
|
| state.fRenderTarget = fRenderTarget.get();
|
| state.fScissor = &fScissor;
|
| @@ -273,37 +223,36 @@ void GrTargetCommands::StencilPath::execute(GrGpu* gpu, const SetState*) {
|
| gpu->stencilPath(this->path(), state);
|
| }
|
|
|
| -void GrTargetCommands::DrawPath::execute(GrGpu* gpu, const SetState* state) {
|
| - SkASSERT(state);
|
| - DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
|
| - &state->fBatchTracker);
|
| +void GrTargetCommands::DrawPath::execute(GrGpu* gpu) {
|
| + if (!fState->fCompiled) {
|
| + gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fState->getPipeline(),
|
| + fState->fBatchTracker);
|
| + fState->fCompiled = true;
|
| + }
|
| + DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(),
|
| + &fState->fDesc, &fState->fBatchTracker);
|
| gpu->drawPath(args, this->path(), fStencilSettings);
|
| }
|
|
|
| -void GrTargetCommands::DrawPaths::execute(GrGpu* gpu, const SetState* state) {
|
| - SkASSERT(state);
|
| - DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
|
| - &state->fBatchTracker);
|
| +void GrTargetCommands::DrawPaths::execute(GrGpu* gpu) {
|
| + if (!fState->fCompiled) {
|
| + gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fState->getPipeline(),
|
| + fState->fBatchTracker);
|
| + fState->fCompiled = true;
|
| + }
|
| + DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(),
|
| + &fState->fDesc, &fState->fBatchTracker);
|
| gpu->drawPaths(args, this->pathRange(),
|
| fIndices, fIndexType,
|
| fTransforms, fTransformType,
|
| fCount, fStencilSettings);
|
| }
|
|
|
| -void GrTargetCommands::DrawBatch::execute(GrGpu*, const SetState* state) {
|
| - SkASSERT(state);
|
| - fBatch->generateGeometry(fBatchTarget, state->getPipeline());
|
| -}
|
| -
|
| -void GrTargetCommands::SetState::execute(GrGpu* gpu, const SetState*) {
|
| - // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we
|
| - // will only have GrBatch and we can delete this
|
| - if (fPrimitiveProcessor) {
|
| - gpu->buildProgramDesc(&fDesc, *fPrimitiveProcessor, *getPipeline(), fBatchTracker);
|
| - }
|
| +void GrTargetCommands::DrawBatch::execute(GrGpu*) {
|
| + fBatchTarget->flushNext(fBatch->numberOfDraws());
|
| }
|
|
|
| -void GrTargetCommands::Clear::execute(GrGpu* gpu, const SetState*) {
|
| +void GrTargetCommands::Clear::execute(GrGpu* gpu) {
|
| if (GrColor_ILLEGAL == fColor) {
|
| gpu->discard(this->renderTarget());
|
| } else {
|
| @@ -311,15 +260,15 @@ void GrTargetCommands::Clear::execute(GrGpu* gpu, const SetState*) {
|
| }
|
| }
|
|
|
| -void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
|
| +void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu) {
|
| gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
|
| }
|
|
|
| -void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) {
|
| +void GrTargetCommands::CopySurface::execute(GrGpu* gpu) {
|
| gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
|
| }
|
|
|
| -void GrTargetCommands::XferBarrier::execute(GrGpu* gpu, const SetState* state) {
|
| +void GrTargetCommands::XferBarrier::execute(GrGpu* gpu) {
|
| gpu->xferBarrier(fBarrierType);
|
| }
|
|
|
| @@ -333,65 +282,10 @@ GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrSurface* dst,
|
| return cs;
|
| }
|
|
|
| -bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
|
| - const GrPrimitiveProcessor* primProc,
|
| - const GrDrawTarget::PipelineInfo& pipelineInfo) {
|
| - SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
|
| - iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
|
| -
|
| - if (ss->getPipeline()->mustSkip()) {
|
| - fCmdBuffer.pop_back();
|
| - return false;
|
| - }
|
| -
|
| - ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
|
| - ss->getPipeline()->getInitBatchTracker());
|
| -
|
| - if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
|
| - fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
|
| - *ss->fPrimitiveProcessor,
|
| - ss->fBatchTracker) &&
|
| - fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
|
| - fCmdBuffer.pop_back();
|
| - } else {
|
| - fPrevState = ss;
|
| - iodb->recordTraceMarkersIfNecessary(ss);
|
| - }
|
| -
|
| - this->recordXferBarrierIfNecessary(iodb, pipelineInfo);
|
| - return true;
|
| -}
|
| -
|
| -bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
|
| - GrBatch* batch,
|
| - const GrDrawTarget::PipelineInfo& pipelineInfo) {
|
| - SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
|
| - iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
|
| -
|
| - if (ss->getPipeline()->mustSkip()) {
|
| - fCmdBuffer.pop_back();
|
| - return false;
|
| - }
|
| -
|
| - batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
|
| -
|
| - if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
|
| - fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
|
| - fCmdBuffer.pop_back();
|
| - } else {
|
| - fPrevState = ss;
|
| - iodb->recordTraceMarkersIfNecessary(ss);
|
| - }
|
| -
|
| - this->recordXferBarrierIfNecessary(iodb, pipelineInfo);
|
| - return true;
|
| -}
|
| -
|
| -void GrTargetCommands::recordXferBarrierIfNecessary(GrInOrderDrawBuffer* iodb,
|
| - const GrDrawTarget::PipelineInfo& info) {
|
| - SkASSERT(fPrevState);
|
| - const GrXferProcessor& xp = *fPrevState->getXferProcessor();
|
| - GrRenderTarget* rt = fPrevState->getRenderTarget();
|
| +void GrTargetCommands::recordXferBarrierIfNecessary(const GrPipeline& pipeline,
|
| + GrInOrderDrawBuffer* iodb) {
|
| + const GrXferProcessor& xp = *pipeline.getXferProcessor();
|
| + GrRenderTarget* rt = pipeline.getRenderTarget();
|
|
|
| GrXferBarrierType barrierType;
|
| if (!xp.willNeedXferBarrier(rt, *iodb->caps(), &barrierType)) {
|
|
|