/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h"

#include "include/core/SkBlendMode.h"
#include "include/core/SkColor.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/base/SkRandom.h"
#include "src/core/SkColorData.h"
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/Blend.h"
#include "src/gpu/BlendFormula.h"
#include "src/gpu/KeyBuilder.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/GrShaderCaps.h"
#include "src/gpu/ganesh/GrXferProcessor.h"
#include "src/gpu/ganesh/glsl/GrGLSLBlend.h"
#include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"

#include <cstring>
#include <memory>
#include <string>

using skgpu::BlendFormula;

class PorterDuffXferProcessor : public GrXferProcessor {
public:
    PorterDuffXferProcessor(BlendFormula blendFormula, GrProcessorAnalysisCoverage coverage)
            : INHERITED(kPorterDuffXferProcessor_ClassID, /*willReadDstColor=*/false, coverage)
            , fBlendFormula(blendFormula) {
    }

    const char* name() const override { return "Porter Duff"; }

    std::unique_ptr<ProgramImpl> makeProgramImpl() const override;

    BlendFormula getBlendFormula() const { return fBlendFormula; }

private:
    void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override;

    bool onHasSecondaryOutput() const override { return fBlendFormula.hasSecondaryOutput(); }

    void onGetBlendInfo(skgpu::BlendInfo* blendInfo) const override {
        blendInfo->fEquation = fBlendFormula.equation();
        blendInfo->fSrcBlend = fBlendFormula.srcCoeff();
        blendInfo->fDstBlend = fBlendFormula.dstCoeff();
        blendInfo->fWritesColor = fBlendFormula.modifiesDst();
    }

    bool onIsEqual(const GrXferProcessor& xpBase) const override {
        const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor>();
        return fBlendFormula == xp.fBlendFormula;
    }

    const BlendFormula fBlendFormula;

    using INHERITED = GrXferProcessor;
};

///////////////////////////////////////////////////////////////////////////////

static void append_color_output(const PorterDuffXferProcessor& xp,
                                GrGLSLXPFragmentBuilder* fragBuilder,
                                BlendFormula::OutputType outputType, const char* output,
                                const char* inColor, const char* inCoverage) {
    SkASSERT(inCoverage);
    SkASSERT(inColor);
    switch (outputType) {
        case BlendFormula::kNone_OutputType:
            fragBuilder->codeAppendf("%s = half4(0.0);", output);
            break;
        case BlendFormula::kCoverage_OutputType:
            fragBuilder->codeAppendf("%s = %s;", output, inCoverage);
            break;
        case BlendFormula::kModulate_OutputType:
            fragBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCoverage);
            break;
        case BlendFormula::kSAModulate_OutputType:
            fragBuilder->codeAppendf("%s = %s.a * %s;", output, inColor, inCoverage);
            break;
        case BlendFormula::kISAModulate_OutputType:
            fragBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inColor, inCoverage);
            break;
        case BlendFormula::kISCModulate_OutputType:
            fragBuilder->codeAppendf("%s = (half4(1.0) - %s) * %s;", output, inColor, inCoverage);
            break;
        default:
            SK_ABORT("Unsupported output type.");
            break;
    }
}

void PorterDuffXferProcessor::onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder* b) const {
    b->add32(fBlendFormula.primaryOutput() | (fBlendFormula.secondaryOutput() << 3));
    static_assert(BlendFormula::kLast_OutputType < 8);
}

std::unique_ptr<GrXferProcessor::ProgramImpl> PorterDuffXferProcessor::makeProgramImpl() const {
    class Impl : public ProgramImpl {
    private:
        void emitOutputsForBlendState(const EmitArgs& args) override {
            const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcessor>();
            GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;

            const BlendFormula& blendFormula = xp.fBlendFormula;
            if (blendFormula.hasSecondaryOutput()) {
                append_color_output(xp,
                                    fragBuilder,
                                    blendFormula.secondaryOutput(),
                                    args.fOutputSecondary,
                                    args.fInputColor,
                                    args.fInputCoverage);
            }
            append_color_output(xp,
                                fragBuilder,
                                blendFormula.primaryOutput(),
                                args.fOutputPrimary,
                                args.fInputColor,
                                args.fInputCoverage);
        }
    };

    return std::make_unique<Impl>();
}

///////////////////////////////////////////////////////////////////////////////

class ShaderPDXferProcessor : public GrXferProcessor {
public:
    ShaderPDXferProcessor(SkBlendMode xfermode, GrProcessorAnalysisCoverage coverage)
            : INHERITED(kShaderPDXferProcessor_ClassID, /*willReadDstColor=*/true, coverage)
            , fXfermode(xfermode) {
    }

    const char* name() const override { return "Porter Duff Shader"; }

    std::unique_ptr<ProgramImpl> makeProgramImpl() const override;

private:
    void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override;

    bool onIsEqual(const GrXferProcessor& xpBase) const override {
        const ShaderPDXferProcessor& xp = xpBase.cast<ShaderPDXferProcessor>();
        return fXfermode == xp.fXfermode;
    }

    const SkBlendMode fXfermode;

    using INHERITED = GrXferProcessor;
};

///////////////////////////////////////////////////////////////////////////////


void ShaderPDXferProcessor::onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder* b) const {
    b->add32(GrGLSLBlend::BlendKey(fXfermode));
}

std::unique_ptr<GrXferProcessor::ProgramImpl> ShaderPDXferProcessor::makeProgramImpl() const {
    class Impl : public ProgramImpl {
    private:
        void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder* fragBuilder,
                                     GrGLSLUniformHandler* uniformHandler,
                                     const char* srcColor,
                                     const char* srcCoverage,
                                     const char* dstColor,
                                     const char* outColor,
                                     const char* outColorSecondary,
                                     const GrXferProcessor& proc) override {
            const ShaderPDXferProcessor& xp = proc.cast<ShaderPDXferProcessor>();

            std::string blendExpr = GrGLSLBlend::BlendExpression(
                    &xp, uniformHandler, &fBlendUniform, srcColor, dstColor, xp.fXfermode);
            fragBuilder->codeAppendf("%s = %s;", outColor, blendExpr.c_str());

            // Apply coverage.
            DefaultCoverageModulation(fragBuilder,
                                      srcCoverage,
                                      dstColor,
                                      outColor,
                                      outColorSecondary,
                                      xp);
        }

        void onSetData(const GrGLSLProgramDataManager& pdman,
                       const GrXferProcessor& proc) override {
            if (fBlendUniform.isValid()) {
                const ShaderPDXferProcessor& xp = proc.cast<ShaderPDXferProcessor>();
                GrGLSLBlend::SetBlendModeUniformData(pdman, fBlendUniform, xp.fXfermode);
            }
        }

        GrGLSLUniformHandler::UniformHandle fBlendUniform;
    };

    return std::make_unique<Impl>();
}

///////////////////////////////////////////////////////////////////////////////

class PDLCDXferProcessor : public GrXferProcessor {
public:
    static sk_sp<const GrXferProcessor> Make(SkBlendMode mode,
                                             const GrProcessorAnalysisColor& inputColor);

    const char* name() const override { return "Porter Duff LCD"; }

    std::unique_ptr<ProgramImpl> makeProgramImpl() const override;

private:
    PDLCDXferProcessor(const SkPMColor4f& blendConstant, float alpha);

    void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override {}

    void onGetBlendInfo(skgpu::BlendInfo* blendInfo) const override {
        blendInfo->fSrcBlend = skgpu::BlendCoeff::kConstC;
        blendInfo->fDstBlend = skgpu::BlendCoeff::kISC;
        blendInfo->fBlendConstant = fBlendConstant;
    }

    bool onIsEqual(const GrXferProcessor& xpBase) const override {
        const PDLCDXferProcessor& xp = xpBase.cast<PDLCDXferProcessor>();
        if (fBlendConstant != xp.fBlendConstant || fAlpha != xp.fAlpha) {
            return false;
        }
        return true;
    }

    SkPMColor4f fBlendConstant;
    float fAlpha;

    using INHERITED = GrXferProcessor;
};

PDLCDXferProcessor::PDLCDXferProcessor(const SkPMColor4f& blendConstant, float alpha)
    : INHERITED(kPDLCDXferProcessor_ClassID, /*willReadDstColor=*/false,
                GrProcessorAnalysisCoverage::kLCD)
    , fBlendConstant(blendConstant)
    , fAlpha(alpha) {
}

sk_sp<const GrXferProcessor> PDLCDXferProcessor::Make(SkBlendMode mode,
                                                      const GrProcessorAnalysisColor& color) {
    if (SkBlendMode::kSrcOver != mode) {
        return nullptr;
    }
    SkPMColor4f blendConstantPM;
    if (!color.isConstant(&blendConstantPM)) {
        return nullptr;
    }
    SkColor4f blendConstantUPM = blendConstantPM.unpremul();
    float alpha = blendConstantUPM.fA;
    blendConstantPM = { blendConstantUPM.fR, blendConstantUPM.fG, blendConstantUPM.fB, 1 };
    return sk_sp<GrXferProcessor>(new PDLCDXferProcessor(blendConstantPM, alpha));
}

std::unique_ptr<GrXferProcessor::ProgramImpl> PDLCDXferProcessor::makeProgramImpl() const {
    class Impl : public ProgramImpl {
    private:
        void emitOutputsForBlendState(const EmitArgs& args) override {
            const char* alpha;
            fAlphaUniform = args.fUniformHandler->addUniform(nullptr,
                                                             kFragment_GrShaderFlag,
                                                             SkSLType::kHalf,
                                                             "alpha",
                                                             &alpha);
            GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
            // We want to force our primary output to be alpha * Coverage, where alpha is the alpha
            // value of the src color. We know that there are no color stages (or we wouldn't have
            // created this xp) and the r,g, and b channels of the op's input color are baked into
            // the blend constant.
            SkASSERT(args.fInputCoverage);
            fragBuilder->codeAppendf("%s = %s * %s;",
                                     args.fOutputPrimary,
                                     alpha, args.fInputCoverage);
        }

        void onSetData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) override {
            float alpha = xp.cast<PDLCDXferProcessor>().fAlpha;
            if (fLastAlpha != alpha) {
                pdm.set1f(fAlphaUniform, alpha);
                fLastAlpha = alpha;
            }
        }

        GrGLSLUniformHandler::UniformHandle fAlphaUniform;
        float fLastAlpha = SK_FloatNaN;
    };

    return std::make_unique<Impl>();
}

///////////////////////////////////////////////////////////////////////////////

constexpr GrPorterDuffXPFactory::GrPorterDuffXPFactory(SkBlendMode xfermode)
        : fBlendMode(xfermode) {}

const GrXPFactory* GrPorterDuffXPFactory::Get(SkBlendMode blendMode) {
    SkASSERT((unsigned)blendMode <= (unsigned)SkBlendMode::kLastCoeffMode);

    static constexpr const GrPorterDuffXPFactory gClearPDXPF(SkBlendMode::kClear);
    static constexpr const GrPorterDuffXPFactory gSrcPDXPF(SkBlendMode::kSrc);
    static constexpr const GrPorterDuffXPFactory gDstPDXPF(SkBlendMode::kDst);
    static constexpr const GrPorterDuffXPFactory gSrcOverPDXPF(SkBlendMode::kSrcOver);
    static constexpr const GrPorterDuffXPFactory gDstOverPDXPF(SkBlendMode::kDstOver);
    static constexpr const GrPorterDuffXPFactory gSrcInPDXPF(SkBlendMode::kSrcIn);
    static constexpr const GrPorterDuffXPFactory gDstInPDXPF(SkBlendMode::kDstIn);
    static constexpr const GrPorterDuffXPFactory gSrcOutPDXPF(SkBlendMode::kSrcOut);
    static constexpr const GrPorterDuffXPFactory gDstOutPDXPF(SkBlendMode::kDstOut);
    static constexpr const GrPorterDuffXPFactory gSrcATopPDXPF(SkBlendMode::kSrcATop);
    static constexpr const GrPorterDuffXPFactory gDstATopPDXPF(SkBlendMode::kDstATop);
    static constexpr const GrPorterDuffXPFactory gXorPDXPF(SkBlendMode::kXor);
    static constexpr const GrPorterDuffXPFactory gPlusPDXPF(SkBlendMode::kPlus);
    static constexpr const GrPorterDuffXPFactory gModulatePDXPF(SkBlendMode::kModulate);
    static constexpr const GrPorterDuffXPFactory gScreenPDXPF(SkBlendMode::kScreen);

    switch (blendMode) {
        case SkBlendMode::kClear:
            return &gClearPDXPF;
        case SkBlendMode::kSrc:
            return &gSrcPDXPF;
        case SkBlendMode::kDst:
            return &gDstPDXPF;
        case SkBlendMode::kSrcOver:
            return &gSrcOverPDXPF;
        case SkBlendMode::kDstOver:
            return &gDstOverPDXPF;
        case SkBlendMode::kSrcIn:
            return &gSrcInPDXPF;
        case SkBlendMode::kDstIn:
            return &gDstInPDXPF;
        case SkBlendMode::kSrcOut:
            return &gSrcOutPDXPF;
        case SkBlendMode::kDstOut:
            return &gDstOutPDXPF;
        case SkBlendMode::kSrcATop:
            return &gSrcATopPDXPF;
        case SkBlendMode::kDstATop:
            return &gDstATopPDXPF;
        case SkBlendMode::kXor:
            return &gXorPDXPF;
        case SkBlendMode::kPlus:
            return &gPlusPDXPF;
        case SkBlendMode::kModulate:
            return &gModulatePDXPF;
        case SkBlendMode::kScreen:
            return &gScreenPDXPF;
        default:
            SK_ABORT("Unexpected blend mode.");
    }
}

sk_sp<const GrXferProcessor> GrPorterDuffXPFactory::makeXferProcessor(
        const GrProcessorAnalysisColor& color, GrProcessorAnalysisCoverage coverage,
        const GrCaps& caps, GrClampType clampType) const {
    bool isLCD = coverage == GrProcessorAnalysisCoverage::kLCD;
    // See comment in MakeSrcOverXferProcessor about color.isOpaque here
    if (isLCD &&
        SkBlendMode::kSrcOver == fBlendMode && color.isConstant() && /*color.isOpaque() &&*/
        !caps.shaderCaps()->fDualSourceBlendingSupport &&
        !caps.shaderCaps()->fDstReadInShaderSupport) {
        // If we don't have dual source blending or in shader dst reads, we fall back to this
        // trick for rendering SrcOver LCD text instead of doing a dst copy.
        return PDLCDXferProcessor::Make(fBlendMode, color);
    }
    BlendFormula blendFormula = [&](){
        if (isLCD) {
            return skgpu::GetLCDBlendFormula(fBlendMode);
        }
        if (fBlendMode == SkBlendMode::kSrcOver && color.isOpaque() &&
            coverage == GrProcessorAnalysisCoverage::kNone &&
            caps.shouldCollapseSrcOverToSrcWhenAble())
        {
            return skgpu::GetBlendFormula(true, false, SkBlendMode::kSrc);
        }
        return skgpu::GetBlendFormula(
                color.isOpaque(), GrProcessorAnalysisCoverage::kNone != coverage, fBlendMode);
    }();

    // Skia always saturates after the kPlus blend mode, so it requires shader-based blending when
    // pixels aren't guaranteed to automatically be normalized (i.e. any floating point config).
    if ((blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->fDualSourceBlendingSupport) ||
        (isLCD && (SkBlendMode::kSrcOver != fBlendMode /*|| !color.isOpaque()*/)) ||
        (GrClampType::kAuto != clampType && SkBlendMode::kPlus == fBlendMode)) {
        return sk_sp<const GrXferProcessor>(new ShaderPDXferProcessor(fBlendMode, coverage));
    }
    return sk_sp<const GrXferProcessor>(new PorterDuffXferProcessor(blendFormula, coverage));
}

static inline GrXPFactory::AnalysisProperties analysis_properties(
        const GrProcessorAnalysisColor& color, const GrProcessorAnalysisCoverage& coverage,
        const GrCaps& caps, GrClampType clampType, SkBlendMode mode) {
    using AnalysisProperties = GrXPFactory::AnalysisProperties;
    AnalysisProperties props = AnalysisProperties::kNone;
    bool hasCoverage = GrProcessorAnalysisCoverage::kNone != coverage;
    bool isLCD = GrProcessorAnalysisCoverage::kLCD == coverage;
    BlendFormula formula = [&](){
        if (isLCD) {
            return skgpu::GetLCDBlendFormula(mode);
        }
        return skgpu::GetBlendFormula(color.isOpaque(), hasCoverage, mode);
    }();

    if (formula.canTweakAlphaForCoverage() && !isLCD) {
        props |= AnalysisProperties::kCompatibleWithCoverageAsAlpha;
    }

    if (isLCD) {
        // See comment in MakeSrcOverXferProcessor about color.isOpaque here
        if (SkBlendMode::kSrcOver == mode && color.isConstant() && /*color.isOpaque() &&*/
            !caps.shaderCaps()->fDualSourceBlendingSupport &&
            !caps.shaderCaps()->fDstReadInShaderSupport) {
            props |= AnalysisProperties::kIgnoresInputColor;
        } else {
            // For LCD blending, if the color is not opaque we must read the dst in shader even if
            // we have dual source blending. The opaqueness check must be done after blending so for
            // simplicity we only allow src-over to not take the dst read path (though src, src-in,
            // and DstATop would also work). We also fall into the dst read case for src-over if we
            // do not have dual source blending.
            if (SkBlendMode::kSrcOver != mode ||
                /*!color.isOpaque() ||*/ // See comment in MakeSrcOverXferProcessor about isOpaque.
                (formula.hasSecondaryOutput() && !caps.shaderCaps()->fDualSourceBlendingSupport)) {
                props |= AnalysisProperties::kReadsDstInShader;
            }
        }
    } else {
        // With dual-source blending we never need the destination color in the shader.
        if (!caps.shaderCaps()->fDualSourceBlendingSupport) {
            if (formula.hasSecondaryOutput()) {
                props |= AnalysisProperties::kReadsDstInShader;
            }
        }
    }

    if (GrClampType::kAuto != clampType && SkBlendMode::kPlus == mode) {
        props |= AnalysisProperties::kReadsDstInShader;
    }

    if (!formula.modifiesDst() || !formula.usesInputColor()) {
        props |= AnalysisProperties::kIgnoresInputColor;
    }
    if (formula.unaffectedByDst() || (formula.unaffectedByDstIfOpaque() && color.isOpaque() &&
                                      !hasCoverage)) {
        props |= AnalysisProperties::kUnaffectedByDstValue;
    }
    return props;
}

GrXPFactory::AnalysisProperties GrPorterDuffXPFactory::analysisProperties(
        const GrProcessorAnalysisColor& color,
        const GrProcessorAnalysisCoverage& coverage,
        const GrCaps& caps,
        GrClampType clampType) const {
    return analysis_properties(color, coverage, caps, clampType, fBlendMode);
}

GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory)

#if defined(GPU_TEST_UTILS)
const GrXPFactory* GrPorterDuffXPFactory::TestGet(GrProcessorTestData* d) {
    SkBlendMode mode = SkBlendMode(d->fRandom->nextULessThan((int)SkBlendMode::kLastCoeffMode));
    return GrPorterDuffXPFactory::Get(mode);
}
#endif

void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp,
                                                 int* outPrimary,
                                                 int* outSecondary) {
    if (!!strcmp(xp->name(), "Porter Duff")) {
        *outPrimary = *outSecondary = -1;
        return;
    }
    BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)->getBlendFormula();
    *outPrimary = blendFormula.primaryOutput();
    *outSecondary = blendFormula.secondaryOutput();
}

////////////////////////////////////////////////////////////////////////////////////////////////
// SrcOver Global functions
////////////////////////////////////////////////////////////////////////////////////////////////
const GrXferProcessor& GrPorterDuffXPFactory::SimpleSrcOverXP() {
    static BlendFormula kSrcOverBlendFormula = skgpu::GetBlendFormula(
            /*isOpaque=*/false, /*hasCoverage=*/false, SkBlendMode::kSrcOver);
    static PorterDuffXferProcessor gSrcOverXP(kSrcOverBlendFormula,
                                              GrProcessorAnalysisCoverage::kSingleChannel);
    return gSrcOverXP;
}

sk_sp<const GrXferProcessor> GrPorterDuffXPFactory::MakeSrcOverXferProcessor(
        const GrProcessorAnalysisColor& color, GrProcessorAnalysisCoverage coverage,
        const GrCaps& caps) {
    // We want to not make an xfer processor if possible. Thus for the simple case where we are not
    // doing lcd blending we will just use our global SimpleSrcOverXP. This slightly differs from
    // the general case where we convert a src-over blend that has solid coverage and an opaque
    // color to src-mode, which allows disabling of blending.
    if (coverage != GrProcessorAnalysisCoverage::kLCD) {
        if (color.isOpaque() && coverage == GrProcessorAnalysisCoverage::kNone &&
            caps.shouldCollapseSrcOverToSrcWhenAble()) {
            BlendFormula blendFormula = skgpu::GetBlendFormula(true, false, SkBlendMode::kSrc);
            return sk_sp<GrXferProcessor>(new PorterDuffXferProcessor(blendFormula, coverage));
        }
        // We return nullptr here, which our caller interprets as meaning "use SimpleSrcOverXP".
        // We don't simply return the address of that XP here because our caller would have to unref
        // it and since it is a global object and GrProgramElement's ref-cnting system is not thread
        // safe.
        return nullptr;
    }

    // Currently up the stack Skia is requiring that the dst is opaque or that the client has said
    // the opaqueness doesn't matter. Thus for src-over we don't need to worry about the src color
    // being opaque or not. This allows us to use faster code paths as well as avoid various bugs
    // that occur with dst reads in the shader blending. For now we disable the check for
    // opaqueness, but in the future we should pass down the knowledge about dst opaqueness and make
    // the correct decision here.
    //
    // This also fixes a chrome bug on macs where we are getting random fuzziness when doing
    // blending in the shader for non opaque sources.
    if (color.isConstant() && /*color.isOpaque() &&*/
        !caps.shaderCaps()->fDualSourceBlendingSupport &&
        !caps.shaderCaps()->fDstReadInShaderSupport) {
        // If we don't have dual source blending or in shader dst reads, we fall
        // back to this trick for rendering SrcOver LCD text instead of doing a
        // dst copy.
        return PDLCDXferProcessor::Make(SkBlendMode::kSrcOver, color);
    }

    BlendFormula blendFormula = skgpu::GetLCDBlendFormula(SkBlendMode::kSrcOver);
    // See comment above regarding why the opaque check is commented out here.
    if (/*!color.isOpaque() ||*/
        (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->fDualSourceBlendingSupport)) {
        return sk_sp<GrXferProcessor>(new ShaderPDXferProcessor(SkBlendMode::kSrcOver, coverage));
    }
    return sk_sp<GrXferProcessor>(new PorterDuffXferProcessor(blendFormula, coverage));
}

sk_sp<const GrXferProcessor> GrPorterDuffXPFactory::MakeNoCoverageXP(SkBlendMode blendmode) {
    BlendFormula formula = skgpu::GetBlendFormula(false, false, blendmode);
    return sk_make_sp<PorterDuffXferProcessor>(formula, GrProcessorAnalysisCoverage::kNone);
}

GrXPFactory::AnalysisProperties GrPorterDuffXPFactory::SrcOverAnalysisProperties(
        const GrProcessorAnalysisColor& color,
        const GrProcessorAnalysisCoverage& coverage,
        const GrCaps& caps,
        GrClampType clampType) {
    return analysis_properties(color, coverage, caps, clampType, SkBlendMode::kSrcOver);
}
