Make GrGLShaderBuilder check whether GrEffect advertised that it would require the dst color or fragment position

R=senorblanco@chromium.org, robertphillips@google.com

Author: bsalomon@google.com

Review URL: https://chromiumcodereview.appspot.com/14998007

git-svn-id: http://skia.googlecode.com/svn/trunk@9074 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
commit-bot@chromium.org 2013-05-09 14:55:46 +00:00
Родитель 504976ef6f
Коммит 8d47ddc19a
10 изменённых файлов: 54 добавлений и 10 удалений

Просмотреть файл

@ -280,10 +280,13 @@ typedef unsigned __int64 uint64_t;
#define GrAlwaysAssert(COND) GR_ALWAYSASSERT(COND) #define GrAlwaysAssert(COND) GR_ALWAYSASSERT(COND)
/** /**
* Crash from unrecoverable condition, optionally with a message. * Crash from unrecoverable condition, optionally with a message. The debug variants only
* crash in a debug build. The message versions print the message regardless of release vs debug.
*/ */
inline void GrCrash() { GrAlwaysAssert(false); } inline void GrCrash() { GrAlwaysAssert(false); }
inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); } inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); }
inline void GrDebugCrash() { GrAssert(false); }
inline void GrDebugCrash(const char* msg) { GrPrintf(msg); GrAssert(false); }
/** /**
* GR_DEBUGCODE compiles the code X in debug builds only * GR_DEBUGCODE compiles the code X in debug builds only

Просмотреть файл

@ -153,7 +153,10 @@ public:
GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); } GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
/** Will this effect read the destination pixel value? */ /** Will this effect read the destination pixel value? */
bool willReadDst() const { return fWillReadDst; } bool willReadDstColor() const { return fWillReadDstColor; }
/** Will this effect read the fragment position? */
bool willReadFragmentPosition() const { return fWillReadFragmentPosition; }
int numVertexAttribs() const { return fVertexAttribTypes.count(); } int numVertexAttribs() const { return fVertexAttribTypes.count(); }
@ -213,7 +216,7 @@ protected:
*/ */
void addVertexAttrib(GrSLType type); void addVertexAttrib(GrSLType type);
GrEffect() : fWillReadDst(false), fEffectRef(NULL) {} GrEffect() : fWillReadDstColor(false), fWillReadFragmentPosition(false), fEffectRef(NULL) {}
/** This should be called by GrEffect subclass factories. See the comment on AutoEffectUnref for /** This should be called by GrEffect subclass factories. See the comment on AutoEffectUnref for
an example factory function. */ an example factory function. */
@ -269,7 +272,14 @@ protected:
* from its constructor. Otherwise, when its generated backend-specific effect class attempts * from its constructor. Otherwise, when its generated backend-specific effect class attempts
* to generate code that reads the destination pixel it will fail. * to generate code that reads the destination pixel it will fail.
*/ */
void setWillReadDst() { fWillReadDst = true; } void setWillReadDstColor() { fWillReadDstColor = true; }
/**
* If the effect will generate a backend-specific effect that will read the fragment position
* in the FS then it must call this method from its constructor. Otherwise, the request to
* access the fragment position will be denied.
*/
void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; }
private: private:
bool isEqual(const GrEffect& other) const { bool isEqual(const GrEffect& other) const {
@ -302,7 +312,8 @@ private:
SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
SkSTArray<kMaxVertexAttribs, GrSLType, true> fVertexAttribTypes; SkSTArray<kMaxVertexAttribs, GrSLType, true> fVertexAttribTypes;
bool fWillReadDst; bool fWillReadDstColor;
bool fWillReadFragmentPosition;
GrEffectRef* fEffectRef; GrEffectRef* fEffectRef;
typedef GrRefCnt INHERITED; typedef GrRefCnt INHERITED;

Просмотреть файл

@ -1358,7 +1358,7 @@ public:
GR_DECLARE_EFFECT_TEST; GR_DECLARE_EFFECT_TEST;
private: private:
XferEffect(SkXfermode::Mode mode) : fMode(mode) { this->setWillReadDst(); } XferEffect(SkXfermode::Mode mode) : fMode(mode) { this->setWillReadDstColor(); }
virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { return true; } virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { return true; }
SkXfermode::Mode fMode; SkXfermode::Mode fMode;

Просмотреть файл

@ -447,6 +447,7 @@ public:
virtual ~GrGLDistantLight() {} virtual ~GrGLDistantLight() {}
virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE; virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE; virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
private: private:
typedef GrGLLight INHERITED; typedef GrGLLight INHERITED;
UniformHandle fDirectionUni; UniformHandle fDirectionUni;
@ -459,6 +460,7 @@ public:
virtual ~GrGLPointLight() {} virtual ~GrGLPointLight() {}
virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE; virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE; virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
private: private:
typedef GrGLLight INHERITED; typedef GrGLLight INHERITED;
SkPoint3 fLocation; SkPoint3 fLocation;
@ -473,6 +475,7 @@ public:
virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE; virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE; virtual void emitSurfaceToLight(GrGLShaderBuilder*, const char* z) SK_OVERRIDE;
virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight) SK_OVERRIDE; virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight) SK_OVERRIDE;
private: private:
typedef GrGLLight INHERITED; typedef GrGLLight INHERITED;
@ -509,6 +512,8 @@ public:
virtual bool isEqual(const SkLight& other) const { virtual bool isEqual(const SkLight& other) const {
return fColor == other.fColor; return fColor == other.fColor;
} }
// Called to know whether the generated GrGLLight will require access to the fragment position.
virtual bool requiresFragmentPosition() const = 0;
protected: protected:
SkLight(SkColor color) SkLight(SkColor color)
@ -553,6 +558,8 @@ public:
return NULL; return NULL;
#endif #endif
} }
virtual bool requiresFragmentPosition() const SK_OVERRIDE { return false; }
virtual bool isEqual(const SkLight& other) const SK_OVERRIDE { virtual bool isEqual(const SkLight& other) const SK_OVERRIDE {
if (other.type() != kDistant_LightType) { if (other.type() != kDistant_LightType) {
return false; return false;
@ -604,6 +611,7 @@ public:
return NULL; return NULL;
#endif #endif
} }
virtual bool requiresFragmentPosition() const SK_OVERRIDE { return true; }
virtual bool isEqual(const SkLight& other) const SK_OVERRIDE { virtual bool isEqual(const SkLight& other) const SK_OVERRIDE {
if (other.type() != kPoint_LightType) { if (other.type() != kPoint_LightType) {
return false; return false;
@ -674,6 +682,7 @@ public:
return NULL; return NULL;
#endif #endif
} }
virtual bool requiresFragmentPosition() const SK_OVERRIDE { return true; }
virtual LightType type() const { return kSpot_LightType; } virtual LightType type() const { return kSpot_LightType; }
const SkPoint3& location() const { return fLocation; } const SkPoint3& location() const { return fLocation; }
const SkPoint3& target() const { return fTarget; } const SkPoint3& target() const { return fTarget; }
@ -1044,6 +1053,9 @@ GrLightingEffect::GrLightingEffect(GrTexture* texture, const SkLight* light, SkS
, fLight(light) , fLight(light)
, fSurfaceScale(surfaceScale) { , fSurfaceScale(surfaceScale) {
fLight->ref(); fLight->ref();
if (light->requiresFragmentPosition()) {
this->setWillReadFragmentPosition();
}
} }
GrLightingEffect::~GrLightingEffect() { GrLightingEffect::~GrLightingEffect() {

Просмотреть файл

@ -666,6 +666,7 @@ public:
private: private:
HairLineEdgeEffect() { HairLineEdgeEffect() {
this->addVertexAttrib(kVec4f_GrSLType); this->addVertexAttrib(kVec4f_GrSLType);
this->setWillReadFragmentPosition();
} }
virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {

Просмотреть файл

@ -220,6 +220,7 @@ private:
GrRectEffect() : GrEffect() { GrRectEffect() : GrEffect() {
this->addVertexAttrib(kVec4f_GrSLType); this->addVertexAttrib(kVec4f_GrSLType);
this->addVertexAttrib(kVec2f_GrSLType); this->addVertexAttrib(kVec2f_GrSLType);
this->setWillReadFragmentPosition();
} }
virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; } virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; }

Просмотреть файл

@ -453,7 +453,7 @@ public:
*/ */
bool willEffectReadDst() const { bool willEffectReadDst() const {
for (int s = 0; s < kNumStages; ++s) { for (int s = 0; s < kNumStages; ++s) {
if (this->isStageEnabled(s) && (*this->getStage(s).getEffect())->willReadDst()) { if (this->isStageEnabled(s) && (*this->getStage(s).getEffect())->willReadDstColor()) {
return true; return true;
} }
} }

Просмотреть файл

@ -87,7 +87,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
const GrBackendEffectFactory& factory = effect->getFactory(); const GrBackendEffectFactory& factory = effect->getFactory();
GrDrawEffect drawEffect(drawState.getStage(s), requiresLocalCoordAttrib); GrDrawEffect drawEffect(drawState.getStage(s), requiresLocalCoordAttrib);
desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()); desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
if (effect->willReadDst()) { if (effect->willReadDstColor()) {
readsDst = true; readsDst = true;
} }
} else { } else {

Просмотреть файл

@ -230,6 +230,14 @@ void GrGLShaderBuilder::nameVariable(SkString* out, char prefix, const char* nam
} }
const char* GrGLShaderBuilder::dstColor() { const char* GrGLShaderBuilder::dstColor() {
if (fCodeStage.inStageCode()) {
const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
if (!effect->willReadDstColor()) {
GrDebugCrash("GrGLEffect asked for dst color but its generating GrEffect "
"did not request access.");
return "";
}
}
static const char kFBFetchColorName[] = "gl_LastFragData[0]"; static const char kFBFetchColorName[] = "gl_LastFragData[0]";
GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType(); GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType();
if (GrGLCaps::kEXT_FBFetchType == fetchType) { if (GrGLCaps::kEXT_FBFetchType == fetchType) {
@ -241,7 +249,7 @@ const char* GrGLShaderBuilder::dstColor() {
} else if (fDstCopySampler.isInitialized()) { } else if (fDstCopySampler.isInitialized()) {
return kDstCopyColorName; return kDstCopyColorName;
} else { } else {
return NULL; return "";
} }
} }
@ -457,6 +465,14 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
} }
const char* GrGLShaderBuilder::fragmentPosition() { const char* GrGLShaderBuilder::fragmentPosition() {
if (fCodeStage.inStageCode()) {
const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
if (!effect->willReadFragmentPosition()) {
GrDebugCrash("GrGLEffect asked for frag position but its generating GrEffect "
"did not request access.");
return "";
}
}
#if 1 #if 1
if (fCtxInfo.caps()->fragCoordConventionsSupport()) { if (fCtxInfo.caps()->fragCoordConventionsSupport()) {
if (!fSetupFragPosition) { if (!fSetupFragPosition) {

Просмотреть файл

@ -63,7 +63,7 @@ void GrGLProgramDesc::setRandom(SkMWCRandom* random,
const GrBackendEffectFactory& factory = (*stages[s]->getEffect())->getFactory(); const GrBackendEffectFactory& factory = (*stages[s]->getEffect())->getFactory();
GrDrawEffect drawEffect(*stages[s], useLocalCoords); GrDrawEffect drawEffect(*stages[s], useLocalCoords);
fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()); fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
if ((*stages[s]->getEffect())->willReadDst()) { if ((*stages[s]->getEffect())->willReadDstColor()) {
dstRead = true; dstRead = true;
} }
} }