Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Unified Diff: src/gpu/gl/GrGLProgram.cpp

Issue 23533066: Move the GL shader compilation step into GrGLShaderBuilder (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/GrGLProgram.h ('k') | src/gpu/gl/GrGLSL.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGLProgram.cpp
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index ac9794d4d5d3f5994cfcb427ae3293c839ff5f3f..f10e8954f20045758ac77e9e75aaf85077fdcaea 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -14,28 +14,13 @@
#include "GrGpuGL.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
-#include "SkTrace.h"
#include "SkXfermode.h"
-#include "SkRTConf.h"
-
SK_DEFINE_INST_COUNT(GrGLProgram)
#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
-SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
- "Print the source code for all shaders generated.");
-
-#define COL_ATTR_NAME "aColor"
-#define COV_ATTR_NAME "aCoverage"
-#define EDGE_ATTR_NAME "aEdge"
-
-namespace {
-inline const char* declared_color_output_name() { return "fsColorOut"; }
-inline const char* dual_source_output_name() { return "dualSourceOut"; }
-}
-
GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
const GrGLProgramDesc& desc,
const GrEffectStage* colorStages[],
@@ -55,9 +40,6 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
: fGpu(gpu)
, fUniformManager(gpu) {
fDesc = desc;
- fVShaderID = 0;
- fGShaderID = 0;
- fFShaderID = 0;
fProgramID = 0;
fDstCopyTexUnit = -1;
@@ -72,24 +54,12 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
}
GrGLProgram::~GrGLProgram() {
- if (fVShaderID) {
- GL_CALL(DeleteShader(fVShaderID));
- }
- if (fGShaderID) {
- GL_CALL(DeleteShader(fGShaderID));
- }
- if (fFShaderID) {
- GL_CALL(DeleteShader(fFShaderID));
- }
if (fProgramID) {
GL_CALL(DeleteProgram(fProgramID));
}
}
void GrGLProgram::abandon() {
- fVShaderID = 0;
- fGShaderID = 0;
- fFShaderID = 0;
fProgramID = 0;
}
@@ -219,167 +189,7 @@ void add_color_filter(GrGLShaderBuilder* builder,
}
}
-GrSLConstantVec GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) {
- switch (fDesc.getHeader().fColorInput) {
- case GrGLProgramDesc::kAttribute_ColorInput: {
- GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
- SkASSERT(NULL != vertexBuilder);
- vertexBuilder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME);
- const char *vsName, *fsName;
- vertexBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
- vertexBuilder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
- *inColor = fsName;
- return kNone_GrSLConstantVec;
- }
- case GrGLProgramDesc::kUniform_ColorInput: {
- const char* name;
- fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
- kVec4f_GrSLType, "Color", &name);
- *inColor = name;
- return kNone_GrSLConstantVec;
- }
- case GrGLProgramDesc::kTransBlack_ColorInput:
- inColor->reset();
- return kZeros_GrSLConstantVec;
- case GrGLProgramDesc::kSolidWhite_ColorInput:
- inColor->reset();
- return kOnes_GrSLConstantVec;
- default:
- GrCrash("Unknown color type.");
- return kNone_GrSLConstantVec;
- }
-}
-
-GrSLConstantVec GrGLProgram::genInputCoverage(GrGLShaderBuilder* builder, SkString* inCoverage) {
- switch (fDesc.getHeader().fCoverageInput) {
- case GrGLProgramDesc::kAttribute_ColorInput: {
- GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
- SkASSERT(NULL != vertexBuilder);
- vertexBuilder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME);
- const char *vsName, *fsName;
- vertexBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
- vertexBuilder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
- *inCoverage = fsName;
- return kNone_GrSLConstantVec;
- }
- case GrGLProgramDesc::kUniform_ColorInput: {
- const char* name;
- fUniformHandles.fCoverageUni =
- builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
- kVec4f_GrSLType, "Coverage", &name);
- *inCoverage = name;
- return kNone_GrSLConstantVec;
- }
- case GrGLProgramDesc::kTransBlack_ColorInput:
- inCoverage->reset();
- return kZeros_GrSLConstantVec;
- case GrGLProgramDesc::kSolidWhite_ColorInput:
- inCoverage->reset();
- return kOnes_GrSLConstantVec;
- default:
- GrCrash("Unknown color type.");
- return kNone_GrSLConstantVec;
- }
-}
-
-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(fGpu->glslGeneration() >= k150_GrGLSLGeneration);
- 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) {
- vertexBuilder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n");
- }
- SkASSERT(vertexBuilder->fGSInputs.count() == vertexBuilder->fGSOutputs.count());
- int count = vertexBuilder->fGSInputs.count();
- for (int i = 0; i < count; ++i) {
- vertexBuilder->gsCodeAppendf("\t\t%s = %s[i];\n",
- vertexBuilder->fGSOutputs[i].getName().c_str(),
- vertexBuilder->fGSInputs[i].getName().c_str());
- }
- vertexBuilder->gsCodeAppend("\t\tEmitVertex();\n"
- "\t}\n"
- "\tEndPrimitive();\n");
- }
-#endif
-}
-
-const char* GrGLProgram::adjustInColor(const SkString& inColor) const {
- if (inColor.size()) {
- return inColor.c_str();
- } else {
- if (GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.getHeader().fColorInput) {
- return GrGLSLOnesVecf(4);
- } else {
- return GrGLSLZerosVecf(4);
- }
- }
-}
-
namespace {
-// prints a shader using params similar to glShaderSource
-void print_shader(GrGLint stringCnt,
- const GrGLchar** strings,
- GrGLint* stringLengths) {
- for (int i = 0; i < stringCnt; ++i) {
- if (NULL == stringLengths || stringLengths[i] < 0) {
- GrPrintf(strings[i]);
- } else {
- GrPrintf("%.*s", stringLengths[i], strings[i]);
- }
- }
-}
-
-// Compiles a GL shader, returns shader ID or 0 if failed params have same meaning as glShaderSource
-GrGLuint compile_shader(const GrGLInterface* gli,
- GrGLenum type,
- int stringCnt,
- const char** strings,
- int* stringLengths) {
- SK_TRACE_EVENT1("GrGLProgram::CompileShader",
- "stringCount", SkStringPrintf("%i", stringCnt).c_str());
-
- GrGLuint shader;
- GR_GL_CALL_RET(gli, shader, CreateShader(type));
- if (0 == shader) {
- return 0;
- }
-
- GrGLint compiled = GR_GL_INIT_ZERO;
- GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths));
- GR_GL_CALL(gli, CompileShader(shader));
- GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled));
-
- if (!compiled) {
- GrGLint infoLen = GR_GL_INIT_ZERO;
- GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen));
- SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
- if (infoLen > 0) {
- // retrieve length even though we don't need it to workaround bug in chrome cmd buffer
- // param validation.
- GrGLsizei length = GR_GL_INIT_ZERO;
- GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1,
- &length, (char*)log.get()));
- print_shader(stringCnt, strings, stringLengths);
- GrPrintf("\n%s", log.get());
- }
- SkDEBUGFAIL("Shader compilation failed!");
- GR_GL_CALL(gli, DeleteShader(shader));
- return 0;
- }
- return shader;
-}
-
-// helper version of above for when shader is already flattened into a single SkString
-GrGLuint compile_shader(const GrGLInterface* gli, GrGLenum type, const SkString& shader) {
- const GrGLchar* str = shader.c_str();
- int length = shader.size();
- return compile_shader(gli, type, 1, &str, &length);
-}
void expand_known_value4f(SkString* string, GrSLConstantVec vec) {
SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec));
@@ -397,50 +207,6 @@ 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) {
-
- SkASSERT(!fVShaderID);
- SkASSERT(!fGShaderID);
- SkASSERT(!fFShaderID);
-
- SkString shader;
- if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) {
- vertexBuilder->vsGetShader(&shader);
- if (c_PrintShaders) {
- GrPrintf(shader.c_str());
- GrPrintf("\n");
- }
- if (!(fVShaderID = compile_shader(fGpu->glInterface(), 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(fGpu->glInterface(), GR_GL_GEOMETRY_SHADER, shader))) {
- return false;
- }
- }
-#endif
- }
-
- builder.fsGetShader(&shader);
- if (c_PrintShaders) {
- GrPrintf(shader.c_str());
- GrPrintf("\n");
- }
- if (!(fFShaderID = compile_shader(fGpu->glInterface(), GR_GL_FRAGMENT_SHADER, shader))) {
- return false;
- }
-
- return true;
-}
-
bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[]) {
SkASSERT(0 == fProgramID);
@@ -449,42 +215,14 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
bool needsVertexShader = true;
- GrGLShaderBuilder builder(fGpu->ctxInfo(), fUniformManager, fDesc, needsVertexShader);
-
+ GrGLShaderBuilder builder(fGpu, 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.
- bool dualSourceOutputWritten = false;
-
- GrGLShaderVar colorOutput;
- bool isColorDeclared = GrGLSLSetupFSColorOuput(fGpu->glslGeneration(),
- declared_color_output_name(),
- &colorOutput);
- if (isColorDeclared) {
- builder.fsOutputAppend(colorOutput);
+ fUniformHandles.fViewMatrixUni = vertexBuilder->getViewMatrixUniform();
}
// incoming color to current stage being processed.
- SkString inColor;
- GrSLConstantVec knownColorValue = this->genInputColor(&builder, &inColor);
+ SkString inColor = builder.getInputColor();
+ GrSLConstantVec knownColorValue = builder.getKnownColorValue();
// Get the coeffs for the Mode-based color filter, determine if color is needed.
SkXfermode::Coeff colorCoeff;
@@ -544,8 +282,8 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
///////////////////////////////////////////////////////////////////////////
// compute the partial coverage
- SkString inCoverage;
- GrSLConstantVec knownCoverageValue = this->genInputCoverage(&builder, &inCoverage);
+ SkString inCoverage = builder.getInputCoverage();
+ GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue();
for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis;
@@ -576,9 +314,8 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
GrGLProgramDesc::CoverageOutput coverageOutput =
static_cast<GrGLProgramDesc::CoverageOutput>(header.fCoverageOutput);
if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(coverageOutput)) {
- builder.fsOutputAppend().set(kVec4f_GrSLType,
- GrGLShaderVar::kOut_TypeModifier,
- dual_source_output_name());
+ const char* secondaryOutputName = builder.enableSecondaryOutput();
+
// default coeff to ones for kCoverage_DualSrcOutput
SkString coeff;
GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec;
@@ -613,8 +350,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
knownCoeffValue,
knownCoverageValue,
false);
- builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulate.c_str());
- dualSourceOutputWritten = true;
+ builder.fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_str());
}
///////////////////////////////////////////////////////////////////////////
@@ -655,33 +391,17 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
} else {
expand_known_value4f(&fragColor, knownFragColorValue);
}
- builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), fragColor.c_str());
-
- ///////////////////////////////////////////////////////////////////////////
- // insert GS
-#ifdef SK_DEBUG
- if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) {
- this->genGeometryShader(vertexBuilder);
- }
-#endif
+ builder.fsCodeAppendf("\t%s = %s;\n", builder.getColorOutputName(), fragColor.c_str());
- ///////////////////////////////////////////////////////////////////////////
- // compile and setup attribs and unis
-
- if (!this->compileShaders(builder)) {
- return false;
- }
-
- if (!this->bindOutputsAttribsAndLinkProgram(builder,
- isColorDeclared,
- dualSourceOutputWritten)) {
+ if (!builder.finish(&fProgramID)) {
return false;
}
- builder.finished(fProgramID);
fUniformHandles.fRTHeightUni = builder.getRTHeightUniform();
fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform();
fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform();
+ fUniformHandles.fColorUni = builder.getColorUniform();
+ fUniformHandles.fCoverageUni = builder.getCoverageUniform();
fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform();
// This must be called after we set fDstCopySamplerUni above.
this->initSamplerUniforms();
@@ -689,82 +409,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
return true;
}
-bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder,
- bool bindColorOut,
- bool bindDualSrcOut) {
- GL_CALL_RET(fProgramID, CreateProgram());
- if (!fProgramID) {
- return false;
- }
-
- if (fVShaderID) {
- GL_CALL(AttachShader(fProgramID, fVShaderID));
- }
- if (fGShaderID) {
- GL_CALL(AttachShader(fProgramID, fGShaderID));
- }
- GL_CALL(AttachShader(fProgramID, fFShaderID));
-
- if (bindColorOut) {
- GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name()));
- }
- if (bindDualSrcOut) {
- GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output_name()));
- }
-
- const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
-
- // Bind the attrib locations to same values for all shaders
- if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) {
- GL_CALL(BindAttribLocation(fProgramID,
- 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::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));
-
- GrGLint linked = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked));
- if (!linked) {
- GrGLint infoLen = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
- SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
- if (infoLen > 0) {
- // retrieve length even though we don't need it to workaround
- // bug in chrome cmd buffer param validation.
- GrGLsizei length = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramInfoLog(fProgramID,
- infoLen+1,
- &length,
- (char*)log.get()));
- GrPrintf((char*)log.get());
- }
- SkDEBUGFAIL("Error linking program");
- GL_CALL(DeleteProgram(fProgramID));
- fProgramID = 0;
- return false;
- }
- return true;
-}
-
void GrGLProgram::initSamplerUniforms() {
GL_CALL(UseProgram(fProgramID));
GrGLint texUnitIdx = 0;
« no previous file with comments | « src/gpu/gl/GrGLProgram.h ('k') | src/gpu/gl/GrGLSL.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698