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
This commit is contained in:
bsalomon@google.com 2013-05-13 18:50:25 +00:00
parent 8686be2fc3
commit b515881446
7 changed files with 63 additions and 28 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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->fDstRead = 0;
desc->fDstReadKey = 0;
}
if (readFragPosition) {
desc->fFragPosKey = GrGLShaderBuilder::KeyForFragmentPosition(drawState.getRenderTarget(),
gpu->glCaps());
} else {
desc->fFragPosKey = 0;
}
desc->fCoverageOutput = kModulate_CoverageOutput;

View File

@ -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;

View File

@ -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
}

View File

@ -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;

View File

@ -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;