Exemple #1
0
void GrGLShaderBuilder::appendTextureLookup(const char* samplerName,
                                            const char* coordName,
                                            uint32_t configComponentMask,
                                            const char* swizzle) {
    append_texture_lookup(&fCode,
                          fProgramBuilder->gpu(),
                          samplerName,
                          coordName,
                          configComponentMask,
                          swizzle,
                          kVec2f_GrSLType);
}
Exemple #2
0
void GrGLShaderBuilder::appendTextureLookup(SkString* out,
                                            const GrGLShaderBuilder::TextureSampler& sampler,
                                            const char* coordName,
                                            GrSLType varyingType) const {
    append_texture_lookup(out,
                          fGpu,
                          this->getUniformCStr(sampler.samplerUniform()),
                          coordName,
                          sampler.configComponentMask(),
                          sampler.swizzle(),
                          varyingType);
}
Exemple #3
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;
}
GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
                                     GrGLUniformManager& uniformManager,
                                     const GrGLProgramDesc& desc)
    : fGpu(gpu)
    , fUniformManager(uniformManager)
    , fFSFeaturesAddedMask(0)
    , fFSInputs(kVarsPerBlock)
    , fFSOutputs(kMaxFSOutputs)
    , fUniforms(kVarsPerBlock)
    , fSetupFragPosition(false)
    , fHasCustomColorOutput(false)
    , fHasSecondaryOutput(false)
    , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) {

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

    // Emit code to read the dst copy textue if necessary.
    if (kNoDstRead_DstReadKey != header.fDstReadKey &&
            GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) {
        bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
        const char* dstCopyTopLeftName;
        const char* dstCopyCoordScaleName;
        uint32_t configMask;
        if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) {
            configMask = kA_GrColorComponentFlag;
        } else {
            configMask = kRGBA_GrColorComponentFlags;
        }
        fDstCopySamplerUniform = this->addUniform(kFragment_Visibility,
                                 kSampler2D_GrSLType,
                                 "DstCopySampler");
        fDstCopyTopLeftUniform = this->addUniform(kFragment_Visibility,
                                 kVec2f_GrSLType,
                                 "DstCopyUpperLeft",
                                 &dstCopyTopLeftName);
        fDstCopyScaleUniform     = 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,
                              this->getUniformCStr(fDstCopySamplerUniform),
                              "_dstTexCoord",
                              configMask,
                              "rgba");
        this->fsCodeAppend(";\n\n");
    }

    if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
        const char* name;
        fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                         kVec4f_GrSLType, "Color", &name);
        fInputColor = GrGLSLExpr4(name);
    } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) {
        fInputColor = GrGLSLExpr4(1);
    } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fColorInput) {
        fInputColor = GrGLSLExpr4(0);
    }

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

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