| 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));
|
|
|