aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-13 18:50:25 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-13 18:50:25 +0000
commitb515881446c303a50d9b2dd38b9163b4e5c625a2 (patch)
tree6e4ccafe63cc8b22cde839fc13011a2f7cb89ff4
parent8686be2fc30528167df99bcfc98ed3d9d88a76d4 (diff)
Key shader on whether frag pos read is relative to top-left or bottom-left
R=robertphillips@google.com Review URL: https://codereview.chromium.org/14633007 git-svn-id: http://skia.googlecode.com/svn/trunk@9113 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/gpu/GrDrawState.h2
-rw-r--r--src/gpu/GrDrawTarget.cpp4
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp17
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h7
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp43
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h16
-rw-r--r--tests/GLProgramsTest.cpp2
7 files changed, 63 insertions, 28 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;
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index d996cd7402..73d6db2f46 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -70,7 +70,7 @@ void GrGLProgramDesc::setRandom(SkMWCRandom* random,
}
if (dstRead) {
- this->fDstRead = GrGLShaderBuilder::KeyForDstRead(dstTexture, gpu->glCaps());
+ this->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstTexture, gpu->glCaps());
}
CoverageOutput coverageOutput;