Add a requiresVertexShader method to GrGLEffect
Adds requiresVertexShader to GrGLEffect and updates the necessary
effects to override it and return true. Also reworks GrGLProgram
and GrGLShaderBuilder so the program creates all the GL effects
at the beginning, and determines if it needs a vertex shader before
creating the shader builder.
R=bsalomon@google.com
Author: cdalton@nvidia.com
Review URL: https://chromiumcodereview.appspot.com/23471008
git-svn-id: http://skia.googlecode.com/svn/trunk@11140 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index ac9794d..ebc5782 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -446,10 +446,32 @@
SkASSERT(0 == fProgramID);
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
+ bool hasExplicitLocalCoords = -1 != header.fLocalCoordAttributeIndex;
- bool needsVertexShader = true;
+ // Get the coeffs for the Mode-based color filter, determine if color is needed.
+ SkXfermode::Coeff colorCoeff;
+ SkXfermode::Coeff filterColorCoeff;
+ SkAssertResult(
+ SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(header.fColorFilterXfermode),
+ &filterColorCoeff,
+ &colorCoeff));
+ bool needColor, needFilterColor;
+ need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor);
- GrGLShaderBuilder builder(fGpu->ctxInfo(), fUniformManager, fDesc, needsVertexShader);
+ // Create the GL effects.
+ bool hasVertexShaderEffects = false;
+
+ SkTArray<GrDrawEffect> colorDrawEffects(needColor ? fDesc.numColorEffects() : 0);
+ if (needColor) {
+ this->buildGLEffects(&GrGLProgram::fColorEffects, colorStages, fDesc.numColorEffects(),
+ hasExplicitLocalCoords, &colorDrawEffects, &hasVertexShaderEffects);
+ }
+
+ SkTArray<GrDrawEffect> coverageDrawEffects(fDesc.numCoverageEffects());
+ this->buildGLEffects(&GrGLProgram::fCoverageEffects, coverageStages, fDesc.numCoverageEffects(),
+ hasExplicitLocalCoords, &coverageDrawEffects, &hasVertexShaderEffects);
+
+ GrGLShaderBuilder builder(fGpu->ctxInfo(), fUniformManager, fDesc, hasVertexShaderEffects);
if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) {
const char* viewMName;
@@ -486,16 +508,6 @@
SkString inColor;
GrSLConstantVec knownColorValue = this->genInputColor(&builder, &inColor);
- // Get the coeffs for the Mode-based color filter, determine if color is needed.
- SkXfermode::Coeff colorCoeff;
- SkXfermode::Coeff filterColorCoeff;
- SkAssertResult(
- SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(header.fColorFilterXfermode),
- &filterColorCoeff,
- &colorCoeff));
- bool needColor, needFilterColor;
- need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor);
-
// used in order for builder to return the per-stage uniform handles.
typedef SkTArray<GrGLUniformManager::UniformHandle, true>* UniHandleArrayPtr;
int maxColorOrCovEffectCnt = GrMax(fDesc.numColorEffects(), fDesc.numCoverageEffects());
@@ -504,20 +516,17 @@
if (needColor) {
for (int e = 0; e < fDesc.numColorEffects(); ++e) {
+ glEffects[e] = fColorEffects[e].fGLEffect;
effectUniformArrays[e] = &fColorEffects[e].fSamplerUnis;
}
- builder.emitEffects(colorStages,
+ builder.emitEffects(glEffects.get(),
+ colorDrawEffects.begin(),
fDesc.effectKeys(),
fDesc.numColorEffects(),
&inColor,
&knownColorValue,
- effectUniformArrays.get(),
- glEffects.get());
-
- for (int e = 0; e < fDesc.numColorEffects(); ++e) {
- fColorEffects[e].fGLEffect = glEffects[e];
- }
+ effectUniformArrays.get());
}
// Insert the color filter. This will soon be replaced by a color effect.
@@ -548,19 +557,17 @@
GrSLConstantVec knownCoverageValue = this->genInputCoverage(&builder, &inCoverage);
for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
+ glEffects[e] = fCoverageEffects[e].fGLEffect;
effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis;
}
- builder.emitEffects(coverageStages,
+ builder.emitEffects(glEffects.get(),
+ coverageDrawEffects.begin(),
fDesc.getEffectKeys() + fDesc.numColorEffects(),
fDesc.numCoverageEffects(),
&inCoverage,
&knownCoverageValue,
- effectUniformArrays.get(),
- glEffects.get());
- for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
- fCoverageEffects[e].fGLEffect = glEffects[e];
- }
+ effectUniformArrays.get());
// discard if coverage is zero
if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageValue) {
@@ -689,6 +696,28 @@
return true;
}
+void GrGLProgram::buildGLEffects(SkTArray<EffectAndSamplers> GrGLProgram::* effectSet,
+ const GrEffectStage* stages[],
+ int count,
+ bool hasExplicitLocalCoords,
+ SkTArray<GrDrawEffect>* drawEffects,
+ bool* hasVertexShaderEffects) {
+ for (int e = 0; e < count; ++e) {
+ SkASSERT(NULL != stages[e] && NULL != stages[e]->getEffect());
+
+ const GrEffectStage& stage = *stages[e];
+ SkNEW_APPEND_TO_TARRAY(drawEffects, GrDrawEffect, (stage, hasExplicitLocalCoords));
+
+ const GrDrawEffect& drawEffect = (*drawEffects)[e];
+ GrGLEffect* effect = (this->*effectSet)[e].fGLEffect =
+ (*stage.getEffect())->getFactory().createGLInstance(drawEffect);
+
+ if (!*hasVertexShaderEffects && effect->requiresVertexShader(drawEffect)) {
+ *hasVertexShaderEffects = true;
+ }
+ }
+}
+
bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder,
bool bindColorOut,
bool bindDualSrcOut) {