Index: src/gpu/gl/GrGLProgram.cpp |
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp |
index a1c4fd5d76fc591c9a7b07a88bcd5362c53f84ba..540ebcaeb32ae4ac1e6fe535327c941d85486723 100644 |
--- a/src/gpu/gl/GrGLProgram.cpp |
+++ b/src/gpu/gl/GrGLProgram.cpp |
@@ -222,10 +222,12 @@ void add_color_filter(GrGLShaderBuilder* builder, |
GrSLConstantVec GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { |
switch (fDesc.getHeader().fColorInput) { |
case GrGLProgramDesc::kAttribute_ColorInput: { |
- builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); |
+ GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); |
+ SkASSERT(NULL != vertexBuilder); |
+ vertexBuilder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); |
const char *vsName, *fsName; |
- builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); |
- builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); |
+ vertexBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); |
+ vertexBuilder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); |
*inColor = fsName; |
return kNone_GrSLConstantVec; |
} |
@@ -251,10 +253,12 @@ GrSLConstantVec GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* |
GrSLConstantVec GrGLProgram::genInputCoverage(GrGLShaderBuilder* builder, SkString* inCoverage) { |
switch (fDesc.getHeader().fCoverageInput) { |
case GrGLProgramDesc::kAttribute_ColorInput: { |
- builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); |
+ GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder(); |
+ SkASSERT(NULL != vertexBuilder); |
+ vertexBuilder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); |
const char *vsName, *fsName; |
- builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); |
- builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); |
+ vertexBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); |
+ vertexBuilder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); |
*inCoverage = fsName; |
return kNone_GrSLConstantVec; |
} |
@@ -278,28 +282,28 @@ GrSLConstantVec GrGLProgram::genInputCoverage(GrGLShaderBuilder* builder, SkStri |
} |
} |
-void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const { |
+void GrGLProgram::genGeometryShader(GrGLShaderBuilder::VertexBuilder* vertexBuilder) const { |
#if GR_GL_EXPERIMENTAL_GS |
// TODO: The builder should add all this glue code. |
if (fDesc.getHeader().fExperimentalGS) { |
SkASSERT(fContext.info().glslGeneration() >= k150_GrGLSLGeneration); |
- builder->fGSHeader.append("layout(triangles) in;\n" |
- "layout(triangle_strip, max_vertices = 6) out;\n"); |
- builder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" |
- "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
+ vertexBuilder->fGSHeader.append("layout(triangles) in;\n" |
+ "layout(triangle_strip, max_vertices = 6) out;\n"); |
+ vertexBuilder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" |
+ "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
if (fDesc.getHeader().fEmitsPointSize) { |
- builder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n"); |
+ vertexBuilder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n"); |
} |
- SkASSERT(builder->fGSInputs.count() == builder->fGSOutputs.count()); |
- int count = builder->fGSInputs.count(); |
+ SkASSERT(vertexBuilder->fGSInputs.count() == vertexBuilder->fGSOutputs.count()); |
+ int count = vertexBuilder->fGSInputs.count(); |
for (int i = 0; i < count; ++i) { |
- builder->gsCodeAppendf("\t\t%s = %s[i];\n", |
- builder->fGSOutputs[i].getName().c_str(), |
- builder->fGSInputs[i].getName().c_str()); |
+ vertexBuilder->gsCodeAppendf("\t\t%s = %s[i];\n", |
+ vertexBuilder->fGSOutputs[i].getName().c_str(), |
+ vertexBuilder->fGSInputs[i].getName().c_str()); |
} |
- builder->gsCodeAppend("\t\tEmitVertex();\n" |
- "\t}\n" |
- "\tEndPrimitive();\n"); |
+ vertexBuilder->gsCodeAppend("\t\tEmitVertex();\n" |
+ "\t}\n" |
+ "\tEndPrimitive();\n"); |
} |
#endif |
} |
@@ -397,31 +401,34 @@ void expand_known_value4f(SkString* string, GrSLConstantVec vec) { |
// compiles all the shaders from builder and stores the shader IDs |
bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) { |
- SkString shader; |
- |
- builder.vsGetShader(&shader); |
- if (c_PrintShaders) { |
- GrPrintf(shader.c_str()); |
- GrPrintf("\n"); |
- } |
+ SkASSERT(!fVShaderID); |
+ SkASSERT(!fGShaderID); |
+ SkASSERT(!fFShaderID); |
- if (!(fVShaderID = compile_shader(fContext, GR_GL_VERTEX_SHADER, shader))) { |
- return false; |
- } |
- |
- fGShaderID = 0; |
-#if GR_GL_EXPERIMENTAL_GS |
- if (fDesc.getHeader().fExperimentalGS) { |
- builder.gsGetShader(&shader); |
+ SkString shader; |
+ if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) { |
+ vertexBuilder->vsGetShader(&shader); |
if (c_PrintShaders) { |
GrPrintf(shader.c_str()); |
GrPrintf("\n"); |
} |
- if (!(fGShaderID = compile_shader(fContext, GR_GL_GEOMETRY_SHADER, shader))) { |
+ if (!(fVShaderID = compile_shader(fContext, GR_GL_VERTEX_SHADER, shader))) { |
return false; |
} |
- } |
+ |
+#if GR_GL_EXPERIMENTAL_GS |
+ if (fDesc.getHeader().fExperimentalGS) { |
+ vertexBuilder->gsGetShader(&shader); |
+ if (c_PrintShaders) { |
+ GrPrintf(shader.c_str()); |
+ GrPrintf("\n"); |
+ } |
+ if (!(fGShaderID = compile_shader(fContext, GR_GL_GEOMETRY_SHADER, shader))) { |
+ return false; |
+ } |
+ } |
#endif |
+ } |
builder.fsGetShader(&shader); |
if (c_PrintShaders) { |
@@ -441,7 +448,28 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
- GrGLShaderBuilder builder(fContext.info(), fUniformManager, fDesc); |
+ bool needsVertexShader = true; |
+ |
+ GrGLShaderBuilder builder(fContext.info(), fUniformManager, fDesc, needsVertexShader); |
+ |
+ if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) { |
+ const char* viewMName; |
+ fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_Visibility, |
+ kMat33f_GrSLType, "ViewM", &viewMName); |
+ |
+ vertexBuilder->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" |
+ "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", |
+ viewMName, vertexBuilder->positionAttribute().c_str()); |
+ |
+ // we output point size in the GS if present |
+ if (header.fEmitsPointSize |
+#if GR_GL_EXPERIMENTAL_GS |
+ && !header.fExperimentalGS |
+#endif |
+ ) { |
+ vertexBuilder->vsCodeAppend("\tgl_PointSize = 1.0;\n"); |
+ } |
+ } |
// the dual source output has no canonical var name, have to |
// declare an output, which is incompatible with gl_FragColor/gl_FragData. |
@@ -452,31 +480,13 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
declared_color_output_name(), |
&colorOutput); |
if (isColorDeclared) { |
- builder.fFSOutputs.push_back(colorOutput); |
+ builder.fsOutputAppend(colorOutput); |
} |
- const char* viewMName; |
- fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_Visibility, |
- kMat33f_GrSLType, "ViewM", &viewMName); |
- |
- |
- 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; |
GrSLConstantVec knownColorValue = this->genInputColor(&builder, &inColor); |
- // we output point size in the GS if present |
- if (header.fEmitsPointSize |
-#if GR_GL_EXPERIMENTAL_GS |
- && !header.fExperimentalGS |
-#endif |
- ) { |
- builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); |
- } |
- |
// Get the coeffs for the Mode-based color filter, determine if color is needed. |
SkXfermode::Coeff colorCoeff; |
SkXfermode::Coeff filterColorCoeff; |
@@ -567,9 +577,9 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
GrGLProgramDesc::CoverageOutput coverageOutput = |
static_cast<GrGLProgramDesc::CoverageOutput>(header.fCoverageOutput); |
if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(coverageOutput)) { |
- builder.fFSOutputs.push_back().set(kVec4f_GrSLType, |
- GrGLShaderVar::kOut_TypeModifier, |
- dual_source_output_name()); |
+ builder.fsOutputAppend().set(kVec4f_GrSLType, |
+ GrGLShaderVar::kOut_TypeModifier, |
+ dual_source_output_name()); |
// default coeff to ones for kCoverage_DualSrcOutput |
SkString coeff; |
GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; |
@@ -651,7 +661,9 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
/////////////////////////////////////////////////////////////////////////// |
// insert GS |
#ifdef SK_DEBUG |
- this->genGeometryShader(&builder); |
+ if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) { |
+ this->genGeometryShader(vertexBuilder); |
+ } |
#endif |
/////////////////////////////////////////////////////////////////////////// |
@@ -686,7 +698,9 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil |
return false; |
} |
- GL_CALL(AttachShader(fProgramID, fVShaderID)); |
+ if (fVShaderID) { |
+ GL_CALL(AttachShader(fProgramID, fVShaderID)); |
+ } |
if (fGShaderID) { |
GL_CALL(AttachShader(fProgramID, fGShaderID)); |
} |
@@ -702,26 +716,28 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil |
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
// Bind the attrib locations to same values for all shaders |
- GL_CALL(BindAttribLocation(fProgramID, |
- header.fPositionAttributeIndex, |
- builder.positionAttribute().c_str())); |
- if (-1 != header.fLocalCoordAttributeIndex) { |
+ if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) { |
GL_CALL(BindAttribLocation(fProgramID, |
- header.fLocalCoordAttributeIndex, |
- builder.localCoordsAttribute().c_str())); |
- } |
- if (-1 != header.fColorAttributeIndex) { |
- GL_CALL(BindAttribLocation(fProgramID, header.fColorAttributeIndex, COL_ATTR_NAME)); |
- } |
- if (-1 != header.fCoverageAttributeIndex) { |
- GL_CALL(BindAttribLocation(fProgramID, header.fCoverageAttributeIndex, COV_ATTR_NAME)); |
- } |
+ header.fPositionAttributeIndex, |
+ vertexBuilder->positionAttribute().c_str())); |
+ if (-1 != header.fLocalCoordAttributeIndex) { |
+ GL_CALL(BindAttribLocation(fProgramID, |
+ header.fLocalCoordAttributeIndex, |
+ vertexBuilder->localCoordsAttribute().c_str())); |
+ } |
+ if (-1 != header.fColorAttributeIndex) { |
+ GL_CALL(BindAttribLocation(fProgramID, header.fColorAttributeIndex, COL_ATTR_NAME)); |
+ } |
+ if (-1 != header.fCoverageAttributeIndex) { |
+ GL_CALL(BindAttribLocation(fProgramID, header.fCoverageAttributeIndex, COV_ATTR_NAME)); |
+ } |
- const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end(); |
- for (const GrGLShaderBuilder::AttributePair* attrib = builder.getEffectAttributes().begin(); |
- attrib != attribEnd; |
- ++attrib) { |
- GL_CALL(BindAttribLocation(fProgramID, attrib->fIndex, attrib->fName.c_str())); |
+ const GrGLShaderBuilder::VertexBuilder::AttributePair* attribEnd = vertexBuilder->getEffectAttributes().end(); |
+ for (const GrGLShaderBuilder::VertexBuilder::AttributePair* attrib = vertexBuilder->getEffectAttributes().begin(); |
+ attrib != attribEnd; |
+ ++attrib) { |
+ GL_CALL(BindAttribLocation(fProgramID, attrib->fIndex, attrib->fName.c_str())); |
+ } |
} |
GL_CALL(LinkProgram(fProgramID)); |