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:
parent
8686be2fc3
commit
b515881446
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user