Index: src/gpu/gl/GrGLProgram.cpp |
=================================================================== |
--- src/gpu/gl/GrGLProgram.cpp (revision 8005) |
+++ src/gpu/gl/GrGLProgram.cpp (working copy) |
@@ -398,7 +398,8 @@ |
* Adds a line to the fragment shader code which modifies the color by |
* the specified color filter. |
*/ |
-void add_color_filter(SkString* fsCode, const char * outputVar, |
+void add_color_filter(GrGLShaderBuilder* builder, |
+ const char * outputVar, |
SkXfermode::Coeff uniformCoeff, |
SkXfermode::Coeff colorCoeff, |
const char* filterColor, |
@@ -407,9 +408,9 @@ |
blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); |
blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor); |
- fsCode->appendf("\t%s = ", outputVar); |
- GrGLSLAdd4f(fsCode, colorStr.c_str(), constStr.c_str()); |
- fsCode->append(";\n"); |
+ SkString sum; |
+ GrGLSLAdd4f(&sum, colorStr.c_str(), constStr.c_str()); |
+ builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); |
} |
} |
@@ -421,64 +422,64 @@ |
builder->fVSAttrs.push_back().set(kVec4f_GrSLType, |
GrGLShaderVar::kAttribute_TypeModifier, |
EDGE_ATTR_NAME); |
- builder->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName); |
+ builder->vsCodeAppendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName); |
switch (fDesc.fVertexEdgeType) { |
case GrDrawState::kHairLine_EdgeType: |
- builder->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", builder->fragmentPosition(), fsName); |
- builder->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); |
+ builder->fsCodeAppendf("\tfloat edgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", builder->fragmentPosition(), fsName); |
+ builder->fsCodeAppendf("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); |
break; |
case GrDrawState::kQuad_EdgeType: |
- builder->fFSCode.append("\tfloat edgeAlpha;\n"); |
+ builder->fsCodeAppendf("\tfloat edgeAlpha;\n"); |
// keep the derivative instructions outside the conditional |
- builder->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); |
- builder->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); |
- builder->fFSCode.appendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName); |
+ builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); |
+ builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); |
+ builder->fsCodeAppendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName); |
// today we know z and w are in device space. We could use derivatives |
- builder->fFSCode.appendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, fsName); |
- builder->fFSCode.append ("\t} else {\n"); |
- builder->fFSCode.appendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" |
- "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", |
- fsName, fsName); |
- builder->fFSCode.appendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); |
- builder->fFSCode.append("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n" |
- "\t}\n"); |
+ builder->fsCodeAppendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, fsName); |
+ builder->fsCodeAppendf ("\t} else {\n"); |
+ builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" |
+ "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", |
+ fsName, fsName); |
+ builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); |
+ builder->fsCodeAppendf("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n" |
+ "\t}\n"); |
if (kES2_GrGLBinding == fContext.info().binding()) { |
- builder->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n"); |
+ builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n"); |
} |
break; |
case GrDrawState::kHairQuad_EdgeType: |
- builder->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); |
- builder->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); |
- builder->fFSCode.appendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" |
- "\t 2.0*%s.x*duvdy.x - duvdy.y);\n", |
- fsName, fsName); |
- builder->fFSCode.appendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); |
- builder->fFSCode.append("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n"); |
- builder->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); |
+ builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); |
+ builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); |
+ builder->fsCodeAppendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" |
+ "\t 2.0*%s.x*duvdy.x - duvdy.y);\n", |
+ fsName, fsName); |
+ builder->fsCodeAppendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); |
+ builder->fsCodeAppend("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n"); |
+ builder->fsCodeAppend("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); |
if (kES2_GrGLBinding == fContext.info().binding()) { |
builder->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n"); |
} |
break; |
case GrDrawState::kCircle_EdgeType: |
- builder->fFSCode.append("\tfloat edgeAlpha;\n"); |
- builder->fFSCode.appendf("\tfloat d = distance(%s.xy, %s.xy);\n", builder->fragmentPosition(), fsName); |
- builder->fFSCode.appendf("\tfloat outerAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName); |
- builder->fFSCode.appendf("\tfloat innerAlpha = %s.w == 0.0 ? 1.0 : smoothstep(%s.w - 0.5, %s.w + 0.5, d);\n", fsName, fsName, fsName); |
- builder->fFSCode.append("\tedgeAlpha = outerAlpha * innerAlpha;\n"); |
+ builder->fsCodeAppend("\tfloat edgeAlpha;\n"); |
+ builder->fsCodeAppendf("\tfloat d = distance(%s.xy, %s.xy);\n", builder->fragmentPosition(), fsName); |
+ builder->fsCodeAppendf("\tfloat outerAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName); |
+ builder->fsCodeAppendf("\tfloat innerAlpha = %s.w == 0.0 ? 1.0 : smoothstep(%s.w - 0.5, %s.w + 0.5, d);\n", fsName, fsName, fsName); |
+ builder->fsCodeAppend("\tedgeAlpha = outerAlpha * innerAlpha;\n"); |
break; |
case GrDrawState::kEllipse_EdgeType: |
- builder->fFSCode.append("\tfloat edgeAlpha;\n"); |
- builder->fFSCode.appendf("\tvec2 offset = (%s.xy - %s.xy);\n", builder->fragmentPosition(), fsName); |
- builder->fFSCode.appendf("\toffset.y *= %s.w;\n", fsName); |
- builder->fFSCode.append("\tfloat d = length(offset);\n"); |
- builder->fFSCode.appendf("\tedgeAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName); |
+ builder->fsCodeAppend("\tfloat edgeAlpha;\n"); |
+ builder->fsCodeAppendf("\tvec2 offset = (%s.xy - %s.xy);\n", builder->fragmentPosition(), fsName); |
+ builder->fsCodeAppendf("\toffset.y *= %s.w;\n", fsName); |
+ builder->fsCodeAppend("\tfloat d = length(offset);\n"); |
+ builder->fsCodeAppendf("\tedgeAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName); |
break; |
default: |
GrCrash("Unknown Edge Type!"); |
break; |
} |
if (fDesc.fDiscardIfOutsideEdge) { |
- builder->fFSCode.appendf("\tif (edgeAlpha <= 0.0) {\n\t\tdiscard;\n\t}\n"); |
+ builder->fsCodeAppend("\tif (edgeAlpha <= 0.0) {\n\t\tdiscard;\n\t}\n"); |
} |
*coverageVar = "edgeAlpha"; |
return true; |
@@ -496,7 +497,7 @@ |
COL_ATTR_NAME); |
const char *vsName, *fsName; |
builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); |
- builder->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName); |
+ builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); |
*inColor = fsName; |
} break; |
case GrGLProgram::Desc::kUniform_ColorInput: { |
@@ -522,8 +523,8 @@ |
fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, |
kVec4f_GrSLType, "Coverage", &covUniName); |
if (inOutCoverage->size()) { |
- builder->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n", |
- covUniName, inOutCoverage->c_str()); |
+ builder->fsCodeAppendf("\tvec4 uniCoverage = %s * %s;\n", |
+ covUniName, inOutCoverage->c_str()); |
*inOutCoverage = "uniCoverage"; |
} else { |
*inOutCoverage = covUniName; |
@@ -531,17 +532,16 @@ |
} |
namespace { |
-void gen_attribute_coverage(GrGLShaderBuilder* segments, |
+void gen_attribute_coverage(GrGLShaderBuilder* builder, |
SkString* inOutCoverage) { |
- segments->fVSAttrs.push_back().set(kVec4f_GrSLType, |
- GrGLShaderVar::kAttribute_TypeModifier, |
- COV_ATTR_NAME); |
+ builder->fVSAttrs.push_back().set(kVec4f_GrSLType, |
+ GrGLShaderVar::kAttribute_TypeModifier, |
+ COV_ATTR_NAME); |
const char *vsName, *fsName; |
- segments->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); |
- segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName); |
+ builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); |
+ builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); |
if (inOutCoverage->size()) { |
- segments->fFSCode.appendf("\tvec4 attrCoverage = %s * %s;\n", |
- fsName, inOutCoverage->c_str()); |
+ builder->fsCodeAppendf("\tvec4 attrCoverage = %s * %s;\n", fsName, inOutCoverage->c_str()); |
*inOutCoverage = "attrCoverage"; |
} else { |
*inOutCoverage = fsName; |
@@ -549,27 +549,28 @@ |
} |
} |
-void GrGLProgram::genGeometryShader(GrGLShaderBuilder* segments) const { |
+void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const { |
#if GR_GL_EXPERIMENTAL_GS |
+ // TODO: The builder should add all this glue code. |
if (fDesc.fExperimentalGS) { |
GrAssert(fContext.info().glslGeneration() >= k150_GrGLSLGeneration); |
- segments->fGSHeader.append("layout(triangles) in;\n" |
+ builder->fGSHeader.append("layout(triangles) in;\n" |
"layout(triangle_strip, max_vertices = 6) out;\n"); |
- segments->fGSCode.append("\tfor (int i = 0; i < 3; ++i) {\n" |
- "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
+ builder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" |
+ "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
if (fDesc.fEmitsPointSize) { |
- segments->fGSCode.append("\t\tgl_PointSize = 1.0;\n"); |
+ builder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n"); |
} |
- GrAssert(segments->fGSInputs.count() == segments->fGSOutputs.count()); |
- int count = segments->fGSInputs.count(); |
+ GrAssert(builder->fGSInputs.count() == builder->fGSOutputs.count()); |
+ int count = builder->fGSInputs.count(); |
for (int i = 0; i < count; ++i) { |
- segments->fGSCode.appendf("\t\t%s = %s[i];\n", |
- segments->fGSOutputs[i].getName().c_str(), |
- segments->fGSInputs[i].getName().c_str()); |
+ builder->gsCodeAppendf("\t\t%s = %s[i];\n", |
+ builder->fGSOutputs[i].getName().c_str(), |
+ builder->fGSInputs[i].getName().c_str()); |
} |
- segments->fGSCode.append("\t\tEmitVertex();\n" |
- "\t}\n" |
- "\tEndPrimitive();\n"); |
+ builder->gsCodeAppend("\t\tEmitVertex();\n" |
+ "\t}\n" |
+ "\tEndPrimitive();\n"); |
} |
#endif |
} |
@@ -758,9 +759,9 @@ |
kMat33f_GrSLType, "ViewM", &viewMName); |
- builder.fVSCode.appendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" |
- "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", |
- viewMName, builder.positionAttribute().getName().c_str()); |
+ builder.vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" |
+ "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", |
+ viewMName, builder.positionAttribute().getName().c_str()); |
// incoming color to current stage being processed. |
SkString inColor; |
@@ -771,7 +772,7 @@ |
// we output point size in the GS if present |
if (fDesc.fEmitsPointSize && !builder.fUsesGS){ |
- builder.fVSCode.append("\tgl_PointSize = 1.0;\n"); |
+ builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); |
} |
// add texture coordinates that are used to the list of vertex attr decls |
@@ -793,7 +794,7 @@ |
// create var to hold stage result |
outColor = "color"; |
outColor.appendS32(s); |
- builder.fFSCode.appendf("\tvec4 %s;\n", outColor.c_str()); |
+ builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); |
const char* inCoords; |
// figure out what our input coords are |
@@ -840,15 +841,13 @@ |
bool wroteFragColorZero = false; |
if (SkXfermode::kZero_Coeff == uniformCoeff && |
SkXfermode::kZero_Coeff == colorCoeff) { |
- builder.fFSCode.appendf("\t%s = %s;\n", |
- colorOutput.getName().c_str(), |
- GrGLSLZerosVecf(4)); |
+ builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4)); |
wroteFragColorZero = true; |
} else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) { |
- builder.fFSCode.append("\tvec4 filteredColor;\n"); |
+ builder.fsCodeAppend("\tvec4 filteredColor;\n"); |
const char* color = adjustInColor(inColor); |
- add_color_filter(&builder.fFSCode, "filteredColor", uniformCoeff, |
- colorCoeff, colorFilterColorUniName, color); |
+ add_color_filter(&builder, "filteredColor", uniformCoeff, |
+ colorCoeff, colorFilterColorUniName, color); |
inColor = "filteredColor"; |
} |
@@ -887,7 +886,7 @@ |
// create var to hold stage output |
outCoverage = "coverage"; |
outCoverage.appendS32(s); |
- builder.fFSCode.appendf("\tvec4 %s;\n", outCoverage.c_str()); |
+ builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str()); |
const char* inCoords; |
// figure out what our input coords are |
@@ -902,8 +901,8 @@ |
// stages don't know how to deal with a scalar input. (Maybe they should. We |
// could pass a GrGLShaderVar) |
if (inCoverageIsScalar) { |
- builder.fFSCode.appendf("\tvec4 %s4 = vec4(%s);\n", |
- inCoverage.c_str(), inCoverage.c_str()); |
+ builder.fsCodeAppendf("\tvec4 %s4 = vec4(%s);\n", |
+ inCoverage.c_str(), inCoverage.c_str()); |
inCoverage.append("4"); |
} |
builder.setCurrentStage(s); |
@@ -939,13 +938,11 @@ |
} |
} |
if (outputIsZero) { |
- builder.fFSCode.appendf("\t%s = %s;\n", |
- dual_source_output_name(), |
- GrGLSLZerosVecf(4)); |
+ builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), GrGLSLZerosVecf(4)); |
} else { |
- builder.fFSCode.appendf("\t%s =", dual_source_output_name()); |
- GrGLSLModulate4f(&builder.fFSCode, coeff.c_str(), inCoverage.c_str()); |
- builder.fFSCode.append(";\n"); |
+ SkString modulate; |
+ GrGLSLModulate4f(&modulate, coeff.c_str(), inCoverage.c_str()); |
+ builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulate.c_str()); |
} |
dualSourceOutputWritten = true; |
} |
@@ -956,13 +953,11 @@ |
if (!wroteFragColorZero) { |
if (coverageIsZero) { |
- builder.fFSCode.appendf("\t%s = %s;\n", |
- colorOutput.getName().c_str(), |
- GrGLSLZerosVecf(4)); |
+ builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4)); |
} else { |
- builder.fFSCode.appendf("\t%s = ", colorOutput.getName().c_str()); |
- GrGLSLModulate4f(&builder.fFSCode, inColor.c_str(), inCoverage.c_str()); |
- builder.fFSCode.append(";\n"); |
+ SkString modulate; |
+ GrGLSLModulate4f(&modulate, inColor.c_str(), inCoverage.c_str()); |
+ builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), modulate.c_str()); |
} |
} |