aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLProgram.cpp16
-rw-r--r--src/gpu/gl/GrGLProgram.h3
-rw-r--r--src/gpu/gl/GrGLProgramStage.cpp6
-rw-r--r--src/gpu/gl/GrGLProgramStage.h10
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp80
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h40
-rw-r--r--src/gpu/gl/GrGLShaderVar.h6
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; }