diff options
-rw-r--r-- | src/effects/SkLightingImageFilter.cpp | 244 | ||||
-rw-r--r-- | src/gpu/gl/GrGLEffect.h | 30 |
2 files changed, 111 insertions, 163 deletions
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index bf9129501c..e25ab9fd3d 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -365,21 +365,39 @@ private: class GrGLLight { public: virtual ~GrGLLight() {} - virtual void setupVariables(GrGLShaderBuilder* builder); - virtual void emitVS(SkString* out) const {} - virtual void emitFuncs(GrGLShaderBuilder* builder) {} - virtual void emitSurfaceToLight(GrGLShaderBuilder*, - SkString* out, - const char* z) const = 0; - virtual void emitLightColor(GrGLShaderBuilder*, - const char *surfaceToLight) const; - virtual void setData(const GrGLUniformManager&, const SkLight* light) const; -private: - typedef SkRefCnt INHERITED; + /** + * This is called by GrGLLightingEffect::emitCode() before either of the two virtual functions + * below. It adds a vec3f uniform visible in the FS that represents the constant light color. + */ + void emitLightColorUniform(GrGLShaderBuilder*); + + /** + * These two functions are called from GrGLLightingEffect's emitCode() function. + * emitSurfaceToLight places an expression in param out that is the vector from the surface to + * the light. The expression will be used in the FS. emitLightColor writes an expression into + * the FS that is the color of the light. Either function may add functions and/or uniforms to + * the FS. The default of emitLightColor appends the name of the constant light color uniform + * and so this function only needs to be overridden if the light color varies spatially. + */ + virtual void emitSurfaceToLight(GrGLShaderBuilder*, SkString* out, const char* z) = 0; + virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight); + + // This is called from GrGLLightingEffect's setData(). Subclasses of GrGLLight must call + // INHERITED::setData(). + virtual void setData(const GrGLUniformManager&, const SkLight* light) const; protected: + /** + * Gets the constant light color uniform. Subclasses can use this in their emitLightColor + * function. + */ + UniformHandle lightColorUni() const { return fColorUni; } + +private: UniformHandle fColorUni; + + typedef SkRefCnt INHERITED; }; /////////////////////////////////////////////////////////////////////////////// @@ -387,11 +405,8 @@ protected: class GrGLDistantLight : public GrGLLight { public: virtual ~GrGLDistantLight() {} - virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE; virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE; - virtual void emitSurfaceToLight(GrGLShaderBuilder*, - SkString* out, - const char* z) const SK_OVERRIDE; + virtual void emitSurfaceToLight(GrGLShaderBuilder*, SkString* out, const char* z) SK_OVERRIDE; private: typedef GrGLLight INHERITED; UniformHandle fDirectionUni; @@ -402,12 +417,8 @@ private: class GrGLPointLight : public GrGLLight { public: virtual ~GrGLPointLight() {} - virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE; virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE; - virtual void emitVS(SkString* out) const SK_OVERRIDE; - virtual void emitSurfaceToLight(GrGLShaderBuilder*, - SkString* out, - const char* z) const SK_OVERRIDE; + virtual void emitSurfaceToLight(GrGLShaderBuilder*, SkString* out, const char* z) SK_OVERRIDE; private: typedef GrGLLight INHERITED; SkPoint3 fLocation; @@ -419,16 +430,9 @@ private: class GrGLSpotLight : public GrGLLight { public: virtual ~GrGLSpotLight() {} - virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE; virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE; - virtual void emitVS(SkString* out) const SK_OVERRIDE; - virtual void emitFuncs(GrGLShaderBuilder* builder); - virtual void emitSurfaceToLight(GrGLShaderBuilder* builder, - SkString* out, - const char* z) const SK_OVERRIDE; - virtual void emitLightColor(GrGLShaderBuilder*, - const char *surfaceToLight) const SK_OVERRIDE; - + virtual void emitSurfaceToLight(GrGLShaderBuilder*, SkString* out, const char* z) SK_OVERRIDE; + virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight) SK_OVERRIDE; private: typedef GrGLLight INHERITED; @@ -938,28 +942,32 @@ SkLight* create_random_light(SkRandom* random) { } -class GrGLLightingEffect : public GrGLLegacyEffect { +class GrGLLightingEffect : public GrGLEffect { public: GrGLLightingEffect(const GrBackendEffectFactory& factory, const GrEffect& effect); virtual ~GrGLLightingEffect(); - virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE; - virtual void emitVS(GrGLShaderBuilder* builder, - const char* vertexCoords) SK_OVERRIDE; - virtual void emitFS(GrGLShaderBuilder* builder, - const char* outputColor, - const char* inputColor, - const TextureSamplerArray&) SK_OVERRIDE; - - virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) = 0; + virtual void emitCode(GrGLShaderBuilder*, + const GrEffect&, + EffectKey, + const char* vertexCoords, + const char* outputColor, + const char* inputColor, + const TextureSamplerArray&) SK_OVERRIDE; static inline EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps); + /** + * Subclasses of GrGLLightingEffect must call INHERITED::setData(); + */ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE; +protected: + virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) = 0; + private: - typedef GrGLLegacyEffect INHERITED; + typedef GrGLEffect INHERITED; UniformHandle fImageIncrementUni; UniformHandle fSurfaceScaleUni; @@ -972,7 +980,6 @@ class GrGLDiffuseLightingEffect : public GrGLLightingEffect { public: GrGLDiffuseLightingEffect(const GrBackendEffectFactory& factory, const GrEffect& effect); - virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE; virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE; virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE; @@ -988,7 +995,6 @@ class GrGLSpecularLightingEffect : public GrGLLightingEffect { public: GrGLSpecularLightingEffect(const GrBackendEffectFactory& factory, const GrEffect& effect); - virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE; virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE; virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE; @@ -1065,27 +1071,21 @@ GrGLLightingEffect::~GrGLLightingEffect() { delete fLight; } -void GrGLLightingEffect::setupVariables(GrGLShaderBuilder* builder) { +void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder, + const GrEffect&, + EffectKey, + const char* vertexCoords, + const char* outputColor, + const char* inputColor, + const TextureSamplerArray& samplers) { fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec2f_GrSLType, "ImageIncrement"); fSurfaceScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType, "SurfaceScale"); - fLight->setupVariables(builder); -} - -void GrGLLightingEffect::emitVS(GrGLShaderBuilder* builder, - const char* vertexCoords) { - fLight->emitVS(&builder->fVSCode); -} - -void GrGLLightingEffect::emitFS(GrGLShaderBuilder* builder, - const char* outputColor, - const char* inputColor, - const TextureSamplerArray& samplers) { + fLight->emitLightColorUniform(builder); SkString* code = &builder->fFSCode; - fLight->emitFuncs(builder); SkString lightFunc; this->emitLightFunc(builder, &lightFunc); static const GrGLShaderVar gSobelArgs[] = { @@ -1191,13 +1191,13 @@ GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrBackendEffectFactor , fKDUni(kInvalidUniformHandle) { } -void GrGLDiffuseLightingEffect::setupVariables(GrGLShaderBuilder* builder) { - INHERITED::setupVariables(builder); - fKDUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType, "KD"); -} - void GrGLDiffuseLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) { - const char* kd = builder->getUniformCStr(fKDUni); + const char* kd; + fKDUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, + "KD", + &kd); + static const GrGLShaderVar gLightArgs[] = { GrGLShaderVar("normal", kVec3f_GrSLType), GrGLShaderVar("surfaceToLight", kVec3f_GrSLType), @@ -1265,17 +1265,14 @@ GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrBackendEffectFact , fShininessUni(kInvalidUniformHandle) { } -void GrGLSpecularLightingEffect::setupVariables(GrGLShaderBuilder* builder) { - INHERITED::setupVariables(builder); +void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) { + const char* ks; + const char* shininess; + fKSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "KS"); + kFloat_GrSLType, "KS", &ks); fShininessUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "Shininess"); -} - -void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) { - const char* ks = builder->getUniformCStr(fKSUni); - const char* shininess = builder->getUniformCStr(fShininessUni); + kFloat_GrSLType, "Shininess", &shininess); static const GrGLShaderVar gLightArgs[] = { GrGLShaderVar("normal", kVec3f_GrSLType), @@ -1305,18 +1302,16 @@ void GrGLSpecularLightingEffect::setData(const GrGLUniformManager& uman, } /////////////////////////////////////////////////////////////////////////////// - -void GrGLLight::emitLightColor(GrGLShaderBuilder* builder, - const char *surfaceToLight) const { - const char* color = builder->getUniformCStr(fColorUni); - builder->fFSCode.append(color); -} - -void GrGLLight::setupVariables(GrGLShaderBuilder* builder) { +void GrGLLight::emitLightColorUniform(GrGLShaderBuilder* builder) { fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, "LightColor"); } +void GrGLLight::emitLightColor(GrGLShaderBuilder* builder, + const char *surfaceToLight) { + builder->fFSCode.append(builder->getUniformCStr(this->lightColorUni())); +} + void GrGLLight::setData(const GrGLUniformManager& uman, const SkLight* light) const { setUniformPoint3(uman, fColorUni, light->color() * SkScalarInvert(SkIntToScalar(255))); @@ -1324,12 +1319,6 @@ void GrGLLight::setData(const GrGLUniformManager& uman, /////////////////////////////////////////////////////////////////////////////// -void GrGLDistantLight::setupVariables(GrGLShaderBuilder* builder) { - INHERITED::setupVariables(builder); - fDirectionUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, - "LightDirection"); -} - void GrGLDistantLight::setData(const GrGLUniformManager& uman, const SkLight* light) const { INHERITED::setData(uman, light); SkASSERT(light->type() == SkLight::kDistant_LightType); @@ -1339,19 +1328,15 @@ void GrGLDistantLight::setData(const GrGLUniformManager& uman, const SkLight* li void GrGLDistantLight::emitSurfaceToLight(GrGLShaderBuilder* builder, SkString* out, - const char* z) const { - const char* dir = builder->getUniformCStr(fDirectionUni); + const char* z) { + const char* dir; + fDirectionUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, + "LightDirection", &dir); out->append(dir); } /////////////////////////////////////////////////////////////////////////////// -void GrGLPointLight::setupVariables(GrGLShaderBuilder* builder) { - INHERITED::setupVariables(builder); - fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, - "LightLocation"); -} - void GrGLPointLight::setData(const GrGLUniformManager& uman, const SkLight* light) const { INHERITED::setData(uman, light); @@ -1360,34 +1345,17 @@ void GrGLPointLight::setData(const GrGLUniformManager& uman, setUniformPoint3(uman, fLocationUni, pointLight->location()); } -void GrGLPointLight::emitVS(SkString* out) const { -} - void GrGLPointLight::emitSurfaceToLight(GrGLShaderBuilder* builder, SkString* out, - const char* z) const { - const char* loc = builder->getUniformCStr(fLocationUni); + const char* z) { + const char* loc; + fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, + "LightLocation", &loc); out->appendf("normalize(%s - vec3(%s.xy, %s))", loc, builder->fragmentPosition(), z); } /////////////////////////////////////////////////////////////////////////////// -void GrGLSpotLight::setupVariables(GrGLShaderBuilder* builder) { - INHERITED::setupVariables(builder); - fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kVec3f_GrSLType, "LightLocation"); - fExponentUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "Exponent"); - fCosInnerConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "CosInnerConeAngle"); - fCosOuterConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "CosOuterConeAngle"); - fConeScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "ConeScale"); - fSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kVec3f_GrSLType, "S"); -} - void GrGLSpotLight::setData(const GrGLUniformManager& uman, const SkLight* light) const { INHERITED::setData(uman, light); @@ -1401,16 +1369,36 @@ void GrGLSpotLight::setData(const GrGLUniformManager& uman, setUniformNormal3(uman, fSUni, spotLight->s()); } -void GrGLSpotLight::emitVS(SkString* out) const { +void GrGLSpotLight::emitSurfaceToLight(GrGLShaderBuilder* builder, + SkString* out, + const char* z) { + const char* location; + fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec3f_GrSLType, "LightLocation", &location); + out->appendf("normalize(%s - vec3(%s.xy, %s))", location, builder->fragmentPosition(), z); } -void GrGLSpotLight::emitFuncs(GrGLShaderBuilder* builder) { - const char* exponent = builder->getUniformCStr(fExponentUni); - const char* cosInner = builder->getUniformCStr(fCosInnerConeAngleUni); - const char* cosOuter = builder->getUniformCStr(fCosOuterConeAngleUni); - const char* coneScale = builder->getUniformCStr(fConeScaleUni); - const char* s = builder->getUniformCStr(fSUni); - const char* color = builder->getUniformCStr(fColorUni); +void GrGLSpotLight::emitLightColor(GrGLShaderBuilder* builder, + const char *surfaceToLight) { + + const char* color = builder->getUniformCStr(this->lightColorUni()); // created by parent class. + + const char* exponent; + const char* cosInner; + const char* cosOuter; + const char* coneScale; + const char* s; + fExponentUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "Exponent", &exponent); + fCosInnerConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "CosInnerConeAngle", &cosInner); + fCosOuterConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "CosOuterConeAngle", &cosOuter); + fConeScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "ConeScale", &coneScale); + fSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec3f_GrSLType, "S", &s); + static const GrGLShaderVar gLightColorArgs[] = { GrGLShaderVar("surfaceToLight", kVec3f_GrSLType) }; @@ -1432,17 +1420,7 @@ void GrGLSpotLight::emitFuncs(GrGLShaderBuilder* builder) { gLightColorArgs, lightColorBody.c_str(), &fLightColorFunc); -} - -void GrGLSpotLight::emitSurfaceToLight(GrGLShaderBuilder* builder, - SkString* out, - const char* z) const { - const char* location= builder->getUniformCStr(fLocationUni); - out->appendf("normalize(%s - vec3(%s.xy, %s))", location, builder->fragmentPosition(), z); -} - -void GrGLSpotLight::emitLightColor(GrGLShaderBuilder* builder, - const char *surfaceToLight) const { + builder->fFSCode.appendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight); } diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h index ad097ed8ec..74d3f0f1a3 100644 --- a/src/gpu/gl/GrGLEffect.h +++ b/src/gpu/gl/GrGLEffect.h @@ -90,34 +90,4 @@ protected: const GrBackendEffectFactory& fFactory; }; -/** - * This allows program stages that implemented an older set of virtual functions on GrGLEffect - * to continue to work by change their parent class to this class. New program stages should not use - * this interface. It will be removed once older stages are modified to implement emitCode(). - */ -class GrGLLegacyEffect : public GrGLEffect { -public: - GrGLLegacyEffect(const GrBackendEffectFactory& factory) : GrGLEffect(factory) {} - - virtual void setupVariables(GrGLShaderBuilder* builder) {}; - virtual void emitVS(GrGLShaderBuilder* builder, - const char* vertexCoords) = 0; - virtual void emitFS(GrGLShaderBuilder* builder, - const char* outputColor, - const char* inputColor, - const TextureSamplerArray&) = 0; - - virtual void emitCode(GrGLShaderBuilder* builder, - const GrEffect&, - EffectKey, - const char* vertexCoords, - const char* outputColor, - const char* inputColor, - const TextureSamplerArray& samplers) { - this->setupVariables(builder); - this->emitVS(builder, vertexCoords); - this->emitFS(builder, outputColor, inputColor, samplers); - } -}; - #endif |