示例#1
0
bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[],
                                   const GrEffectStage* coverageStages[]) {
    const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();

    ///////////////////////////////////////////////////////////////////////////
    // emit code to read the dst copy texture, if necessary
    if (kNoDstRead_DstReadKey != header.fDstReadKey && !fGpu->glCaps().fbFetchSupport()) {
        bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
        const char* dstCopyTopLeftName;
        const char* dstCopyCoordScaleName;
        const char* dstCopySamplerName;
        uint32_t configMask;
        if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) {
            configMask = kA_GrColorComponentFlag;
        } else {
            configMask = kRGBA_GrColorComponentFlags;
        }
        fUniformHandles.fDstCopySamplerUni =
            this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopySampler",
                             &dstCopySamplerName);
        fUniformHandles.fDstCopyTopLeftUni =
            this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUpperLeft",
                             &dstCopyTopLeftName);
        fUniformHandles.fDstCopyScaleUni =
            this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyCoordScale",
                             &dstCopyCoordScaleName);
        const char* fragPos = this->fragmentPosition();
        this->fsCodeAppend("\t// Read color from copy of the destination.\n");
        this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n",
                            fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
        if (!topDown) {
            this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n");
        }
        this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName);
        append_texture_lookup(&fFSCode,
                              fGpu,
                              dstCopySamplerName,
                              "_dstTexCoord",
                              configMask,
                              "rgba");
        this->fsCodeAppend(";\n\n");
    }

    ///////////////////////////////////////////////////////////////////////////
    // get the initial color and coverage to feed into the first effect in each effect chain

    GrGLSLExpr4 inputColor;
    GrGLSLExpr4 inputCoverage;

    if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
        const char* name;
        fUniformHandles.fColorUni =
            this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color",
                             &name);
        inputColor = GrGLSLExpr4(name);
    }

    if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
        const char* name;
        fUniformHandles.fCoverageUni =
            this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage",
                             &name);
        inputCoverage = GrGLSLExpr4(name);
    } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) {
        inputCoverage = GrGLSLExpr4(1);
    }

    if (k110_GrGLSLGeneration != fGpu->glslGeneration()) {
        fFSOutputs.push_back().set(kVec4f_GrSLType,
                                   GrGLShaderVar::kOut_TypeModifier,
                                   declared_color_output_name());
        fHasCustomColorOutput = true;
    }

    this->emitCodeBeforeEffects(&inputColor, &inputCoverage);

    ///////////////////////////////////////////////////////////////////////////
    // emit the per-effect code for both color and coverage effects

    GrGLProgramDesc::EffectKeyProvider colorKeyProvider(
        &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType);
    fColorEffects.reset(this->createAndEmitEffects(colorStages,
                                                   this->desc().numColorEffects(),
                                                   colorKeyProvider,
                                                   &inputColor));

    GrGLProgramDesc::EffectKeyProvider coverageKeyProvider(
        &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType);
    fCoverageEffects.reset(this->createAndEmitEffects(coverageStages,
                                                      this->desc().numCoverageEffects(),
                                                      coverageKeyProvider,
                                                      &inputCoverage));

    this->emitCodeAfterEffects();

    ///////////////////////////////////////////////////////////////////////////
    // write the secondary color output if necessary
    if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
        const char* secondaryOutputName = this->enableSecondaryOutput();

        // default coeff to ones for kCoverage_DualSrcOutput
        GrGLSLExpr4 coeff(1);
        if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
            // Get (1-A) into coeff
            coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
        } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput ==
                   header.fCoverageOutput){
            // Get (1-RGBA) into coeff
            coeff = GrGLSLExpr4(1) - inputColor;
        }
        // Get coeff * coverage into modulate and then write that to the dual source output.
        this->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
    }

    ///////////////////////////////////////////////////////////////////////////
    // combine color and coverage as frag color

    // Get "color * coverage" into fragColor
    GrGLSLExpr4 fragColor = inputColor * inputCoverage;
    // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
    if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
        GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;

        GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor());

        fragColor = fragColor + dstContribution;
    }
    this->fsCodeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str());

    if (!this->finish()) {
        return false;
    }

    return true;
}
示例#2
0
bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
                             const GrEffectStage* colorStages[],
                             const GrEffectStage* coverageStages[]) {
    SkASSERT(0 == fProgramID);

    const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();

    // incoming color to current stage being processed.
    GrGLSLExpr4 inColor = builder->getInputColor();

    fColorEffects.reset(
        builder->createAndEmitEffects(colorStages,
                                      fDesc.effectKeys(),
                                      fDesc.numColorEffects(),
                                      &inColor));

    ///////////////////////////////////////////////////////////////////////////
    // compute the partial coverage
    GrGLSLExpr4 inCoverage = builder->getInputCoverage();

    fCoverageEffects.reset(
        builder->createAndEmitEffects(coverageStages,
                                      fDesc.getEffectKeys() + fDesc.numColorEffects(),
                                      fDesc.numCoverageEffects(),
                                      &inCoverage));

    if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
        const char* secondaryOutputName = builder->enableSecondaryOutput();

        // default coeff to ones for kCoverage_DualSrcOutput
        GrGLSLExpr4 coeff(1);
        if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
            // Get (1-A) into coeff
            coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inColor.a());
        } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == header.fCoverageOutput) {
            // Get (1-RGBA) into coeff
            coeff = GrGLSLExpr4(1) - inColor;
        }
        // Get coeff * coverage into modulate and then write that to the dual source output.
        builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inCoverage).c_str());
    }

    ///////////////////////////////////////////////////////////////////////////
    // combine color and coverage as frag color

    // Get "color * coverage" into fragColor
    GrGLSLExpr4 fragColor = inColor * inCoverage;
    // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
    if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
        GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inCoverage;

        GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(builder->dstColor());

        fragColor = fragColor + dstContribution;
    }
    builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragColor.c_str());

    if (!builder->finish(&fProgramID)) {
        return false;
    }

    fUniformHandles.fRTHeightUni = builder->getRTHeightUniform();
    fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform();
    fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform();
    fUniformHandles.fColorUni = builder->getColorUniform();
    fUniformHandles.fCoverageUni = builder->getCoverageUniform();
    fUniformHandles.fDstCopySamplerUni = builder->getDstCopySamplerUniform();
    // This must be called after we set fDstCopySamplerUni above.
    this->initSamplerUniforms();

    return true;
}