Extract six functions from GrGLProgram::genStageCode() to shorten it by
~170 LOC.
git-svn-id: http://skia.googlecode.com/svn/trunk@2498 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp
index 4b4140d..e05b6c3 100644
--- a/src/gpu/GrGLProgram.cpp
+++ b/src/gpu/GrGLProgram.cpp
@@ -1287,6 +1287,100 @@
// Stage code generation
//============================================================================
+static bool genRadial2GradientCoordMapping(int stageNum,
+ ShaderCodeSegments* segments,
+ const char* radial2VaryingFSName,
+ const char* radial2ParamsName,
+ GrStringBuilder& sampleCoords,
+ GrStringBuilder& fsCoordName,
+ int varyingDims,
+ int coordDims) {
+ GrStringBuilder cName("c");
+ GrStringBuilder ac4Name("ac4");
+ GrStringBuilder rootName("root");
+
+ cName.appendS32(stageNum);
+ ac4Name.appendS32(stageNum);
+ rootName.appendS32(stageNum);
+
+ // if we were able to interpolate the linear component bVar is the varying
+ // otherwise compute it
+ GrStringBuilder bVar;
+ if (coordDims == varyingDims) {
+ bVar = radial2VaryingFSName;
+ GrAssert(2 == varyingDims);
+ } else {
+ GrAssert(3 == varyingDims);
+ bVar = "b";
+ bVar.appendS32(stageNum);
+ segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
+ bVar.c_str(), radial2ParamsName,
+ fsCoordName.c_str(), radial2ParamsName);
+ }
+
+ // c = (x^2)+(y^2) - params[4]
+ segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
+ cName.c_str(), fsCoordName.c_str(),
+ fsCoordName.c_str(),
+ radial2ParamsName);
+ // ac4 = 4.0 * params[0] * c
+ segments->fFSCode.appendf("\tfloat %s = %s[0] * 4.0 * %s;\n",
+ ac4Name.c_str(), radial2ParamsName,
+ cName.c_str());
+
+ // root = sqrt(b^2-4ac)
+ // (abs to avoid exception due to fp precision)
+ segments->fFSCode.appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
+ rootName.c_str(), bVar.c_str(), bVar.c_str(),
+ ac4Name.c_str());
+
+ // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
+ // y coord is 0.5 (texture is effectively 1D)
+ sampleCoords.printf("vec2((-%s + %s[5] * %s) * %s[1], 0.5)",
+ bVar.c_str(), radial2ParamsName,
+ rootName.c_str(), radial2ParamsName);
+ return true;
+}
+
+static bool genRadial2GradientDegenerateCoordMapping(int stageNum,
+ ShaderCodeSegments* segments,
+ const char* radial2VaryingFSName,
+ const char* radial2ParamsName,
+ GrStringBuilder& sampleCoords,
+ GrStringBuilder& fsCoordName,
+ int varyingDims,
+ int coordDims) {
+ GrStringBuilder cName("c");
+
+ cName.appendS32(stageNum);
+
+ // if we were able to interpolate the linear component bVar is the varying
+ // otherwise compute it
+ GrStringBuilder bVar;
+ if (coordDims == varyingDims) {
+ bVar = radial2VaryingFSName;
+ GrAssert(2 == varyingDims);
+ } else {
+ GrAssert(3 == varyingDims);
+ bVar = "b";
+ bVar.appendS32(stageNum);
+ segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
+ bVar.c_str(), radial2ParamsName,
+ fsCoordName.c_str(), radial2ParamsName);
+ }
+
+ // c = (x^2)+(y^2) - params[4]
+ segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
+ cName.c_str(), fsCoordName.c_str(),
+ fsCoordName.c_str(),
+ radial2ParamsName);
+
+ // x coord is: -c/b
+ // y coord is 0.5 (texture is effectively 1D)
+ sampleCoords.printf("vec2((-%s / %s), 0.5)", cName.c_str(), bVar.c_str());
+ return true;
+}
+
void GrGLProgram::genStageCode(const GrGLInterface* gl,
int stageNum,
const GrGLProgram::StageDesc& desc,
@@ -1366,60 +1460,19 @@
if (StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping ||
StageDesc::kRadial2GradientDegenerate_CoordMapping == desc.fCoordMapping) {
-
- GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
- radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
- radial2FSParams->setArrayCount(6);
- radial2_param_name(stageNum, radial2FSParams->accessName());
- segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
- radial2ParamsName = radial2FSParams->getName().c_str();
-
- locations->fRadial2Uni = kUseUniform;
-
- // for radial grads without perspective we can pass the linear
- // part of the quadratic as a varying.
- if (varyingDims == coordDims) {
- GrAssert(2 == coordDims);
- append_varying(GrGLShaderVar::kFloat_Type,
- "Radial2BCoeff",
- stageNum,
- segments,
- &radial2VaryingVSName,
- &radial2VaryingFSName);
-
- // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
- const char* r2ParamName = radial2FSParams->getName().c_str();
- segments->fVSCode.appendf("\t%s = 2.0 *(%s[2] * %s.x - %s[3]);\n",
- radial2VaryingVSName, r2ParamName,
- varyingVSName, r2ParamName);
- }
+ radial2ParamsName = this->genRadialVS(stageNum, segments,
+ locations,
+ &radial2VaryingVSName,
+ &radial2VaryingFSName,
+ varyingVSName,
+ varyingDims, coordDims);
}
const char* kernelName = NULL;
const char* imageIncrementName = NULL;
if (ProgramDesc::StageDesc::kConvolution_FetchMode == desc.fFetchMode) {
-
- GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
- kernel->setType(GrGLShaderVar::kFloat_Type);
- kernel->setArrayCount(desc.fKernelWidth);
- GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
- imgInc->setType(GrGLShaderVar::kVec2f_Type);
-
- convolve_param_names(stageNum,
- kernel->accessName(),
- imgInc->accessName());
- kernelName = kernel->getName().c_str();
- imageIncrementName = imgInc->getName().c_str();
-
- // need image increment in both VS and FS
- segments->fVSUnis.push_back(*imgInc).setEmitPrecision(true);
-
- locations->fKernelUni = kUseUniform;
- locations->fImageIncrementUni = kUseUniform;
- float scale = (desc.fKernelWidth - 1) * 0.5f;
- segments->fVSCode.appendf("\t%s -= vec2(%g, %g) * %s;\n",
- varyingVSName, scale, scale,
- imageIncrementName);
+ this->genConvolutionVS(stageNum, desc, segments, locations,
+ &kernelName, &imageIncrementName, varyingVSName);
}
/// Fragment Shader Stuff
@@ -1465,84 +1518,22 @@
sampleCoords.printf("vec2(length(%s.xy), 0.5)", fsCoordName.c_str());
complexCoord = true;
break;
- case StageDesc::kRadial2Gradient_CoordMapping: {
- GrStringBuilder cName("c");
- GrStringBuilder ac4Name("ac4");
- GrStringBuilder rootName("root");
+ case StageDesc::kRadial2Gradient_CoordMapping:
+ complexCoord = genRadial2GradientCoordMapping(
+ stageNum, segments,
+ radial2VaryingFSName, radial2ParamsName,
+ sampleCoords, fsCoordName,
+ varyingDims, coordDims);
- cName.appendS32(stageNum);
- ac4Name.appendS32(stageNum);
- rootName.appendS32(stageNum);
+ break;
+ case StageDesc::kRadial2GradientDegenerate_CoordMapping:
+ complexCoord = genRadial2GradientDegenerateCoordMapping(
+ stageNum, segments,
+ radial2VaryingFSName, radial2ParamsName,
+ sampleCoords, fsCoordName,
+ varyingDims, coordDims);
+ break;
- // if we were able to interpolate the linear component bVar is the varying
- // otherwise compute it
- GrStringBuilder bVar;
- if (coordDims == varyingDims) {
- bVar = radial2VaryingFSName;
- GrAssert(2 == varyingDims);
- } else {
- GrAssert(3 == varyingDims);
- bVar = "b";
- bVar.appendS32(stageNum);
- segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
- bVar.c_str(), radial2ParamsName,
- fsCoordName.c_str(), radial2ParamsName);
- }
-
- // c = (x^2)+(y^2) - params[4]
- segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
- cName.c_str(), fsCoordName.c_str(),
- fsCoordName.c_str(),
- radial2ParamsName);
- // ac4 = 4.0 * params[0] * c
- segments->fFSCode.appendf("\tfloat %s = %s[0] * 4.0 * %s;\n",
- ac4Name.c_str(), radial2ParamsName,
- cName.c_str());
-
- // root = sqrt(b^2-4ac)
- // (abs to avoid exception due to fp precision)
- segments->fFSCode.appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
- rootName.c_str(), bVar.c_str(), bVar.c_str(),
- ac4Name.c_str());
-
- // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
- // y coord is 0.5 (texture is effectively 1D)
- sampleCoords.printf("vec2((-%s + %s[5] * %s) * %s[1], 0.5)",
- bVar.c_str(), radial2ParamsName,
- rootName.c_str(), radial2ParamsName);
- complexCoord = true;
- break;}
- case StageDesc::kRadial2GradientDegenerate_CoordMapping: {
- GrStringBuilder cName("c");
-
- cName.appendS32(stageNum);
-
- // if we were able to interpolate the linear component bVar is the varying
- // otherwise compute it
- GrStringBuilder bVar;
- if (coordDims == varyingDims) {
- bVar = radial2VaryingFSName;
- GrAssert(2 == varyingDims);
- } else {
- GrAssert(3 == varyingDims);
- bVar = "b";
- bVar.appendS32(stageNum);
- segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
- bVar.c_str(), radial2ParamsName,
- fsCoordName.c_str(), radial2ParamsName);
- }
-
- // c = (x^2)+(y^2) - params[4]
- segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
- cName.c_str(), fsCoordName.c_str(),
- fsCoordName.c_str(),
- radial2ParamsName);
-
- // x coord is: -c/b
- // y coord is 0.5 (texture is effectively 1D)
- sampleCoords.printf("vec2((-%s / %s), 0.5)", cName.c_str(), bVar.c_str());
- complexCoord = true;
- break;}
};
const char* smear;
@@ -1572,52 +1563,158 @@
locations->fTexDomUni = kUseUniform;
}
- if (StageDesc::k2x2_FetchMode == desc.fFetchMode) {
- locations->fNormalizedTexelSizeUni = kUseUniform;
- if (complexCoord) {
- // assign the coord to a var rather than compute 4x.
- GrStringBuilder coordVar("tCoord");
- coordVar.appendS32(stageNum);
- segments->fFSCode.appendf("\t%s %s = %s;\n",
- float_vector_type_str(coordDims),
- coordVar.c_str(), sampleCoords.c_str());
- sampleCoords = coordVar;
- }
- GrAssert(2 == coordDims);
- GrStringBuilder accumVar("accum");
- accumVar.appendS32(stageNum);
- segments->fFSCode.appendf("\tvec4 %s = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords.c_str(), texelSizeName, texelSizeName, smear);
- segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords.c_str(), texelSizeName, texelSizeName, smear);
- segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords.c_str(), texelSizeName, texelSizeName, smear);
- segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords.c_str(), texelSizeName, texelSizeName, smear);
- segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str());
- } else if (ProgramDesc::StageDesc::kConvolution_FetchMode == desc.fFetchMode) {
- GrStringBuilder sumVar("sum");
- sumVar.appendS32(stageNum);
- GrStringBuilder coordVar("coord");
- coordVar.appendS32(stageNum);
-
- segments->fFSCode.appendf("\tvec4 %s = vec4(0, 0, 0, 0);\n",
- sumVar.c_str());
- segments->fFSCode.appendf("\tvec2 %s = %s;\n",
- coordVar.c_str(),
- sampleCoords.c_str());
- segments->fFSCode.appendf("\tfor (int i = 0; i < %d; i++) {\n",
- desc.fKernelWidth);
- segments->fFSCode.appendf("\t\t%s += %s(%s, %s)%s * %s[i];\n",
- sumVar.c_str(), texFunc.c_str(),
- samplerName, coordVar.c_str(), smear,
- kernelName);
- segments->fFSCode.appendf("\t\t%s += %s;\n",
- coordVar.c_str(),
- imageIncrementName);
- segments->fFSCode.appendf("\t}\n");
- segments->fFSCode.appendf("\t%s = %s%s;\n", fsOutColor,
- sumVar.c_str(), modulate.c_str());
- } else {
+ switch (desc.fFetchMode) {
+ case StageDesc::k2x2_FetchMode:
+ this->gen2x2FS(stageNum, segments, locations, &sampleCoords,
+ samplerName, texelSizeName, smear, fsOutColor,
+ texFunc, modulate, complexCoord, coordDims);
+ break;
+ case ProgramDesc::StageDesc::kConvolution_FetchMode:
+ this->genConvolutionFS(stageNum, desc, segments,
+ samplerName, kernelName, smear, imageIncrementName, fsOutColor,
+ sampleCoords, texFunc, modulate);
+ break;
+ default:
segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n",
fsOutColor, texFunc.c_str(),
samplerName, sampleCoords.c_str(),
smear, modulate.c_str());
}
}
+
+const char* GrGLProgram::genRadialVS(int stageNum,
+ ShaderCodeSegments* segments,
+ StageUniLocations* locations,
+ const char** radial2VaryingVSName,
+ const char** radial2VaryingFSName,
+ const char* varyingVSName,
+ int varyingDims, int coordDims) const {
+
+ GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
+ radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
+ radial2FSParams->setArrayCount(6);
+ radial2_param_name(stageNum, radial2FSParams->accessName());
+ segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
+
+ locations->fRadial2Uni = kUseUniform;
+
+ // for radial grads without perspective we can pass the linear
+ // part of the quadratic as a varying.
+ if (varyingDims == coordDims) {
+ GrAssert(2 == coordDims);
+ append_varying(GrGLShaderVar::kFloat_Type,
+ "Radial2BCoeff",
+ stageNum,
+ segments,
+ radial2VaryingVSName,
+ radial2VaryingFSName);
+
+ // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
+ const char* r2ParamName = radial2FSParams->getName().c_str();
+ segments->fVSCode.appendf("\t%s = 2.0 *(%s[2] * %s.x - %s[3]);\n",
+ *radial2VaryingVSName, r2ParamName,
+ varyingVSName, r2ParamName);
+ }
+
+ return radial2FSParams->getName().c_str();
+}
+
+
+void GrGLProgram::gen2x2FS(int stageNum,
+ ShaderCodeSegments* segments,
+ StageUniLocations* locations,
+ GrStringBuilder* sampleCoords,
+ const char* samplerName,
+ const char* texelSizeName,
+ const char* smear,
+ const char* fsOutColor,
+ GrStringBuilder& texFunc,
+ GrStringBuilder& modulate,
+ bool complexCoord,
+ int coordDims) const {
+ locations->fNormalizedTexelSizeUni = kUseUniform;
+ if (complexCoord) {
+ // assign the coord to a var rather than compute 4x.
+ GrStringBuilder coordVar("tCoord");
+ coordVar.appendS32(stageNum);
+ segments->fFSCode.appendf("\t%s %s = %s;\n",
+ float_vector_type_str(coordDims),
+ coordVar.c_str(), sampleCoords->c_str());
+ *sampleCoords = coordVar;
+ }
+ GrAssert(2 == coordDims);
+ GrStringBuilder accumVar("accum");
+ accumVar.appendS32(stageNum);
+ segments->fFSCode.appendf("\tvec4 %s = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
+ segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
+ segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
+ segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
+ segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str());
+
+}
+
+void GrGLProgram::genConvolutionVS(int stageNum,
+ const ProgramDesc::StageDesc& desc,
+ ShaderCodeSegments* segments,
+ StageUniLocations* locations,
+ const char** kernelName,
+ const char** imageIncrementName,
+ const char* varyingVSName) const {
+ GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
+ kernel->setType(GrGLShaderVar::kFloat_Type);
+ kernel->setArrayCount(desc.fKernelWidth);
+ GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
+ imgInc->setType(GrGLShaderVar::kVec2f_Type);
+
+ convolve_param_names(stageNum,
+ kernel->accessName(),
+ imgInc->accessName());
+ *kernelName = kernel->getName().c_str();
+ *imageIncrementName = imgInc->getName().c_str();
+
+ // need image increment in both VS and FS
+ segments->fVSUnis.push_back(*imgInc).setEmitPrecision(true);
+
+ locations->fKernelUni = kUseUniform;
+ locations->fImageIncrementUni = kUseUniform;
+ float scale = (desc.fKernelWidth - 1) * 0.5f;
+ segments->fVSCode.appendf("\t%s -= vec2(%g, %g) * %s;\n",
+ varyingVSName, scale, scale,
+ *imageIncrementName);
+}
+
+void GrGLProgram::genConvolutionFS(int stageNum,
+ const ProgramDesc::StageDesc& desc,
+ ShaderCodeSegments* segments,
+ const char* samplerName,
+ const char* kernelName,
+ const char* smear,
+ const char* imageIncrementName,
+ const char* fsOutColor,
+ GrStringBuilder& sampleCoords,
+ GrStringBuilder& texFunc,
+ GrStringBuilder& modulate) const {
+ GrStringBuilder sumVar("sum");
+ sumVar.appendS32(stageNum);
+ GrStringBuilder coordVar("coord");
+ coordVar.appendS32(stageNum);
+
+ segments->fFSCode.appendf("\tvec4 %s = vec4(0, 0, 0, 0);\n",
+ sumVar.c_str());
+ segments->fFSCode.appendf("\tvec2 %s = %s;\n",
+ coordVar.c_str(),
+ sampleCoords.c_str());
+ segments->fFSCode.appendf("\tfor (int i = 0; i < %d; i++) {\n",
+ desc.fKernelWidth);
+ segments->fFSCode.appendf("\t\t%s += %s(%s, %s)%s * %s[i];\n",
+ sumVar.c_str(), texFunc.c_str(),
+ samplerName, coordVar.c_str(), smear,
+ kernelName);
+ segments->fFSCode.appendf("\t\t%s += %s;\n",
+ coordVar.c_str(),
+ imageIncrementName);
+ segments->fFSCode.appendf("\t}\n");
+ segments->fFSCode.appendf("\t%s = %s%s;\n", fsOutColor,
+ sumVar.c_str(), modulate.c_str());
+}
+