// TODO Processors cannot output zeros because an empty string is all 1s // the fix is to allow effects to take the GrGLSLExpr4 directly void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentProcessor& fp, int index, const GrGLSLExpr4& input, GrGLSLExpr4* output) { // Program builders have a bit of state we need to clear with each effect AutoStageAdvance adv(this); this->nameExpression(output, "output"); // Enclose custom code in a block to avoid namespace conflicts SkString openBrace; openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name()); fFS.codeAppend(openBrace.c_str()); this->emitAndInstallProc(fp, index, output->c_str(), input.isOnes() ? nullptr : input.c_str()); fFS.codeAppend("}"); }
void GrGLShaderBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programEffectsBuilder, const GrEffectStage* effectStages[], int effectCnt, const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* fsInOutColor) { bool effectEmitted = false; GrGLSLExpr4 inColor = *fsInOutColor; GrGLSLExpr4 outColor; for (int e = 0; e < effectCnt; ++e) { SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect()); const GrEffectStage& stage = *effectStages[e]; CodeStage::AutoStageRestore csar(&fCodeStage, &stage); if (inColor.isZeros()) { SkString inColorName; // Effects have no way to communicate zeros, they treat an empty string as ones. this->nameVariable(&inColorName, '\0', "input"); this->fsCodeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor.c_str()); inColor = inColorName; } // create var to hold stage result SkString outColorName; this->nameVariable(&outColorName, '\0', "output"); this->fsCodeAppendf("\tvec4 %s;\n", outColorName.c_str()); outColor = outColorName; programEffectsBuilder->emitEffect(stage, keyProvider.get(e), outColor.c_str(), inColor.isOnes() ? NULL : inColor.c_str(), fCodeStage.stageIndex()); inColor = outColor; effectEmitted = true; } if (effectEmitted) { *fsInOutColor = outColor; } }