Chromium Code Reviews| 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, |
| + builder->fVSAttrs.push_back().set(kVec4f_GrSLType, |
|
robertphillips
2013/03/07 15:23:16
spaces
bsalomon
2013/03/07 15:44:22
Done.
|
| 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()); |
| } |
| } |