Some GrGLShaderBuilder cleanup
Review URL: https://codereview.appspot.com/6500043/
git-svn-id: http://skia.googlecode.com/svn/trunk@5322 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index c73e884..408e702 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -1148,7 +1148,7 @@
interiorNormalBody.c_str(),
&interiorNormalName);
- code->appendf("\t\tvec2 coord = %s;\n", builder->fSampleCoords.c_str());
+ code->appendf("\t\tvec2 coord = %s;\n", builder->defaultTexCoordsName());
code->appendf("\t\tfloat m[9];\n");
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 846fd28..3145321 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -134,10 +134,10 @@
const char* samplerName) {
SkString* code = &state->fFSCode;
- code->appendf("\t\tvec2 coord = %s;\n", state->fSampleCoords.c_str());
+ code->appendf("\t\tvec2 coord = %s;\n", state->defaultTexCoordsName());
code->appendf("\t\tvec2 zoom_coord = %s + %s / %s;\n",
state->getUniformCStr(fOffsetVar),
- state->fSampleCoords.c_str(),
+ state->defaultTexCoordsName(),
state->getUniformCStr(fZoomVar));
code->appendf("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 4bde3f0..eb121a7 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -334,7 +334,7 @@
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
code->appendf("\t\tvec2 coord = %s - %d.0 * %s;\n",
- builder->fSampleCoords.c_str(), fRadius, imgInc);
+ builder->defaultTexCoordsName(), fRadius, imgInc);
code->appendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width());
code->appendf("\t\t\tvalue = %s(value, ", func);
builder->emitTextureLookup(samplerName, "coord");
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 6bcc1ba..891b1cd 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -702,10 +702,11 @@
const char* tName,
const char* outputColor,
const char* samplerName) {
- builder->fSampleCoords.printf("vec2(%s, %s)", tName,
- builder->getUniformVariable(fFSYUni).c_str());
- builder->fComplexCoord = true;
- builder->emitDefaultFetch(outputColor, samplerName);
+
+ builder->fFSCode.appendf("\tvec2 coord = vec2(%s, %s);\n",
+ tName,
+ builder->getUniformVariable(fFSYUni).c_str());
+ builder->emitTextureLookupAndModulate(outputColor, samplerName, "coord");
}
/////////////////////////////////////////////////////////////////////
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 357d1db..78d2f24 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -552,7 +552,7 @@
const char* inputColor,
const char* samplerName) {
SkString t;
- t.printf("%s.x", builder->fSampleCoords.c_str());
+ t.printf("%s.x", builder->defaultTexCoordsName());
this->emitColorLookup(builder, t.c_str(), outputColor, samplerName);
}
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index e11356a..317ab68 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -552,7 +552,7 @@
const char* inputColor,
const char* samplerName) {
SkString t;
- t.printf("length(%s.xy)", builder->fSampleCoords.c_str());
+ t.printf("length(%s.xy)", builder->defaultTexCoordsName());
this->emitColorLookup(builder, t.c_str(), outputColor, samplerName);
}
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index 5b3e4b4..15547de 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -458,7 +458,7 @@
const char* samplerName) {
SkString t;
t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5",
- builder->fSampleCoords.c_str(), builder->fSampleCoords.c_str());
+ builder->defaultTexCoordsName(), builder->defaultTexCoordsName());
this->emitColorLookup(builder, t.c_str(), outputColor, samplerName);
}
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index cdea8d4..8b32ab6 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -479,7 +479,7 @@
// For radial gradients without perspective we can pass the linear
// part of the quadratic as a varying.
- if (builder->fVaryingDims == builder->fCoordDims) {
+ if (!builder->defaultTextureMatrixIsPerspective()) {
builder->addVarying(kFloat_GrSLType, "Conical2BCoeff",
&fVSVaryingName, &fFSVaryingName);
}
@@ -497,7 +497,7 @@
// For radial gradients without perspective we can pass the linear
// part of the quadratic as a varying.
- if (builder->fVaryingDims == builder->fCoordDims) {
+ if (!builder->defaultTextureMatrixIsPerspective()) {
// 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(),
@@ -535,14 +535,12 @@
// If we we're able to interpolate the linear component,
// bVar is the varying; otherwise compute it
SkString bVar;
- if (builder->fCoordDims == builder->fVaryingDims) {
+ if (!builder->defaultTextureMatrixIsPerspective()) {
bVar = fFSVaryingName;
- GrAssert(2 == builder->fVaryingDims);
} else {
- GrAssert(3 == builder->fVaryingDims);
bVar = "b";
code->appendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n",
- bVar.c_str(), p2.c_str(), builder->fSampleCoords.c_str(),
+ bVar.c_str(), p2.c_str(), builder->defaultTexCoordsName(),
p3.c_str(), p5.c_str());
}
@@ -552,7 +550,7 @@
// c = (x^2)+(y^2) - params[4]
code->appendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(),
- builder->fSampleCoords.c_str(), builder->fSampleCoords.c_str(),
+ builder->defaultTexCoordsName(), builder->defaultTexCoordsName(),
p4.c_str());
// Non-degenerate case (quadratic)
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 8da6f83..693dc32 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -512,7 +512,7 @@
// For radial gradients without perspective we can pass the linear
// part of the quadratic as a varying.
- if (builder->fVaryingDims == builder->fCoordDims) {
+ if (!builder->defaultTextureMatrixIsPerspective()) {
builder->addVarying(kFloat_GrSLType, "Radial2BCoeff",
&fVSVaryingName, &fFSVaryingName);
}
@@ -528,7 +528,7 @@
// For radial gradients without perspective we can pass the linear
// part of the quadratic as a varying.
- if (builder->fVaryingDims == builder->fCoordDims) {
+ if (!builder->defaultTextureMatrixIsPerspective()) {
// r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
code->appendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
fVSVaryingName, p2.c_str(),
@@ -561,22 +561,21 @@
// If we we're able to interpolate the linear component,
// bVar is the varying; otherwise compute it
SkString bVar;
- if (builder->fCoordDims == builder->fVaryingDims) {
+ if (!builder->defaultTextureMatrixIsPerspective()) {
bVar = fFSVaryingName;
- GrAssert(2 == builder->fVaryingDims);
} else {
- 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(),
- builder->fSampleCoords.c_str(), p3.c_str());
+ builder->defaultTexCoordsName(), p3.c_str());
}
// c = (x^2)+(y^2) - params[4]
code->appendf("\tfloat %s = dot(%s, %s) - %s;\n",
- cName.c_str(), builder->fSampleCoords.c_str(),
- builder->fSampleCoords.c_str(),
+ cName.c_str(),
+ builder->defaultTexCoordsName(),
+ builder->defaultTexCoordsName(),
p4.c_str());
// If we aren't degenerate, emit some extra code, and accept a slightly
diff --git a/src/gpu/effects/GrColorTableEffect.cpp b/src/gpu/effects/GrColorTableEffect.cpp
index 227c915..46e42603 100644
--- a/src/gpu/effects/GrColorTableEffect.cpp
+++ b/src/gpu/effects/GrColorTableEffect.cpp
@@ -69,26 +69,22 @@
const GrTextureAccess& access = *fCustomStage.textureAccess(0);
code->appendf("\t\t%s.a = ", outputColor);
- builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
- access,
+ builder->emitCustomTextureLookup(access,
samplerName,
"vec2(coord.a, 0.125)");
code->appendf("\t\t%s.r = ", outputColor);
- builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
- access,
+ builder->emitCustomTextureLookup(access,
samplerName,
"vec2(coord.r, 0.375)");
code->appendf("\t\t%s.g = ", outputColor);
- builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
- access,
+ builder->emitCustomTextureLookup(access,
samplerName,
"vec2(coord.g, 0.625)");
code->appendf("\t\t%s.b = ", outputColor);
- builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
- access,
+ builder->emitCustomTextureLookup(access,
samplerName,
"vec2(coord.b, 0.875)");
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 1067906..fbf5a40 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -24,7 +24,7 @@
const char* inputColor,
const char* samplerName) SK_OVERRIDE {
builder->fFSCode.append("\tvec4 tempColor;\n");
- builder->emitDefaultFetch("tempColor", samplerName);
+ builder->emitTextureLookupAndModulate("tempColor", samplerName);
if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
GrAssert(fSwapRedAndBlue);
builder->fFSCode.appendf("\t%s = tempColor.bgra;\n", outputColor);
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index 2cefbc4..162a0cc 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -75,7 +75,7 @@
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
code->appendf("\t\tvec2 coord = %s - %d.0 * %s;\n",
- builder->fSampleCoords.c_str(), fRadius, imgInc);
+ builder->defaultTexCoordsName(), fRadius, imgInc);
// Manually unroll loop because some drivers don't; yields 20-30% speedup.
for (int i = 0; i < width; i++) {
diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp
index e1856c9..42a8bf9 100644
--- a/src/gpu/effects/GrSingleTextureEffect.cpp
+++ b/src/gpu/effects/GrSingleTextureEffect.cpp
@@ -23,7 +23,7 @@
const char* outputColor,
const char* inputColor,
const char* samplerName) SK_OVERRIDE {
- builder->emitDefaultFetch(outputColor, samplerName);
+ builder->emitTextureLookupAndModulate(outputColor, samplerName);
}
static inline StageKey GenKey(const GrCustomStage&, const GrGLCaps&) { return 0; }
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
index 9384b28..a67dd49 100644
--- a/src/gpu/effects/GrTextureDomainEffect.cpp
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -50,16 +50,12 @@
const char* outputColor,
const char* inputColor,
const char* samplerName) {
- SkString coordVar("clampCoord");
- builder->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
- GrGLShaderVar::TypeString(GrSLFloatVectorType(builder->fCoordDims)),
- coordVar.c_str(),
- builder->fSampleCoords.c_str(),
+ builder->fFSCode.appendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
+ builder->defaultTexCoordsName(),
builder->getUniformCStr(fNameUni),
builder->getUniformCStr(fNameUni));
- builder->fSampleCoords = coordVar;
- builder->emitDefaultFetch(outputColor, samplerName);
+ builder->emitTextureLookupAndModulate(outputColor, samplerName, "clampCoord");
}
void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman,
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index a82e527..9613697 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -1000,6 +1000,7 @@
const GrGLProgram::StageDesc& desc = fDesc.fStages[stageNum];
StageUniforms& uniforms = fUniforms.fStages[stageNum];
GrGLProgramStage* customStage = fProgramStage[stageNum];
+ GrAssert(NULL != customStage);
GrAssert((desc.fInConfigFlags & StageDesc::kInConfigBitMask) == desc.fInConfigFlags);
@@ -1010,25 +1011,29 @@
// decide whether we need a matrix to transform texture coords and whether the varying needs a
// perspective coord.
const char* matName = NULL;
+ GrSLType texCoordVaryingType;
if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
- builder->fVaryingDims = builder->fCoordDims;
+ texCoordVaryingType = kVec2f_GrSLType;
} else {
uniforms.fTextureMatrixUni = builder->addUniform(GrGLShaderBuilder::kVertex_ShaderType,
kMat33f_GrSLType, "TexM", &matName);
const GrGLShaderVar& mat = builder->getUniformVariable(uniforms.fTextureMatrixUni);
if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
- builder->fVaryingDims = builder->fCoordDims;
+ texCoordVaryingType = kVec2f_GrSLType;
} else {
- builder->fVaryingDims = builder->fCoordDims + 1;
+ texCoordVaryingType = kVec3f_GrSLType;
}
}
- GrAssert(builder->fVaryingDims > 0);
+ const char *varyingVSName, *varyingFSName;
+ builder->addVarying(texCoordVaryingType,
+ "Stage",
+ &varyingVSName,
+ &varyingFSName);
+ builder->setupTextureAccess(varyingFSName, texCoordVaryingType);
- // Must setup variables after computing segments->fVaryingDims
- if (NULL != customStage) {
- customStage->setupVariables(builder);
- }
+ // Must setup variables after calling setupTextureAccess
+ customStage->setupVariables(builder);
const char* samplerName;
uniforms.fSamplerUniforms.push_back(builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
@@ -1036,45 +1041,29 @@
"Sampler",
&samplerName));
- const char *varyingVSName, *varyingFSName;
- builder->addVarying(GrSLFloatVectorType(builder->fVaryingDims),
- "Stage",
- &varyingVSName,
- &varyingFSName);
-
if (!matName) {
- GrAssert(builder->fVaryingDims == builder->fCoordDims);
+ GrAssert(kVec2f_GrSLType == texCoordVaryingType);
builder->fVSCode.appendf("\t%s = %s;\n", varyingVSName, vsInCoord);
} else {
// varying = texMatrix * texCoord
builder->fVSCode.appendf("\t%s = (%s * vec3(%s, 1))%s;\n",
varyingVSName, matName, vsInCoord,
- vector_all_coords(builder->fVaryingDims));
+ vector_all_coords(GrSLTypeToVecLength(texCoordVaryingType)));
}
- if (NULL != customStage) {
- builder->fVSCode.appendf("\t{ // stage %d %s\n",
- stageNum, customStage->name());
- customStage->emitVS(builder, varyingVSName);
- builder->fVSCode.appendf("\t}\n");
- }
-
- /// Fragment Shader Stuff
-
- builder->fSampleCoords = varyingFSName;
-
- builder->setupTextureAccess(stageNum);
+ builder->fVSCode.appendf("\t{ // stage %d %s\n",
+ stageNum, customStage->name());
+ customStage->emitVS(builder, varyingVSName);
+ builder->fVSCode.appendf("\t}\n");
builder->computeSwizzle(desc.fInConfigFlags);
builder->computeModulate(fsInColor);
- if (NULL != customStage) {
- // Enclose custom code in a block to avoid namespace conflicts
- builder->fFSCode.appendf("\t{ // stage %d %s \n",
- stageNum, customStage->name());
- customStage->emitFS(builder, fsOutColor, fsInColor,
- samplerName);
- builder->fFSCode.appendf("\t}\n");
- }
+ // Enclose custom code in a block to avoid namespace conflicts
+ builder->fFSCode.appendf("\t{ // stage %d %s \n",
+ stageNum, customStage->name());
+ customStage->emitFS(builder, fsOutColor, fsInColor,
+ samplerName);
+ builder->fFSCode.appendf("\t}\n");
builder->setNonStage();
}
diff --git a/src/gpu/gl/GrGLSL.cpp b/src/gpu/gl/GrGLSL.cpp
index ff4d498..f1f7d92 100644
--- a/src/gpu/gl/GrGLSL.cpp
+++ b/src/gpu/gl/GrGLSL.cpp
@@ -80,9 +80,16 @@
return HOMOGS[count];
}
+const char* GrGLSLVectorHomogCoord(GrSLType type) {
+ return GrGLSLVectorHomogCoord(GrSLTypeToVecLength(type));
+}
+
const char* GrGLSLVectorNonhomogCoords(int count) {
static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
return NONHOMOGS[count];
}
+const char* GrGLSLVectorNonhomogCoord(GrSLType type) {
+ return GrGLSLVectorNonhomogCoords(GrSLTypeToVecLength(type));
+}
diff --git a/src/gpu/gl/GrGLSL.h b/src/gpu/gl/GrGLSL.h
index d766dd9..f69385f 100644
--- a/src/gpu/gl/GrGLSL.h
+++ b/src/gpu/gl/GrGLSL.h
@@ -45,6 +45,23 @@
kSampler2D_GrSLType
};
+namespace {
+inline int GrSLTypeToVecLength(GrSLType type) {
+ static const int kVecLengths[] = {
+ 0, // kVoid_GrSLType
+ 1, // kFloat_GrSLType
+ 2, // kVec2f_GrSLType
+ 3, // kVec3f_GrSLType
+ 4, // kVec4f_GrSLType
+ 1, // kMat33f_GrSLType
+ 1, // kMat44f_GrSLType
+ 1, // kSampler2D_GrSLType
+ };
+ GrAssert((size_t) type < GR_ARRAY_COUNT(kVecLengths));
+ return kVecLengths[type];
+}
+}
+
/**
* Gets the most recent GLSL Generation compatible with the OpenGL context.
*/
@@ -82,11 +99,12 @@
GrSLType GrSLFloatVectorType(int count);
/** Return the GLSL swizzle operator for a homogenous component of a vector
- with the given number of coordnates, e.g. 2 -> ".y", 3 -> ".z" */
+ with the given number of coordinates, e.g. 2 -> ".y", 3 -> ".z" */
const char* GrGLSLVectorHomogCoord(int count);
+const char* GrGLSLVectorHomogCoord(GrSLType type);
/** Return the GLSL swizzle operator for a nonhomogenous components of a vector
- with the given number of coordnates, e.g. 2 -> ".x", 3 -> ".xy" */
+ with the given number of coordinates, e.g. 2 -> ".x", 3 -> ".xy" */
const char* GrGLSLVectorNonhomogCoords(int count);
-
+const char* GrGLSLVectorNonhomogCoords(GrSLType type);
#endif
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index 2243a7c..5aa3a54 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -22,29 +22,25 @@
typedef GrGLUniformManager::UniformHandle UniformHandle;
///////////////////////////////////////////////////////////////////////////////
-static SkString build_sampler_string(GrGLShaderBuilder::SamplerMode samplerMode) {
- SkString sampler("texture2D");
- switch (samplerMode) {
- case GrGLShaderBuilder::kDefault_SamplerMode:
- break;
- case GrGLShaderBuilder::kProj_SamplerMode:
- sampler.append("Proj");
- break;
- case GrGLShaderBuilder::kExplicitDivide_SamplerMode:
- break;
- }
+namespace {
- return sampler;
+inline const char* sample_function_name(GrSLType type) {
+ if (kVec2f_GrSLType == type) {
+ return "texture2D";
+ } else {
+ GrAssert(kVec3f_GrSLType == type);
+ return "texture2DProj";
+ }
}
-static bool texture_requires_alpha_to_red_swizzle(const GrGLCaps& caps,
+inline bool texture_requires_alpha_to_red_swizzle(const GrGLCaps& caps,
const GrTextureAccess& access) {
return GrPixelConfigIsAlphaOnly(access.getTexture()->config()) && caps.textureRedSupport() &&
access.referencesAlpha();
}
-static SkString build_swizzle_string(const GrTextureAccess& textureAccess,
- const GrGLCaps& caps) {
+SkString build_swizzle_string(const GrTextureAccess& textureAccess,
+ const GrGLCaps& caps) {
const GrTextureAccess::Swizzle& swizzle = textureAccess.getSwizzle();
if (0 == swizzle[0]) {
return SkString("");
@@ -63,6 +59,8 @@
return swizzleOut;
}
+}
+
///////////////////////////////////////////////////////////////////////////////
// Architectural assumption: always 2-d input coords.
@@ -79,8 +77,7 @@
, fFSInputs(kVarsPerBlock)
, fFSOutputs(kMaxFSOutputs)
, fUsesGS(false)
- , fVaryingDims(0)
- , fComplexCoord(false)
+ , fTexCoordVaryingType(kVoid_GrSLType)
, fContext(ctx)
, fUniformManager(uniformManager)
, fCurrentStage(kNonStageIdx) {
@@ -107,65 +104,59 @@
}
}
-void GrGLShaderBuilder::setupTextureAccess(int stageNum) {
- SkString retval;
-
- SamplerMode mode = kDefault_SamplerMode;
- // FIXME: we aren't currently using Proj.
- if (fVaryingDims != fCoordDims) {
- mode = kExplicitDivide_SamplerMode;
+void GrGLShaderBuilder::setupTextureAccess(const char* varyingFSName, GrSLType varyingType) {
+ // FIXME: We don't know how the custom stage will manipulate the coords. So we give up on using
+ // projective texturing and always give the stage 2D coords. This will be fixed when custom
+ // stages are repsonsible for setting up their own tex coords / tex matrices.
+ switch (varyingType) {
+ case kVec2f_GrSLType:
+ fDefaultTexCoordsName = varyingFSName;
+ fTexCoordVaryingType = kVec2f_GrSLType;
+ break;
+ case kVec3f_GrSLType: {
+ fDefaultTexCoordsName = "inCoord";
+ GrAssert(kNonStageIdx != fCurrentStage);
+ fDefaultTexCoordsName.appendS32(fCurrentStage);
+ fTexCoordVaryingType = kVec3f_GrSLType;
+ fFSCode.appendf("\t%s %s = %s.xy / %s.z;\n",
+ GrGLShaderVar::TypeString(kVec2f_GrSLType),
+ fDefaultTexCoordsName.c_str(),
+ varyingFSName,
+ varyingFSName);
+ break;
+ }
+ default:
+ GrCrash("Tex coords must either be Vec2f or Vec3f");
}
-
- switch (mode) {
- case kDefault_SamplerMode:
- GrAssert(fVaryingDims == fCoordDims);
- // Do nothing
- break;
- case kProj_SamplerMode:
- // Do nothing
- break;
- case kExplicitDivide_SamplerMode:
- retval = "inCoord";
- retval.appendS32(stageNum);
- fFSCode.appendf("\t%s %s = %s%s / %s%s;\n",
- GrGLShaderVar::TypeString
- (GrSLFloatVectorType(fCoordDims)),
- retval.c_str(),
- fSampleCoords.c_str(),
- GrGLSLVectorNonhomogCoords(fVaryingDims),
- fSampleCoords.c_str(),
- GrGLSLVectorHomogCoord(fVaryingDims));
- fSampleCoords = retval;
- break;
- }
- fTexFunc = build_sampler_string(mode);
- fComplexCoord = false;
}
void GrGLShaderBuilder::emitTextureLookup(const char* samplerName,
- const char* coordName) {
+ const char* coordName,
+ GrSLType varyingType) {
if (NULL == coordName) {
- coordName = fSampleCoords.c_str();
+ coordName = fDefaultTexCoordsName.c_str();
+ varyingType = kVec2f_GrSLType;
}
- fFSCode.appendf("%s(%s, %s)", fTexFunc.c_str(), samplerName, coordName);
+ fFSCode.appendf("%s(%s, %s)", sample_function_name(varyingType), samplerName, coordName);
}
-void GrGLShaderBuilder::emitDefaultFetch(const char* outColor,
- const char* samplerName) {
+void GrGLShaderBuilder::emitTextureLookupAndModulate(const char* outColor,
+ const char* samplerName,
+ const char* coordName,
+ GrSLType varyingType) {
fFSCode.appendf("\t%s = ", outColor);
- this->emitTextureLookup(samplerName);
+ this->emitTextureLookup(samplerName, coordName, varyingType);
fFSCode.appendf("%s%s;\n", fSwizzle.c_str(), fModulate.c_str());
}
-void GrGLShaderBuilder::emitCustomTextureLookup(SamplerMode samplerMode,
- const GrTextureAccess& textureAccess,
+void GrGLShaderBuilder::emitCustomTextureLookup(const GrTextureAccess& textureAccess,
const char* samplerName,
- const char* coordName) {
+ const char* coordName,
+ GrSLType varyingType) {
GrAssert(samplerName && coordName);
- SkString sampler = build_sampler_string(samplerMode);
SkString swizzle = build_swizzle_string(textureAccess, fContext.caps());
- fFSCode.appendf("%s( %s, %s)%s;\n", sampler.c_str(), samplerName,
+ fFSCode.appendf("%s( %s, %s)%s;\n", sample_function_name(varyingType), samplerName,
coordName, swizzle.c_str());
}
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index 31d603a..66de5ab 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -23,7 +23,6 @@
class GrGLShaderBuilder {
public:
-
enum ShaderType {
kVertex_ShaderType = 0x1,
kGeometry_ShaderType = 0x2,
@@ -35,36 +34,45 @@
void computeSwizzle(uint32_t configFlags);
void computeModulate(const char* fsInColor);
- // TODO: needs a better name
- enum SamplerMode {
- kDefault_SamplerMode,
- kProj_SamplerMode,
- kExplicitDivide_SamplerMode // must do an explicit divide
- };
-
/** Determines whether we should use texture2D() or texture2Dproj(), and if an explicit divide
is required for the sample coordinates, creates the new variable and emits the code to
- initialize it. */
- void setupTextureAccess(int stageNum);
+ initialize it. This should only be called by GrGLProgram.*/
+ void setupTextureAccess(const char* varyingFSName, GrSLType varyingType);
/** texture2D(samplerName, coordName), with projection if necessary; if coordName is not
- specified, uses fSampleCoords. */
+ specified, uses fSampleCoords. coordType must either be Vec2f or Vec3f. The latter is
+ interpreted as projective texture coords. */
void emitTextureLookup(const char* samplerName,
- const char* coordName = NULL);
+ const char* coordName = NULL,
+ GrSLType coordType = kVec2f_GrSLType);
- /** sets outColor to results of texture lookup, with swizzle, and/or modulate as necessary */
- void emitDefaultFetch(const char* outColor,
- const char* samplerName);
+ /** sets outColor to results of texture lookup, with swizzle, and/or modulate as necessary. If
+ coordName is NULL then it as if defaultTexCoordsName() was passed. coordType must be either
+ kVec2f or kVec3f. */
+ void emitTextureLookupAndModulate(const char* outColor,
+ const char* samplerName,
+ const char* coordName = NULL,
+ GrSLType coordType = kVec2f_GrSLType);
+
+ /** Gets the name of the default texture coords which are always kVec2f */
+ const char* defaultTexCoordsName() const { return fDefaultTexCoordsName.c_str(); }
+
+ /* Returns true if the texture matrix from which the default texture coords are computed has
+ perspective. */
+ bool defaultTextureMatrixIsPerspective() const {
+ return fTexCoordVaryingType == kVec3f_GrSLType;
+ }
/** Emits a texture lookup to the shader code with the form:
texture2D{Proj}(samplerName, coordName).swizzle
The routine selects the type of texturing based on samplerMode.
The generated swizzle state is built based on the format of the texture and the requested
- swizzle access pattern. */
- void emitCustomTextureLookup(SamplerMode samplerMode,
- const GrTextureAccess& textureAccess,
+ swizzle access pattern. coordType must either be Vec2f or Vec3f. The latter is interpreted
+ as projective texture coords.*/
+ void emitCustomTextureLookup(const GrTextureAccess& textureAccess,
const char* samplerName,
- const char* coordName);
+ const char* coordName,
+ GrSLType coordType = kVec2f_GrSLType);
/** Emits a helper function outside of main(). Currently ShaderType must be
kFragment_ShaderType. */
@@ -162,19 +170,9 @@
/// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
//@{
- int fVaryingDims;
- static const int fCoordDims = 2;
-
- /// True if fSampleCoords is an expression; false if it's a bare
- /// variable name
- bool fComplexCoord;
- SkString fSampleCoords;
-
SkString fSwizzle;
SkString fModulate;
- SkString fTexFunc;
-
//@}
private:
@@ -186,6 +184,14 @@
GrGLUniformManager& fUniformManager;
int fCurrentStage;
SkString fFSFunctions;
+
+ /// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
+ //@{
+ GrSLType fTexCoordVaryingType; // the type, either Vec2f or Vec3f, of the coords passed
+ // as a varying from the VS to the FS.
+ SkString fDefaultTexCoordsName; // the name of the default 2D coords value.
+ //@}
+
};
#endif