/*
 * 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 "effects/GrPorterDuffXferProcessor.h"

#include "GrBlend.h"
#include "GrCaps.h"
#include "GrProcessor.h"
#include "GrProcOptInfo.h"
#include "GrTypes.h"
#include "GrXferProcessor.h"
#include "gl/GrGLBlend.h"
#include "gl/GrGLXferProcessor.h"
#include "gl/builders/GrGLFragmentShaderBuilder.h"
#include "gl/builders/GrGLProgramBuilder.h"

/**
 * Wraps the shader outputs and HW blend state that comprise a Porter Duff blend mode with coverage.
 */
struct BlendFormula {
public:
    /**
     * Values the shader can write to primary and secondary outputs. These must all be modulated by
     * coverage to support mixed samples. The XP will ignore the multiplies when not using coverage.
     */
    enum OutputType {
        kNone_OutputType,        //<! 0
        kCoverage_OutputType,    //<! inputCoverage
        kModulate_OutputType,    //<! inputColor * inputCoverage
        kISAModulate_OutputType, //<! (1 - inputColor.a) * inputCoverage
        kISCModulate_OutputType, //<! (1 - inputColor) * inputCoverage

        kLast_OutputType = kISCModulate_OutputType
    };

    enum Properties {
        kModifiesDst_Property              = 1,
        kUsesDstColor_Property             = 1 << 1,
        kUsesInputColor_Property           = 1 << 2,
        kCanTweakAlphaForCoverage_Property = 1 << 3,

        kLast_Property = kCanTweakAlphaForCoverage_Property
    };

    BlendFormula& operator =(const BlendFormula& other) {
        fData = other.fData;
        return *this;
    }

    bool operator ==(const BlendFormula& other) const {
        return fData == other.fData;
    }

    bool hasSecondaryOutput() const { return kNone_OutputType != fSecondaryOutputType; }
    bool modifiesDst() const { return SkToBool(fProps & kModifiesDst_Property); }
    bool usesDstColor() const { return SkToBool(fProps & kUsesDstColor_Property); }
    bool usesInputColor() const { return SkToBool(fProps & kUsesInputColor_Property); }
    bool canTweakAlphaForCoverage() const {
        return SkToBool(fProps & kCanTweakAlphaForCoverage_Property);
    }

    /**
     * Deduce the properties of a compile-time constant BlendFormula.
     */
    template<OutputType PrimaryOut, OutputType SecondaryOut,
             GrBlendEquation BlendEquation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
    struct get_properties : skstd::integral_constant<Properties, static_cast<Properties>(

        (GR_BLEND_MODIFIES_DST(BlendEquation, SrcCoeff, DstCoeff) ?
            kModifiesDst_Property : 0) |

        (GR_BLEND_COEFFS_USE_DST_COLOR(SrcCoeff, DstCoeff) ?
            kUsesDstColor_Property : 0) |

        ((PrimaryOut >= kModulate_OutputType && GR_BLEND_COEFFS_USE_SRC_COLOR(SrcCoeff,DstCoeff)) ||
         (SecondaryOut >= kModulate_OutputType && GR_BLEND_COEFF_REFS_SRC2(DstCoeff)) ?
            kUsesInputColor_Property : 0) |  // We assert later that SrcCoeff doesn't ref src2.

        (kModulate_OutputType == PrimaryOut &&
         kNone_OutputType == SecondaryOut &&
         GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(BlendEquation, SrcCoeff, DstCoeff) ?
            kCanTweakAlphaForCoverage_Property : 0))> {

        // The provided formula should already be optimized.
        GR_STATIC_ASSERT((kNone_OutputType == PrimaryOut) ==
                         !GR_BLEND_COEFFS_USE_SRC_COLOR(SrcCoeff, DstCoeff));
        GR_STATIC_ASSERT(!GR_BLEND_COEFF_REFS_SRC2(SrcCoeff));
        GR_STATIC_ASSERT((kNone_OutputType == SecondaryOut) ==
                         !GR_BLEND_COEFF_REFS_SRC2(DstCoeff));
        GR_STATIC_ASSERT(PrimaryOut != SecondaryOut || kNone_OutputType == PrimaryOut);
        GR_STATIC_ASSERT(kNone_OutputType != PrimaryOut || kNone_OutputType == SecondaryOut);
    };

    union {
        struct {
            // We allot the enums one more bit than they require because MSVC seems to sign-extend
            // them when the top bit is set. (This is in violation of the C++03 standard 9.6/4)
            OutputType        fPrimaryOutputType    : 4;
            OutputType        fSecondaryOutputType  : 4;
            GrBlendEquation   fBlendEquation        : 6;
            GrBlendCoeff      fSrcCoeff             : 6;
            GrBlendCoeff      fDstCoeff             : 6;
            Properties        fProps                : 32 - (4 + 4 + 6 + 6 + 6);
        };
        uint32_t fData;
    };

    GR_STATIC_ASSERT(kLast_OutputType      < (1 << 3));
    GR_STATIC_ASSERT(kLast_GrBlendEquation < (1 << 5));
    GR_STATIC_ASSERT(kLast_GrBlendCoeff    < (1 << 5));
    GR_STATIC_ASSERT(kLast_Property        < (1 << 6));
};

GR_STATIC_ASSERT(4 == sizeof(BlendFormula));

GR_MAKE_BITFIELD_OPS(BlendFormula::Properties);

/**
 * Initialize a compile-time constant BlendFormula and automatically deduce fProps.
 */
#define INIT_BLEND_FORMULA(PRIMARY_OUT, SECONDARY_OUT, BLEND_EQUATION, SRC_COEFF, DST_COEFF) \
    {{{PRIMARY_OUT, \
       SECONDARY_OUT, \
       BLEND_EQUATION, SRC_COEFF, DST_COEFF, \
       BlendFormula::get_properties<PRIMARY_OUT, SECONDARY_OUT, \
                                    BLEND_EQUATION, SRC_COEFF, DST_COEFF>::value}}}

/**
 * When there is no coverage, or the blend mode can tweak alpha for coverage, we use the standard
 * Porter Duff formula.
 */
#define COEFF_FORMULA(SRC_COEFF, DST_COEFF) \
    INIT_BLEND_FORMULA(BlendFormula::kModulate_OutputType, \
                       BlendFormula::kNone_OutputType, \
                       kAdd_GrBlendEquation, SRC_COEFF, DST_COEFF)

/**
 * When the coeffs are (Zero, Zero), we clear the dst. This formula has its own macro so we can set
 * the primary output type to none.
 */
#define DST_CLEAR_FORMULA \
    INIT_BLEND_FORMULA(BlendFormula::kNone_OutputType, \
                       BlendFormula::kNone_OutputType, \
                       kAdd_GrBlendEquation, kZero_GrBlendCoeff, kZero_GrBlendCoeff)

/**
 * When the coeffs are (Zero, One), we don't write to the dst at all. This formula has its own macro
 * so we can set the primary output type to none.
 */
#define NO_DST_WRITE_FORMULA \
    INIT_BLEND_FORMULA(BlendFormula::kNone_OutputType, \
                       BlendFormula::kNone_OutputType, \
                       kAdd_GrBlendEquation, kZero_GrBlendCoeff, kOne_GrBlendCoeff)

/**
 * When there is coverage, the equation with f=coverage is:
 *
 *   D' = f * (S * srcCoeff + D * dstCoeff) + (1-f) * D
 *
 * This can be rewritten as:
 *
 *   D' = f * S * srcCoeff + D * (1 - [f * (1 - dstCoeff)])
 *
 * To implement this formula, we output [f * (1 - dstCoeff)] for the secondary color and replace the
 * HW dst coeff with IS2C.
 *
 * Xfer modes: dst-atop (Sa!=1)
 */
#define COVERAGE_FORMULA(ONE_MINUS_DST_COEFF_MODULATE_OUTPUT, SRC_COEFF) \
    INIT_BLEND_FORMULA(BlendFormula::kModulate_OutputType, \
                       ONE_MINUS_DST_COEFF_MODULATE_OUTPUT, \
                       kAdd_GrBlendEquation, SRC_COEFF, kIS2C_GrBlendCoeff)

/**
 * When there is coverage and the src coeff is Zero, the equation with f=coverage becomes:
 *
 *   D' = f * D * dstCoeff + (1-f) * D
 *
 * This can be rewritten as:
 *
 *   D' = D - D * [f * (1 - dstCoeff)]
 *
 * To implement this formula, we output [f * (1 - dstCoeff)] for the primary color and use a reverse
 * subtract HW blend equation with coeffs of (DC, One).
 *
 * Xfer modes: clear, dst-out (Sa=1), dst-in (Sa!=1), modulate (Sc!=1)
 */
#define COVERAGE_SRC_COEFF_ZERO_FORMULA(ONE_MINUS_DST_COEFF_MODULATE_OUTPUT) \
    INIT_BLEND_FORMULA(ONE_MINUS_DST_COEFF_MODULATE_OUTPUT, \
                       BlendFormula::kNone_OutputType, \
                       kReverseSubtract_GrBlendEquation, kDC_GrBlendCoeff, kOne_GrBlendCoeff)

/**
 * When there is coverage and the dst coeff is Zero, the equation with f=coverage becomes:
 *
 *   D' = f * S * srcCoeff + (1-f) * D
 *
 * To implement this formula, we output [f] for the secondary color and replace the HW dst coeff
 * with IS2A. (Note that we can avoid dual source blending when Sa=1 by using ISA.)
 *
 * Xfer modes (Sa!=1): src, src-in, src-out
 */
#define COVERAGE_DST_COEFF_ZERO_FORMULA(SRC_COEFF) \
    INIT_BLEND_FORMULA(BlendFormula::kModulate_OutputType, \
                       BlendFormula::kCoverage_OutputType, \
                       kAdd_GrBlendEquation, SRC_COEFF, kIS2A_GrBlendCoeff)

/**
 * This table outlines the blend formulas we will use with each xfermode, with and without coverage,
 * with and without an opaque input color. Optimization properties are deduced at compile time so we
 * can make runtime decisions quickly. RGB coverage is not supported.
 */
static const BlendFormula gBlendTable[2][2][SkXfermode::kLastCoeffMode + 1] = {

                     /*>> No coverage, input color unknown <<*/ {{

    /* clear */      DST_CLEAR_FORMULA,
    /* src */        COEFF_FORMULA(   kOne_GrBlendCoeff,    kZero_GrBlendCoeff),
    /* dst */        NO_DST_WRITE_FORMULA,
    /* src-over */   COEFF_FORMULA(   kOne_GrBlendCoeff,    kISA_GrBlendCoeff),
    /* dst-over */   COEFF_FORMULA(   kIDA_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* src-in */     COEFF_FORMULA(   kDA_GrBlendCoeff,     kZero_GrBlendCoeff),
    /* dst-in */     COEFF_FORMULA(   kZero_GrBlendCoeff,   kSA_GrBlendCoeff),
    /* src-out */    COEFF_FORMULA(   kIDA_GrBlendCoeff,    kZero_GrBlendCoeff),
    /* dst-out */    COEFF_FORMULA(   kZero_GrBlendCoeff,   kISA_GrBlendCoeff),
    /* src-atop */   COEFF_FORMULA(   kDA_GrBlendCoeff,     kISA_GrBlendCoeff),
    /* dst-atop */   COEFF_FORMULA(   kIDA_GrBlendCoeff,    kSA_GrBlendCoeff),
    /* xor */        COEFF_FORMULA(   kIDA_GrBlendCoeff,    kISA_GrBlendCoeff),
    /* plus */       COEFF_FORMULA(   kOne_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* modulate */   COEFF_FORMULA(   kZero_GrBlendCoeff,   kSC_GrBlendCoeff),
    /* screen */     COEFF_FORMULA(   kOne_GrBlendCoeff,    kISC_GrBlendCoeff),

                     }, /*>> Has coverage, input color unknown <<*/ {

    /* clear */      COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_OutputType),
    /* src */        COVERAGE_DST_COEFF_ZERO_FORMULA(kOne_GrBlendCoeff),
    /* dst */        NO_DST_WRITE_FORMULA,
    /* src-over */   COEFF_FORMULA(   kOne_GrBlendCoeff,    kISA_GrBlendCoeff),
    /* dst-over */   COEFF_FORMULA(   kIDA_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* src-in */     COVERAGE_DST_COEFF_ZERO_FORMULA(kDA_GrBlendCoeff),
    /* dst-in */     COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISAModulate_OutputType),
    /* src-out */    COVERAGE_DST_COEFF_ZERO_FORMULA(kIDA_GrBlendCoeff),
    /* dst-out */    COEFF_FORMULA(   kZero_GrBlendCoeff,   kISA_GrBlendCoeff),
    /* src-atop */   COEFF_FORMULA(   kDA_GrBlendCoeff,     kISA_GrBlendCoeff),
    /* dst-atop */   COVERAGE_FORMULA(BlendFormula::kISAModulate_OutputType, kIDA_GrBlendCoeff),
    /* xor */        COEFF_FORMULA(   kIDA_GrBlendCoeff,    kISA_GrBlendCoeff),
    /* plus */       COEFF_FORMULA(   kOne_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* modulate */   COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_OutputType),
    /* screen */     COEFF_FORMULA(   kOne_GrBlendCoeff,    kISC_GrBlendCoeff),

                     }}, /*>> No coverage, input color opaque <<*/ {{

    /* clear */      DST_CLEAR_FORMULA,
    /* src */        COEFF_FORMULA(   kOne_GrBlendCoeff,    kZero_GrBlendCoeff),
    /* dst */        NO_DST_WRITE_FORMULA,
    /* src-over */   COEFF_FORMULA(   kOne_GrBlendCoeff,    kZero_GrBlendCoeff),
    /* dst-over */   COEFF_FORMULA(   kIDA_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* src-in */     COEFF_FORMULA(   kDA_GrBlendCoeff,     kZero_GrBlendCoeff),
    /* dst-in */     NO_DST_WRITE_FORMULA,
    /* src-out */    COEFF_FORMULA(   kIDA_GrBlendCoeff,    kZero_GrBlendCoeff),
    /* dst-out */    DST_CLEAR_FORMULA,
    /* src-atop */   COEFF_FORMULA(   kDA_GrBlendCoeff,     kZero_GrBlendCoeff),
    /* dst-atop */   COEFF_FORMULA(   kIDA_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* xor */        COEFF_FORMULA(   kIDA_GrBlendCoeff,    kZero_GrBlendCoeff),
    /* plus */       COEFF_FORMULA(   kOne_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* modulate */   COEFF_FORMULA(   kZero_GrBlendCoeff,   kSC_GrBlendCoeff),
    /* screen */     COEFF_FORMULA(   kOne_GrBlendCoeff,    kISC_GrBlendCoeff),

                     }, /*>> Has coverage, input color opaque <<*/ {

    /* clear */      COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_OutputType),
    /* src */        COEFF_FORMULA(   kOne_GrBlendCoeff,    kISA_GrBlendCoeff),
    /* dst */        NO_DST_WRITE_FORMULA,
    /* src-over */   COEFF_FORMULA(   kOne_GrBlendCoeff,    kISA_GrBlendCoeff),
    /* dst-over */   COEFF_FORMULA(   kIDA_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* src-in */     COEFF_FORMULA(   kDA_GrBlendCoeff,     kISA_GrBlendCoeff),
    /* dst-in */     NO_DST_WRITE_FORMULA,
    /* src-out */    COEFF_FORMULA(   kIDA_GrBlendCoeff,    kISA_GrBlendCoeff),
    /* dst-out */    COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_OutputType),
    /* src-atop */   COEFF_FORMULA(   kDA_GrBlendCoeff,     kISA_GrBlendCoeff),
    /* dst-atop */   COEFF_FORMULA(   kIDA_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* xor */        COEFF_FORMULA(   kIDA_GrBlendCoeff,    kISA_GrBlendCoeff),
    /* plus */       COEFF_FORMULA(   kOne_GrBlendCoeff,    kOne_GrBlendCoeff),
    /* modulate */   COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_OutputType),
    /* screen */     COEFF_FORMULA(   kOne_GrBlendCoeff,    kISC_GrBlendCoeff),
}}};

static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI,
                                      const GrProcOptInfo& coveragePOI,
                                      bool hasMixedSamples,
                                      SkXfermode::Mode xfermode) {
    SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode);
    SkASSERT(!coveragePOI.isFourChannelOutput());

    bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples;
    return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][xfermode];
}

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

class PorterDuffXferProcessor : public GrXferProcessor {
public:
    PorterDuffXferProcessor(BlendFormula blendFormula) : fBlendFormula(blendFormula) {
        this->initClassID<PorterDuffXferProcessor>();
    }

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

    GrGLXferProcessor* createGLInstance() const override;

    BlendFormula getBlendFormula() const { return fBlendFormula; }

private:
    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
                                                 const GrProcOptInfo& coveragePOI,
                                                 bool doesStencilWrite,
                                                 GrColor* overrideColor,
                                                 const GrCaps& caps) override;

    void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;

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

    void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
        blendInfo->fEquation = fBlendFormula.fBlendEquation;
        blendInfo->fSrcBlend = fBlendFormula.fSrcCoeff;
        blendInfo->fDstBlend = fBlendFormula.fDstCoeff;
        blendInfo->fWriteColor = fBlendFormula.modifiesDst();
    }

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

    const BlendFormula fBlendFormula;

    typedef GrXferProcessor INHERITED;
};

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

static void append_color_output(const PorterDuffXferProcessor& xp, GrGLXPFragmentBuilder* fsBuilder,
                                BlendFormula::OutputType outputType, const char* output,
                                const char* inColor, const char* inCoverage) {
    switch (outputType) {
        case BlendFormula::kNone_OutputType:
            fsBuilder->codeAppendf("%s = vec4(0.0);", output);
            break;
        case BlendFormula::kCoverage_OutputType:
            // We can have a coverage formula while not reading coverage if there are mixed samples.
            fsBuilder->codeAppendf("%s = %s;",
                                   output, xp.readsCoverage() ? inCoverage : "vec4(1.0)");
            break;
        case BlendFormula::kModulate_OutputType:
            if (xp.readsCoverage()) {
                fsBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCoverage);
            } else {
                fsBuilder->codeAppendf("%s = %s;", output, inColor);
            }
            break;
        case BlendFormula::kISAModulate_OutputType:
            if (xp.readsCoverage()) {
                fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inColor, inCoverage);
            } else {
                fsBuilder->codeAppendf("%s = vec4(1.0 - %s.a);", output, inColor);
            }
            break;
        case BlendFormula::kISCModulate_OutputType:
            if (xp.readsCoverage()) {
                fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", output, inColor, inCoverage);
            } else {
                fsBuilder->codeAppendf("%s = vec4(1.0) - %s;", output, inColor);
            }
            break;
        default:
            SkFAIL("Unsupported output type.");
            break;
    }
}

class GLPorterDuffXferProcessor : public GrGLXferProcessor {
public:
    static void GenKey(const GrProcessor& processor, GrProcessorKeyBuilder* b) {
        const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcessor>();
        b->add32(SkToInt(xp.readsCoverage()) |
                 (xp.getBlendFormula().fPrimaryOutputType << 1) |
                 (xp.getBlendFormula().fSecondaryOutputType << 4));
        GR_STATIC_ASSERT(BlendFormula::kLast_OutputType < 8);
    };

private:
    void emitOutputsForBlendState(const EmitArgs& args) override {
        const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcessor>();
        GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();

        BlendFormula blendFormula = xp.getBlendFormula();
        if (blendFormula.hasSecondaryOutput()) {
            append_color_output(xp, fsBuilder, blendFormula.fSecondaryOutputType,
                                args.fOutputSecondary, args.fInputColor, args.fInputCoverage);
        }
        append_color_output(xp, fsBuilder, blendFormula.fPrimaryOutputType,
                            args.fOutputPrimary, args.fInputColor, args.fInputCoverage);
    }

    void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) override {}

    typedef GrGLXferProcessor INHERITED;
};

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

void PorterDuffXferProcessor::onGetGLProcessorKey(const GrGLSLCaps&,
                                                  GrProcessorKeyBuilder* b) const {
    GLPorterDuffXferProcessor::GenKey(*this, b);
}

GrGLXferProcessor* PorterDuffXferProcessor::createGLInstance() const {
    return new GLPorterDuffXferProcessor;
}

GrXferProcessor::OptFlags
PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI,
                                            const GrProcOptInfo& coveragePOI,
                                            bool doesStencilWrite,
                                            GrColor* overrideColor,
                                            const GrCaps& caps) {
    GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
    if (!fBlendFormula.modifiesDst()) {
        if (!doesStencilWrite) {
            optFlags |= GrXferProcessor::kSkipDraw_OptFlag;
        }
        optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag |
                     GrXferProcessor::kIgnoreCoverage_OptFlag |
                     GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag);
    } else {
        if (!fBlendFormula.usesInputColor()) {
            optFlags |= GrXferProcessor::kIgnoreColor_OptFlag;
        }
        if (coveragePOI.isSolidWhite()) {
            optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag;
        }
        if (colorPOI.allStagesMultiplyInput() && fBlendFormula.canTweakAlphaForCoverage()) {
            optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag;
        }
    }
    return optFlags;
}

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

class ShaderPDXferProcessor : public GrXferProcessor {
public:
    ShaderPDXferProcessor(const DstTexture* dstTexture,
                          bool hasMixedSamples,
                          SkXfermode::Mode xfermode)
        : INHERITED(dstTexture, true, hasMixedSamples)
        , fXfermode(xfermode) {
        this->initClassID<ShaderPDXferProcessor>();
    }

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

    GrGLXferProcessor* createGLInstance() const override;

    SkXfermode::Mode getXfermode() const { return fXfermode; }

private:
    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo&, const GrProcOptInfo&,
                                                 bool, GrColor*, const GrCaps&) override {
        return kNone_OptFlags;
    }

    void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;

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

    const SkXfermode::Mode fXfermode;

    typedef GrXferProcessor INHERITED;
};

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

class GLShaderPDXferProcessor : public GrGLXferProcessor {
public:
    static void GenKey(const GrProcessor& processor, GrProcessorKeyBuilder* b) {
        const ShaderPDXferProcessor& xp = processor.cast<ShaderPDXferProcessor>();
        b->add32(xp.getXfermode());
    }

private:
    void emitBlendCodeForDstRead(GrGLXPBuilder* pb, const char* srcColor, const char* dstColor,
                                 const char* outColor, const GrXferProcessor& proc) override {
        const ShaderPDXferProcessor& xp = proc.cast<ShaderPDXferProcessor>();
        GrGLXPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();

        GrGLBlend::AppendPorterDuffBlend(fsBuilder, srcColor, dstColor, outColor, xp.getXfermode());
    }

    void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) override {}

    typedef GrGLXferProcessor INHERITED;
};

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

void ShaderPDXferProcessor::onGetGLProcessorKey(const GrGLSLCaps&,
                                                  GrProcessorKeyBuilder* b) const {
    GLShaderPDXferProcessor::GenKey(*this, b);
}

GrGLXferProcessor* ShaderPDXferProcessor::createGLInstance() const {
    return new GLShaderPDXferProcessor;
}

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

class PDLCDXferProcessor : public GrXferProcessor {
public:
    static GrXferProcessor* Create(SkXfermode::Mode xfermode, const GrProcOptInfo& colorPOI);

    ~PDLCDXferProcessor() override;

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

    GrGLXferProcessor* createGLInstance() const override;

private:
    PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha);

    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
                                                 const GrProcOptInfo& coveragePOI,
                                                 bool doesStencilWrite,
                                                 GrColor* overrideColor,
                                                 const GrCaps& caps) override;

    void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;

    void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
        blendInfo->fSrcBlend = kConstC_GrBlendCoeff;
        blendInfo->fDstBlend = kISC_GrBlendCoeff;
        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;
    }

    GrColor      fBlendConstant;
    uint8_t      fAlpha;

    typedef GrXferProcessor INHERITED;
};

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

class GLPDLCDXferProcessor : public GrGLXferProcessor {
public:
    GLPDLCDXferProcessor(const GrProcessor&) {}

    virtual ~GLPDLCDXferProcessor() {}

    static void GenKey(const GrProcessor& processor, const GrGLSLCaps& caps,
                       GrProcessorKeyBuilder* b) {}

private:
    void emitOutputsForBlendState(const EmitArgs& args) override {
        GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();

        fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
                               args.fInputCoverage);
    }

    void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) override {};

    typedef GrGLXferProcessor INHERITED;
};

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

PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha)
    : fBlendConstant(blendConstant)
    , fAlpha(alpha) {
    this->initClassID<PDLCDXferProcessor>();
}

GrXferProcessor* PDLCDXferProcessor::Create(SkXfermode::Mode xfermode,
                                            const GrProcOptInfo& colorPOI) {
    if (SkXfermode::kSrcOver_Mode != xfermode) {
        return nullptr;
    }

    if (kRGBA_GrColorComponentFlags != colorPOI.validFlags()) {
        return nullptr;
    }

    GrColor blendConstant = GrUnPreMulColor(colorPOI.color());
    uint8_t alpha = GrColorUnpackA(blendConstant);
    blendConstant |= (0xff << GrColor_SHIFT_A);

    return new PDLCDXferProcessor(blendConstant, alpha);
}

PDLCDXferProcessor::~PDLCDXferProcessor() {
}

void PDLCDXferProcessor::onGetGLProcessorKey(const GrGLSLCaps& caps,
                                             GrProcessorKeyBuilder* b) const {
    GLPDLCDXferProcessor::GenKey(*this, caps, b);
}

GrGLXferProcessor* PDLCDXferProcessor::createGLInstance() const {
    return new GLPDLCDXferProcessor(*this);
}

GrXferProcessor::OptFlags
PDLCDXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI,
                                       const GrProcOptInfo& coveragePOI,
                                       bool doesStencilWrite,
                                       GrColor* overrideColor,
                                       const GrCaps& caps) {
        // We want to force our primary output to be alpha * Coverage, where alpha is the alpha
        // value of the blend the constant. We should already have valid blend coeff's if we are at
        // a point where we have RGB coverage. We don't need any color stages since the known color
        // output is already baked into the blendConstant.
        *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha);
        return GrXferProcessor::kOverrideColor_OptFlag;
}

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

GrPorterDuffXPFactory::GrPorterDuffXPFactory(SkXfermode::Mode xfermode)
    : fXfermode(xfermode) {
    SkASSERT(fXfermode <= SkXfermode::kLastCoeffMode);
    this->initClassID<GrPorterDuffXPFactory>();
}

GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode xfermode) {
    static GrPorterDuffXPFactory gClearPDXPF(SkXfermode::kClear_Mode);
    static GrPorterDuffXPFactory gSrcPDXPF(SkXfermode::kSrc_Mode);
    static GrPorterDuffXPFactory gDstPDXPF(SkXfermode::kDst_Mode);
    static GrPorterDuffXPFactory gSrcOverPDXPF(SkXfermode::kSrcOver_Mode);
    static GrPorterDuffXPFactory gDstOverPDXPF(SkXfermode::kDstOver_Mode);
    static GrPorterDuffXPFactory gSrcInPDXPF(SkXfermode::kSrcIn_Mode);
    static GrPorterDuffXPFactory gDstInPDXPF(SkXfermode::kDstIn_Mode);
    static GrPorterDuffXPFactory gSrcOutPDXPF(SkXfermode::kSrcOut_Mode);
    static GrPorterDuffXPFactory gDstOutPDXPF(SkXfermode::kDstOut_Mode);
    static GrPorterDuffXPFactory gSrcATopPDXPF(SkXfermode::kSrcATop_Mode);
    static GrPorterDuffXPFactory gDstATopPDXPF(SkXfermode::kDstATop_Mode);
    static GrPorterDuffXPFactory gXorPDXPF(SkXfermode::kXor_Mode);
    static GrPorterDuffXPFactory gPlusPDXPF(SkXfermode::kPlus_Mode);
    static GrPorterDuffXPFactory gModulatePDXPF(SkXfermode::kModulate_Mode);
    static GrPorterDuffXPFactory gScreenPDXPF(SkXfermode::kScreen_Mode);

    static GrPorterDuffXPFactory* gFactories[] = {
        &gClearPDXPF, &gSrcPDXPF, &gDstPDXPF, &gSrcOverPDXPF, &gDstOverPDXPF, &gSrcInPDXPF,
        &gDstInPDXPF, &gSrcOutPDXPF, &gDstOutPDXPF, &gSrcATopPDXPF, &gDstATopPDXPF, &gXorPDXPF,
        &gPlusPDXPF, &gModulatePDXPF, &gScreenPDXPF
    };
    GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFactories) == SkXfermode::kLastCoeffMode + 1);

    if (xfermode < 0 || xfermode > SkXfermode::kLastCoeffMode) {
        return nullptr;
    }
    return SkRef(gFactories[xfermode]);
}

GrXferProcessor*
GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
                                             const GrProcOptInfo& colorPOI,
                                             const GrProcOptInfo& covPOI,
                                             bool hasMixedSamples,
                                             const DstTexture* dstTexture) const {
    if (covPOI.isFourChannelOutput()) {
        SkASSERT(!dstTexture || !dstTexture->texture());
        return PDLCDXferProcessor::Create(fXfermode, colorPOI);
    }

    BlendFormula blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode);
    if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
        return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode);
    }

    SkASSERT(!dstTexture || !dstTexture->texture());
    return new PorterDuffXferProcessor(blendFormula);
}

bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/,
                                                uint32_t knownColorFlags) const {
    if (SkXfermode::kSrcOver_Mode == fXfermode &&
        kRGBA_GrColorComponentFlags == knownColorFlags) {
        return true;
    }
    return false;
}

void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
                                                     InvariantBlendedColor* blendedColor) const {
    // Find the blended color info based on the formula that does not have coverage.
    BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][fXfermode];
    if (colorFormula.usesDstColor()) {
        blendedColor->fWillBlendWithDst = true;
        blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
        return;
    }

    blendedColor->fWillBlendWithDst = false;

    SkASSERT(kAdd_GrBlendEquation == colorFormula.fBlendEquation);

    switch (colorFormula.fSrcCoeff) {
        case kZero_GrBlendCoeff:
            blendedColor->fKnownColor = 0;
            blendedColor->fKnownColorFlags = kRGBA_GrColorComponentFlags;
            return;

        case kOne_GrBlendCoeff:
            blendedColor->fKnownColor = colorPOI.color();
            blendedColor->fKnownColorFlags = colorPOI.validFlags();
            return;

        default:
            blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
            return;
    }
}

bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps,
                                             const GrProcOptInfo& colorPOI,
                                             const GrProcOptInfo& covPOI,
                                             bool hasMixedSamples) const {
    if (caps.shaderCaps()->dualSourceBlendingSupport()) {
        return false;
    }
    if (covPOI.isFourChannelOutput()) {
        return false; // The LCD XP will abort rather than doing a dst read.
    }
    // We fallback on the shader XP when the blend formula would use dual source blending but we
    // don't have support for it.
    return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSecondaryOutput();
}

GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);

const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) {
    SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermode::kLastCoeffMode));
    return GrPorterDuffXPFactory::Create(mode);
}

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.fPrimaryOutputType;
    *outSecondary = blendFormula.fSecondaryOutputType;
}
