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.
|
* 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) {
|
for (int s = 0; s < kNumStages; ++s) {
|
||||||
if (this->isStageEnabled(s) && (*this->getStage(s).getEffect())->willReadDstColor()) {
|
if (this->isStageEnabled(s) && (*this->getStage(s).getEffect())->willReadDstColor()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -407,7 +407,7 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) {
|
bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) {
|
||||||
if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDst()) {
|
if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDstColor()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
GrRenderTarget* rt = this->drawState()->getRenderTarget();
|
GrRenderTarget* rt = this->drawState()->getRenderTarget();
|
||||||
@ -639,7 +639,7 @@ void GrDrawTarget::onDrawRect(const GrRect& rect,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SkTLazy<SkRect> bounds;
|
SkTLazy<SkRect> bounds;
|
||||||
if (this->getDrawState().willEffectReadDst()) {
|
if (this->getDrawState().willEffectReadDstColor()) {
|
||||||
bounds.init();
|
bounds.init();
|
||||||
this->getDrawState().getViewMatrix().mapRect(bounds.get(), rect);
|
this->getDrawState().getViewMatrix().mapRect(bounds.get(), rect);
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool readsDst = false;
|
bool readsDst = false;
|
||||||
|
bool readFragPosition = false;
|
||||||
int lastEnabledStage = -1;
|
int lastEnabledStage = -1;
|
||||||
|
|
||||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||||
@ -90,6 +91,9 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
if (effect->willReadDstColor()) {
|
if (effect->willReadDstColor()) {
|
||||||
readsDst = true;
|
readsDst = true;
|
||||||
}
|
}
|
||||||
|
if (effect->willReadFragmentPosition()) {
|
||||||
|
readFragPosition = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
desc->fEffectKeys[s] = 0;
|
desc->fEffectKeys[s] = 0;
|
||||||
}
|
}
|
||||||
@ -101,10 +105,17 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
if (NULL != dstCopy) {
|
if (NULL != dstCopy) {
|
||||||
dstCopyTexture = dstCopy->texture();
|
dstCopyTexture = dstCopy->texture();
|
||||||
}
|
}
|
||||||
desc->fDstRead = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps());
|
desc->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps());
|
||||||
GrAssert(0 != desc->fDstRead);
|
GrAssert(0 != desc->fDstReadKey);
|
||||||
} else {
|
} 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;
|
desc->fCoverageOutput = kModulate_CoverageOutput;
|
||||||
|
@ -79,7 +79,7 @@ private:
|
|||||||
// (1 - colorRGB) as the secondary output. Only set if dual source blending is supported.
|
// (1 - colorRGB) as the secondary output. Only set if dual source blending is supported.
|
||||||
kSecondaryCoverageISC_CoverageOutput,
|
kSecondaryCoverageISC_CoverageOutput,
|
||||||
// Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
|
// 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,
|
kCombineWithDst_CoverageOutput,
|
||||||
|
|
||||||
kCoverageOutputCnt
|
kCoverageOutputCnt
|
||||||
@ -105,9 +105,12 @@ private:
|
|||||||
bool fExperimentalGS;
|
bool fExperimentalGS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GrGLShaderBuilder::DstReadKey fDstRead; // set by GrGLShaderBuilder if there
|
GrGLShaderBuilder::DstReadKey fDstReadKey; // set by GrGLShaderBuilder if there
|
||||||
// are effects that must read the dst.
|
// are effects that must read the dst.
|
||||||
// Otherwise, 0.
|
// 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)
|
// should the FS discard if the coverage is zero (to avoid stencil manipulation)
|
||||||
SkBool8 fDiscardIfZeroCoverage;
|
SkBool8 fDiscardIfZeroCoverage;
|
||||||
|
@ -112,7 +112,8 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
|
|||||||
, fSetupFragPosition(false)
|
, fSetupFragPosition(false)
|
||||||
, fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle)
|
, fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle)
|
||||||
, fDstCopyTopLeftUniform (GrGLUniformManager::kInvalidUniformHandle)
|
, fDstCopyTopLeftUniform (GrGLUniformManager::kInvalidUniformHandle)
|
||||||
, fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle) {
|
, fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle)
|
||||||
|
, fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.fFragPosKey) {
|
||||||
|
|
||||||
fPositionVar = &fVSAttrs.push_back();
|
fPositionVar = &fVSAttrs.push_back();
|
||||||
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
|
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
|
||||||
@ -125,13 +126,13 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
|
|||||||
fLocalCoordsVar = fPositionVar;
|
fLocalCoordsVar = fPositionVar;
|
||||||
}
|
}
|
||||||
// Emit code to read the dst copy textue if necessary.
|
// 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()) {
|
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* dstCopyTopLeftName;
|
||||||
const char* dstCopyCoordScaleName;
|
const char* dstCopyCoordScaleName;
|
||||||
uint32_t configMask;
|
uint32_t configMask;
|
||||||
if (SkToBool(kUseAlphaConfig_DstReadKeyBit & desc.fDstRead)) {
|
if (SkToBool(kUseAlphaConfig_DstReadKeyBit & desc.fDstReadKey)) {
|
||||||
configMask = kA_GrColorComponentFlag;
|
configMask = kA_GrColorComponentFlag;
|
||||||
} else {
|
} else {
|
||||||
configMask = kRGBA_GrColorComponentFlags;
|
configMask = kRGBA_GrColorComponentFlags;
|
||||||
@ -351,6 +352,16 @@ GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture*
|
|||||||
return static_cast<DstReadKey>(key);
|
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) {
|
const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
|
||||||
if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
|
if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
|
||||||
if (caps.textureRedSupport()) {
|
if (caps.textureRedSupport()) {
|
||||||
@ -473,8 +484,16 @@ const char* GrGLShaderBuilder::fragmentPosition() {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 1
|
if (fTopLeftFragPosRead) {
|
||||||
if (fCtxInfo.caps()->fragCoordConventionsSupport()) {
|
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) {
|
if (!fSetupFragPosition) {
|
||||||
SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature));
|
SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature));
|
||||||
fFSInputs.push_back().set(kVec4f_GrSLType,
|
fFSInputs.push_back().set(kVec4f_GrSLType,
|
||||||
@ -506,18 +525,6 @@ const char* GrGLShaderBuilder::fragmentPosition() {
|
|||||||
GrAssert(GrGLUniformManager::kInvalidUniformHandle != fRTHeightUniform);
|
GrAssert(GrGLUniformManager::kInvalidUniformHandle != fRTHeightUniform);
|
||||||
return kCoordName;
|
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&);
|
const GrGLCaps&);
|
||||||
|
|
||||||
typedef uint8_t DstReadKey;
|
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
|
/** 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
|
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&);
|
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
|
/** 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. */
|
the generated shader code. This potentially allows greater reuse of cached shaders. */
|
||||||
static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
|
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.
|
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;
|
const GrGLContextInfo& fCtxInfo;
|
||||||
GrGLUniformManager& fUniformManager;
|
GrGLUniformManager& fUniformManager;
|
||||||
uint32_t fFSFeaturesAddedMask;
|
uint32_t fFSFeaturesAddedMask;
|
||||||
@ -443,6 +455,8 @@ private:
|
|||||||
GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform;
|
GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform;
|
||||||
GrGLUniformManager::UniformHandle fDstCopyScaleUniform;
|
GrGLUniformManager::UniformHandle fDstCopyScaleUniform;
|
||||||
|
|
||||||
|
bool fTopLeftFragPosRead;
|
||||||
|
|
||||||
SkSTArray<10, AttributePair, true> fEffectAttributes;
|
SkSTArray<10, AttributePair, true> fEffectAttributes;
|
||||||
|
|
||||||
GrGLShaderVar* fPositionVar;
|
GrGLShaderVar* fPositionVar;
|
||||||
|
@ -70,7 +70,7 @@ void GrGLProgramDesc::setRandom(SkMWCRandom* random,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dstRead) {
|
if (dstRead) {
|
||||||
this->fDstRead = GrGLShaderBuilder::KeyForDstRead(dstTexture, gpu->glCaps());
|
this->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstTexture, gpu->glCaps());
|
||||||
}
|
}
|
||||||
|
|
||||||
CoverageOutput coverageOutput;
|
CoverageOutput coverageOutput;
|
||||||
|
Loading…
Reference in New Issue
Block a user