diff options
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 16 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.h | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 80 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.h | 40 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderVar.h | 6 |
7 files changed, 105 insertions, 56 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 1ad9817372..d13620cb20 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -932,7 +932,7 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl, return false; } - this->getUniformLocationsAndInitCache(gl, programData); + this->getUniformLocationsAndInitCache(builder, gl, programData); return true; } @@ -1003,7 +1003,8 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLContextInfo& gl, return true; } -void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl, +void GrGLProgram::getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder, + const GrGLContextInfo& gl, CachedData* programData) const { const GrGLint& progID = programData->fProgramID; @@ -1066,8 +1067,7 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl, } if (NULL != programData->fCustomStage[s]) { - programData->fCustomStage[s]-> - initUniforms(gl.interface(), progID); + programData->fCustomStage[s]->initUniforms(&builder, gl.interface(), progID); } } } @@ -1118,10 +1118,12 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, } else { SkString texMatName; tex_matrix_name(stageNum, &texMatName); - const GrGLShaderVar* mat = &segments->addUniform(GrGLShaderBuilder::kVertex_ShaderType, - kMat33f_GrSLType, texMatName.c_str()); + GrGLShaderBuilder::UniformHandle m = + segments->addUniform(GrGLShaderBuilder::kVertex_ShaderType, + kMat33f_GrSLType, texMatName.c_str()); + const GrGLShaderVar& mat = segments->getUniformVariable(m); // Can't use texMatName.c_str() because it's on the stack! - matName = mat->getName().c_str(); + matName = mat.getName().c_str(); locations->fTextureMatrixUni = kUseUniform; if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) { diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index 0be08b3b39..bebaa58e0b 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -366,7 +366,8 @@ private: CachedData* programData) const; // Binds uniforms; initializes cache to invalid values. - void getUniformLocationsAndInitCache(const GrGLContextInfo& gl, + void getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder, + const GrGLContextInfo& gl, CachedData* programData) const; friend class GrGpuGL; diff --git a/src/gpu/gl/GrGLProgramStage.cpp b/src/gpu/gl/GrGLProgramStage.cpp index c1d4942015..fe103ad866 100644 --- a/src/gpu/gl/GrGLProgramStage.cpp +++ b/src/gpu/gl/GrGLProgramStage.cpp @@ -17,11 +17,13 @@ GrGLProgramStage::~GrGLProgramStage() { /////////////////////////////////////////////////////////////////////////////// -void GrGLProgramStage::setupVariables(GrGLShaderBuilder* state, int stage) { +void GrGLProgramStage::setupVariables(GrGLShaderBuilder*, int stage) { } -void GrGLProgramStage::initUniforms(const GrGLInterface*, int progID) { +void GrGLProgramStage::initUniforms(const GrGLShaderBuilder*, + const GrGLInterface*, + int progID) { } diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h index d5c79b4f65..6350ae34b8 100644 --- a/src/gpu/gl/GrGLProgramStage.h +++ b/src/gpu/gl/GrGLProgramStage.h @@ -48,7 +48,7 @@ public: virtual ~GrGLProgramStage(); /** Create any uniforms or varyings the vertex shader requires. */ - virtual void setupVariables(GrGLShaderBuilder* state, int stage); + virtual void setupVariables(GrGLShaderBuilder* builder, int stage); /** Appends vertex code to the appropriate SkString on the state. @@ -56,7 +56,7 @@ public: Vertex shader input is a vec2 of coordinates, which may be altered. The code will be inside an otherwise-empty block. */ - virtual void emitVS(GrGLShaderBuilder* state, + virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) = 0; /** Appends fragment code to the appropriate SkString @@ -68,14 +68,16 @@ public: a function here for them to call into that'll apply any texture domain - but do we force them to be honest about texture domain parameters? */ - virtual void emitFS(GrGLShaderBuilder* state, + virtual void emitFS(GrGLShaderBuilder* builder, const char* outputColor, const char* inputColor, const char* samplerName) = 0; /** Binds uniforms; we must have already bound the program and determined its GL program ID. */ - virtual void initUniforms(const GrGLInterface* gl, int programID); + virtual void initUniforms(const GrGLShaderBuilder* builder, + const GrGLInterface* gl, + int programID); /** A GrGLCustomStage instance can be reused with any GrCustomStage that produces the same stage key; this function reads data from diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 3303bf2729..7fa804a7e5 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -23,13 +23,12 @@ static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar: //const int GrGLShaderBuilder::fCoordDims = 2; GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx) - : fVSUnis(kVarsPerBlock) + : fUniforms(kVarsPerBlock) , fVSAttrs(kVarsPerBlock) , fVSOutputs(kVarsPerBlock) , fGSInputs(kVarsPerBlock) , fGSOutputs(kVarsPerBlock) , fFSInputs(kVarsPerBlock) - , fFSUnis(kVarsPerBlock) , fFSOutputs(kMaxFSOutputs) , fUsesGS(false) , fVaryingDims(0) @@ -116,38 +115,45 @@ void GrGLShaderBuilder::emitDefaultFetch(const char* outColor, fFSCode.appendf("%s%s;\n", fSwizzle.c_str(), fModulate.c_str()); } -const GrGLShaderVar& GrGLShaderBuilder::addUniform(uint32_t visibility, - GrSLType type, - const char* name, - int stageNum, - int count) { +namespace { +inline int handle_to_index(GrGLShaderBuilder::UniformHandle h) { return ~h; } +inline GrGLShaderBuilder::UniformHandle index_to_handle(int i) { return ~i; } +} + +GrGLShaderBuilder::UniformHandle GrGLShaderBuilder::addUniform(uint32_t visibility, + GrSLType type, + const char* name, + int stageNum, + int count) { GrAssert(name && strlen(name)); static const uint32_t kVisibilityMask = kVertex_ShaderType | kFragment_ShaderType; GrAssert(0 == (~kVisibilityMask & visibility)); GrAssert(0 != visibility); - GrGLShaderVar* var = NULL; - if (kVertex_ShaderType & visibility) { - var = &fVSUnis.push_back(); - } else { - GrAssert(kFragment_ShaderType & visibility); - var = &fFSUnis.push_back(); - } - var->setType(type); - var->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); - var->setName(name); + Uniform& uni = fUniforms.push_back(); + UniformHandle h = index_to_handle(fUniforms.count() - 1); + uni.fVariable.setType(type); + uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); + uni.fVariable.setName(name); if (stageNum >= 0) { - var->accessName()->appendS32(stageNum); + uni.fVariable.accessName()->appendS32(stageNum); } - var->setArrayCount(count); + uni.fVariable.setArrayCount(count); + uni.fVisibility = visibility; + // If it is visible in both the VS and FS, the precision must match. + // We declare a default FS precision, but not a default VS. So set the var + // to use the default FS precision. if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) { // the fragment and vertex precisions must match - var->setPrecision(kDefaultFragmentPrecision); - fFSUnis.push_back(*var); + uni.fVariable.setPrecision(kDefaultFragmentPrecision); } - return *var; + return h; +} + +const GrGLShaderVar& GrGLShaderBuilder::getUniformVariable(UniformHandle u) const { + return fUniforms[handle_to_index(u)].fVariable; } void GrGLShaderBuilder::addVarying(GrSLType type, @@ -222,31 +228,37 @@ inline void append_default_precision_qualifier(GrGLShaderVar::Precision p, } } } +} -void append_decls(const GrGLShaderBuilder::VarArray& vars, - const GrGLContextInfo& ctx, - SkString* string) { +void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { for (int i = 0; i < vars.count(); ++i) { - vars[i].appendDecl(ctx, string); + vars[i].appendDecl(fContext, out); } } + +void GrGLShaderBuilder::appendUniformDecls(ShaderType stype, SkString* out) const { + for (int i = 0; i < fUniforms.count(); ++i) { + if (fUniforms[i].fVisibility & stype) { + fUniforms[i].fVariable.appendDecl(fContext, out); + } + } } void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { switch (type) { case kVertex_ShaderType: *shaderStr = fHeader; - append_decls(fVSUnis, fContext, shaderStr); - append_decls(fVSAttrs, fContext, shaderStr); - append_decls(fVSOutputs, fContext, shaderStr); + this->appendUniformDecls(kVertex_ShaderType, shaderStr); + this->appendDecls(fVSAttrs, shaderStr); + this->appendDecls(fVSOutputs, shaderStr); shaderStr->append(fVSCode); break; case kGeometry_ShaderType: if (fUsesGS) { *shaderStr = fHeader; shaderStr->append(fGSHeader); - append_decls(fGSInputs, fContext, shaderStr); - append_decls(fGSOutputs, fContext, shaderStr); + this->appendDecls(fGSInputs, shaderStr); + this->appendDecls(fGSOutputs, shaderStr); shaderStr->append(fGSCode); } else { shaderStr->reset(); @@ -257,11 +269,11 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { append_default_precision_qualifier(kDefaultFragmentPrecision, fContext.binding(), shaderStr); - append_decls(fFSUnis, fContext, shaderStr); - append_decls(fFSInputs, fContext, shaderStr); + this->appendUniformDecls(kFragment_ShaderType, shaderStr); + this->appendDecls(fFSInputs, shaderStr); // We shouldn't have declared outputs on 1.10 GrAssert(k110_GrGLSLGeneration != fContext.glslGeneration() || fFSOutputs.empty()); - append_decls(fFSOutputs, fContext, shaderStr); + this->appendDecls(fFSOutputs, shaderStr); shaderStr->append(fFSFunctions); shaderStr->append(fFSCode); break; diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 5884a90f85..892fcbee47 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -22,7 +22,9 @@ class GrGLContextInfo; class GrGLShaderBuilder { public: - typedef GrTAllocator<GrGLShaderVar> VarArray; + + typedef int UniformHandle; + static const UniformHandle kInvalidUniformHandle = 0; enum ShaderType { kVertex_ShaderType = 0x1, @@ -62,11 +64,20 @@ public: from which shaders the uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not supported at this time. */ - const GrGLShaderVar& addUniform(uint32_t visibility, - GrSLType type, - const char* name, - int stageNum = -1, - int count = GrGLShaderVar::kNonArray); + UniformHandle addUniform(uint32_t visibility, + GrSLType type, + const char* name, + int stageNum = -1, + int count = GrGLShaderVar::kNonArray); + + const GrGLShaderVar& getUniformVariable(UniformHandle) const; + + /** + * Shorcut for getUniformVariable(u).c_str() + */ + const char* getUniformCStr(UniformHandle u) const { + return this->getUniformVariable(u).c_str(); + } /** Add a varying variable to the current program to pass values between vertex and fragment shaders. If the last two parameters are non-NULL, they are filled in with the name @@ -88,17 +99,30 @@ public: /** Called after building is complete to get the final shader string. */ void getShader(ShaderType, SkString*) const; +private: + typedef GrTAllocator<GrGLShaderVar> VarArray; + + struct Uniform { + GrGLShaderVar fVariable; + uint32_t fVisibility; + }; + + typedef GrTAllocator<Uniform> UniformArray; + void appendDecls(const VarArray&, SkString*) const; + void appendUniformDecls(ShaderType, SkString*) const; + + UniformArray fUniforms; + // TODO: Everything below here private. +public: SkString fHeader; // VS+FS, GLSL version, etc - VarArray fVSUnis; VarArray fVSAttrs; VarArray fVSOutputs; VarArray fGSInputs; VarArray fGSOutputs; VarArray fFSInputs; SkString fGSHeader; // layout qualifiers specific to GS - VarArray fFSUnis; VarArray fFSOutputs; SkString fFSFunctions; SkString fVSCode; diff --git a/src/gpu/gl/GrGLShaderVar.h b/src/gpu/gl/GrGLShaderVar.h index 2eccd3b1e8..0231d214d3 100644 --- a/src/gpu/gl/GrGLShaderVar.h +++ b/src/gpu/gl/GrGLShaderVar.h @@ -171,12 +171,18 @@ public: */ void setName(const SkString& n) { fName = n; } void setName(const char* n) { fName = n; } + /** * Get the var name. */ const SkString& getName() const { return fName; } /** + * Shortcut for this->getName().c_str(); + */ + const char* c_str() const { return this->getName().c_str(); } + + /** * Get the type of the var */ GrSLType getType() const { return fType; } |