Index: src/gpu/gl/GrGLProgram.cpp |
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp |
index ac9794d4d5d3f5994cfcb427ae3293c839ff5f3f..ebc57827c5d69393fd745563c56304283b5b2271 100644 |
--- a/src/gpu/gl/GrGLProgram.cpp |
+++ b/src/gpu/gl/GrGLProgram.cpp |
@@ -446,10 +446,32 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
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 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
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 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
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 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
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 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[], |
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) { |