diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrDrawState.h | 2 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 17 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.h | 7 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 43 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.h | 16 |
6 files changed, 62 insertions, 27 deletions
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 91a8723e52..230b2faa47 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -451,7 +451,7 @@ public: /** * Checks whether any of the effects will read the dst pixel color. */ - bool willEffectReadDst() const { + bool willEffectReadDstColor() const { for (int s = 0; s < kNumStages; ++s) { if (this->isStageEnabled(s) && (*this->getStage(s).getEffect())->willReadDstColor()) { return true; diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 7268015720..aa475b3ee6 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -407,7 +407,7 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, } bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) { - if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDst()) { + if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDstColor()) { return true; } GrRenderTarget* rt = this->drawState()->getRenderTarget(); @@ -639,7 +639,7 @@ void GrDrawTarget::onDrawRect(const GrRect& rect, } } SkTLazy<SkRect> bounds; - if (this->getDrawState().willEffectReadDst()) { + if (this->getDrawState().willEffectReadDstColor()) { bounds.init(); this->getDrawState().getViewMatrix().mapRect(bounds.get(), rect); } diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index a1cd85e9f4..532923a19c 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -76,6 +76,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState, } bool readsDst = false; + bool readFragPosition = false; int lastEnabledStage = -1; for (int s = 0; s < GrDrawState::kNumStages; ++s) { @@ -90,6 +91,9 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState, if (effect->willReadDstColor()) { readsDst = true; } + if (effect->willReadFragmentPosition()) { + readFragPosition = true; + } } else { desc->fEffectKeys[s] = 0; } @@ -101,10 +105,17 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState, if (NULL != dstCopy) { dstCopyTexture = dstCopy->texture(); } - desc->fDstRead = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps()); - GrAssert(0 != desc->fDstRead); + desc->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps()); + GrAssert(0 != desc->fDstReadKey); + } else { + desc->fDstReadKey = 0; + } + + if (readFragPosition) { + desc->fFragPosKey = GrGLShaderBuilder::KeyForFragmentPosition(drawState.getRenderTarget(), + gpu->glCaps()); } else { - desc->fDstRead = 0; + desc->fFragPosKey = 0; } desc->fCoverageOutput = kModulate_CoverageOutput; diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h index 45714a0dc6..b49cb722c0 100644 --- a/src/gpu/gl/GrGLProgramDesc.h +++ b/src/gpu/gl/GrGLProgramDesc.h @@ -79,7 +79,7 @@ private: // (1 - colorRGB) as the secondary output. Only set if dual source blending is supported. kSecondaryCoverageISC_CoverageOutput, // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This - // can only be set if fDstRead is set. + // can only be set if fDstReadKey is non-zero. kCombineWithDst_CoverageOutput, kCoverageOutputCnt @@ -105,9 +105,12 @@ private: bool fExperimentalGS; #endif - GrGLShaderBuilder::DstReadKey fDstRead; // set by GrGLShaderBuilder if there + GrGLShaderBuilder::DstReadKey fDstReadKey; // set by GrGLShaderBuilder if there // are effects that must read the dst. // Otherwise, 0. + GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuilder if there are + // effects that read the fragment position. + // Otherwise, 0. // should the FS discard if the coverage is zero (to avoid stencil manipulation) SkBool8 fDiscardIfZeroCoverage; diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 98d7e4c97e..ddcc61574c 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -112,7 +112,8 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, , fSetupFragPosition(false) , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) , fDstCopyTopLeftUniform (GrGLUniformManager::kInvalidUniformHandle) - , fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle) { + , fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle) + , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.fFragPosKey) { fPositionVar = &fVSAttrs.push_back(); fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); @@ -125,13 +126,13 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, fLocalCoordsVar = fPositionVar; } // Emit code to read the dst copy textue if necessary. - if (kNoDstRead_DstReadKey != desc.fDstRead && + if (kNoDstRead_DstReadKey != desc.fDstReadKey && GrGLCaps::kNone_FBFetchType == ctxInfo.caps()->fbFetchType()) { - bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & desc.fDstRead); + bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & desc.fDstReadKey); const char* dstCopyTopLeftName; const char* dstCopyCoordScaleName; uint32_t configMask; - if (SkToBool(kUseAlphaConfig_DstReadKeyBit & desc.fDstRead)) { + if (SkToBool(kUseAlphaConfig_DstReadKeyBit & desc.fDstReadKey)) { configMask = kA_GrColorComponentFlag; } else { configMask = kRGBA_GrColorComponentFlags; @@ -351,6 +352,16 @@ GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* return static_cast<DstReadKey>(key); } +GrGLShaderBuilder::FragPosKey GrGLShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst, + const GrGLCaps&) { + if (kTopLeft_GrSurfaceOrigin == dst->origin()) { + return kTopLeftFragPosRead_FragPosKey; + } else { + return kBottomLeftFragPosRead_FragPosKey; + } +} + + const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) { if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) { if (caps.textureRedSupport()) { @@ -473,8 +484,16 @@ const char* GrGLShaderBuilder::fragmentPosition() { return ""; } } -#if 1 - if (fCtxInfo.caps()->fragCoordConventionsSupport()) { + if (fTopLeftFragPosRead) { + if (!fSetupFragPosition) { + fFSInputs.push_back().set(kVec4f_GrSLType, + GrGLShaderVar::kIn_TypeModifier, + "gl_FragCoord", + GrGLShaderVar::kDefault_Precision); + fSetupFragPosition = true; + } + return "gl_FragCoord"; + } else if (fCtxInfo.caps()->fragCoordConventionsSupport()) { if (!fSetupFragPosition) { SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature)); fFSInputs.push_back().set(kVec4f_GrSLType, @@ -506,18 +525,6 @@ const char* GrGLShaderBuilder::fragmentPosition() { GrAssert(GrGLUniformManager::kInvalidUniformHandle != fRTHeightUniform); return kCoordName; } -#else - // This is the path we'll need to use once we have support for TopLeft - // render targets. - if (!fSetupFragPosition) { - fFSInputs.push_back().set(kVec4f_GrSLType, - GrGLShaderVar::kIn_TypeModifier, - "gl_FragCoord", - GrGLShaderVar::kDefault_Precision); - fSetupFragPosition = true; - } - return "gl_FragCoord"; -#endif } diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 6e990aad01..b67846a621 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -193,12 +193,18 @@ public: const GrGLCaps&); typedef uint8_t DstReadKey; + typedef uint8_t FragPosKey; /** Returns a key for adding code to read the copy-of-dst color in service of effects that require reading the dst. It must not return 0 because 0 indicates that there is no dst - copy read at all. */ + copy read at all (in which case this function should not be called). */ static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&); + /** Returns a key for reading the fragment location. This should only be called if there is an + effect that will requires the fragment position. If the fragment position is not required, + the key is 0. */ + static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&); + /** If texture swizzling is available using tex parameters then it is preferred over mangling the generated shader code. This potentially allows greater reuse of cached shaders. */ static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps); @@ -424,6 +430,12 @@ private: kTopLeftOrigin_DstReadKeyBit = 0x4, // Set if dst-copy origin is top-left. }; + enum { + kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed. + kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left. + kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left. + }; + const GrGLContextInfo& fCtxInfo; GrGLUniformManager& fUniformManager; uint32_t fFSFeaturesAddedMask; @@ -443,6 +455,8 @@ private: GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform; GrGLUniformManager::UniformHandle fDstCopyScaleUniform; + bool fTopLeftFragPosRead; + SkSTArray<10, AttributePair, true> fEffectAttributes; GrGLShaderVar* fPositionVar; |