diff options
author | egdaniel <egdaniel@google.com> | 2015-02-04 06:14:22 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-04 06:14:22 -0800 |
commit | 3e9dfdb3784c0cbfecf7589a74aa9aff7ef40abd (patch) | |
tree | 8c92e754fbf5da2879845543632987c52479735e /src | |
parent | 3b7f7b092c8233a651248da8f23e1cfc85ac829b (diff) |
Revert "Move DstCopy on gpu into the GrXferProcessor."
This reverts commit 74a11753604768bf461b80cabb66060e8564d82c.
TBR=joshualitt@google.com,bsalomon@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Review URL: https://codereview.chromium.org/896163003
Diffstat (limited to 'src')
33 files changed, 341 insertions, 329 deletions
diff --git a/src/effects/SkArithmeticMode_gpu.cpp b/src/effects/SkArithmeticMode_gpu.cpp index 8022d668b4..48b7bcd610 100644 --- a/src/effects/SkArithmeticMode_gpu.cpp +++ b/src/effects/SkArithmeticMode_gpu.cpp @@ -166,15 +166,7 @@ public: ~GLArithmeticXP() SK_OVERRIDE {} - static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, - GrProcessorKeyBuilder* b) { - const GrArithmeticXP& arith = processor.cast<GrArithmeticXP>(); - uint32_t key = arith.enforcePMColor() ? 1 : 0; - b->add32(key); - } - -private: - void onEmitCode(const EmitArgs& args) SK_OVERRIDE { + void emitCode(const EmitArgs& args) SK_OVERRIDE { GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); const char* dstColor = fsBuilder->dstColor(); @@ -192,13 +184,21 @@ private: args.fInputCoverage, dstColor); } - void onSetData(const GrGLProgramDataManager& pdman, - const GrXferProcessor& processor) SK_OVERRIDE { + void setData(const GrGLProgramDataManager& pdman, + const GrXferProcessor& processor) SK_OVERRIDE { const GrArithmeticXP& arith = processor.cast<GrArithmeticXP>(); pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); fEnforcePMColor = arith.enforcePMColor(); }; + static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, + GrProcessorKeyBuilder* b) { + const GrArithmeticXP& arith = processor.cast<GrArithmeticXP>(); + uint32_t key = arith.enforcePMColor() ? 1 : 0; + b->add32(key); + } + +private: GrGLProgramDataManager::UniformHandle fKUni; bool fEnforcePMColor; @@ -207,18 +207,17 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrArithmeticXP::GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor, - const GrDeviceCoordTexture* dstCopy, bool willReadDstColor) - : INHERITED(dstCopy, willReadDstColor) - , fK1(k1) +GrArithmeticXP::GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor) + : fK1(k1) , fK2(k2) , fK3(k3) , fK4(k4) , fEnforcePMColor(enforcePMColor) { this->initClassID<GrPorterDuffXferProcessor>(); + this->setWillReadDstColor(); } -void GrArithmeticXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { +void GrArithmeticXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { GLArithmeticXP::GenKey(*this, caps, b); } diff --git a/src/effects/SkArithmeticMode_gpu.h b/src/effects/SkArithmeticMode_gpu.h index b282e22427..2998eabc3b 100644 --- a/src/effects/SkArithmeticMode_gpu.h +++ b/src/effects/SkArithmeticMode_gpu.h @@ -13,7 +13,6 @@ #if SK_SUPPORT_GPU #include "GrCoordTransform.h" -#include "GrDrawTargetCaps.h" #include "GrFragmentProcessor.h" #include "GrTextureAccess.h" #include "GrTypes.h" @@ -73,17 +72,16 @@ private: class GrArithmeticXP : public GrXferProcessor { public: - static GrXferProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor, - const GrDeviceCoordTexture* dstCopy, - bool willReadDstColor) { - return SkNEW_ARGS(GrArithmeticXP, (k1, k2, k3, k4, enforcePMColor, dstCopy, - willReadDstColor)); + static GrXferProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor) { + return SkNEW_ARGS(GrArithmeticXP, (k1, k2, k3, k4, enforcePMColor)); } ~GrArithmeticXP() SK_OVERRIDE {}; const char* name() const SK_OVERRIDE { return "Arithmetic"; } + void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; bool hasSecondaryOutput() const SK_OVERRIDE { return false; } @@ -107,10 +105,7 @@ public: bool enforcePMColor() const { return fEnforcePMColor; } private: - GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor, - const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); - - void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor); bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { const GrArithmeticXP& xp = xpBase.cast<GrArithmeticXP>(); @@ -138,6 +133,11 @@ public: return SkNEW_ARGS(GrArithmeticXPFactory, (k1, k2, k3, k4, enforcePMColor)); } + GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const SK_OVERRIDE { + return GrArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor); + } + bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE { return true; } @@ -154,18 +154,11 @@ public: void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, GrXPFactory::InvariantOutput*) const SK_OVERRIDE; + bool willReadDst() const SK_OVERRIDE { return true; } + private: GrArithmeticXPFactory(float k1, float k2, float k3, float k4, bool enforcePMColor); - GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE { - return GrArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor, dstCopy, - this->willReadDstColor()); - } - - bool willReadDstColor() const SK_OVERRIDE { return true; } - bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE { const GrArithmeticXPFactory& xpf = xpfBase.cast<GrArithmeticXPFactory>(); if (fK1 != xpf.fK1 || diff --git a/src/gpu/GrBatchTarget.cpp b/src/gpu/GrBatchTarget.cpp index 7a2d14e923..494bc474f8 100644 --- a/src/gpu/GrBatchTarget.cpp +++ b/src/gpu/GrBatchTarget.cpp @@ -21,7 +21,8 @@ void GrBatchTarget::flush() { BufferedFlush* bf = iter.get(); const GrPipeline* pipeline = bf->fPipeline; const GrPrimitiveProcessor* primProc = bf->fPrimitiveProcessor.get(); - fGpu->buildProgramDesc(&desc, *primProc, *pipeline, bf->fBatchTracker); + fGpu->buildProgramDesc(&desc, *primProc, *pipeline, pipeline->descInfo(), + bf->fBatchTracker); GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker); for (int i = 0; i < bf->fDraws.count(); i++) { @@ -39,7 +40,8 @@ void GrBatchTarget::flushNext(int n) { BufferedFlush* bf = fIter.get(); const GrPipeline* pipeline = bf->fPipeline; const GrPrimitiveProcessor* primProc = bf->fPrimitiveProcessor.get(); - fGpu->buildProgramDesc(&desc, *primProc, *pipeline, bf->fBatchTracker); + fGpu->buildProgramDesc(&desc, *primProc, *pipeline, pipeline->descInfo(), + bf->fBatchTracker); GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker); for (int i = 0; i < bf->fDraws.count(); i++) { diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index b4cd5a3675..b89d70ea2b 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -384,15 +384,15 @@ bool GrDrawTarget::checkDraw(const GrPipelineBuilder& pipelineBuilder, return true; } -bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder, +bool GrDrawTarget::setupDstReadIfNecessary(GrPipelineBuilder* pipelineBuilder, GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds) { - if (!pipelineBuilder.willXPNeedDstCopy(*this->caps())) { + if (this->caps()->dstReadInShaderSupport() || !pipelineBuilder->willEffectReadDstColor()) { return true; } SkIRect copyRect; const GrClipData* clip = this->getClip(); - GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); + GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); clip->getConservativeBounds(rt, ©Rect); if (drawBounds) { @@ -416,9 +416,6 @@ bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil this->initCopySurfaceDstDesc(rt, &desc); desc.fWidth = copyRect.width(); desc.fHeight = copyRect.height(); - // Only xfer processors can use dst copies, and the contract with the XP is that we always - // supply a copy texture with origin in the top left. - desc.fOrigin = kTopLeft_GrSurfaceOrigin; SkAutoTUnref<GrTexture> copy( fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); @@ -473,9 +470,14 @@ void GrDrawTarget::drawIndexed(GrPipelineBuilder* pipelineBuilder, info.setDevBounds(*devBounds); } + // TODO: We should continue with incorrect blending. + GrDeviceCoordTexture dstCopy; + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { + return; + } this->setDrawBuffers(&info, gp->getVertexStride()); - this->onDraw(*pipelineBuilder, gp, info, scissorState); + this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL); } } @@ -512,9 +514,15 @@ void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder, info.setDevBounds(*devBounds); } + // TODO: We should continue with incorrect blending. + GrDeviceCoordTexture dstCopy; + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { + return; + } + this->setDrawBuffers(&info, gp->getVertexStride()); - this->onDraw(*pipelineBuilder, gp, info, scissorState); + this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL); } } @@ -533,7 +541,12 @@ void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, return; } - this->onDrawBatch(batch, *pipelineBuilder, scissorState, devBounds); + GrDeviceCoordTexture dstCopy; + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { + return; + } + + this->onDrawBatch(batch, *pipelineBuilder, scissorState, dstCopy.texture() ? &dstCopy : NULL); } static const GrStencilSettings& winding_path_stencil_settings() { @@ -623,8 +636,13 @@ void GrDrawTarget::drawPath(GrPipelineBuilder* pipelineBuilder, pipelineBuilder->getRenderTarget()->getStencilBuffer(), &stencilSettings); + GrDeviceCoordTexture dstCopy; + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, &devBounds)) { + return; + } + this->onDrawPath(*pipelineBuilder, pathProc, path, scissorState, stencilSettings, - &devBounds); + dstCopy.texture() ? &dstCopy : NULL); } void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder, @@ -658,12 +676,18 @@ void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder, pipelineBuilder->getRenderTarget()->getStencilBuffer(), &stencilSettings); - // Don't compute a bounding box for dst copy texture, we'll opt + // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt // 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. + GrDeviceCoordTexture dstCopy; + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, NULL)) { + return; + } + this->onDrawPaths(*pipelineBuilder, pathProc, pathRange, indices, indexType, transformValues, - transformType, count, scissorState, stencilSettings, NULL); + transformType, count, scissorState, stencilSettings, + dstCopy.texture() ? &dstCopy : NULL); } void GrDrawTarget::clear(const SkIRect* rect, @@ -769,6 +793,12 @@ void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder, info.setDevBounds(*devBounds); } + // TODO: We should continue with incorrect blending. + GrDeviceCoordTexture dstCopy; + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { + return; + } + while (instanceCount) { info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw); info.fVertexCount = info.fInstanceCount * verticesPerInstance; @@ -782,7 +812,8 @@ void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder, info.fVertexCount, info.fIndexCount)) { this->setDrawBuffers(&info, gp->getVertexStride()); - this->onDraw(*pipelineBuilder, gp, info, scissorState); + this->onDraw(*pipelineBuilder, gp, info, scissorState, + dstCopy.texture() ? &dstCopy : NULL); } info.fStartVertex += info.fVertexCount; instanceCount -= info.fInstanceCount; diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 1b6651716c..18265c8fb7 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -677,7 +677,7 @@ protected: // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required // 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&, + bool setupDstReadIfNecessary(GrPipelineBuilder*, GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds); @@ -720,11 +720,12 @@ private: virtual void onDraw(const GrPipelineBuilder&, const GrGeometryProcessor*, const DrawInfo&, - const GrScissorState&) = 0; + const GrScissorState&, + const GrDeviceCoordTexture* dstCopy) = 0; virtual void onDrawBatch(GrBatch*, const GrPipelineBuilder&, const GrScissorState&, - const SkRect* devBounds) = 0; + const GrDeviceCoordTexture* dstCopy) = 0; // TODO copy in order drawbuffer onDrawRect to here virtual void onDrawRect(GrPipelineBuilder*, GrColor color, @@ -743,7 +744,7 @@ private: const GrPath*, const GrScissorState&, const GrStencilSettings&, - const SkRect* devBounds) = 0; + const GrDeviceCoordTexture* dstCopy) = 0; virtual void onDrawPaths(const GrPipelineBuilder&, const GrPathProcessor*, const GrPathRange*, @@ -754,7 +755,7 @@ private: int count, const GrScissorState&, const GrStencilSettings&, - const SkRect* devBounds) = 0; + const GrDeviceCoordTexture*) = 0; virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, GrRenderTarget* renderTarget) = 0; diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 8a3c32b7ab..8c458f18e8 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -298,6 +298,7 @@ public: virtual void buildProgramDesc(GrProgramDesc*, const GrPrimitiveProcessor&, const GrPipeline&, + const GrProgramDesc::DescInfo&, const GrBatchTracker&) const = 0; // Called to determine whether a copySurface call would succeed or not. Derived diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 3e177ed207..e59df80e96 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -247,13 +247,14 @@ int GrInOrderDrawBuffer::concatInstancedDraw(const GrPipelineBuilder& pipelineBu void GrInOrderDrawBuffer::onDraw(const GrPipelineBuilder& pipelineBuilder, const GrGeometryProcessor* gp, const DrawInfo& info, - const GrScissorState& scissorState) { + const GrScissorState& scissorState, + const GrDeviceCoordTexture* dstCopy) { SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer())); // This closeBatch call is required because we may introduce new draws when we setup clip this->closeBatch(); - if (!this->recordStateAndShouldDraw(pipelineBuilder, gp, scissorState, info.getDevBounds())) { + if (!this->recordStateAndShouldDraw(pipelineBuilder, gp, scissorState, dstCopy)) { return; } @@ -275,8 +276,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 GrDeviceCoordTexture* dstCopy) { + if (!this->recordStateAndShouldDraw(batch, pipelineBuilder, scissorState, dstCopy)) { return; } @@ -315,11 +316,11 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPipelineBuilder& pipelineBuilder, const GrPath* path, const GrScissorState& scissorState, const GrStencilSettings& stencilSettings, - const SkRect* devBounds) { + const GrDeviceCoordTexture* dstCopy) { this->closeBatch(); // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering? - if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, devBounds)) { + if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, dstCopy)) { return; } DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); @@ -337,14 +338,14 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPipelineBuilder& pipelineBuilder, int count, const GrScissorState& scissorState, const GrStencilSettings& stencilSettings, - const SkRect* devBounds) { + const GrDeviceCoordTexture* dstCopy) { SkASSERT(pathRange); SkASSERT(indices); SkASSERT(transformValues); this->closeBatch(); - if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, devBounds)) { + if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, dstCopy)) { return; } @@ -488,6 +489,7 @@ void GrInOrderDrawBuffer::onFlush() { if (ss->fPrimitiveProcessor) { this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor, ss->fPipeline, + ss->fPipeline.descInfo(), ss->fBatchTracker); } currentState = ss; @@ -582,14 +584,10 @@ bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, 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; - } + const GrDeviceCoordTexture* dstCopy) { SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (pipelineBuilder, primProc, *this->getGpu()->caps(), - scissor, &dstCopy)); + scissor, dstCopy)); if (ss->fPipeline.mustSkip()) { fCmdBuffer.pop_back(); return false; @@ -614,17 +612,13 @@ bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrPipelineBuilder& pipe bool GrInOrderDrawBuffer::recordStateAndShouldDraw(GrBatch* batch, const GrPipelineBuilder& pipelineBuilder, const GrScissorState& scissor, - const SkRect* devBounds) { - GrDeviceCoordTexture dstCopy; - if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { - return false; - } + const GrDeviceCoordTexture* dstCopy) { // 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)); + dstCopy)); if (ss->fPipeline.mustSkip()) { fCmdBuffer.pop_back(); return false; diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index 3d1bd7c43e..bf9237d426 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -233,11 +233,12 @@ private: void onDraw(const GrPipelineBuilder&, const GrGeometryProcessor*, const DrawInfo&, - const GrScissorState&) SK_OVERRIDE; + const GrScissorState&, + const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; void onDrawBatch(GrBatch*, const GrPipelineBuilder&, const GrScissorState&, - const SkRect* devBounds) SK_OVERRIDE; + const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; void onDrawRect(GrPipelineBuilder*, GrColor, const SkMatrix& viewMatrix, @@ -255,7 +256,7 @@ private: const GrPath*, const GrScissorState&, const GrStencilSettings&, - const SkRect* devBounds) SK_OVERRIDE; + const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; void onDrawPaths(const GrPipelineBuilder&, const GrPathProcessor*, const GrPathRange*, @@ -266,7 +267,7 @@ private: int count, const GrScissorState&, const GrStencilSettings&, - const SkRect* devBounds) SK_OVERRIDE; + const GrDeviceCoordTexture*) SK_OVERRIDE; void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, @@ -287,11 +288,11 @@ private: bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(const GrPipelineBuilder&, const GrPrimitiveProcessor*, const GrScissorState&, - const SkRect*); + const GrDeviceCoordTexture*); bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(GrBatch*, const GrPipelineBuilder&, const GrScissorState&, - const SkRect*); + const GrDeviceCoordTexture*); // 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..911169e336 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -48,7 +48,7 @@ void GrPipeline::internalConstructor(const GrPipelineBuilder& pipelineBuilder, const GrDeviceCoordTexture* dstCopy) { // Create XferProcessor from DS's XPFactory SkAutoTUnref<GrXferProcessor> xferProcessor( - pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI, dstCopy, caps)); + pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI)); GrColor overrideColor = GrColor_ILLEGAL; if (colorPOI.firstEffectiveStageIndex() != 0) { @@ -82,6 +82,10 @@ void GrPipeline::internalConstructor(const GrPipelineBuilder& pipelineBuilder, fScissorState = scissorState; fStencilSettings = pipelineBuilder.getStencil(); fDrawFace = pipelineBuilder.getDrawFace(); + // TODO move this out of GrPipeline + if (dstCopy) { + fDstCopy = *dstCopy; + } fFlags = 0; if (pipelineBuilder.isHWAntialias()) { @@ -103,6 +107,8 @@ void GrPipeline::internalConstructor(const GrPipelineBuilder& pipelineBuilder, this->adjustProgramFromOptimizations(pipelineBuilder, optFlags, colorPOI, coveragePOI, &firstColorStageIdx, &firstCoverageStageIdx); + fDescInfo.fReadsDst = fXferProcessor->willReadDstColor(); + bool usesLocalCoords = false; // Copy Stages from PipelineBuilder to Pipeline @@ -136,20 +142,20 @@ void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelin const GrProcOptInfo& coveragePOI, int* firstColorStageIdx, int* firstCoverageStageIdx) { - fReadsFragPosition = false; + fDescInfo.fReadsFragPosition = false; if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) || (flags & GrXferProcessor::kOverrideColor_OptFlag)) { *firstColorStageIdx = pipelineBuilder.numColorStages(); } else { - fReadsFragPosition = colorPOI.readsFragPosition(); + fDescInfo.fReadsFragPosition = colorPOI.readsFragPosition(); } if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) { *firstCoverageStageIdx = pipelineBuilder.numCoverageStages(); } else { if (coveragePOI.readsFragPosition()) { - fReadsFragPosition = true; + fDescInfo.fReadsFragPosition = true; } } } @@ -163,7 +169,8 @@ bool GrPipeline::isEqual(const GrPipeline& that) const { this->fScissorState != that.fScissorState || this->fFlags != that.fFlags || this->fStencilSettings != that.fStencilSettings || - this->fDrawFace != that.fDrawFace) { + this->fDrawFace != that.fDrawFace || + this->fDstCopy.texture() != that.fDstCopy.texture()) { return false; } diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h index 8480c00458..24d0b62795 100644 --- a/src/gpu/GrPipeline.h +++ b/src/gpu/GrPipeline.h @@ -132,7 +132,9 @@ public: /////////////////////////////////////////////////////////////////////////// - bool readsFragPosition() const { return fReadsFragPosition; } + const GrDeviceCoordTexture* getDstCopy() const { return fDstCopy.texture() ? &fDstCopy : NULL; } + + const GrProgramDesc::DescInfo& descInfo() const { return fDescInfo; } const GrPipelineInfo& getInitBatchTracker() const { return fInitBT; } @@ -175,10 +177,11 @@ private: GrScissorState fScissorState; GrStencilSettings fStencilSettings; GrPipelineBuilder::DrawFace fDrawFace; + GrDeviceCoordTexture fDstCopy; uint32_t fFlags; ProgramXferProcessor fXferProcessor; FragmentStageArray fFragmentStages; - bool fReadsFragPosition; + GrProgramDesc::DescInfo fDescInfo; GrPipelineInfo fInitBT; // This function is equivalent to the offset into fFragmentStages where coverage stages begin. diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp index 54d357fd23..90aee748c9 100644 --- a/src/gpu/GrPipelineBuilder.cpp +++ b/src/gpu/GrPipelineBuilder.cpp @@ -101,8 +101,8 @@ bool GrPipelineBuilder::canUseFracCoveragePrimProc(GrColor color, //////////////////////////////////////////////////////////////////////////////s -bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps) const { - return this->getXPFactory()->willNeedDstCopy(caps); +bool GrPipelineBuilder::willEffectReadDstColor() const { + return this->getXPFactory()->willReadDst(); } void GrPipelineBuilder::AutoRestoreEffects::set(GrPipelineBuilder* pipelineBuilder) { diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index 5743c39dc5..df9a1c85ee 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -102,9 +102,10 @@ public: const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; } /** - * Checks whether the xp will need a copy of the destination to correctly blend. + * Checks whether the xp will read the dst pixel color. + * TODO: remove when we have dstCpy contained inside of GrXP */ - bool willXPNeedDstCopy(const GrDrawTargetCaps& caps) const; + bool willEffectReadDstColor() const; /** * The xfer processor factory. diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h index 66e0e06b8c..e07e116733 100644 --- a/src/gpu/GrProgramDesc.h +++ b/src/gpu/GrProgramDesc.h @@ -55,6 +55,9 @@ public: } struct KeyHeader { + uint8_t fDstReadKey; // set by GrGLShaderBuilder if there + // are effects that must read the dst. + // Otherwise, 0. uint8_t fFragPosKey; // set by GrGLShaderBuilder if there are // effects that read the fragment position. // Otherwise, 0. @@ -76,6 +79,20 @@ public: // This should really only be used internally, base classes should return their own headers const KeyHeader& header() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); } + // A struct to communicate descriptor information to the program descriptor builder + struct DescInfo { + bool operator==(const DescInfo& that) const { + return fReadsDst == that.fReadsDst && + fReadsFragPosition == that.fReadsFragPosition; + } + bool operator!=(const DescInfo& that) const { return !(*this == that); }; + + // These flags give aggregated info on the processor stages that are used when building + // programs. + bool fReadsDst; + bool fReadsFragPosition; + }; + private: template<typename T, size_t OFFSET> T* atOffset() { return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET); diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp index 2f32eb5d4a..05a4a5f956 100644 --- a/src/gpu/GrTest.cpp +++ b/src/gpu/GrTest.cpp @@ -142,6 +142,7 @@ public: size_t rowBytes) const SK_OVERRIDE { return false; } void buildProgramDesc(GrProgramDesc*,const GrPrimitiveProcessor&, const GrPipeline&, + const GrProgramDesc::DescInfo&, const GrBatchTracker&) const SK_OVERRIDE {} void discard(GrRenderTarget*) SK_OVERRIDE {} diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp deleted file mode 100644 index 87d5fe65ac..0000000000 --- a/src/gpu/GrXferProcessor.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrXferProcessor.h" -#include "gl/GrGLCaps.h" - -GrXferProcessor::GrXferProcessor() : fWillReadDstColor(false), fDstCopyTextureOffset() { -} - -GrXferProcessor::GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor) - : fWillReadDstColor(willReadDstColor) - , fDstCopyTextureOffset() { - if (dstCopy && dstCopy->texture()) { - fDstCopy.reset(dstCopy->texture()); - fDstCopyTextureOffset = dstCopy->offset(); - SkASSERT(kTopLeft_GrSurfaceOrigin == fDstCopy.getTexture()->origin()); - this->addTextureAccess(&fDstCopy); - } -} - -void GrXferProcessor::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { - uint32_t key = this->willReadDstColor() ? 0x1 : 0x0; - b->add32(key); - this->onGetGLProcessorKey(caps, b); -} - -/////////////////////////////////////////////////////////////////////////////// - -GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - const GrDeviceCoordTexture* dstCopy, - const GrDrawTargetCaps& caps) const { -#ifdef SK_DEBUG - if (this->willReadDstColor()) { - if (!caps.dstReadInShaderSupport()) { - SkASSERT(dstCopy && dstCopy->texture()); - } else { - SkASSERT(!dstCopy || !dstCopy->texture()); - } - } else { - SkASSERT(!dstCopy || !dstCopy->texture()); - - } -#endif - return this->onCreateXferProcessor(colorPOI, coveragePOI, dstCopy); -} - -bool GrXPFactory::willNeedDstCopy(const GrDrawTargetCaps& caps) const { - return (this->willReadDstColor() && !caps.dstReadInShaderSupport()); -} - diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp index 7025d20395..fe286f6bf5 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.cpp +++ b/src/gpu/effects/GrCoverageSetOpXP.cpp @@ -21,15 +21,7 @@ public: ~GrGLCoverageSetOpXP() SK_OVERRIDE {} - static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, - GrProcessorKeyBuilder* b) { - const GrCoverageSetOpXP& xp = processor.cast<GrCoverageSetOpXP>(); - uint32_t key = xp.invertCoverage() ? 0x0 : 0x1; - b->add32(key); - }; - -private: - void onEmitCode(const EmitArgs& args) SK_OVERRIDE { + void emitCode(const EmitArgs& args) SK_OVERRIDE { const GrCoverageSetOpXP& xp = args.fXP.cast<GrCoverageSetOpXP>(); GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); @@ -40,8 +32,16 @@ private: } } - void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}; + void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}; + static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, + GrProcessorKeyBuilder* b) { + const GrCoverageSetOpXP& xp = processor.cast<GrCoverageSetOpXP>(); + uint32_t key = xp.invertCoverage() ? 0x0 : 0x1; + b->add32(key); + }; + +private: typedef GrGLXferProcessor INHERITED; }; @@ -56,7 +56,7 @@ GrCoverageSetOpXP::GrCoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage) GrCoverageSetOpXP::~GrCoverageSetOpXP() { } -void GrCoverageSetOpXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { +void GrCoverageSetOpXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { GrGLCoverageSetOpXP::GenKey(*this, caps, b); } @@ -179,10 +179,8 @@ GrXPFactory* GrCoverageSetOpXPFactory::Create(SkRegion::Op regionOp, bool invert } } -GrXferProcessor* -GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& covPOI, - const GrDeviceCoordTexture* dstCopy) const { +GrXferProcessor* GrCoverageSetOpXPFactory::createXferProcessor(const GrProcOptInfo& /* colorPOI*/, + const GrProcOptInfo& covPOI) const { return GrCoverageSetOpXP::Create(fRegionOp, fInvertCoverage); } diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h index 0bc9e91170..a144f975b7 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.h +++ b/src/gpu/effects/GrCoverageSetOpXP.h @@ -29,6 +29,8 @@ public: const char* name() const SK_OVERRIDE { return "Coverage Set Op"; } + void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; bool hasSecondaryOutput() const SK_OVERRIDE { return false; } @@ -46,8 +48,6 @@ public: private: GrCoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage); - void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { const GrCoverageSetOpXP& xp = xpBase.cast<GrCoverageSetOpXP>(); return (fRegionOp == xp.fRegionOp && @@ -66,6 +66,9 @@ class GrCoverageSetOpXPFactory : public GrXPFactory { public: static GrXPFactory* Create(SkRegion::Op regionOp, bool invertCoverage = false); + GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const SK_OVERRIDE; + bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE { return true; } @@ -80,15 +83,11 @@ public: void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, GrXPFactory::InvariantOutput*) const SK_OVERRIDE; + bool willReadDst() const SK_OVERRIDE { return false; } + private: GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage); - GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; - - bool willReadDstColor() const SK_OVERRIDE { return false; } - bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE { const GrCoverageSetOpXPFactory& xpf = xpfBase.cast<GrCoverageSetOpXPFactory>(); return fRegionOp == xpf.fRegionOp; diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index b77bf2fad1..9aa7153109 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -499,15 +499,7 @@ public: GLCustomXP(const GrXferProcessor&) {} ~GLCustomXP() SK_OVERRIDE {} - static void GenKey(const GrXferProcessor& proc, const GrGLCaps&, GrProcessorKeyBuilder* b) { - uint32_t key = proc.numTextures(); - SkASSERT(key <= 1); - key |= proc.cast<GrCustomXP>().mode() << 1; - b->add32(key); - } - -private: - void onEmitCode(const EmitArgs& args) SK_OVERRIDE { + void emitCode(const EmitArgs& args) SK_OVERRIDE { SkXfermode::Mode mode = args.fXP.cast<GrCustomXP>().mode(); GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); const char* dstColor = fsBuilder->dstColor(); @@ -519,20 +511,28 @@ private: args.fInputCoverage, dstColor); } - void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {} + void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {} + static void GenKey(const GrXferProcessor& proc, const GrGLCaps&, GrProcessorKeyBuilder* b) { + uint32_t key = proc.numTextures(); + SkASSERT(key <= 1); + key |= proc.cast<GrCustomXP>().mode() << 1; + b->add32(key); + } + +private: typedef GrGLFragmentProcessor INHERITED; }; /////////////////////////////////////////////////////////////////////////////// -GrCustomXP::GrCustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, - bool willReadDstColor) - : INHERITED(dstCopy, willReadDstColor), fMode(mode) { +GrCustomXP::GrCustomXP(SkXfermode::Mode mode) + : fMode(mode) { this->initClassID<GrCustomXP>(); + this->setWillReadDstColor(); } -void GrCustomXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { +void GrCustomXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { GLCustomXP::GenKey(*this, caps, b); } diff --git a/src/gpu/effects/GrCustomXfermodePriv.h b/src/gpu/effects/GrCustomXfermodePriv.h index 681c805ba7..45a9d3005d 100644 --- a/src/gpu/effects/GrCustomXfermodePriv.h +++ b/src/gpu/effects/GrCustomXfermodePriv.h @@ -9,7 +9,6 @@ #define GrCustomXfermodePriv_DEFINED #include "GrCoordTransform.h" -#include "GrDrawTargetCaps.h" #include "GrFragmentProcessor.h" #include "GrTextureAccess.h" #include "GrXferProcessor.h" @@ -58,12 +57,11 @@ private: class GrCustomXP : public GrXferProcessor { public: - static GrXferProcessor* Create(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, - bool willReadDstColor) { + static GrXferProcessor* Create(SkXfermode::Mode mode) { if (!GrCustomXfermode::IsSupportedMode(mode)) { return NULL; } else { - return SkNEW_ARGS(GrCustomXP, (mode, dstCopy, willReadDstColor)); + return SkNEW_ARGS(GrCustomXP, (mode)); } } @@ -71,6 +69,8 @@ public: const char* name() const SK_OVERRIDE { return "Custom Xfermode"; } + void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; bool hasSecondaryOutput() const SK_OVERRIDE { return false; } @@ -90,9 +90,7 @@ public: SkXfermode::Mode mode() const { return fMode; } private: - GrCustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); - - void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + GrCustomXP(SkXfermode::Mode mode); bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE; @@ -107,6 +105,11 @@ class GrCustomXPFactory : public GrXPFactory { public: GrCustomXPFactory(SkXfermode::Mode mode); + GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const SK_OVERRIDE { + return GrCustomXP::Create(fMode); + } + bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE { return true; } @@ -123,15 +126,9 @@ public: void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, GrXPFactory::InvariantOutput*) const SK_OVERRIDE; -private: - GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE { - return GrCustomXP::Create(fMode, dstCopy, this->willReadDstColor()); - } - - bool willReadDstColor() const SK_OVERRIDE { return true; } + bool willReadDst() const SK_OVERRIDE { return true; } +private: bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE { const GrCustomXPFactory& xpf = xpfBase.cast<GrCustomXPFactory>(); return fMode == xpf.fMode; diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp index 83b6d23119..9383385192 100644 --- a/src/gpu/effects/GrDisableColorXP.cpp +++ b/src/gpu/effects/GrDisableColorXP.cpp @@ -17,10 +17,7 @@ public: ~GrGLDisableColorXP() SK_OVERRIDE {} - static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {} - -private: - void onEmitCode(const EmitArgs& args) SK_OVERRIDE { + void emitCode(const EmitArgs& args) SK_OVERRIDE { // This emit code should be empty. However, on the nexus 6 there is a driver bug where if // you do not give gl_FragColor a value, the gl context is lost and we end up drawing // nothing. So this fix just sets the gl_FragColor arbitrarily to 0. @@ -28,8 +25,11 @@ private: fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); } - void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {} + void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {} + static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {} + +private: typedef GrGLXferProcessor INHERITED; }; @@ -39,7 +39,7 @@ GrDisableColorXP::GrDisableColorXP() { this->initClassID<GrDisableColorXP>(); } -void GrDisableColorXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { +void GrDisableColorXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const { GrGLDisableColorXP::GenKey(*this, caps, b); } @@ -57,10 +57,8 @@ GrDisableColorXPFactory::GrDisableColorXPFactory() { this->initClassID<GrDisableColorXPFactory>(); } -GrXferProcessor* -GrDisableColorXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& covPOI, - const GrDeviceCoordTexture* dstCopy) const { +GrXferProcessor* GrDisableColorXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& covPOI) const { return GrDisableColorXP::Create(); } diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index da6fa4523b..d62c3201dd 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -27,6 +27,8 @@ public: const char* name() const SK_OVERRIDE { return "Disable Color"; } + void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; + GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; bool hasSecondaryOutput() const SK_OVERRIDE { return false; } @@ -44,8 +46,6 @@ public: private: GrDisableColorXP(); - void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE; - bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { return true; } @@ -61,6 +61,9 @@ public: return SkNEW(GrDisableColorXPFactory); } + GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const SK_OVERRIDE; + bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE { return true; } @@ -78,15 +81,11 @@ public: output->fWillBlendWithDst = 0; } + bool willReadDst() const SK_OVERRIDE { return false; } + private: GrDisableColorXPFactory(); - GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; - - bool willReadDstColor() 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 320d943392..5038aa333f 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -38,15 +38,7 @@ public: virtual ~GrGLPorterDuffXferProcessor() {} - static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, - GrProcessorKeyBuilder* b) { - const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>(); - b->add32(xp.primaryOutputType()); - b->add32(xp.secondaryOutputType()); - }; - -private: - void onEmitCode(const EmitArgs& args) SK_OVERRIDE { + void emitCode(const EmitArgs& args) SK_OVERRIDE { const GrPorterDuffXferProcessor& xp = args.fXP.cast<GrPorterDuffXferProcessor>(); GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); if (xp.hasSecondaryOutput()) { @@ -88,18 +80,23 @@ private: } } - void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}; + void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}; + static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, + GrProcessorKeyBuilder* b) { + const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>(); + b->add32(xp.primaryOutputType()); + b->add32(xp.secondaryOutputType()); + }; + +private: typedef GrGLXferProcessor INHERITED; }; /////////////////////////////////////////////////////////////////////////////// -GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, - GrBlendCoeff dstBlend, - GrColor constant, - const GrDeviceCoordTexture* dstCopy, - bool willReadDstColor) +GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, + GrColor constant) : fSrcBlend(srcBlend) , fDstBlend(dstBlend) , fBlendConstant(constant) @@ -111,8 +108,8 @@ GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrPorterDuffXferProcessor::~GrPorterDuffXferProcessor() { } -void GrPorterDuffXferProcessor::onGetGLProcessorKey(const GrGLCaps& caps, - GrProcessorKeyBuilder* b) const { +void GrPorterDuffXferProcessor::getGLProcessorKey(const GrGLCaps& caps, + GrProcessorKeyBuilder* b) const { GrGLPorterDuffXferProcessor::GenKey(*this, caps, b); } @@ -356,20 +353,16 @@ GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) { } } -GrXferProcessor* -GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& covPOI, - const GrDeviceCoordTexture* dstCopy) const { +GrXferProcessor* GrPorterDuffXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& covPOI) const { if (!covPOI.isFourChannelOutput()) { - return GrPorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, - this->willReadDstColor()); + return GrPorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff); } else { if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); return GrPorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_GrBlendCoeff, - blendConstant, dstCopy, - this->willReadDstColor()); + blendConstant); } else { return NULL; } @@ -491,10 +484,6 @@ void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, output->fWillBlendWithDst = false; } -bool GrPorterDuffXPFactory::willReadDstColor() const { - return false; -} - GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 6419aa6b52..dd55abb0a6 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -1451,8 +1451,10 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, void GrGLGpu::buildProgramDesc(GrProgramDesc* desc, const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, + const GrProgramDesc::DescInfo& descInfo, const GrBatchTracker& batchTracker) const { - if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, this, batchTracker)) { + if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, descInfo, this, + batchTracker)) { SkDEBUGFAIL("Failed to generate GL program descriptor"); } } diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 18f0f749c4..7eda014344 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -108,6 +108,7 @@ public: void buildProgramDesc(GrProgramDesc*, const GrPrimitiveProcessor&, const GrPipeline&, + const GrProgramDesc::DescInfo&, const GrBatchTracker&) const SK_OVERRIDE; private: diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index eebcf6b2f3..ad63dc4ea7 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -61,6 +61,10 @@ void GrGLProgram::abandon() { void GrGLProgram::initSamplerUniforms() { GL_CALL(UseProgram(fProgramID)); GrGLint texUnitIdx = 0; + if (fBuiltinUniformHandles.fDstCopySamplerUni.isValid()) { + fProgramDataManager.setSampler(fBuiltinUniformHandles.fDstCopySamplerUni, texUnitIdx); + fDstCopyTexUnit = texUnitIdx++; + } this->initSamplers(fGeometryProcessor.get(), &texUnitIdx); if (fXferProcessor.get()) { this->initSamplers(fXferProcessor.get(), &texUnitIdx); @@ -103,15 +107,38 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline const GrBatchTracker& batchTracker) { this->setRenderTargetState(primProc, pipeline); + const GrDeviceCoordTexture* dstCopy = pipeline.getDstCopy(); + if (dstCopy) { + if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) { + fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyTopLeftUni, + static_cast<GrGLfloat>(dstCopy->offset().fX), + static_cast<GrGLfloat>(dstCopy->offset().fY)); + fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyScaleUni, + 1.f / dstCopy->texture()->width(), + 1.f / dstCopy->texture()->height()); + GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()); + static GrTextureParams kParams; // the default is clamp, nearest filtering. + fGpu->bindTexture(fDstCopyTexUnit, kParams, texture); + } else { + SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid()); + SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid()); + } + } else { + SkASSERT(!fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()); + SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid()); + SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid()); + } + // we set the textures, and uniforms for installed processors in a generic way, but subclasses // of GLProgram determine how to set coord transforms fGeometryProcessor->fGLProc->setData(fProgramDataManager, primProc, batchTracker); this->bindTextures(fGeometryProcessor.get(), primProc); - const GrXferProcessor& xp = *pipeline.getXferProcessor(); - fXferProcessor->fGLProc->setData(fProgramDataManager, xp); - this->bindTextures(fXferProcessor.get(), xp); - + if (fXferProcessor.get()) { + const GrXferProcessor& xp = *pipeline.getXferProcessor(); + fXferProcessor->fGLProc->setData(fProgramDataManager, xp); + this->bindTextures(fXferProcessor.get(), xp); + } this->setFragmentData(primProc, pipeline); // Some of GrGLProgram subclasses need to update state here diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index abe2439495..32f831e84c 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -89,6 +89,7 @@ static bool get_meta_key(const GrProcessor& proc, bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc, const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, + const GrProgramDesc::DescInfo& descInfo, const GrGLGpu* gpu, const GrBatchTracker& batchTracker) { // The descriptor is used as a cache key. Thus when a field of the @@ -134,7 +135,21 @@ bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc, // make sure any padding in the header is zeroed. memset(header, 0, kHeaderSize); - if (pipeline.readsFragPosition()) { + if (descInfo.fReadsDst) { + const GrDeviceCoordTexture* dstCopy = pipeline.getDstCopy(); + SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); + const GrTexture* dstCopyTexture = NULL; + if (dstCopy) { + dstCopyTexture = dstCopy->texture(); + } + header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture, + gpu->glCaps()); + SkASSERT(0 != header->fDstReadKey); + } else { + header->fDstReadKey = 0; + } + + if (descInfo.fReadsFragPosition) { header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(pipeline.getRenderTarget(), gpu->glCaps()); diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h index f2371556bf..e4db4c3581 100644 --- a/src/gpu/gl/GrGLProgramDesc.h +++ b/src/gpu/gl/GrGLProgramDesc.h @@ -47,6 +47,8 @@ public: * general draw information, as well as the specific color, geometry, * and coverage stages which will be used to generate the GL Program for * this optstate. + * @param DescInfo A descriptor info struct, generated by the optstate, which contains a number + * of important facts about the program the built descriptor will represent * @param GrGLGpu A GL Gpu, the caps and Gpu object are used to output processor specific * parts of the descriptor. * @param GrDeviceCoordTexture A dstCopy texture, which may be null if frame buffer fetch is @@ -56,6 +58,7 @@ public: static bool Build(GrProgramDesc*, const GrPrimitiveProcessor&, const GrPipeline&, + const GrProgramDesc::DescInfo&, const GrGLGpu*, const GrBatchTracker&); }; diff --git a/src/gpu/gl/GrGLXferProcessor.cpp b/src/gpu/gl/GrGLXferProcessor.cpp deleted file mode 100644 index 5e8c00a976..0000000000 --- a/src/gpu/gl/GrGLXferProcessor.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "gl/GrGLXferProcessor.h" - -#include "GrXferProcessor.h" -#include "gl/builders/GrGLFragmentShaderBuilder.h" -#include "gl/builders/GrGLProgramBuilder.h" - -void GrGLXferProcessor::emitCode(const EmitArgs& args) { - if (args.fXP.getDstCopyTexture()) { - GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); - const char* dstColor = fsBuilder->dstColor(); - - const char* dstCopyTopLeftName; - const char* dstCopyCoordScaleName; - - fDstCopyTopLeftUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, - kVec2f_GrSLType, - kDefault_GrSLPrecision, - "DstCopyUpperLeft", - &dstCopyTopLeftName); - fDstCopyScaleUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, - kVec2f_GrSLType, - kDefault_GrSLPrecision, - "DstCopyCoordScale", - &dstCopyCoordScaleName); - const char* fragPos = fsBuilder->fragmentPosition(); - - fsBuilder->codeAppend("// Read color from copy of the destination.\n"); - fsBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;", - fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); - fsBuilder->codeAppendf("vec4 %s = ", dstColor); - fsBuilder->appendTextureLookup(args.fSamplers[0], "_dstTexCoord", kVec2f_GrSLType); - fsBuilder->codeAppend(";"); - } - - this->onEmitCode(args); -} - -void GrGLXferProcessor::setData(const GrGLProgramDataManager& pdm, const GrXferProcessor& xp) { - if (xp.getDstCopyTexture()) { - if (fDstCopyTopLeftUni.isValid()) { - pdm.set2f(fDstCopyTopLeftUni, static_cast<GrGLfloat>(xp.dstCopyTextureOffset().fX), - static_cast<GrGLfloat>(xp.dstCopyTextureOffset().fY)); - pdm.set2f(fDstCopyScaleUni, 1.f / xp.getDstCopyTexture()->width(), - 1.f / xp.getDstCopyTexture()->height()); - } else { - SkASSERT(!fDstCopyScaleUni.isValid()); - } - } else { - SkASSERT(!fDstCopyTopLeftUni.isValid()); - SkASSERT(!fDstCopyScaleUni.isValid()); - } - this->onSetData(pdm, xp); -} - diff --git a/src/gpu/gl/GrGLXferProcessor.h b/src/gpu/gl/GrGLXferProcessor.h index 7f60f32fe5..5c92559031 100644 --- a/src/gpu/gl/GrGLXferProcessor.h +++ b/src/gpu/gl/GrGLXferProcessor.h @@ -11,7 +11,6 @@ #include "GrGLProcessor.h" class GrGLXPBuilder; -class GrXferProcessor; class GrGLXferProcessor { public: @@ -47,25 +46,16 @@ public: * This is similar to emitCode() in the base class, except it takes a full shader builder. * This allows the effect subclass to emit vertex code. */ - void emitCode(const EmitArgs&); + virtual void emitCode(const EmitArgs&) = 0; /** A GrGLXferProcessor instance can be reused with any GrGLXferProcessor that produces the same stage key; this function reads data from a GrGLXferProcessor and uploads any uniform variables required by the shaders created in emitCode(). The GrXferProcessor parameter is guaranteed to be of the same type that created this GrGLXferProcessor and - to have an identical processor key as the one that created this GrGLXferProcessor. This - function calls onSetData on the subclass of GrGLXferProcessor - */ - void setData(const GrGLProgramDataManager& pdm, const GrXferProcessor& xp); - + to have an identical processor key as the one that created this GrGLXferProcessor. */ + virtual void setData(const GrGLProgramDataManager&, + const GrXferProcessor&) = 0; private: - virtual void onEmitCode(const EmitArgs&) = 0; - - virtual void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) = 0; - - GrGLProgramDataManager::UniformHandle fDstCopyTopLeftUni; - GrGLProgramDataManager::UniformHandle fDstCopyScaleUni; - typedef GrGLProcessor INHERITED; }; #endif diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp index 86c622d456..61932f3084 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp @@ -179,9 +179,56 @@ const char* GrGLFragmentShaderBuilder::dstColor() { fbFetchColorName = declared_color_output_name(); } return fbFetchColorName; - } else { + } else if (fProgramBuilder->fUniformHandles.fDstCopySamplerUni.isValid()) { return kDstCopyColorName; - } + } else { + return ""; + } +} + +void GrGLFragmentShaderBuilder::emitCodeToReadDstTexture() { + bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & fProgramBuilder->header().fDstReadKey); + const char* dstCopyTopLeftName; + const char* dstCopyCoordScaleName; + const char* dstCopySamplerName; + uint32_t configMask; + if (SkToBool(kUseAlphaConfig_DstReadKeyBit & fProgramBuilder->header().fDstReadKey)) { + configMask = kA_GrColorComponentFlag; + } else { + configMask = kRGBA_GrColorComponentFlags; + } + fProgramBuilder->fUniformHandles.fDstCopySamplerUni = + fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, + kSampler2D_GrSLType, + kDefault_GrSLPrecision, + "DstCopySampler", + &dstCopySamplerName); + fProgramBuilder->fUniformHandles.fDstCopyTopLeftUni = + fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, + kVec2f_GrSLType, + kDefault_GrSLPrecision, + "DstCopyUpperLeft", + &dstCopyTopLeftName); + fProgramBuilder->fUniformHandles.fDstCopyScaleUni = + fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, + kVec2f_GrSLType, + kDefault_GrSLPrecision, + "DstCopyCoordScale", + &dstCopyCoordScaleName); + const char* fragPos = this->fragmentPosition(); + + this->codeAppend("// Read color from copy of the destination.\n"); + this->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;", + fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); + if (!topDown) { + this->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;"); + } + this->codeAppendf("vec4 %s = ", GrGLFragmentShaderBuilder::kDstCopyColorName); + this->appendTextureLookup(dstCopySamplerName, + "_dstTexCoord", + configMask, + "rgba"); + this->codeAppend(";"); } void GrGLFragmentShaderBuilder::enableCustomOutput() { diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index 903c5e1d7b..688bbe6269 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -97,6 +97,7 @@ public: private: // Private public interface, used by GrGLProgramBuilder to build a fragment shader + void emitCodeToReadDstTexture(); void enableCustomOutput(); void enableSecondaryOutput(); const char* getPrimaryColorOutputName() const; diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index bb278be395..088169622c 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -56,6 +56,12 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp GrGLProgramBuilder* pb = builder.get(); + // emit code to read the dst copy texture, if necessary + if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != pb->header().fDstReadKey && + !gpu->glCaps().fbFetchSupport()) { + pb->fFS.emitCodeToReadDstTexture(); + } + // TODO: Once all stages can handle taking a float or vec4 and correctly handling them we can // seed correctly here GrGLSLExpr4 inputColor; diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index a9288cc9b0..4b40cefad0 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -267,6 +267,11 @@ public: // We use the render target height to provide a y-down frag coord when specifying // origin_upper_left is not supported. UniformHandle fRTHeightUni; + + // Uniforms for computing texture coords to do the dst-copy lookup + UniformHandle fDstCopyTopLeftUni; + UniformHandle fDstCopyScaleUni; + UniformHandle fDstCopySamplerUni; }; protected: |