diff options
Diffstat (limited to 'src/gpu/gl/GrGLProgram.cpp')
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 79 |
1 files changed, 54 insertions, 25 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index ac9794d4d5..ebc57827c5 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) { |