diff options
author | 2015-02-13 09:00:33 -0800 | |
---|---|---|
committer | 2015-02-13 09:00:33 -0800 | |
commit | e36914cb205699526988127a827d1a76c9a98d39 (patch) | |
tree | 3676983831392cede5b42a471d905bed491d3dfd /src/gpu | |
parent | f89f60f6972569a41fa737c786d238559027fede (diff) |
Pass in ProcOptInfos into willNeedDstCopy on XPs
BUG=skia:
Review URL: https://codereview.chromium.org/912413002
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 101 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 50 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 93 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.h | 67 | ||||
-rw-r--r-- | src/gpu/GrPipeline.cpp | 30 | ||||
-rw-r--r-- | src/gpu/GrPipeline.h | 19 | ||||
-rw-r--r-- | src/gpu/GrPipelineBuilder.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrPipelineBuilder.h | 20 | ||||
-rw-r--r-- | src/gpu/GrXferProcessor.cpp | 7 | ||||
-rw-r--r-- | src/gpu/effects/GrCoverageSetOpXP.h | 5 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomXfermode.cpp | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomXfermodePriv.h | 5 | ||||
-rw-r--r-- | src/gpu/effects/GrDisableColorXP.h | 5 | ||||
-rw-r--r-- | src/gpu/effects/GrPorterDuffXferProcessor.cpp | 7 |
14 files changed, 229 insertions, 188 deletions
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index cb60f11c09..e22c45bafc 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -12,6 +12,7 @@ #include "GrContext.h" #include "GrDrawTargetCaps.h" #include "GrPath.h" +#include "GrPipeline.h" #include "GrRenderTarget.h" #include "GrSurfacePriv.h" #include "GrTemplates.h" @@ -385,9 +386,11 @@ bool GrDrawTarget::checkDraw(const GrPipelineBuilder& pipelineBuilder, } bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder, + const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds) { - if (!pipelineBuilder.willXPNeedDstCopy(*this->caps())) { + if (!pipelineBuilder.willXPNeedDstCopy(*this->caps(), colorPOI, coveragePOI)) { return true; } SkIRect copyRect; @@ -470,9 +473,15 @@ void GrDrawTarget::drawIndexed(GrPipelineBuilder* pipelineBuilder, info.setDevBounds(*devBounds); } + GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds, + this); + if (pipelineInfo.mustSkipDraw()) { + return; + } + this->setDrawBuffers(&info, gp->getVertexStride()); - this->onDraw(*pipelineBuilder, gp, info, scissorState); + this->onDraw(gp, info, pipelineInfo); } } @@ -509,9 +518,15 @@ void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder, info.setDevBounds(*devBounds); } + GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds, + this); + if (pipelineInfo.mustSkipDraw()) { + return; + } + this->setDrawBuffers(&info, gp->getVertexStride()); - this->onDraw(*pipelineBuilder, gp, info, scissorState); + this->onDraw(gp, info, pipelineInfo); } } @@ -530,7 +545,17 @@ void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, return; } - this->onDrawBatch(batch, *pipelineBuilder, scissorState, devBounds); + // init batch and my other crap + GrBatchOpt batchOpt; + batchOpt.fCanTweakAlphaForCoverage = pipelineBuilder->canTweakAlphaForCoverage(); + batch->initBatchOpt(batchOpt); + + GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, batch, devBounds, this); + if (pipelineInfo.mustSkipDraw()) { + return; + } + + this->onDrawBatch(batch, pipelineInfo); } static const GrStencilSettings& winding_path_stencil_settings() { @@ -620,8 +645,13 @@ void GrDrawTarget::drawPath(GrPipelineBuilder* pipelineBuilder, pipelineBuilder->getRenderTarget()->getStencilBuffer(), &stencilSettings); - this->onDrawPath(*pipelineBuilder, pathProc, path, scissorState, stencilSettings, - &devBounds); + GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, &devBounds, + this); + if (pipelineInfo.mustSkipDraw()) { + return; + } + + this->onDrawPath(pathProc, path, stencilSettings, pipelineInfo); } void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder, @@ -659,8 +689,13 @@ void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder, // instead for it to just copy the entire dst. Realistically this is a moot // point, because any context that supports NV_path_rendering will also // support NV_blend_equation_advanced. - this->onDrawPaths(*pipelineBuilder, pathProc, pathRange, indices, indexType, transformValues, - transformType, count, scissorState, stencilSettings, NULL); + GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, NULL, this); + if (pipelineInfo.mustSkipDraw()) { + return; + } + + this->onDrawPaths(pathProc, pathRange, indices, indexType, transformValues, + transformType, count, stencilSettings, pipelineInfo); } void GrDrawTarget::clear(const SkIRect* rect, @@ -778,8 +813,15 @@ void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder, info.fStartIndex, info.fVertexCount, info.fIndexCount)) { + + GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds, + this); + if (pipelineInfo.mustSkipDraw()) { + return; + } + this->setDrawBuffers(&info, gp->getVertexStride()); - this->onDraw(*pipelineBuilder, gp, info, scissorState); + this->onDraw(gp, info, pipelineInfo); } info.fStartVertex += info.fVertexCount; instanceCount -= info.fInstanceCount; @@ -985,6 +1027,47 @@ bool GrDrawTarget::internalCanCopySurface(const GrSurface* dst, this->onCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint); } +void GrDrawTarget::setupPipeline(const PipelineInfo& pipelineInfo, + GrPipeline* pipeline) { + SkNEW_PLACEMENT_ARGS(pipeline, GrPipeline, (*pipelineInfo.fPipelineBuilder, + pipelineInfo.fColorPOI, + pipelineInfo.fCoveragePOI, + *this->caps(), + *pipelineInfo.fScissor, + &pipelineInfo.fDstCopy)); +} +/////////////////////////////////////////////////////////////////////////////// + +GrDrawTarget::PipelineInfo::PipelineInfo(GrPipelineBuilder* pipelineBuilder, + GrScissorState* scissor, + const GrPrimitiveProcessor* primProc, + const SkRect* devBounds, + GrDrawTarget* target) + : fPipelineBuilder(pipelineBuilder) + , fScissor(scissor) { + fColorPOI = fPipelineBuilder->colorProcInfo(primProc); + fCoveragePOI = fPipelineBuilder->coverageProcInfo(primProc); + if (!target->setupDstReadIfNecessary(*fPipelineBuilder, fColorPOI, fCoveragePOI, + &fDstCopy, devBounds)) { + fPipelineBuilder = NULL; + } +} + +GrDrawTarget::PipelineInfo::PipelineInfo(GrPipelineBuilder* pipelineBuilder, + GrScissorState* scissor, + const GrBatch* batch, + const SkRect* devBounds, + GrDrawTarget* target) + : fPipelineBuilder(pipelineBuilder) + , fScissor(scissor) { + fColorPOI = fPipelineBuilder->colorProcInfo(batch); + fCoveragePOI = fPipelineBuilder->coverageProcInfo(batch); + if (!target->setupDstReadIfNecessary(*fPipelineBuilder, fColorPOI, fCoveragePOI, + &fDstCopy, devBounds)) { + fPipelineBuilder = NULL; + } +} + /////////////////////////////////////////////////////////////////////////////// void GrDrawTargetCaps::reset() { diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 65407e653b..f9f25f15fa 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -33,6 +33,7 @@ class GrClipData; class GrDrawTargetCaps; class GrPath; class GrPathRange; +class GrPipeline; class GrDrawTarget : public SkRefCnt { public: @@ -680,9 +681,36 @@ protected: // but couldn't be made. Otherwise, returns true. This method needs to be protected because it // needs to be accessed by GLPrograms to setup a correct drawstate bool setupDstReadIfNecessary(const GrPipelineBuilder&, + const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds); + struct PipelineInfo { + PipelineInfo(GrPipelineBuilder* pipelineBuilder, GrScissorState* scissor, + const GrPrimitiveProcessor* primProc, const SkRect* devBounds, + GrDrawTarget* target); + + PipelineInfo(GrPipelineBuilder* pipelineBuilder, GrScissorState* scissor, + const GrBatch* batch, const SkRect* devBounds, GrDrawTarget* target); + + bool willBlendWithDst(const GrPrimitiveProcessor* primProc) const { + return fPipelineBuilder->willBlendWithDst(primProc); + } + private: + friend class GrDrawTarget; + + bool mustSkipDraw() const { return (NULL == fPipelineBuilder); } + + GrPipelineBuilder* fPipelineBuilder; + GrScissorState* fScissor; + GrProcOptInfo fColorPOI; + GrProcOptInfo fCoveragePOI; + GrDeviceCoordTexture fDstCopy; + }; + + void setupPipeline(const PipelineInfo& pipelineInfo, GrPipeline* pipeline); + private: /** * This will be called before allocating a texture as a dst for copySurface. This function @@ -719,14 +747,8 @@ private: virtual void geometrySourceWillPush() = 0; virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0; // subclass called to perform drawing - virtual void onDraw(const GrPipelineBuilder&, - const GrGeometryProcessor*, - const DrawInfo&, - const GrScissorState&) = 0; - virtual void onDrawBatch(GrBatch*, - const GrPipelineBuilder&, - const GrScissorState&, - const SkRect* devBounds) = 0; + virtual void onDraw(const GrGeometryProcessor*, const DrawInfo&, const PipelineInfo&) = 0; + virtual void onDrawBatch(GrBatch*, const PipelineInfo&) = 0; // TODO copy in order drawbuffer onDrawRect to here virtual void onDrawRect(GrPipelineBuilder*, GrColor color, @@ -740,23 +762,19 @@ private: const GrPath*, const GrScissorState&, const GrStencilSettings&) = 0; - virtual void onDrawPath(const GrPipelineBuilder&, - const GrPathProcessor*, + virtual void onDrawPath(const GrPathProcessor*, const GrPath*, - const GrScissorState&, const GrStencilSettings&, - const SkRect* devBounds) = 0; - virtual void onDrawPaths(const GrPipelineBuilder&, - const GrPathProcessor*, + const PipelineInfo&) = 0; + virtual void onDrawPaths(const GrPathProcessor*, const GrPathRange*, const void* indices, PathIndexType, const float transformValues[], PathTransformType, int count, - const GrScissorState&, const GrStencilSettings&, - const SkRect* devBounds) = 0; + const PipelineInfo&) = 0; virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, GrRenderTarget* renderTarget) = 0; diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 1840ca32d7..eb3d19da9c 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -190,8 +190,7 @@ void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder, &devBounds); } -int GrInOrderDrawBuffer::concatInstancedDraw(const GrPipelineBuilder& pipelineBuilder, - const DrawInfo& info) { +int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { SkASSERT(!fCmdBuffer.empty()); SkASSERT(info.isInstanced()); @@ -244,20 +243,19 @@ int GrInOrderDrawBuffer::concatInstancedDraw(const GrPipelineBuilder& pipelineBu return instancesToConcat; } -void GrInOrderDrawBuffer::onDraw(const GrPipelineBuilder& pipelineBuilder, - const GrGeometryProcessor* gp, +void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp, const DrawInfo& info, - const GrScissorState& scissorState) { + const PipelineInfo& pipelineInfo) { SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer())); this->closeBatch(); - if (!this->recordStateAndShouldDraw(pipelineBuilder, gp, scissorState, info.getDevBounds())) { + if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) { return; } Draw* draw; if (info.isInstanced()) { - int instancesConcated = this->concatInstancedDraw(pipelineBuilder, info); + int instancesConcated = this->concatInstancedDraw(info); if (info.instanceCount() > instancesConcated) { draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info)); draw->fInfo.adjustInstanceCount(-instancesConcated); @@ -271,10 +269,8 @@ void GrInOrderDrawBuffer::onDraw(const GrPipelineBuilder& pipelineBuilder, } void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch, - const GrPipelineBuilder& pipelineBuilder, - const GrScissorState& scissorState, - const SkRect* devBounds) { - if (!this->recordStateAndShouldDraw(batch, pipelineBuilder, scissorState, devBounds)) { + const PipelineInfo& pipelineInfo) { + if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) { return; } @@ -310,16 +306,14 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder this->recordTraceMarkersIfNecessary(); } -void GrInOrderDrawBuffer::onDrawPath(const GrPipelineBuilder& pipelineBuilder, - const GrPathProcessor* pathProc, +void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc, const GrPath* path, - const GrScissorState& scissorState, const GrStencilSettings& stencilSettings, - const SkRect* devBounds) { + const PipelineInfo& pipelineInfo) { this->closeBatch(); // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering? - if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, devBounds)) { + if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) { return; } DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); @@ -327,23 +321,21 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPipelineBuilder& pipelineBuilder, this->recordTraceMarkersIfNecessary(); } -void GrInOrderDrawBuffer::onDrawPaths(const GrPipelineBuilder& pipelineBuilder, - const GrPathProcessor* pathProc, +void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc, const GrPathRange* pathRange, const void* indices, PathIndexType indexType, const float transformValues[], PathTransformType transformType, int count, - const GrScissorState& scissorState, const GrStencilSettings& stencilSettings, - const SkRect* devBounds) { + const PipelineInfo& pipelineInfo) { SkASSERT(pathRange); SkASSERT(indices); SkASSERT(transformValues); this->closeBatch(); - if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, devBounds)) { + if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) { return; } @@ -373,7 +365,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPipelineBuilder& pipelineBuilder, transformType == previous->fTransformType && stencilSettings == previous->fStencilSettings && path_fill_type_is_winding(stencilSettings) && - !pipelineBuilder.willBlendWithDst(pathProc)) { + !pipelineInfo.willBlendWithDst(pathProc)) { // Fold this DrawPaths call into the one previous. previous->fCount += count; return; @@ -492,7 +484,7 @@ void GrInOrderDrawBuffer::onFlush() { // only have GrBatch and we can delete this if (ss->fPrimitiveProcessor) { this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor, - ss->fPipeline, + *ss->getPipeline(), ss->fBatchTracker); } currentState = ss; @@ -514,7 +506,7 @@ void GrInOrderDrawBuffer::onFlush() { void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const SetState* state) { SkASSERT(state); - DrawArgs args(state->fPrimitiveProcessor.get(), &state->fPipeline, &state->fDesc, + DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc, &state->fBatchTracker); buf->getGpu()->draw(args, fInfo); } @@ -532,14 +524,14 @@ void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const S void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, const SetState* state) { SkASSERT(state); - DrawArgs args(state->fPrimitiveProcessor.get(), &state->fPipeline, &state->fDesc, + DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc, &state->fBatchTracker); buf->getGpu()->drawPath(args, this->path(), fStencilSettings); } void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const SetState* state) { SkASSERT(state); - DrawArgs args(state->fPrimitiveProcessor.get(), &state->fPipeline, &state->fDesc, + DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc, &state->fBatchTracker); buf->getGpu()->drawPaths(args, this->pathRange(), &buf->fPathIndexBuffer[fIndicesLocation], fIndexType, @@ -549,7 +541,7 @@ void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const Set void GrInOrderDrawBuffer::DrawBatch::execute(GrInOrderDrawBuffer* buf, const SetState* state) { SkASSERT(state); - fBatch->generateGeometry(buf->getBatchTarget(), &state->fPipeline); + fBatch->generateGeometry(buf->getBatchTarget(), state->getPipeline()); } void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {} @@ -585,30 +577,24 @@ bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, return false; } -bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrPipelineBuilder& pipelineBuilder, - const GrPrimitiveProcessor* primProc, - const GrScissorState& scissor, - const SkRect* devBounds) { - GrDeviceCoordTexture dstCopy; - if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { - return false; - } - SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, - (pipelineBuilder, primProc, *this->getGpu()->caps(), - scissor, &dstCopy)); - if (ss->fPipeline.mustSkip()) { +bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc, + const PipelineInfo& pipelineInfo) { + SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc)); + this->setupPipeline(pipelineInfo, ss->pipelineLocation()); + + if (ss->getPipeline()->mustSkip()) { fCmdBuffer.pop_back(); return false; } ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker, - ss->fPipeline.getInitBatchTracker()); + ss->getPipeline()->getInitBatchTracker()); if (fPrevState && fPrevState->fPrimitiveProcessor.get() && fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker, *ss->fPrimitiveProcessor, ss->fBatchTracker) && - fPrevState->fPipeline.isEqual(ss->fPipeline)) { + fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { fCmdBuffer.pop_back(); } else { fPrevState = ss; @@ -617,29 +603,20 @@ bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrPipelineBuilder& pipe return true; } -bool GrInOrderDrawBuffer::recordStateAndShouldDraw(GrBatch* batch, - const GrPipelineBuilder& pipelineBuilder, - const GrScissorState& scissor, - const SkRect* devBounds) { - GrDeviceCoordTexture dstCopy; - if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { - return false; - } - // 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, pipelineBuilder, *this->getGpu()->caps(), scissor, - &dstCopy)); - if (ss->fPipeline.mustSkip()) { +bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch, + const PipelineInfo& pipelineInfo) { + SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ()); + this->setupPipeline(pipelineInfo, ss->pipelineLocation()); + + if (ss->getPipeline()->mustSkip()) { fCmdBuffer.pop_back(); return false; } - batch->initBatchTracker(ss->fPipeline.getInitBatchTracker()); + batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker()); if (fPrevState && !fPrevState->fPrimitiveProcessor.get() && - fPrevState->fPipeline.isEqual(ss->fPipeline)) { + fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { fCmdBuffer.pop_back(); } else { this->closeBatch(); diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index f271207abc..73d0898149 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -188,28 +188,28 @@ private: // TODO: rename to SetPipeline once pp, batch tracker, and desc are removed struct SetState : public Cmd { - // TODO get rid of the prim proc version of this when we use batch everywhere - SetState(const GrPipelineBuilder& pipelineBuilder, const GrPrimitiveProcessor* primProc, - const GrDrawTargetCaps& caps, - const GrScissorState& scissor, const GrDeviceCoordTexture* dstCopy) + // TODO get rid of the prim proc parameter when we use batch everywhere + SetState(const GrPrimitiveProcessor* primProc = NULL) : Cmd(kSetState_Cmd) - , fPrimitiveProcessor(primProc) - , fPipeline(pipelineBuilder, primProc, caps, scissor, dstCopy) {} + , fPrimitiveProcessor(primProc) {} - SetState(GrBatch* batch, - const GrPipelineBuilder& pipelineBuilder, - const GrDrawTargetCaps& caps, - const GrScissorState& scissor, const GrDeviceCoordTexture* dstCopy) - : Cmd(kSetState_Cmd) - , fPipeline(batch, pipelineBuilder, caps, scissor, dstCopy) {} + ~SetState() { reinterpret_cast<GrPipeline*>(fPipeline.get())->~GrPipeline(); } + + // This function is only for getting the location in memory where we will create our + // pipeline object. + GrPipeline* pipelineLocation() { return reinterpret_cast<GrPipeline*>(fPipeline.get()); } + + const GrPipeline* getPipeline() const { + return reinterpret_cast<const GrPipeline*>(fPipeline.get()); + } void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE; typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor; - ProgramPrimitiveProcessor fPrimitiveProcessor; - const GrPipeline fPipeline; - GrProgramDesc fDesc; - GrBatchTracker fBatchTracker; + ProgramPrimitiveProcessor fPrimitiveProcessor; + SkAlignedSStorage<sizeof(GrPipeline)> fPipeline; + GrProgramDesc fDesc; + GrBatchTracker fBatchTracker; }; struct DrawBatch : public Cmd { @@ -230,14 +230,8 @@ private: void onFlush() SK_OVERRIDE; // overrides from GrDrawTarget - void onDraw(const GrPipelineBuilder&, - const GrGeometryProcessor*, - const DrawInfo&, - const GrScissorState&) SK_OVERRIDE; - void onDrawBatch(GrBatch*, - const GrPipelineBuilder&, - const GrScissorState&, - const SkRect* devBounds) SK_OVERRIDE; + void onDraw(const GrGeometryProcessor*, const DrawInfo&, const PipelineInfo&) SK_OVERRIDE; + void onDrawBatch(GrBatch*, const PipelineInfo&) SK_OVERRIDE; void onDrawRect(GrPipelineBuilder*, GrColor, const SkMatrix& viewMatrix, @@ -250,23 +244,19 @@ private: const GrPath*, const GrScissorState&, const GrStencilSettings&) SK_OVERRIDE; - void onDrawPath(const GrPipelineBuilder&, - const GrPathProcessor*, + void onDrawPath(const GrPathProcessor*, const GrPath*, - const GrScissorState&, const GrStencilSettings&, - const SkRect* devBounds) SK_OVERRIDE; - void onDrawPaths(const GrPipelineBuilder&, - const GrPathProcessor*, + const PipelineInfo&) SK_OVERRIDE; + void onDrawPaths(const GrPathProcessor*, const GrPathRange*, const void* indices, PathIndexType, const float transformValues[], PathTransformType, int count, - const GrScissorState&, const GrStencilSettings&, - const SkRect* devBounds) SK_OVERRIDE; + const PipelineInfo&) SK_OVERRIDE; void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, @@ -278,20 +268,15 @@ private: // Attempts to concat instances from info onto the previous draw. info must represent an // instanced draw. The caller must have already recorded a new draw state and clip if necessary. - int concatInstancedDraw(const GrPipelineBuilder&, const DrawInfo&); + int concatInstancedDraw(const DrawInfo&); // Determines whether the current draw operation requires a new GrPipeline and if so // records it. If the draw can be skipped false is returned and no new GrPipeline is // recorded. // TODO delete the primproc variant when we have batches everywhere - bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(const GrPipelineBuilder&, - const GrPrimitiveProcessor*, - const GrScissorState&, - const SkRect*); - bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(GrBatch*, - const GrPipelineBuilder&, - const GrScissorState&, - const SkRect*); + bool SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(const GrPrimitiveProcessor*, + const PipelineInfo&); + bool SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(GrBatch*, const PipelineInfo&); // We lazily record clip changes in order to skip clips that have no effect. void recordClipIfNecessary(); diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index bd508e9dc1..3ccc72b8df 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -15,37 +15,11 @@ #include "GrXferProcessor.h" GrPipeline::GrPipeline(const GrPipelineBuilder& pipelineBuilder, - const GrPrimitiveProcessor* primProc, + const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, const GrDrawTargetCaps& caps, const GrScissorState& scissorState, const GrDeviceCoordTexture* dstCopy) { - const GrProcOptInfo& colorPOI = pipelineBuilder.colorProcInfo(primProc); - const GrProcOptInfo& coveragePOI = pipelineBuilder.coverageProcInfo(primProc); - - this->internalConstructor(pipelineBuilder, colorPOI, coveragePOI, caps, scissorState, dstCopy); -} - -GrPipeline::GrPipeline(GrBatch* batch, - const GrPipelineBuilder& pipelineBuilder, - const GrDrawTargetCaps& caps, - const GrScissorState& scissorState, - const GrDeviceCoordTexture* dstCopy) { - GrBatchOpt batchOpt; - batchOpt.fCanTweakAlphaForCoverage = pipelineBuilder.canTweakAlphaForCoverage(); - batch->initBatchOpt(batchOpt); - - const GrProcOptInfo& colorPOI = pipelineBuilder.colorProcInfo(batch); - const GrProcOptInfo& coveragePOI = pipelineBuilder.coverageProcInfo(batch); - - this->internalConstructor(pipelineBuilder, colorPOI, coveragePOI, caps, scissorState, dstCopy); -} - -void GrPipeline::internalConstructor(const GrPipelineBuilder& pipelineBuilder, - const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - const GrDrawTargetCaps& caps, - const GrScissorState& scissorState, - const GrDeviceCoordTexture* dstCopy) { // Create XferProcessor from DS's XPFactory SkAutoTUnref<GrXferProcessor> xferProcessor( pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI, dstCopy, caps)); diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h index 8480c00458..61b40d0c4d 100644 --- a/src/gpu/GrPipeline.h +++ b/src/gpu/GrPipeline.h @@ -29,14 +29,13 @@ class GrPipeline { public: SK_DECLARE_INST_COUNT(GrPipeline) - // TODO get rid of this version of the constructor when we use batch everywhere - GrPipeline(const GrPipelineBuilder& pipelineBuilder, const GrPrimitiveProcessor*, - const GrDrawTargetCaps&, const GrScissorState&, + GrPipeline(const GrPipelineBuilder&, + const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + const GrDrawTargetCaps&, + const GrScissorState&, const GrDeviceCoordTexture* dstCopy); - GrPipeline(GrBatch*, const GrPipelineBuilder&, const GrDrawTargetCaps&, - const GrScissorState&, const GrDeviceCoordTexture* dstCopy); - /* * Returns true if it is possible to combine the two GrPipelines and it will update 'this' * to subsume 'that''s draw. @@ -137,14 +136,6 @@ public: const GrPipelineInfo& getInitBatchTracker() const { return fInitBT; } private: - // TODO we can have one constructor once GrBatch is complete - void internalConstructor(const GrPipelineBuilder&, - const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - const GrDrawTargetCaps&, - const GrScissorState&, - const GrDeviceCoordTexture* dstCopy); - /** * Alter the program desc and inputs (attribs and processors) based on the blend optimization. */ diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp index 54d357fd23..6885eb0dd8 100644 --- a/src/gpu/GrPipelineBuilder.cpp +++ b/src/gpu/GrPipelineBuilder.cpp @@ -101,8 +101,10 @@ bool GrPipelineBuilder::canUseFracCoveragePrimProc(GrColor color, //////////////////////////////////////////////////////////////////////////////s -bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps) const { - return this->getXPFactory()->willNeedDstCopy(caps); +bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps, + const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const { + return this->getXPFactory()->willNeedDstCopy(caps, colorPOI, coveragePOI); } void GrPipelineBuilder::AutoRestoreEffects::set(GrPipelineBuilder* pipelineBuilder) { diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index c6adf870b3..72f8e28c57 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -103,7 +103,8 @@ public: /** * Checks whether the xp will need a copy of the destination to correctly blend. */ - bool willXPNeedDstCopy(const GrDrawTargetCaps& caps) const; + bool willXPNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const; /** * The xfer processor factory. @@ -388,15 +389,6 @@ public: GrPipelineBuilder& operator= (const GrPipelineBuilder& that); -private: - // Calculating invariant color / coverage information is expensive, so we partially cache the - // results. - // - // canUseFracCoveragePrimProc() - Called in regular skia draw, caches results but only for a - // specific color and coverage. May be called multiple times - // willBlendWithDst() - only called by Nvpr, does not cache results - // GrOptDrawState constructor - never caches results - // TODO delete when we have Batch const GrProcOptInfo& colorProcInfo(const GrPrimitiveProcessor* pp) const { this->calcColorInvariantOutput(pp); @@ -417,6 +409,14 @@ private: this->calcCoverageInvariantOutput(batch); return fCoverageProcInfo; } +private: + // Calculating invariant color / coverage information is expensive, so we partially cache the + // results. + // + // canUseFracCoveragePrimProc() - Called in regular skia draw, caches results but only for a + // specific color and coverage. May be called multiple times + // willBlendWithDst() - only called by Nvpr, does not cache results + // GrOptDrawState constructor - never caches results /** * Primproc variants of the calc functions diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp index e98ae407a8..321dcfd5e8 100644 --- a/src/gpu/GrXferProcessor.cpp +++ b/src/gpu/GrXferProcessor.cpp @@ -38,7 +38,7 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI, const GrDeviceCoordTexture* dstCopy, const GrDrawTargetCaps& caps) const { #ifdef SK_DEBUG - if (this->willReadDstColor()) { + if (this->willReadDstColor(colorPOI, coveragePOI)) { if (!caps.dstReadInShaderSupport()) { SkASSERT(dstCopy && dstCopy->texture()); } else { @@ -52,7 +52,8 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI, return this->onCreateXferProcessor(colorPOI, coveragePOI, dstCopy); } -bool GrXPFactory::willNeedDstCopy(const GrDrawTargetCaps& caps) const { - return (this->willReadDstColor() && !caps.dstReadInShaderSupport()); +bool GrXPFactory::willNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const { + return (this->willReadDstColor(colorPOI, coveragePOI) && !caps.dstReadInShaderSupport()); } diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h index 730d549b74..01dce95211 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.h +++ b/src/gpu/effects/GrCoverageSetOpXP.h @@ -39,7 +39,10 @@ private: const GrProcOptInfo& coveragePOI, const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; - bool willReadDstColor() const SK_OVERRIDE { return false; } + bool willReadDstColor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const SK_OVERRIDE { + return false; + } bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE { const GrCoverageSetOpXPFactory& xpf = xpfBase.cast<GrCoverageSetOpXPFactory>(); diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index c7b82be3a6..8d8f9f251d 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -611,7 +611,7 @@ GrXferProcessor* GrCustomXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, const GrDeviceCoordTexture* dstCopy) const { - return CustomXP::Create(fMode, dstCopy, this->willReadDstColor()); + return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(colorPOI, coveragePOI)); } diff --git a/src/gpu/effects/GrCustomXfermodePriv.h b/src/gpu/effects/GrCustomXfermodePriv.h index 2a2f69f69e..959b079603 100644 --- a/src/gpu/effects/GrCustomXfermodePriv.h +++ b/src/gpu/effects/GrCustomXfermodePriv.h @@ -81,7 +81,10 @@ private: const GrProcOptInfo& coveragePOI, const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; - bool willReadDstColor() const SK_OVERRIDE { return true; } + bool willReadDstColor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const SK_OVERRIDE { + return true; + } bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE { const GrCustomXPFactory& xpf = xpfBase.cast<GrCustomXPFactory>(); diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index fef0f1ee3b..fe60b595a0 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -43,7 +43,10 @@ private: const GrProcOptInfo& coveragePOI, const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; - bool willReadDstColor() const SK_OVERRIDE { return false; } + bool willReadDstColor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const SK_OVERRIDE { + return false; + } bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE { return true; diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 09ccf4eecc..6f2b63f5cb 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -458,14 +458,14 @@ GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrDeviceCoordTexture* dstCopy) const { if (!covPOI.isFourChannelOutput()) { return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, - this->willReadDstColor()); + this->willReadDstColor(colorPOI, covPOI)); } else { if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_GrBlendCoeff, blendConstant, dstCopy, - this->willReadDstColor()); + this->willReadDstColor(colorPOI, covPOI)); } else { return NULL; } @@ -587,7 +587,8 @@ void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, output->fWillBlendWithDst = false; } -bool GrPorterDuffXPFactory::willReadDstColor() const { +bool GrPorterDuffXPFactory::willReadDstColor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const { return false; } |