Add GL uniform manager
Review URL: http://codereview.appspot.com/6423066/
git-svn-id: http://skia.googlecode.com/svn/trunk@4758 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 8c1f4f7..3a39d0c 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -21,16 +21,6 @@
#define GL_CALL(X) GR_GL_CALL(fContextInfo.interface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContextInfo.interface(), R, X)
-namespace {
-
-enum {
- /// Used to mark a StageUniLocation field that should be bound
- /// to a uniform during getUniformLocationsAndInitCache().
- kUseUniform = 2000
-};
-
-} // namespace
-
#define PRINT_SHADERS 0
typedef GrGLProgram::Desc::StageDesc StageDesc;
@@ -104,15 +94,27 @@
GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
const Desc& desc,
- GrCustomStage** customStages) : fContextInfo(gl) {
+ GrCustomStage** customStages)
+: fContextInfo(gl)
+, fUniformManager(gl) {
fDesc = desc;
fVShaderID = 0;
fGShaderID = 0;
fFShaderID = 0;
fProgramID = 0;
+
+ fViewMatrix = GrMatrix::InvalidMatrix();
+ fViewportSize.set(-1, -1);
+ fColor = GrColor_ILLEGAL;
+ fColorFilterColor = GrColor_ILLEGAL;
+
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
fProgramStage[s] = NULL;
+ fTextureMatrices[s] = GrMatrix::InvalidMatrix();
+ // this is arbitrary, just initialize to something
+ fTextureOrientation[s] = GrGLTexture::kBottomUp_Orientation;
}
+
this->genProgram(customStages);
}
@@ -399,9 +401,8 @@
*inColor = fsName;
} break;
case GrGLProgram::Desc::kUniform_ColorInput:
- builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec4f_GrSLType, COL_UNI_NAME);
- fUniLocations.fColorUni = kUseUniform;
+ fUniforms.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec4f_GrSLType, COL_UNI_NAME);
*inColor = COL_UNI_NAME;
break;
case GrGLProgram::Desc::kTransBlack_ColorInput:
@@ -416,9 +417,8 @@
}
void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOutCoverage) {
- builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec4f_GrSLType, COV_UNI_NAME);
- fUniLocations.fCoverageUni = kUseUniform;
+ fUniforms.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec4f_GrSLType, COV_UNI_NAME);
if (inOutCoverage->size()) {
builder->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n",
COV_UNI_NAME, inOutCoverage->c_str());
@@ -589,15 +589,12 @@
return true;
}
-
bool GrGLProgram::genProgram(GrCustomStage** customStages) {
GrAssert(0 == fProgramID);
- GrGLShaderBuilder builder(fContextInfo);
+ GrGLShaderBuilder builder(fContextInfo, fUniformManager);
const uint32_t& layout = fDesc.fVertexLayout;
- fUniLocations.reset();
-
#if GR_GL_EXPERIMENTAL_GS
builder.fUsesGS = fDesc.fExperimentalGS;
#endif
@@ -658,9 +655,8 @@
builder.fFSOutputs.push_back(colorOutput);
}
- builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType,
- kMat33f_GrSLType, VIEW_MATRIX_NAME);
- fUniLocations.fViewMatrixUni = kUseUniform;
+ fUniforms.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType,
+ kMat33f_GrSLType, VIEW_MATRIX_NAME);
builder.fVSAttrs.push_back().set(kVec2f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier,
@@ -748,9 +744,8 @@
}
}
if (needColorFilterUniform) {
- builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec4f_GrSLType, COL_FILTER_UNI_NAME);
- fUniLocations.fColorFilterUni = kUseUniform;
+ fUniforms.fColorFilterUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec4f_GrSLType, COL_FILTER_UNI_NAME);
}
bool wroteFragColorZero = false;
if (SkXfermode::kZero_Coeff == uniformCoeff &&
@@ -768,12 +763,10 @@
inColor = "filteredColor";
}
if (applyColorMatrix) {
- builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kMat44f_GrSLType, COL_MATRIX_UNI_NAME);
- builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec4f_GrSLType, COL_MATRIX_VEC_UNI_NAME);
- fUniLocations.fColorMatrixUni = kUseUniform;
- fUniLocations.fColorMatrixVecUni = kUseUniform;
+ fUniforms.fColorMatrixUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kMat44f_GrSLType, COL_MATRIX_UNI_NAME);
+ fUniforms.fColorMatrixVecUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec4f_GrSLType, COL_MATRIX_VEC_UNI_NAME);
builder.fFSCode.append("\tvec4 matrixedColor;\n");
const char* color = adjustInColor(inColor);
addColorMatrix(&builder.fFSCode, "matrixedColor", color);
@@ -927,7 +920,8 @@
return false;
}
- this->getUniformLocationsAndInitCache(builder);
+ builder.finished(fProgramID);
+ this->initSamplerUniforms();
return true;
}
@@ -993,78 +987,14 @@
return true;
}
-void GrGLProgram::getUniformLocationsAndInitCache(const GrGLShaderBuilder& builder) {
-
- if (kUseUniform == fUniLocations.fViewMatrixUni) {
- GL_CALL_RET(fUniLocations.fViewMatrixUni, GetUniformLocation(fProgramID, VIEW_MATRIX_NAME));
- GrAssert(kUnusedUniform != fUniLocations.fViewMatrixUni);
- }
- if (kUseUniform == fUniLocations.fColorUni) {
- GL_CALL_RET(fUniLocations.fColorUni, GetUniformLocation(fProgramID, COL_UNI_NAME));
- GrAssert(kUnusedUniform != fUniLocations.fColorUni);
- }
- if (kUseUniform == fUniLocations.fColorFilterUni) {
- GL_CALL_RET(fUniLocations.fColorFilterUni,
- GetUniformLocation(fProgramID, COL_FILTER_UNI_NAME));
- GrAssert(kUnusedUniform != fUniLocations.fColorFilterUni);
- }
-
- if (kUseUniform == fUniLocations.fColorMatrixUni) {
- GL_CALL_RET(fUniLocations.fColorMatrixUni,
- GetUniformLocation(fProgramID, COL_MATRIX_UNI_NAME));
- }
-
- if (kUseUniform == fUniLocations.fColorMatrixVecUni) {
- GL_CALL_RET(fUniLocations.fColorMatrixVecUni,
- GetUniformLocation(fProgramID, COL_MATRIX_VEC_UNI_NAME));
- }
-
- if (kUseUniform == fUniLocations.fCoverageUni) {
- GL_CALL_RET(fUniLocations.fCoverageUni,GetUniformLocation(fProgramID, COV_UNI_NAME));
- GrAssert(kUnusedUniform != fUniLocations.fCoverageUni);
- }
-
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- StageUniLocations& locations = fUniLocations.fStages[s];
- if (fDesc.fStages[s].isEnabled()) {
- if (kUseUniform == locations.fTextureMatrixUni) {
- SkString texMName;
- tex_matrix_name(s, &texMName);
- GL_CALL_RET(locations.fTextureMatrixUni,
- GetUniformLocation(fProgramID, texMName.c_str()));
- //color filter table effect does not consumer coords gen'ed by matrix.
- //GrAssert(kUnusedUniform != locations.fTextureMatrixUni);
- }
-
- if (kUseUniform == locations.fSamplerUni) {
- SkString samplerName;
- sampler_name(s, &samplerName);
- GL_CALL_RET(locations.fSamplerUni,
- GetUniformLocation(fProgramID,samplerName.c_str()));
- GrAssert(kUnusedUniform != locations.fSamplerUni);
- }
-
- if (NULL != fProgramStage[s]) {
- fProgramStage[s]->initUniforms(&builder, fContextInfo.interface(), fProgramID);
- }
- }
- }
+void GrGLProgram::initSamplerUniforms() {
GL_CALL(UseProgram(fProgramID));
-
// init sampler unis and set bogus values for state tracking
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- if (kUnusedUniform != fUniLocations.fStages[s].fSamplerUni) {
- GL_CALL(Uniform1i(fUniLocations.fStages[s].fSamplerUni, s));
+ if (GrGLUniformManager::kInvalidUniformHandle != fUniforms.fStages[s].fSamplerUni) {
+ fUniformManager.setSampler(fUniforms.fStages[s].fSamplerUni, s);
}
- fTextureMatrices[s] = GrMatrix::InvalidMatrix();
- // this is arbitrary, just initialize to something
- fTextureOrientation[s] = GrGLTexture::kBottomUp_Orientation;
- // Must not reset fStageOverride[] here.
}
- fViewMatrix = GrMatrix::InvalidMatrix();
- fViewportSize.set(-1, -1);
- fColor = GrColor_ILLEGAL;
- fColorFilterColor = GrColor_ILLEGAL;
}
///////////////////////////////////////////////////////////////////////////////
@@ -1078,7 +1008,7 @@
GrAssert(stageNum >= 0 && stageNum <= GrDrawState::kNumStages);
const GrGLProgram::StageDesc& desc = fDesc.fStages[stageNum];
- StageUniLocations& locations = fUniLocations.fStages[stageNum];
+ StageUniforms& uniforms = fUniforms.fStages[stageNum];
GrGLProgramStage* customStage = fProgramStage[stageNum];
GrAssert((desc.fInConfigFlags & StageDesc::kInConfigBitMask) == desc.fInConfigFlags);
@@ -1093,13 +1023,11 @@
} else {
SkString texMatName;
tex_matrix_name(stageNum, &texMatName);
- GrGLShaderBuilder::UniformHandle m =
- segments->addUniform(GrGLShaderBuilder::kVertex_ShaderType,
- kMat33f_GrSLType, texMatName.c_str());
- const GrGLShaderVar& mat = segments->getUniformVariable(m);
+ uniforms.fTextureMatrixUni = segments->addUniform(GrGLShaderBuilder::kVertex_ShaderType,
+ kMat33f_GrSLType, texMatName.c_str());
+ const GrGLShaderVar& mat = segments->getUniformVariable(uniforms.fTextureMatrixUni);
// Can't use texMatName.c_str() because it's on the stack!
matName = mat.getName().c_str();
- locations.fTextureMatrixUni = kUseUniform;
if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
segments->fVaryingDims = segments->fCoordDims;
@@ -1116,9 +1044,8 @@
SkString samplerName;
sampler_name(stageNum, &samplerName);
- segments->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kSampler2D_GrSLType, samplerName.c_str());
- locations.fSamplerUni = kUseUniform;
+ uniforms.fSamplerUni = segments->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kSampler2D_GrSLType, samplerName.c_str());
const char *varyingVSName, *varyingFSName;
segments->addVarying(GrSLFloatVectorType(segments->fVaryingDims),