aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-16 13:36:18 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-16 13:36:18 +0000
commit032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7a (patch)
tree7b97452a7937949417cc40a4817cf4c4ede8e4ab /src
parent96cbd2c4d2ea7e138b65923a46fb77bc096a6782 (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.cpp492
-rw-r--r--src/gpu/effects/GrConvolutionEffect.cpp80
-rw-r--r--src/gpu/effects/GrGradientEffects.cpp235
-rw-r--r--src/gpu/effects/GrMorphologyEffect.cpp64
-rw-r--r--src/gpu/gl/GrGLProgram.cpp16
-rw-r--r--src/gpu/gl/GrGLProgram.h3
-rw-r--r--src/gpu/gl/GrGLProgramStage.cpp6
-rw-r--r--src/gpu/gl/GrGLProgramStage.h10
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp80
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h40
-rw-r--r--src/gpu/gl/GrGLShaderVar.h6
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; }