// 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("}");
}
示例#2
0
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;
    }
}