diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-07-16 13:36:18 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-07-16 13:36:18 +0000 |
commit | 032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7a (patch) | |
tree | 7b97452a7937949417cc40a4817cf4c4ede8e4ab /src | |
parent | 96cbd2c4d2ea7e138b65923a46fb77bc096a6782 (diff) |
Remove uniform var pointers from custom effects
Review URL: http://codereview.appspot.com/6374067/
git-svn-id: http://skia.googlecode.com/svn/trunk@4616 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/effects/SkLightingImageFilter.cpp | 492 | ||||
-rw-r--r-- | src/gpu/effects/GrConvolutionEffect.cpp | 80 | ||||
-rw-r--r-- | src/gpu/effects/GrGradientEffects.cpp | 235 | ||||
-rw-r--r-- | src/gpu/effects/GrMorphologyEffect.cpp | 64 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 16 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.h | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 80 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.h | 40 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderVar.h | 6 |
11 files changed, 570 insertions, 462 deletions
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index d4e2a3e259..1e15155fc5 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -18,6 +18,10 @@ class GrGLDiffuseLightingEffect; class GrGLSpecularLightingEffect; +// For brevity, and these definitions are likely to move to a different class soon. +typedef GrGLShaderBuilder::UniformHandle UniformHandle; +static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle; + // FIXME: Eventually, this should be implemented properly, and put in // SkScalar.h. #define SkScalarPow(x, y) SkFloatToScalar(powf(SkScalarToFloat(x), SkScalarToFloat(y))) @@ -359,20 +363,24 @@ private: class GrGLLight { public: virtual ~GrGLLight() {} - virtual void setupVariables(GrGLShaderBuilder* state, int stage); - virtual void emitVS(SkString* builder) const {} - virtual void emitFuncs(SkString* builder) const {} - virtual void emitSurfaceToLight(SkString* builder, const char* z) const = 0; - virtual void emitLightColor(SkString* builder, const char *surfaceToLight) const; - virtual void initUniforms(const GrGLInterface* gl, int programID); + virtual void setupVariables(GrGLShaderBuilder* builder, int stage); + virtual void emitVS(SkString* out) const {} + virtual void emitFuncs(const GrGLShaderBuilder* builder, SkString* out) const {} + virtual void emitSurfaceToLight(const GrGLShaderBuilder*, + SkString* out, + const char* z) const = 0; + virtual void emitLightColor(const GrGLShaderBuilder*, + SkString* out, + const char *surfaceToLight) const; + virtual void initUniforms(const GrGLShaderBuilder*, const GrGLInterface* gl, int programID); virtual void setData(const GrGLInterface*, const GrRenderTarget* rt, const SkLight* light) const; private: typedef SkRefCnt INHERITED; protected: - const GrGLShaderVar* fColorVar; - int fColorVarLocation; + UniformHandle fColorUni; + int fColorLocation; }; /////////////////////////////////////////////////////////////////////////////// @@ -380,14 +388,18 @@ protected: class GrGLDistantLight : public GrGLLight { public: virtual ~GrGLDistantLight() {} - virtual void setupVariables(GrGLShaderBuilder* state, int stage) SK_OVERRIDE; - virtual void initUniforms(const GrGLInterface* gl, int programID) SK_OVERRIDE; + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder*, + const GrGLInterface* gl, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; - virtual void emitSurfaceToLight(SkString* builder, const char* z) const SK_OVERRIDE; + virtual void emitSurfaceToLight(const GrGLShaderBuilder*, + SkString* out, + const char* z) const SK_OVERRIDE; private: typedef GrGLLight INHERITED; - const GrGLShaderVar* fDirectionVar; + UniformHandle fDirectionUni; int fDirectionLocation; }; @@ -396,16 +408,20 @@ private: class GrGLPointLight : public GrGLLight { public: virtual ~GrGLPointLight() {} - virtual void setupVariables(GrGLShaderBuilder* state, int stage); - virtual void initUniforms(const GrGLInterface* gl, int programID); + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder*, + const GrGLInterface*, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; - virtual void emitVS(SkString* builder) const; - virtual void emitSurfaceToLight(SkString* builder, const char* z) const SK_OVERRIDE; + virtual void emitVS(SkString* out) const SK_OVERRIDE; + virtual void emitSurfaceToLight(const GrGLShaderBuilder*, + SkString* out, + const char* z) const SK_OVERRIDE; private: typedef GrGLLight INHERITED; SkPoint3 fLocation; - const GrGLShaderVar* fLocationVar; + UniformHandle fLocationUni; int fLocationLocation; }; @@ -414,29 +430,35 @@ private: class GrGLSpotLight : public GrGLLight { public: virtual ~GrGLSpotLight() {} - virtual void setupVariables(GrGLShaderBuilder* state, int stage); - virtual void initUniforms(const GrGLInterface* gl, int programID); + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const SK_OVERRIDE; - virtual void emitVS(SkString* builder) const; - virtual void emitFuncs(SkString* builder) const; - virtual void emitSurfaceToLight(SkString* builder, const char* z) const SK_OVERRIDE; - virtual void emitLightColor(SkString* builder, const char *surfaceToLight) const; + virtual void emitVS(SkString* out) const SK_OVERRIDE; + virtual void emitFuncs(const GrGLShaderBuilder* builder, SkString* out) const; + virtual void emitSurfaceToLight(const GrGLShaderBuilder* builder, + SkString* out, + const char* z) const SK_OVERRIDE; + virtual void emitLightColor(const GrGLShaderBuilder*, + SkString* out, + const char *surfaceToLight) const SK_OVERRIDE; private: typedef GrGLLight INHERITED; - const GrGLShaderVar* fLocationVar; - int fLocationLocation; - const GrGLShaderVar* fExponentVar; - int fExponentLocation; - const GrGLShaderVar* fCosOuterConeAngleVar; - int fCosOuterConeAngleLocation; - const GrGLShaderVar* fCosInnerConeAngleVar; - int fCosInnerConeAngleLocation; - const GrGLShaderVar* fConeScaleVar; - int fConeScaleLocation; - const GrGLShaderVar* fSVar; - int fSLocation; + UniformHandle fLocationUni; + int fLocationLocation; + UniformHandle fExponentUni; + int fExponentLocation; + UniformHandle fCosOuterConeAngleUni; + int fCosOuterConeAngleLocation; + UniformHandle fCosInnerConeAngleUni; + int fCosInnerConeAngleLocation; + UniformHandle fConeScaleUni; + int fConeScaleLocation; + UniformHandle fSUni; + int fSLocation; }; }; @@ -870,20 +892,22 @@ public: const GrCustomStage& stage); virtual ~GrGLLightingEffect(); - virtual void setupVariables(GrGLShaderBuilder* state, + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void emitVS(GrGLShaderBuilder* state, + virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) SK_OVERRIDE; - virtual void emitFS(GrGLShaderBuilder* state, + virtual void emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void emitLightFunc(SkString* funcs) = 0; + virtual void emitLightFunc(const GrGLShaderBuilder*, SkString* funcs) = 0; static inline StageKey GenKey(const GrCustomStage& s); - virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface*, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface*, const GrCustomStage&, const GrRenderTarget*, @@ -892,11 +916,11 @@ public: private: typedef GrGLProgramStage INHERITED; - const GrGLShaderVar* fImageIncrementVar; - GrGLint fImageIncrementLocation; - const GrGLShaderVar* fSurfaceScaleVar; - GrGLint fSurfaceScaleLocation; - GrGLLight* fLight; + UniformHandle fImageIncrementUni; + GrGLint fImageIncrementLocation; + UniformHandle fSurfaceScaleUni; + GrGLint fSurfaceScaleLocation; + GrGLLight* fLight; }; /////////////////////////////////////////////////////////////////////////////// @@ -905,10 +929,12 @@ class GrGLDiffuseLightingEffect : public GrGLLightingEffect { public: GrGLDiffuseLightingEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage); - virtual void setupVariables(GrGLShaderBuilder* state, + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void emitLightFunc(SkString* funcs) SK_OVERRIDE; - virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE; + virtual void emitLightFunc(const GrGLShaderBuilder*, SkString* funcs) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder*, + const GrGLInterface*, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface*, const GrCustomStage&, const GrRenderTarget*, @@ -917,8 +943,8 @@ public: private: typedef GrGLLightingEffect INHERITED; - const GrGLShaderVar* fKDVar; - GrGLint fKDLocation; + UniformHandle fKDUni; + GrGLint fKDLocation; }; /////////////////////////////////////////////////////////////////////////////// @@ -927,10 +953,12 @@ class GrGLSpecularLightingEffect : public GrGLLightingEffect { public: GrGLSpecularLightingEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage); - virtual void setupVariables(GrGLShaderBuilder* state, + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void emitLightFunc(SkString* funcs) SK_OVERRIDE; - virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE; + virtual void emitLightFunc(const GrGLShaderBuilder*, SkString* funcs) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder*, + const GrGLInterface*, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface*, const GrCustomStage&, const GrRenderTarget*, @@ -939,10 +967,10 @@ public: private: typedef GrGLLightingEffect INHERITED; - const GrGLShaderVar* fKSVar; - GrGLint fKSLocation; - const GrGLShaderVar* fShininessVar; - GrGLint fShininessLocation; + UniformHandle fKSUni; + GrGLint fKSLocation; + UniformHandle fShininessUni; + GrGLint fShininessLocation; }; /////////////////////////////////////////////////////////////////////////////// @@ -988,9 +1016,9 @@ bool GrDiffuseLightingEffect::isEqual(const GrCustomStage& sBase) const { GrGLLightingEffect::GrGLLightingEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : GrGLProgramStage(factory) - , fImageIncrementVar(NULL) + , fImageIncrementUni(kInvalidUniformHandle) , fImageIncrementLocation(0) - , fSurfaceScaleVar(NULL) + , fSurfaceScaleUni(kInvalidUniformHandle) , fSurfaceScaleLocation(0) { const GrLightingEffect& m = static_cast<const GrLightingEffect&>(stage); fLight = m.light()->createGLLight(); @@ -1000,40 +1028,40 @@ GrGLLightingEffect::~GrGLLightingEffect() { delete fLight; } -void GrGLLightingEffect::setupVariables(GrGLShaderBuilder* state, int stage) { - fImageIncrementVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kVec2f_GrSLType, "uImageIncrement", stage); - fSurfaceScaleVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uSurfaceScale", stage); - fLight->setupVariables(state, stage); -} - -void GrGLLightingEffect::emitVS(GrGLShaderBuilder* state, - const char* vertexCoords) { - fLight->emitVS(&state->fVSCode); -} - -void GrGLLightingEffect::initUniforms(const GrGLInterface* gl, - int programID) { - GR_GL_CALL_RET(gl, fSurfaceScaleLocation, - GetUniformLocation(programID, - fSurfaceScaleVar->getName().c_str())); - GR_GL_CALL_RET(gl, fImageIncrementLocation, - GetUniformLocation(programID, - fImageIncrementVar->getName().c_str())); - fLight->initUniforms(gl, programID); -} - -void GrGLLightingEffect::emitFS(GrGLShaderBuilder* state, - const char* outputColor, - const char* inputColor, - const char* samplerName) { - SkString* code = &state->fFSCode; - SkString* funcs = &state->fFSFunctions; - fLight->emitFuncs(funcs); - emitLightFunc(funcs); +void GrGLLightingEffect::setupVariables(GrGLShaderBuilder* builder, int stage) { + fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec2f_GrSLType, + "uImageIncrement", stage); + fSurfaceScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, + "uSurfaceScale", stage); + fLight->setupVariables(builder, stage); +} + +void GrGLLightingEffect::emitVS(GrGLShaderBuilder* builder, + const char* vertexCoords) { + fLight->emitVS(&builder->fVSCode); +} + +void GrGLLightingEffect::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID) { + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); + const char* surfScale = builder->getUniformCStr(fSurfaceScaleUni); + + GR_GL_CALL_RET(gl, fSurfaceScaleLocation, GetUniformLocation(programID, surfScale)); + GR_GL_CALL_RET(gl, fImageIncrementLocation, GetUniformLocation(programID, imgInc)); + fLight->initUniforms(builder, gl, programID); +} + +void GrGLLightingEffect::emitFS(GrGLShaderBuilder* builder, + const char* outputColor, + const char* inputColor, + const char* samplerName) { + SkString* code = &builder->fFSCode; + SkString* funcs = &builder->fFSFunctions; + fLight->emitFuncs(builder, funcs); + this->emitLightFunc(builder, funcs); funcs->appendf("float sobel(float a, float b, float c, float d, float e, float f, float scale) {\n"); funcs->appendf("\treturn (-a + b - 2.0 * c + 2.0 * d -e + f) * scale;\n"); funcs->appendf("}\n"); @@ -1046,26 +1074,30 @@ vec3 interiorNormal(float m[9], float surfaceScale) {\n\ sobel(m[0], m[6], m[1], m[7], m[2], m[8], 0.25),\n\ surfaceScale);\n}\n"); - code->appendf("\t\tvec2 coord = %s;\n", state->fSampleCoords.c_str()); + code->appendf("\t\tvec2 coord = %s;\n", builder->fSampleCoords.c_str()); code->appendf("\t\tfloat m[9];\n"); + + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); + const char* surfScale = builder->getUniformCStr(fSurfaceScaleUni); + int index = 0; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { SkString texCoords; - texCoords.appendf("coord + vec2(%d, %d) * %s", dx, dy, fImageIncrementVar->getName().c_str()); + texCoords.appendf("coord + vec2(%d, %d) * %s", dx, dy, imgInc); code->appendf("\t\tm[%d] = ", index++); - state->emitTextureLookup(samplerName, texCoords.c_str()); + builder->emitTextureLookup(samplerName, texCoords.c_str()); code->appendf(".a;\n"); } } code->appendf("\t\tvec3 surfaceToLight = "); SkString arg; - arg.appendf("%s * m[4]", fSurfaceScaleVar->getName().c_str()); - fLight->emitSurfaceToLight(code, arg.c_str()); + arg.appendf("%s * m[4]", surfScale); + fLight->emitSurfaceToLight(builder, code, arg.c_str()); code->appendf(";\n"); - code->appendf("\t\t%s = light(interiorNormal(m, %s), surfaceToLight, ", outputColor, fSurfaceScaleVar->getName().c_str()); - fLight->emitLightColor(code, "surfaceToLight"); - code->appendf(")%s;\n", state->fModulate.c_str()); + code->appendf("\t\t%s = light(interiorNormal(m, %s), surfaceToLight, ", outputColor, surfScale); + fLight->emitLightColor(builder, code, "surfaceToLight"); + code->appendf(")%s;\n", builder->fModulate.c_str()); } GrGLProgramStage::StageKey GrGLLightingEffect::GenKey( @@ -1093,28 +1125,28 @@ void GrGLLightingEffect::setData(const GrGLInterface* gl, GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : INHERITED(factory, stage) - , fKDVar(NULL) + , fKDUni(kInvalidUniformHandle) , fKDLocation(0) { } -void GrGLDiffuseLightingEffect::setupVariables(GrGLShaderBuilder* state, int stage) { - INHERITED::setupVariables(state, stage); - fKDVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uKD", stage); +void GrGLDiffuseLightingEffect::setupVariables(GrGLShaderBuilder* builder, int stage) { + INHERITED::setupVariables(builder, stage); + fKDUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType, "uKD", + stage); } -void GrGLDiffuseLightingEffect::initUniforms(const GrGLInterface* gl, +void GrGLDiffuseLightingEffect::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, int programID) { - INHERITED::initUniforms(gl, programID); - GR_GL_CALL_RET(gl, fKDLocation, - GetUniformLocation(programID, - fKDVar->getName().c_str())); + INHERITED::initUniforms(builder, gl, programID); + const char* kd = builder->getUniformCStr(fKDUni); + GR_GL_CALL_RET(gl, fKDLocation, GetUniformLocation(programID, kd)); } -void GrGLDiffuseLightingEffect::emitLightFunc(SkString* funcs) { +void GrGLDiffuseLightingEffect::emitLightFunc(const GrGLShaderBuilder* builder, SkString* funcs) { + const char* kd = builder->getUniformCStr(fKDUni); funcs->appendf("vec4 light(vec3 normal, vec3 surfaceToLight, vec3 lightColor) {\n"); - funcs->appendf("\tfloat colorScale = %s * dot(normal, surfaceToLight);\n", fKDVar->getName().c_str()); + funcs->appendf("\tfloat colorScale = %s * dot(normal, surfaceToLight);\n", kd); funcs->appendf("\treturn vec4(lightColor * clamp(colorScale, 0.0, 1.0), 1.0);\n"); funcs->appendf("}\n"); } @@ -1154,37 +1186,37 @@ bool GrSpecularLightingEffect::isEqual(const GrCustomStage& sBase) const { GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : GrGLLightingEffect(factory, stage) - , fKSVar(NULL) + , fKSUni(kInvalidUniformHandle) , fKSLocation(0) - , fShininessVar(NULL) + , fShininessUni(kInvalidUniformHandle) , fShininessLocation(0) { } -void GrGLSpecularLightingEffect::setupVariables(GrGLShaderBuilder* state, int stage) { - INHERITED::setupVariables(state, stage); - fKSVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uKS", stage); - fShininessVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uShininess", stage); +void GrGLSpecularLightingEffect::setupVariables(GrGLShaderBuilder* builder, int stage) { + INHERITED::setupVariables(builder, stage); + fKSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uKS", stage); + fShininessUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uShininess", stage); } -void GrGLSpecularLightingEffect::initUniforms(const GrGLInterface* gl, - int programID) { - INHERITED::initUniforms(gl, programID); - GR_GL_CALL_RET(gl, fKSLocation, - GetUniformLocation(programID, fKSVar->getName().c_str())); - GR_GL_CALL_RET(gl, fShininessLocation, - GetUniformLocation(programID, fShininessVar->getName().c_str())); +void GrGLSpecularLightingEffect::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID) { + INHERITED::initUniforms(builder, gl, programID); + const char* ks = builder->getUniformCStr(fKSUni); + const char* shininess = builder->getUniformCStr(fShininessUni); + GR_GL_CALL_RET(gl, fKSLocation, GetUniformLocation(programID, ks)); + GR_GL_CALL_RET(gl, fShininessLocation, GetUniformLocation(programID, shininess)); } -void GrGLSpecularLightingEffect::emitLightFunc(SkString* funcs) { +void GrGLSpecularLightingEffect::emitLightFunc(const GrGLShaderBuilder* builder, SkString* funcs) { funcs->appendf("vec4 light(vec3 normal, vec3 surfaceToLight, vec3 lightColor) {\n"); funcs->appendf("\tvec3 halfDir = vec3(normalize(surfaceToLight + vec3(0, 0, 1)));\n"); - funcs->appendf("\tfloat colorScale = %s * pow(dot(normal, halfDir), %s);\n", - fKSVar->getName().c_str(), fShininessVar->getName().c_str()); + const char* ks = builder->getUniformCStr(fKSUni); + const char* shininess = builder->getUniformCStr(fShininessUni); + funcs->appendf("\tfloat colorScale = %s * pow(dot(normal, halfDir), %s);\n", ks, shininess); funcs->appendf("\treturn vec4(lightColor * clamp(colorScale, 0.0, 1.0), 1.0);\n"); funcs->appendf("}\n"); } @@ -1202,23 +1234,28 @@ void GrGLSpecularLightingEffect::setData(const GrGLInterface* gl, /////////////////////////////////////////////////////////////////////////////// -void GrGLLight::emitLightColor(SkString* builder, const char *surfaceToLight) const { - builder->append(fColorVar->getName().c_str()); +void GrGLLight::emitLightColor(const GrGLShaderBuilder* builder, + SkString* out, + const char *surfaceToLight) const { + const char* color = builder->getUniformCStr(fColorUni); + out->append(color); } -void GrGLLight::setupVariables(GrGLShaderBuilder* state, int stage) { - fColorVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kVec3f_GrSLType, "uLightColor", stage); +void GrGLLight::setupVariables(GrGLShaderBuilder* builder, int stage) { + const GrGLShaderVar& colorVar = builder->getUniformVariable(fColorUni); + fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec3f_GrSLType, "uLightColor", stage); } -void GrGLLight::initUniforms(const GrGLInterface* gl, int programID) { - GR_GL_CALL_RET(gl, fColorVarLocation, - GetUniformLocation(programID, fColorVar->getName().c_str())); +void GrGLLight::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID) { + const char* color = builder->getUniformCStr(fColorUni); + GR_GL_CALL_RET(gl, fColorLocation, GetUniformLocation(programID, color)); } void GrGLLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const { - setUniformPoint3(gl, fColorVarLocation, light->color() * SkScalarInvert(SkIntToScalar(255))); + setUniformPoint3(gl, fColorLocation, light->color() * SkScalarInvert(SkIntToScalar(255))); } GrGLLight* SkDistantLight::createGLLight() const { @@ -1227,17 +1264,18 @@ GrGLLight* SkDistantLight::createGLLight() const { /////////////////////////////////////////////////////////////////////////////// -void GrGLDistantLight::setupVariables(GrGLShaderBuilder* state, int stage) { - INHERITED::setupVariables(state, stage); - fDirectionVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, - "uLightDirection", stage); +void GrGLDistantLight::setupVariables(GrGLShaderBuilder* builder, int stage) { + INHERITED::setupVariables(builder, stage); + fDirectionUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, + "uLightDirection", stage); } -void GrGLDistantLight::initUniforms(const GrGLInterface* gl, int programID) { - INHERITED::initUniforms(gl, programID); - GR_GL_CALL_RET(gl, fDirectionLocation, - GetUniformLocation(programID, fDirectionVar->getName().c_str())); +void GrGLDistantLight::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID) { + INHERITED::initUniforms(builder, gl, programID); + const char* dir = builder->getUniformCStr(fDirectionUni); + GR_GL_CALL_RET(gl, fDirectionLocation, GetUniformLocation(programID, dir)); } void GrGLDistantLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const { @@ -1247,24 +1285,27 @@ void GrGLDistantLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt setUniformNormal3(gl, fDirectionLocation, distantLight->direction()); } -void GrGLDistantLight::emitSurfaceToLight(SkString* builder, +void GrGLDistantLight::emitSurfaceToLight(const GrGLShaderBuilder* builder, + SkString* out, const char* z) const { - builder->append(fDirectionVar->getName().c_str()); + const char* dir = builder->getUniformCStr(fDirectionUni); + out->append(dir); } /////////////////////////////////////////////////////////////////////////////// -void GrGLPointLight::setupVariables(GrGLShaderBuilder* state, int stage) { - INHERITED::setupVariables(state, stage); - fLocationVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, - "uLightLocation", stage); +void GrGLPointLight::setupVariables(GrGLShaderBuilder* builder, int stage) { + INHERITED::setupVariables(builder, stage); + fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType, + "uLightLocation", stage); } -void GrGLPointLight::initUniforms(const GrGLInterface* gl, int programID) { - INHERITED::initUniforms(gl, programID); - GR_GL_CALL_RET(gl, fLocationLocation, - GetUniformLocation(programID, fLocationVar->getName().c_str())); +void GrGLPointLight::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID) { + INHERITED::initUniforms(builder, gl, programID); + const char* loc = builder->getUniformCStr(fLocationUni); + GR_GL_CALL_RET(gl, fLocationLocation, GetUniformLocation(programID, loc)); } void GrGLPointLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const { @@ -1274,54 +1315,47 @@ void GrGLPointLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, setUniformPoint3FlipY(gl, fLocationLocation, pointLight->location(), rt->height()); } -void GrGLPointLight::emitVS(SkString* builder) const { +void GrGLPointLight::emitVS(SkString* out) const { } -void GrGLPointLight::emitSurfaceToLight(SkString* builder, - const char* z) const { - const char *lName = fLocationVar->getName().c_str(); - builder->appendf( - "normalize(%s - vec3(gl_FragCoord.xy, %s))", lName, z); +void GrGLPointLight::emitSurfaceToLight(const GrGLShaderBuilder* builder, SkString* out, const char* z) const { + const char* loc = builder->getUniformCStr(fLocationUni); + out->appendf( + "normalize(%s - vec3(gl_FragCoord.xy, %s))", loc, z); } /////////////////////////////////////////////////////////////////////////////// -void GrGLSpotLight::setupVariables(GrGLShaderBuilder* state, int stage) { - INHERITED::setupVariables(state, stage); - fLocationVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kVec3f_GrSLType, "uLightLocation", stage); - fExponentVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uExponent", stage); - fCosInnerConeAngleVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uCosInnerConeAngle", stage); - fCosOuterConeAngleVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uCosOuterConeAngle", stage); - fConeScaleVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uConeScale", stage); - fSVar = &state->addUniform( - GrGLShaderBuilder::kFragment_ShaderType, - kVec3f_GrSLType, "uS", stage); -} - -void GrGLSpotLight::initUniforms(const GrGLInterface* gl, int programID) { - INHERITED::initUniforms(gl, programID); - GR_GL_CALL_RET(gl, fLocationLocation, - GetUniformLocation(programID, fLocationVar->getName().c_str())); - GR_GL_CALL_RET(gl, fExponentLocation, - GetUniformLocation(programID, fExponentVar->getName().c_str())); - GR_GL_CALL_RET(gl, fCosInnerConeAngleLocation, - GetUniformLocation(programID, fCosInnerConeAngleVar->getName().c_str())); - GR_GL_CALL_RET(gl, fCosOuterConeAngleLocation, - GetUniformLocation(programID, fCosOuterConeAngleVar->getName().c_str())); - GR_GL_CALL_RET(gl, fConeScaleLocation, - GetUniformLocation(programID, fConeScaleVar->getName().c_str())); - GR_GL_CALL_RET(gl, fSLocation, - GetUniformLocation(programID, fSVar->getName().c_str())); +void GrGLSpotLight::setupVariables(GrGLShaderBuilder* builder, int stage) { + INHERITED::setupVariables(builder, stage); + fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec3f_GrSLType, "uLightLocation", stage); + fExponentUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uExponent", stage); + fCosInnerConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uCosInnerConeAngle", stage); + fCosOuterConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uCosOuterConeAngle", stage); + fConeScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uConeScale", stage); + fSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec3f_GrSLType, "uS", stage); +} + +void GrGLSpotLight::initUniforms(const GrGLShaderBuilder* builder, const GrGLInterface* gl, int programID) { + INHERITED::initUniforms(builder, gl, programID); + const char* location = builder->getUniformCStr(fLocationUni); + 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); + GR_GL_CALL_RET(gl, fLocationLocation, GetUniformLocation(programID, location)); + GR_GL_CALL_RET(gl, fExponentLocation, GetUniformLocation(programID, exponent)); + GR_GL_CALL_RET(gl, fCosInnerConeAngleLocation, GetUniformLocation(programID, cosInner)); + GR_GL_CALL_RET(gl, fCosOuterConeAngleLocation, GetUniformLocation(programID, cosOuter)); + GR_GL_CALL_RET(gl, fConeScaleLocation, GetUniformLocation(programID, coneScale)); + GR_GL_CALL_RET(gl, fSLocation, GetUniformLocation(programID, s)); } void GrGLSpotLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, const SkLight* light) const { @@ -1336,30 +1370,40 @@ void GrGLSpotLight::setData(const GrGLInterface* gl, const GrRenderTarget* rt, c setUniformNormal3(gl, fSLocation, spotLight->s()); } -void GrGLSpotLight::emitVS(SkString* builder) const { +void GrGLSpotLight::emitVS(SkString* out) const { } -void GrGLSpotLight::emitFuncs(SkString* builder) const { - builder->appendf("vec3 lightColor(vec3 surfaceToLight) {\n"); - builder->appendf("\tfloat cosAngle = -dot(surfaceToLight, %s);\n", fSVar->getName().c_str()); - builder->appendf("\tif (cosAngle < %s) {\n", fCosOuterConeAngleVar->getName().c_str()); - builder->appendf("\t\treturn vec3(0);\n"); - builder->appendf("\t}\n"); - builder->appendf("\tfloat scale = pow(cosAngle, %s);\n", fExponentVar->getName().c_str()); - builder->appendf("\tif (cosAngle < %s) {\n", fCosInnerConeAngleVar->getName().c_str()); - builder->appendf("\t\treturn %s * scale * (cosAngle - %s) * %s;\n", fColorVar->getName().c_str(), fCosOuterConeAngleVar->getName().c_str(), fConeScaleVar->getName().c_str()); - builder->appendf("\t}\n"); - builder->appendf("\treturn %s;\n", fColorVar->getName().c_str()); - builder->appendf("}\n"); +void GrGLSpotLight::emitFuncs(const GrGLShaderBuilder* builder, SkString* out) const { + 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); + + out->appendf("vec3 lightColor(vec3 surfaceToLight) {\n"); + out->appendf("\tfloat cosAngle = -dot(surfaceToLight, %s);\n", s); + out->appendf("\tif (cosAngle < %s) {\n", cosOuter); + out->appendf("\t\treturn vec3(0);\n"); + out->appendf("\t}\n"); + out->appendf("\tfloat scale = pow(cosAngle, %s);\n", exponent); + out->appendf("\tif (cosAngle < %s) {\n", cosInner); + out->appendf("\t\treturn %s * scale * (cosAngle - %s) * %s;\n", color, cosOuter, coneScale); + out->appendf("\t}\n"); + out->appendf("\treturn %s;\n", color); + out->appendf("}\n"); } -void GrGLSpotLight::emitSurfaceToLight(SkString* builder, const char* z) const { - builder->appendf( - "normalize(%s - vec3(gl_FragCoord.xy, %s))", fLocationVar->getName().c_str(), z); +void GrGLSpotLight::emitSurfaceToLight(const GrGLShaderBuilder* builder, + SkString* out, + const char* z) const { + const char* location= builder->getUniformCStr(fLocationUni); + out->appendf("normalize(%s - vec3(gl_FragCoord.xy, %s))", location, z); } -void GrGLSpotLight::emitLightColor(SkString* builder, const char *surfaceToLight) const { - builder->appendf("lightColor(%s)", surfaceToLight); +void GrGLSpotLight::emitLightColor(const GrGLShaderBuilder* builder, + SkString* out, const char *surfaceToLight) const { + out->appendf("lightColor(%s)", surfaceToLight); } SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp index 3804d57130..a16313eac8 100644 --- a/src/gpu/effects/GrConvolutionEffect.cpp +++ b/src/gpu/effects/GrConvolutionEffect.cpp @@ -11,21 +11,27 @@ #include "gl/GrGLTexture.h" #include "GrProgramStageFactory.h" +// For brevity, and these definitions are likely to move to a different class soon. +typedef GrGLShaderBuilder::UniformHandle UniformHandle; +static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle; + class GrGLConvolutionEffect : public GrGLProgramStage { public: GrGLConvolutionEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage); - virtual void setupVariables(GrGLShaderBuilder* state, + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void emitVS(GrGLShaderBuilder* state, + virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) SK_OVERRIDE; - virtual void emitFS(GrGLShaderBuilder* state, + virtual void emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder*, + const GrGLInterface*, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface*, const GrCustomStage&, @@ -37,11 +43,11 @@ public: private: int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); } - int fRadius; - const GrGLShaderVar* fKernelVar; - GrGLint fKernelLocation; - const GrGLShaderVar* fImageIncrementVar; - GrGLint fImageIncrementLocation; + int fRadius; + UniformHandle fKernelUni; + GrGLint fKernelLocation; + UniformHandle fImageIncrementUni; + GrGLint fImageIncrementLocation; typedef GrGLProgramStage INHERITED; }; @@ -49,72 +55,72 @@ private: GrGLConvolutionEffect::GrGLConvolutionEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : GrGLProgramStage(factory) - , fKernelVar(NULL) + , fKernelUni(kInvalidUniformHandle) , fKernelLocation(0) - , fImageIncrementVar(NULL) + , fImageIncrementUni(kInvalidUniformHandle) , fImageIncrementLocation(0) { const GrConvolutionEffect& c = static_cast<const GrConvolutionEffect&>(stage); fRadius = c.radius(); } -void GrGLConvolutionEffect::setupVariables(GrGLShaderBuilder* state, +void GrGLConvolutionEffect::setupVariables(GrGLShaderBuilder* builder, int stage) { - fImageIncrementVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType | - GrGLShaderBuilder::kVertex_ShaderType, - kVec2f_GrSLType, "uImageIncrement", stage); - fKernelVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uKernel", stage, this->width()); + fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType | + GrGLShaderBuilder::kVertex_ShaderType, + kVec2f_GrSLType, "uImageIncrement", stage); + fKernelUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uKernel", stage, this->width()); fImageIncrementLocation = kUseUniform; fKernelLocation = kUseUniform; } -void GrGLConvolutionEffect::emitVS(GrGLShaderBuilder* state, +void GrGLConvolutionEffect::emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) { - SkString* code = &state->fVSCode; - code->appendf("\t\t%s -= vec2(%d, %d) * %s;\n", - vertexCoords, fRadius, fRadius, - fImageIncrementVar->getName().c_str()); + SkString* code = &builder->fVSCode; + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); + code->appendf("\t\t%s -= vec2(%d, %d) * %s;\n", vertexCoords, fRadius, fRadius, imgInc); } -void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* state, +void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) { - SkString* code = &state->fFSCode; + SkString* code = &builder->fFSCode; code->appendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor); - code->appendf("\t\tvec2 coord = %s;\n", state->fSampleCoords.c_str()); + code->appendf("\t\tvec2 coord = %s;\n", builder->fSampleCoords.c_str()); int width = this ->width(); + const GrGLShaderVar& kernel = builder->getUniformVariable(fKernelUni); + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); // Manually unroll loop because some drivers don't; yields 20-30% speedup. for (int i = 0; i < width; i++) { SkString index; SkString kernelIndex; index.appendS32(i); - fKernelVar->appendArrayAccess(index.c_str(), &kernelIndex); + kernel.appendArrayAccess(index.c_str(), &kernelIndex); code->appendf("\t\t%s += ", outputColor); - state->emitTextureLookup(samplerName, "coord"); + builder->emitTextureLookup(samplerName, "coord"); code->appendf(" * %s;\n", kernelIndex.c_str()); - code->appendf("\t\tcoord += %s;\n", - fImageIncrementVar->getName().c_str()); + code->appendf("\t\tcoord += %s;\n", imgInc); } - if (state->fModulate.size()) { + if (builder->fModulate.size()) { code->appendf("\t\t%s = %s%s;\n", outputColor, outputColor, - state->fModulate.c_str()); + builder->fModulate.c_str()); } } -void GrGLConvolutionEffect::initUniforms(const GrGLInterface* gl, +void GrGLConvolutionEffect::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, int programID) { - GR_GL_CALL_RET(gl, fImageIncrementLocation, - GetUniformLocation(programID, - fImageIncrementVar->getName().c_str())); - GR_GL_CALL_RET(gl, fKernelLocation, - GetUniformLocation(programID, fKernelVar->getName().c_str())); + const char* kernel = builder->getUniformCStr(fKernelUni); + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); + GR_GL_CALL_RET(gl, fImageIncrementLocation, GetUniformLocation(programID, imgInc)); + GR_GL_CALL_RET(gl, fKernelLocation, GetUniformLocation(programID, kernel)); } void GrGLConvolutionEffect::setData(const GrGLInterface* gl, diff --git a/src/gpu/effects/GrGradientEffects.cpp b/src/gpu/effects/GrGradientEffects.cpp index 3125657af2..57767b3827 100644 --- a/src/gpu/effects/GrGradientEffects.cpp +++ b/src/gpu/effects/GrGradientEffects.cpp @@ -19,9 +19,9 @@ public: const GrCustomStage&) : INHERITED (factory) { } virtual ~GrGLRadialGradient() { } - virtual void emitVS(GrGLShaderBuilder* state, + virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) SK_OVERRIDE { } - virtual void emitFS(GrGLShaderBuilder* state, + virtual void emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) SK_OVERRIDE; @@ -34,15 +34,15 @@ private: }; -void GrGLRadialGradient::emitFS(GrGLShaderBuilder* state, +void GrGLRadialGradient::emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) { - state->fSampleCoords.printf("vec2(length(%s.xy), 0.5)", - state->fSampleCoords.c_str()); - state->fComplexCoord = true; + builder->fSampleCoords.printf("vec2(length(%s.xy), 0.5)", + builder->fSampleCoords.c_str()); + builder->fComplexCoord = true; - state->emitDefaultFetch(outputColor, samplerName); + builder->emitDefaultFetch(outputColor, samplerName); } @@ -69,6 +69,10 @@ bool GrRadialGradient::isEqual(const GrCustomStage& sBase) const { ///////////////////////////////////////////////////////////////////// +// For brevity, and these definitions are likely to move to a different class soon. +typedef GrGLShaderBuilder::UniformHandle UniformHandle; +static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle; + class GrGLRadial2Gradient : public GrGLProgramStage { public: @@ -77,15 +81,17 @@ public: const GrCustomStage&); virtual ~GrGLRadial2Gradient() { } - virtual void setupVariables(GrGLShaderBuilder* state, + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void emitVS(GrGLShaderBuilder* state, + virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) SK_OVERRIDE; - virtual void emitFS(GrGLShaderBuilder* state, + virtual void emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface*, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface*, const GrCustomStage&, const GrRenderTarget*, @@ -97,10 +103,10 @@ public: protected: - const GrGLShaderVar* fVSParamVar; - GrGLint fVSParamLocation; - const GrGLShaderVar* fFSParamVar; - GrGLint fFSParamLocation; + UniformHandle fVSParamUni; + GrGLint fVSParamLocation; + UniformHandle fFSParamUni; + GrGLint fFSParamLocation; const char* fVSVaryingName; const char* fFSVaryingName; @@ -126,8 +132,8 @@ GrGLRadial2Gradient::GrGLRadial2Gradient( const GrProgramStageFactory& factory, const GrCustomStage& baseData) : INHERITED(factory) - , fVSParamVar(NULL) - , fFSParamVar(NULL) + , fVSParamUni(kInvalidUniformHandle) + , fFSParamUni(kInvalidUniformHandle) , fVSVaryingName(NULL) , fFSVaryingName(NULL) , fCachedCenter(GR_ScalarMax) @@ -139,37 +145,37 @@ GrGLRadial2Gradient::GrGLRadial2Gradient( fIsDegenerate = data.isDegenerate(); } -void GrGLRadial2Gradient::setupVariables(GrGLShaderBuilder* state, int stage) { +void GrGLRadial2Gradient::setupVariables(GrGLShaderBuilder* builder, int stage) { // 2 copies of uniform array, 1 for each of vertex & fragment shader, // to work around Xoom bug. Doesn't seem to cause performance decrease // in test apps, but need to keep an eye on it. - fVSParamVar = &state->addUniform(GrGLShaderBuilder::kVertex_ShaderType, - kFloat_GrSLType, "uRadial2VSParams", stage, 6); - fFSParamVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uRadial2FSParams", stage, 6); + fVSParamUni = builder->addUniform(GrGLShaderBuilder::kVertex_ShaderType, + kFloat_GrSLType, "uRadial2VSParams", stage, 6); + fFSParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uRadial2FSParams", stage, 6); fVSParamLocation = GrGLProgramStage::kUseUniform; fFSParamLocation = GrGLProgramStage::kUseUniform; // For radial gradients without perspective we can pass the linear // part of the quadratic as a varying. - if (state->fVaryingDims == state->fCoordDims) { - state->addVarying(kFloat_GrSLType, "Radial2BCoeff", stage, + if (builder->fVaryingDims == builder->fCoordDims) { + builder->addVarying(kFloat_GrSLType, "Radial2BCoeff", stage, &fVSVaryingName, &fFSVaryingName); } } -void GrGLRadial2Gradient::emitVS(GrGLShaderBuilder* state, +void GrGLRadial2Gradient::emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) { - SkString* code = &state->fVSCode; + SkString* code = &builder->fVSCode; SkString p2; SkString p3; - fVSParamVar->appendArrayAccess(2, &p2); - fVSParamVar->appendArrayAccess(3, &p3); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); // For radial gradients without perspective we can pass the linear // part of the quadratic as a varying. - if (state->fVaryingDims == state->fCoordDims) { + if (builder->fVaryingDims == builder->fCoordDims) { // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3]) code->appendf("\t%s = 2.0 *(%s * %s.x - %s);\n", fVSVaryingName, p2.c_str(), @@ -177,11 +183,11 @@ void GrGLRadial2Gradient::emitVS(GrGLShaderBuilder* state, } } -void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* state, +void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) { - SkString* code = &state->fFSCode; + SkString* code = &builder->fFSCode; SkString cName("c"); SkString ac4Name("ac4"); SkString rootName("root"); @@ -191,32 +197,32 @@ void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* state, SkString p3; SkString p4; SkString p5; - fFSParamVar->appendArrayAccess(0, &p0); - fFSParamVar->appendArrayAccess(1, &p1); - fFSParamVar->appendArrayAccess(2, &p2); - fFSParamVar->appendArrayAccess(3, &p3); - fFSParamVar->appendArrayAccess(4, &p4); - fFSParamVar->appendArrayAccess(5, &p5); + builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); + builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); + builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); + builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); + builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); + builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); // If we we're able to interpolate the linear component, // bVar is the varying; otherwise compute it SkString bVar; - if (state->fCoordDims == state->fVaryingDims) { + if (builder->fCoordDims == builder->fVaryingDims) { bVar = fFSVaryingName; - GrAssert(2 == state->fVaryingDims); + GrAssert(2 == builder->fVaryingDims); } else { - GrAssert(3 == state->fVaryingDims); + GrAssert(3 == builder->fVaryingDims); bVar = "b"; //bVar.appendS32(stageNum); code->appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", bVar.c_str(), p2.c_str(), - state->fSampleCoords.c_str(), p3.c_str()); + builder->fSampleCoords.c_str(), p3.c_str()); } // c = (x^2)+(y^2) - params[4] code->appendf("\tfloat %s = dot(%s, %s) - %s;\n", - cName.c_str(), state->fSampleCoords.c_str(), - state->fSampleCoords.c_str(), + cName.c_str(), builder->fSampleCoords.c_str(), + builder->fSampleCoords.c_str(), p4.c_str()); // If we aren't degenerate, emit some extra code, and accept a slightly @@ -236,25 +242,27 @@ void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* state, // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1] // y coord is 0.5 (texture is effectively 1D) - state->fSampleCoords.printf("vec2((-%s + %s * %s) * %s, 0.5)", - bVar.c_str(), p5.c_str(), - rootName.c_str(), p1.c_str()); + builder->fSampleCoords.printf("vec2((-%s + %s * %s) * %s, 0.5)", + bVar.c_str(), p5.c_str(), + rootName.c_str(), p1.c_str()); } else { // x coord is: -c/b // y coord is 0.5 (texture is effectively 1D) - state->fSampleCoords.printf("vec2((-%s / %s), 0.5)", - cName.c_str(), bVar.c_str()); + builder->fSampleCoords.printf("vec2((-%s / %s), 0.5)", + cName.c_str(), bVar.c_str()); } - state->fComplexCoord = true; + builder->fComplexCoord = true; - state->emitDefaultFetch(outputColor, samplerName); + builder->emitDefaultFetch(outputColor, samplerName); } -void GrGLRadial2Gradient::initUniforms(const GrGLInterface* gl, int programID) { - GR_GL_CALL_RET(gl, fVSParamLocation, - GetUniformLocation(programID, fVSParamVar->getName().c_str())); - GR_GL_CALL_RET(gl, fFSParamLocation, - GetUniformLocation(programID, fFSParamVar->getName().c_str())); +void GrGLRadial2Gradient::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID) { + const char* vsParam = builder->getUniformCStr(fVSParamUni); + const char* fsParam = builder->getUniformCStr(fFSParamUni); + GR_GL_CALL_RET(gl, fVSParamLocation, GetUniformLocation(programID, vsParam)); + GR_GL_CALL_RET(gl, fFSParamLocation, GetUniformLocation(programID, fsParam)); } void GrGLRadial2Gradient::setData(const GrGLInterface* gl, @@ -335,15 +343,17 @@ public: const GrCustomStage&); virtual ~GrGLConical2Gradient() { } - virtual void setupVariables(GrGLShaderBuilder* state, + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; - virtual void emitVS(GrGLShaderBuilder* state, + virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) SK_OVERRIDE; - virtual void emitFS(GrGLShaderBuilder* state, + virtual void emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) SK_OVERRIDE; - virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE; + virtual void initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface*, + int programID) SK_OVERRIDE; virtual void setData(const GrGLInterface*, const GrCustomStage&, const GrRenderTarget*, @@ -355,10 +365,10 @@ public: protected: - const GrGLShaderVar* fVSParamVar; - GrGLint fVSParamLocation; - const GrGLShaderVar* fFSParamVar; - GrGLint fFSParamLocation; + UniformHandle fVSParamUni; + GrGLint fVSParamLocation; + UniformHandle fFSParamUni; + GrGLint fFSParamLocation; const char* fVSVaryingName; const char* fFSVaryingName; @@ -384,8 +394,8 @@ GrGLConical2Gradient::GrGLConical2Gradient( const GrProgramStageFactory& factory, const GrCustomStage& baseData) : INHERITED(factory) - , fVSParamVar(NULL) - , fFSParamVar(NULL) + , fVSParamUni(kInvalidUniformHandle) + , fFSParamUni(kInvalidUniformHandle) , fVSVaryingName(NULL) , fFSVaryingName(NULL) , fCachedCenter(GR_ScalarMax) @@ -397,39 +407,39 @@ GrGLConical2Gradient::GrGLConical2Gradient( fIsDegenerate = data.isDegenerate(); } -void GrGLConical2Gradient::setupVariables(GrGLShaderBuilder* state, int stage) { +void GrGLConical2Gradient::setupVariables(GrGLShaderBuilder* builder, int stage) { // 2 copies of uniform array, 1 for each of vertex & fragment shader, // to work around Xoom bug. Doesn't seem to cause performance decrease // in test apps, but need to keep an eye on it. - fVSParamVar = &state->addUniform(GrGLShaderBuilder::kVertex_ShaderType, - kFloat_GrSLType, "uConical2VSParams", stage, 6); - fFSParamVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kFloat_GrSLType, "uConical2FSParams", stage, 6); + fVSParamUni = builder->addUniform(GrGLShaderBuilder::kVertex_ShaderType, + kFloat_GrSLType, "uConical2VSParams", stage, 6); + fFSParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kFloat_GrSLType, "uConical2FSParams", stage, 6); fVSParamLocation = GrGLProgramStage::kUseUniform; fFSParamLocation = GrGLProgramStage::kUseUniform; // For radial gradients without perspective we can pass the linear // part of the quadratic as a varying. - if (state->fVaryingDims == state->fCoordDims) { - state->addVarying(kFloat_GrSLType, "Conical2BCoeff", stage, - &fVSVaryingName, &fFSVaryingName); + if (builder->fVaryingDims == builder->fCoordDims) { + builder->addVarying(kFloat_GrSLType, "Conical2BCoeff", stage, + &fVSVaryingName, &fFSVaryingName); } } -void GrGLConical2Gradient::emitVS(GrGLShaderBuilder* state, +void GrGLConical2Gradient::emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) { - SkString* code = &state->fVSCode; + SkString* code = &builder->fVSCode; SkString p2; // distance between centers SkString p3; // start radius SkString p5; // difference in radii (r1 - r0) - fVSParamVar->appendArrayAccess(2, &p2); - fVSParamVar->appendArrayAccess(3, &p3); - fVSParamVar->appendArrayAccess(5, &p5); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5); // For radial gradients without perspective we can pass the linear // part of the quadratic as a varying. - if (state->fVaryingDims == state->fCoordDims) { + if (builder->fVaryingDims == builder->fCoordDims) { // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5]) code->appendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n", fVSVaryingName, p2.c_str(), @@ -437,11 +447,11 @@ void GrGLConical2Gradient::emitVS(GrGLShaderBuilder* state, } } -void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* state, +void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) { - SkString* code = &state->fFSCode; + SkString* code = &builder->fFSCode; SkString cName("c"); SkString ac4Name("ac4"); @@ -456,24 +466,25 @@ void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* state, SkString p3; // start radius SkString p4; // start radius squared SkString p5; // difference in radii (r1 - r0) - fFSParamVar->appendArrayAccess(0, &p0); - fFSParamVar->appendArrayAccess(1, &p1); - fFSParamVar->appendArrayAccess(2, &p2); - fFSParamVar->appendArrayAccess(3, &p3); - fFSParamVar->appendArrayAccess(4, &p4); - fFSParamVar->appendArrayAccess(5, &p5); + + builder->getUniformVariable(fVSParamUni).appendArrayAccess(0, &p0); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(1, &p1); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(4, &p4); + builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5); // If we we're able to interpolate the linear component, // bVar is the varying; otherwise compute it SkString bVar; - if (state->fCoordDims == state->fVaryingDims) { + if (builder->fCoordDims == builder->fVaryingDims) { bVar = fFSVaryingName; - GrAssert(2 == state->fVaryingDims); + GrAssert(2 == builder->fVaryingDims); } else { - GrAssert(3 == state->fVaryingDims); + GrAssert(3 == builder->fVaryingDims); bVar = "b"; code->appendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n", - bVar.c_str(), p2.c_str(), state->fSampleCoords.c_str(), + bVar.c_str(), p2.c_str(), builder->fSampleCoords.c_str(), p3.c_str(), p5.c_str()); } @@ -483,7 +494,7 @@ void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* state, // c = (x^2)+(y^2) - params[4] code->appendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(), - state->fSampleCoords.c_str(), state->fSampleCoords.c_str(), + builder->fSampleCoords.c_str(), builder->fSampleCoords.c_str(), p4.c_str()); // Non-degenerate case (quadratic) @@ -527,8 +538,8 @@ void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* state, // y coord is 0.5 (texture is effectively 1D) code->appendf("\t\t"); - state->fSampleCoords.printf("vec2(%s, 0.5)", tName.c_str()); - state->emitDefaultFetch(outputColor, samplerName); + builder->fSampleCoords.printf("vec2(%s, 0.5)", tName.c_str()); + builder->emitDefaultFetch(outputColor, samplerName); // otherwise, if r(t) for the larger root was <= 0, try the other root code->appendf("\t\t} else {\n"); @@ -541,8 +552,8 @@ void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* state, // y coord is 0.5 (texture is effectively 1D) code->appendf("\t\t\t"); - state->fSampleCoords.printf("vec2(%s, 0.5)", tName.c_str()); - state->emitDefaultFetch(outputColor, samplerName); + builder->fSampleCoords.printf("vec2(%s, 0.5)", tName.c_str()); + builder->emitDefaultFetch(outputColor, samplerName); // end if (r(t) > 0) for smaller root code->appendf("\t\t\t}\n"); @@ -560,18 +571,20 @@ void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* state, code->appendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), p5.c_str(), p3.c_str()); code->appendf("\t"); - state->fSampleCoords.printf("vec2(%s, 0.5)", tName.c_str()); - state->emitDefaultFetch(outputColor, samplerName); + builder->fSampleCoords.printf("vec2(%s, 0.5)", tName.c_str()); + builder->emitDefaultFetch(outputColor, samplerName); code->appendf("\t}\n"); } - state->fComplexCoord = true; + builder->fComplexCoord = true; } -void GrGLConical2Gradient::initUniforms(const GrGLInterface* gl, int programID) { - GR_GL_CALL_RET(gl, fVSParamLocation, - GetUniformLocation(programID, fVSParamVar->getName().c_str())); - GR_GL_CALL_RET(gl, fFSParamLocation, - GetUniformLocation(programID, fFSParamVar->getName().c_str())); +void GrGLConical2Gradient::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID) { + const char* vsParam = builder->getUniformCStr(fVSParamUni); + const char* fsParam = builder->getUniformCStr(fFSParamUni); + GR_GL_CALL_RET(gl, fVSParamLocation, GetUniformLocation(programID, vsParam)); + GR_GL_CALL_RET(gl, fFSParamLocation, GetUniformLocation(programID, fsParam)); } void GrGLConical2Gradient::setData(const GrGLInterface* gl, @@ -655,9 +668,9 @@ public: const GrCustomStage&) : INHERITED (factory) { } virtual ~GrGLSweepGradient() { } - virtual void emitVS(GrGLShaderBuilder* state, + virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) SK_OVERRIDE { } - virtual void emitFS(GrGLShaderBuilder* state, + virtual void emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) SK_OVERRIDE; @@ -670,16 +683,16 @@ private: }; -void GrGLSweepGradient::emitFS(GrGLShaderBuilder* state, +void GrGLSweepGradient::emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) { - state->fSampleCoords.printf( + builder->fSampleCoords.printf( "vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)", - state->fSampleCoords.c_str(), state->fSampleCoords.c_str()); - state->fComplexCoord = true; + builder->fSampleCoords.c_str(), builder->fSampleCoords.c_str()); + builder->fComplexCoord = true; - state->emitDefaultFetch(outputColor, samplerName); + builder->emitDefaultFetch(outputColor, samplerName); } ///////////////////////////////////////////////////////////////////// diff --git a/src/gpu/effects/GrMorphologyEffect.cpp b/src/gpu/effects/GrMorphologyEffect.cpp index 180b5eb3a6..6699989f04 100644 --- a/src/gpu/effects/GrMorphologyEffect.cpp +++ b/src/gpu/effects/GrMorphologyEffect.cpp @@ -18,7 +18,7 @@ public: GrGLMorphologyEffect (const GrProgramStageFactory& factory, const GrCustomStage& stage); - virtual void setupVariables(GrGLShaderBuilder* state, + virtual void setupVariables(GrGLShaderBuilder* builder, int stage) SK_OVERRIDE; virtual void emitVS(GrGLShaderBuilder* state, const char* vertexCoords) SK_OVERRIDE; @@ -29,8 +29,10 @@ public: static inline StageKey GenKey(const GrCustomStage& s); - virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface*, + virtual void initUniforms(const GrGLShaderBuilder*, + const GrGLInterface*, + int programID) SK_OVERRIDE; + virtual void setData(const GrGLInterface*, const GrCustomStage&, const GrRenderTarget*, int stageNum) SK_OVERRIDE; @@ -40,7 +42,7 @@ private: int fRadius; GrMorphologyEffect::MorphologyType fType; - const GrGLShaderVar* fImageIncrementVar; + GrGLShaderBuilder::UniformHandle fImageIncrementUni; GrGLint fImageIncrementLocation; typedef GrGLProgramStage INHERITED; @@ -49,50 +51,47 @@ private: GrGLMorphologyEffect ::GrGLMorphologyEffect(const GrProgramStageFactory& factory, const GrCustomStage& stage) : GrGLProgramStage(factory) - , fImageIncrementVar(NULL) + , fImageIncrementUni(GrGLShaderBuilder::kInvalidUniformHandle) , fImageIncrementLocation(0) { const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(stage); fRadius = m.radius(); fType = m.type(); } -void GrGLMorphologyEffect::setupVariables(GrGLShaderBuilder* state, int stage) { - fImageIncrementVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType | - GrGLShaderBuilder::kVertex_ShaderType, - kVec2f_GrSLType, "uImageIncrement", stage); +void GrGLMorphologyEffect::setupVariables(GrGLShaderBuilder* builder, int stage) { + fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType | + GrGLShaderBuilder::kVertex_ShaderType, + kVec2f_GrSLType, "uImageIncrement", stage); } -void GrGLMorphologyEffect::emitVS(GrGLShaderBuilder* state, +void GrGLMorphologyEffect::emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) { - SkString* code = &state->fVSCode; - code->appendf("\t\t%s -= vec2(%d, %d) * %s;\n", - vertexCoords, fRadius, fRadius, - fImageIncrementVar->getName().c_str()); + SkString* code = &builder->fVSCode; + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); + code->appendf("\t\t%s -= vec2(%d, %d) * %s;\n", vertexCoords, fRadius, fRadius, imgInc); } -void GrGLMorphologyEffect::initUniforms(const GrGLInterface* gl, +void GrGLMorphologyEffect::initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, int programID) { - GR_GL_CALL_RET(gl, fImageIncrementLocation, - GetUniformLocation(programID, - fImageIncrementVar->getName().c_str())); + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); + GR_GL_CALL_RET(gl, fImageIncrementLocation, GetUniformLocation(programID, imgInc)); } -void GrGLMorphologyEffect ::emitFS(GrGLShaderBuilder* state, +void GrGLMorphologyEffect ::emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) { - SkString* code = &state->fFSCode; - // const char* texFunc = "texture2D"; - // bool complexCoord = false; + SkString* code = &builder->fFSCode; const char* func; switch (fType) { case GrContext::kErode_MorphologyType: - state->fFSCode.appendf("\t\tvec4 value = vec4(1, 1, 1, 1);\n"); + code->appendf("\t\tvec4 value = vec4(1, 1, 1, 1);\n"); func = "min"; break; case GrContext::kDilate_MorphologyType: - state->fFSCode.appendf("\t\tvec4 value = vec4(0, 0, 0, 0);\n"); + code->appendf("\t\tvec4 value = vec4(0, 0, 0, 0);\n"); func = "max"; break; default: @@ -100,19 +99,16 @@ void GrGLMorphologyEffect ::emitFS(GrGLShaderBuilder* state, func = ""; // suppress warning break; } + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); - code->appendf("\t\tvec2 coord = %s;\n", state->fSampleCoords.c_str()); + code->appendf("\t\tvec2 coord = %s;\n", builder->fSampleCoords.c_str()); code->appendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width()); - state->fFSCode.appendf("\t\t\tvalue = %s(value, ", func); - state->emitTextureLookup(samplerName, "coord"); - state->fFSCode.appendf(");\n"); - code->appendf("\t\t\tcoord += %s;\n", - fImageIncrementVar->getName().c_str()); + code->appendf("\t\t\tvalue = %s(value, ", func); + builder->emitTextureLookup(samplerName, "coord"); + code->appendf(");\n"); + code->appendf("\t\t\tcoord += %s;\n", imgInc); code->appendf("\t\t}\n"); - - state->fFSCode.appendf("\t\t%s = value%s;\n", - outputColor, - state->fModulate.c_str()); + code->appendf("\t\t%s = value%s;\n", outputColor, builder->fModulate.c_str()); } GrGLProgramStage::StageKey GrGLMorphologyEffect::GenKey( diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 1ad9817372..d13620cb20 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -932,7 +932,7 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl, return false; } - this->getUniformLocationsAndInitCache(gl, programData); + this->getUniformLocationsAndInitCache(builder, gl, programData); return true; } @@ -1003,7 +1003,8 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLContextInfo& gl, return true; } -void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl, +void GrGLProgram::getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder, + const GrGLContextInfo& gl, CachedData* programData) const { const GrGLint& progID = programData->fProgramID; @@ -1066,8 +1067,7 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl, } if (NULL != programData->fCustomStage[s]) { - programData->fCustomStage[s]-> - initUniforms(gl.interface(), progID); + programData->fCustomStage[s]->initUniforms(&builder, gl.interface(), progID); } } } @@ -1118,10 +1118,12 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, } else { SkString texMatName; tex_matrix_name(stageNum, &texMatName); - const GrGLShaderVar* mat = &segments->addUniform(GrGLShaderBuilder::kVertex_ShaderType, - kMat33f_GrSLType, texMatName.c_str()); + GrGLShaderBuilder::UniformHandle m = + segments->addUniform(GrGLShaderBuilder::kVertex_ShaderType, + kMat33f_GrSLType, texMatName.c_str()); + const GrGLShaderVar& mat = segments->getUniformVariable(m); // Can't use texMatName.c_str() because it's on the stack! - matName = mat->getName().c_str(); + matName = mat.getName().c_str(); locations->fTextureMatrixUni = kUseUniform; if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) { diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index 0be08b3b39..bebaa58e0b 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -366,7 +366,8 @@ private: CachedData* programData) const; // Binds uniforms; initializes cache to invalid values. - void getUniformLocationsAndInitCache(const GrGLContextInfo& gl, + void getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder, + const GrGLContextInfo& gl, CachedData* programData) const; friend class GrGpuGL; diff --git a/src/gpu/gl/GrGLProgramStage.cpp b/src/gpu/gl/GrGLProgramStage.cpp index c1d4942015..fe103ad866 100644 --- a/src/gpu/gl/GrGLProgramStage.cpp +++ b/src/gpu/gl/GrGLProgramStage.cpp @@ -17,11 +17,13 @@ GrGLProgramStage::~GrGLProgramStage() { /////////////////////////////////////////////////////////////////////////////// -void GrGLProgramStage::setupVariables(GrGLShaderBuilder* state, int stage) { +void GrGLProgramStage::setupVariables(GrGLShaderBuilder*, int stage) { } -void GrGLProgramStage::initUniforms(const GrGLInterface*, int progID) { +void GrGLProgramStage::initUniforms(const GrGLShaderBuilder*, + const GrGLInterface*, + int progID) { } diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h index d5c79b4f65..6350ae34b8 100644 --- a/src/gpu/gl/GrGLProgramStage.h +++ b/src/gpu/gl/GrGLProgramStage.h @@ -48,7 +48,7 @@ public: virtual ~GrGLProgramStage(); /** Create any uniforms or varyings the vertex shader requires. */ - virtual void setupVariables(GrGLShaderBuilder* state, int stage); + virtual void setupVariables(GrGLShaderBuilder* builder, int stage); /** Appends vertex code to the appropriate SkString on the state. @@ -56,7 +56,7 @@ public: Vertex shader input is a vec2 of coordinates, which may be altered. The code will be inside an otherwise-empty block. */ - virtual void emitVS(GrGLShaderBuilder* state, + virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) = 0; /** Appends fragment code to the appropriate SkString @@ -68,14 +68,16 @@ public: a function here for them to call into that'll apply any texture domain - but do we force them to be honest about texture domain parameters? */ - virtual void emitFS(GrGLShaderBuilder* state, + virtual void emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) = 0; /** Binds uniforms; we must have already bound the program and determined its GL program ID. */ - virtual void initUniforms(const GrGLInterface* gl, int programID); + virtual void initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID); /** A GrGLCustomStage instance can be reused with any GrCustomStage that produces the same stage key; this function reads data from diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 3303bf2729..7fa804a7e5 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -23,13 +23,12 @@ static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar: //const int GrGLShaderBuilder::fCoordDims = 2; GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx) - : fVSUnis(kVarsPerBlock) + : fUniforms(kVarsPerBlock) , fVSAttrs(kVarsPerBlock) , fVSOutputs(kVarsPerBlock) , fGSInputs(kVarsPerBlock) , fGSOutputs(kVarsPerBlock) , fFSInputs(kVarsPerBlock) - , fFSUnis(kVarsPerBlock) , fFSOutputs(kMaxFSOutputs) , fUsesGS(false) , fVaryingDims(0) @@ -116,38 +115,45 @@ void GrGLShaderBuilder::emitDefaultFetch(const char* outColor, fFSCode.appendf("%s%s;\n", fSwizzle.c_str(), fModulate.c_str()); } -const GrGLShaderVar& GrGLShaderBuilder::addUniform(uint32_t visibility, - GrSLType type, - const char* name, - int stageNum, - int count) { +namespace { +inline int handle_to_index(GrGLShaderBuilder::UniformHandle h) { return ~h; } +inline GrGLShaderBuilder::UniformHandle index_to_handle(int i) { return ~i; } +} + +GrGLShaderBuilder::UniformHandle GrGLShaderBuilder::addUniform(uint32_t visibility, + GrSLType type, + const char* name, + int stageNum, + int count) { GrAssert(name && strlen(name)); static const uint32_t kVisibilityMask = kVertex_ShaderType | kFragment_ShaderType; GrAssert(0 == (~kVisibilityMask & visibility)); GrAssert(0 != visibility); - GrGLShaderVar* var = NULL; - if (kVertex_ShaderType & visibility) { - var = &fVSUnis.push_back(); - } else { - GrAssert(kFragment_ShaderType & visibility); - var = &fFSUnis.push_back(); - } - var->setType(type); - var->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); - var->setName(name); + Uniform& uni = fUniforms.push_back(); + UniformHandle h = index_to_handle(fUniforms.count() - 1); + uni.fVariable.setType(type); + uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); + uni.fVariable.setName(name); if (stageNum >= 0) { - var->accessName()->appendS32(stageNum); + uni.fVariable.accessName()->appendS32(stageNum); } - var->setArrayCount(count); + uni.fVariable.setArrayCount(count); + uni.fVisibility = visibility; + // If it is visible in both the VS and FS, the precision must match. + // We declare a default FS precision, but not a default VS. So set the var + // to use the default FS precision. if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) { // the fragment and vertex precisions must match - var->setPrecision(kDefaultFragmentPrecision); - fFSUnis.push_back(*var); + uni.fVariable.setPrecision(kDefaultFragmentPrecision); } - return *var; + return h; +} + +const GrGLShaderVar& GrGLShaderBuilder::getUniformVariable(UniformHandle u) const { + return fUniforms[handle_to_index(u)].fVariable; } void GrGLShaderBuilder::addVarying(GrSLType type, @@ -222,31 +228,37 @@ inline void append_default_precision_qualifier(GrGLShaderVar::Precision p, } } } +} -void append_decls(const GrGLShaderBuilder::VarArray& vars, - const GrGLContextInfo& ctx, - SkString* string) { +void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { for (int i = 0; i < vars.count(); ++i) { - vars[i].appendDecl(ctx, string); + vars[i].appendDecl(fContext, out); } } + +void GrGLShaderBuilder::appendUniformDecls(ShaderType stype, SkString* out) const { + for (int i = 0; i < fUniforms.count(); ++i) { + if (fUniforms[i].fVisibility & stype) { + fUniforms[i].fVariable.appendDecl(fContext, out); + } + } } void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { switch (type) { case kVertex_ShaderType: *shaderStr = fHeader; - append_decls(fVSUnis, fContext, shaderStr); - append_decls(fVSAttrs, fContext, shaderStr); - append_decls(fVSOutputs, fContext, shaderStr); + this->appendUniformDecls(kVertex_ShaderType, shaderStr); + this->appendDecls(fVSAttrs, shaderStr); + this->appendDecls(fVSOutputs, shaderStr); shaderStr->append(fVSCode); break; case kGeometry_ShaderType: if (fUsesGS) { *shaderStr = fHeader; shaderStr->append(fGSHeader); - append_decls(fGSInputs, fContext, shaderStr); - append_decls(fGSOutputs, fContext, shaderStr); + this->appendDecls(fGSInputs, shaderStr); + this->appendDecls(fGSOutputs, shaderStr); shaderStr->append(fGSCode); } else { shaderStr->reset(); @@ -257,11 +269,11 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { append_default_precision_qualifier(kDefaultFragmentPrecision, fContext.binding(), shaderStr); - append_decls(fFSUnis, fContext, shaderStr); - append_decls(fFSInputs, fContext, shaderStr); + this->appendUniformDecls(kFragment_ShaderType, shaderStr); + this->appendDecls(fFSInputs, shaderStr); // We shouldn't have declared outputs on 1.10 GrAssert(k110_GrGLSLGeneration != fContext.glslGeneration() || fFSOutputs.empty()); - append_decls(fFSOutputs, fContext, shaderStr); + this->appendDecls(fFSOutputs, shaderStr); shaderStr->append(fFSFunctions); shaderStr->append(fFSCode); break; diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 5884a90f85..892fcbee47 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -22,7 +22,9 @@ class GrGLContextInfo; class GrGLShaderBuilder { public: - typedef GrTAllocator<GrGLShaderVar> VarArray; + + typedef int UniformHandle; + static const UniformHandle kInvalidUniformHandle = 0; enum ShaderType { kVertex_ShaderType = 0x1, @@ -62,11 +64,20 @@ public: from which shaders the uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not supported at this time. */ - const GrGLShaderVar& addUniform(uint32_t visibility, - GrSLType type, - const char* name, - int stageNum = -1, - int count = GrGLShaderVar::kNonArray); + UniformHandle addUniform(uint32_t visibility, + GrSLType type, + const char* name, + int stageNum = -1, + int count = GrGLShaderVar::kNonArray); + + const GrGLShaderVar& getUniformVariable(UniformHandle) const; + + /** + * Shorcut for getUniformVariable(u).c_str() + */ + const char* getUniformCStr(UniformHandle u) const { + return this->getUniformVariable(u).c_str(); + } /** Add a varying variable to the current program to pass values between vertex and fragment shaders. If the last two parameters are non-NULL, they are filled in with the name @@ -88,17 +99,30 @@ public: /** Called after building is complete to get the final shader string. */ void getShader(ShaderType, SkString*) const; +private: + typedef GrTAllocator<GrGLShaderVar> VarArray; + + struct Uniform { + GrGLShaderVar fVariable; + uint32_t fVisibility; + }; + + typedef GrTAllocator<Uniform> UniformArray; + void appendDecls(const VarArray&, SkString*) const; + void appendUniformDecls(ShaderType, SkString*) const; + + UniformArray fUniforms; + // TODO: Everything below here private. +public: SkString fHeader; // VS+FS, GLSL version, etc - VarArray fVSUnis; VarArray fVSAttrs; VarArray fVSOutputs; VarArray fGSInputs; VarArray fGSOutputs; VarArray fFSInputs; SkString fGSHeader; // layout qualifiers specific to GS - VarArray fFSUnis; VarArray fFSOutputs; SkString fFSFunctions; SkString fVSCode; diff --git a/src/gpu/gl/GrGLShaderVar.h b/src/gpu/gl/GrGLShaderVar.h index 2eccd3b1e8..0231d214d3 100644 --- a/src/gpu/gl/GrGLShaderVar.h +++ b/src/gpu/gl/GrGLShaderVar.h @@ -171,12 +171,18 @@ public: */ void setName(const SkString& n) { fName = n; } void setName(const char* n) { fName = n; } + /** * Get the var name. */ const SkString& getName() const { return fName; } /** + * Shortcut for this->getName().c_str(); + */ + const char* c_str() const { return this->getName().c_str(); } + + /** * Get the type of the var */ GrSLType getType() const { return fType; } |