/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkXfermode_DEFINED
#define SkXfermode_DEFINED

#include "SkBlendMode.h"
#include "SkColor.h"
#include "SkFlattenable.h"

class GrFragmentProcessor;
class GrTexture;
class GrXPFactory;
class SkRasterPipeline;
class SkString;

struct SkArithmeticParams;

struct SkPM4f;
typedef SkPM4f (*SkXfermodeProc4f)(const SkPM4f& src, const SkPM4f& dst);

/** \class SkXfermode
 *
 *  SkXfermode is the base class for objects that are called to implement custom
 *  "transfer-modes" in the drawing pipeline. The static function Create(Modes)
 *  can be called to return an instance of any of the predefined subclasses as
 *  specified in the Modes enum. When an SkXfermode is assigned to an SkPaint,
 *  then objects drawn with that paint have the xfermode applied.
 *
 *  All subclasses are required to be reentrant-safe : it must be legal to share
 *  the same instance between several threads.
 */
class SK_API SkXfermode : public SkFlattenable {
public:
    virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
                        const SkAlpha aa[]) const;
    virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
                        const SkAlpha aa[]) const;
    virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
                        const SkAlpha aa[]) const;

    /** Enum of possible coefficients to describe some xfermodes
     */
    enum Coeff {
        kZero_Coeff,    /** 0 */
        kOne_Coeff,     /** 1 */
        kSC_Coeff,      /** src color */
        kISC_Coeff,     /** inverse src color (i.e. 1 - sc) */
        kDC_Coeff,      /** dst color */
        kIDC_Coeff,     /** inverse dst color (i.e. 1 - dc) */
        kSA_Coeff,      /** src alpha */
        kISA_Coeff,     /** inverse src alpha (i.e. 1 - sa) */
        kDA_Coeff,      /** dst alpha */
        kIDA_Coeff,     /** inverse dst alpha (i.e. 1 - da) */

        kCoeffCount
    };

    /** List of predefined xfermodes.
        The algebra for the modes uses the following symbols:
        Sa, Sc  - source alpha and color
        Da, Dc - destination alpha and color (before compositing)
        [a, c] - Resulting (alpha, color) values
        For these equations, the colors are in premultiplied state.
        If no xfermode is specified, kSrcOver is assumed.
        The modes are ordered by those that can be expressed as a pair of Coeffs, followed by those
        that aren't Coeffs but have separable r,g,b computations, and finally
        those that are not separable.
     */
    enum Mode {
        kClear_Mode,    //!< [0, 0]
        kSrc_Mode,      //!< [Sa, Sc]
        kDst_Mode,      //!< [Da, Dc]
        kSrcOver_Mode,  //!< [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)]
        kDstOver_Mode,  //!< [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)]
        kSrcIn_Mode,    //!< [Sa * Da, Sc * Da]
        kDstIn_Mode,    //!< [Da * Sa, Dc * Sa]
        kSrcOut_Mode,   //!< [Sa * (1 - Da), Sc * (1 - Da)]
        kDstOut_Mode,   //!< [Da * (1 - Sa), Dc * (1 - Sa)]
        kSrcATop_Mode,  //!< [Da, Sc * Da + Dc * (1 - Sa)]
        kDstATop_Mode,  //!< [Sa, Dc * Sa + Sc * (1 - Da)]
        kXor_Mode,      //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)]
        kPlus_Mode,     //!< [Sa + Da, Sc + Dc]
        kModulate_Mode, // multiplies all components (= alpha and color)

        // Following blend modes are defined in the CSS Compositing standard:
        // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending
        kScreen_Mode,
        kLastCoeffMode = kScreen_Mode,

        kOverlay_Mode,
        kDarken_Mode,
        kLighten_Mode,
        kColorDodge_Mode,
        kColorBurn_Mode,
        kHardLight_Mode,
        kSoftLight_Mode,
        kDifference_Mode,
        kExclusion_Mode,
        kMultiply_Mode,
        kLastSeparableMode = kMultiply_Mode,

        kHue_Mode,
        kSaturation_Mode,
        kColor_Mode,
        kLuminosity_Mode,
        kLastMode = kLuminosity_Mode
    };

    /**
     * Gets the name of the Mode as a string.
     */
    static const char* ModeName(Mode);
    static const char* ModeName(SkBlendMode mode) {
        return ModeName(Mode(mode));
    }

    /**
     *  If the xfermode is one of the modes in the Mode enum, then asMode()
     *  returns true and sets (if not null) mode accordingly. Otherwise it
     *  returns false and ignores the mode parameter.
     */
    virtual bool asMode(Mode* mode) const;

    /**
     *  The same as calling xfermode->asMode(mode), except that this also checks
     *  if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
     */
    static bool AsMode(const SkXfermode*, Mode* mode);
    static bool AsMode(const sk_sp<SkXfermode>& xfer, Mode* mode) {
        return AsMode(xfer.get(), mode);
    }

    /**
     *  Returns true if the xfermode claims to be the specified Mode. This works
     *  correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus
     *  you can say this without checking for a null...
     *
     *  If (SkXfermode::IsMode(paint.getXfermode(),
     *                         SkXfermode::kDstOver_Mode)) {
     *      ...
     *  }
     */
    static bool IsMode(const SkXfermode* xfer, Mode mode);
    static bool IsMode(const sk_sp<SkXfermode>& xfer, Mode mode) {
        return IsMode(xfer.get(), mode);
    }

    /** Return an SkXfermode object for the specified mode.
     */
    static sk_sp<SkXfermode> Make(SkBlendMode);
    static sk_sp<SkXfermode> Make(Mode m) { return Make((SkBlendMode)m); }

    /**
     *  Skia maintains global xfermode objects corresponding to each BlendMode. This returns a
     *  ptr to that global xfermode (or null if the mode is srcover). Thus the caller may use
     *  the returned ptr, but it should leave its refcnt untouched.
     */
    static SkXfermode* Peek(SkBlendMode mode) {
        sk_sp<SkXfermode> xfer = Make(mode);
        if (!xfer) {
            SkASSERT(SkBlendMode::kSrcOver == mode);
            return nullptr;
        }
        SkASSERT(!xfer->unique());
        return xfer.get();
    }

    SkBlendMode blend() const {
        Mode mode;
        SkAssertResult(this->asMode(&mode));
        return (SkBlendMode)mode;
    }

    static SkXfermodeProc GetProc(SkBlendMode);
    static SkXfermodeProc4f GetProc4f(SkBlendMode);

    /**
     *  If the specified mode can be represented by a pair of Coeff, then return
     *  true and set (if not NULL) the corresponding coeffs. If the mode is
     *  not representable as a pair of Coeffs, return false and ignore the
     *  src and dst parameters.
     */
    static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst);
    static bool ModeAsCoeff(SkBlendMode mode, Coeff* src, Coeff* dst) {
        return ModeAsCoeff((Mode)mode, src, dst);
    }

    /**
     * Returns whether or not the xfer mode can support treating coverage as alpha
     */
    virtual bool supportsCoverageAsAlpha() const;

    /**
     *  The same as calling xfermode->supportsCoverageAsAlpha(), except that this also checks if
     *  the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
     */
    static bool SupportsCoverageAsAlpha(const SkXfermode* xfer);
    static bool SupportsCoverageAsAlpha(const sk_sp<SkXfermode>& xfer) {
        return SupportsCoverageAsAlpha(xfer.get());
    }

    enum SrcColorOpacity {
        // The src color is known to be opaque (alpha == 255)
        kOpaque_SrcColorOpacity = 0,
        // The src color is known to be fully transparent (color == 0)
        kTransparentBlack_SrcColorOpacity = 1,
        // The src alpha is known to be fully transparent (alpha == 0)
        kTransparentAlpha_SrcColorOpacity = 2,
        // The src color opacity is unknown
        kUnknown_SrcColorOpacity = 3
    };

    /**
     * Returns whether or not the result of the draw with the xfer mode will be opaque or not. The
     * input to this call is an enum describing known information about the opacity of the src color
     * that will be given to the xfer mode.
     */
    virtual bool isOpaque(SrcColorOpacity opacityType) const;

    /**
     *  The same as calling xfermode->isOpaque(...), except that this also checks if
     *  the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
     */
    static bool IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType);
    static bool IsOpaque(const sk_sp<SkXfermode>& xfer, SrcColorOpacity opacityType) {
        return IsOpaque(xfer.get(), opacityType);
    }
    static bool IsOpaque(SkBlendMode, SrcColorOpacity);

#if SK_SUPPORT_GPU
    /** Used by the SkXfermodeImageFilter to blend two colors via a GrFragmentProcessor.
        The input to the returned FP is the src color. The dst color is
        provided by the dst param which becomes a child FP of the returned FP.
        It is legal for the function to return a null output. This indicates that
        the output of the blend is simply the src color.
     */
    virtual sk_sp<GrFragmentProcessor> makeFragmentProcessorForImageFilter(
                                                            sk_sp<GrFragmentProcessor> dst) const;

    /** A subclass must implement this factory function to work with the GPU backend.
        The xfermode will return a factory for which the caller will get a ref. It is up
        to the caller to install it. XferProcessors cannot use a background texture.
      */
    virtual sk_sp<GrXPFactory> asXPFactory() const;
#endif

    SK_TO_STRING_PUREVIRT()
    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
    SK_DEFINE_FLATTENABLE_TYPE(SkXfermode)

    enum D32Flags {
        kSrcIsOpaque_D32Flag  = 1 << 0,
        kSrcIsSingle_D32Flag  = 1 << 1,
        kDstIsSRGB_D32Flag    = 1 << 2,
    };
    typedef void (*D32Proc)(SkBlendMode, uint32_t dst[], const SkPM4f src[],
                            int count, const SkAlpha coverage[]);
    static D32Proc GetD32Proc(SkBlendMode, uint32_t flags);

    enum F16Flags {
        kSrcIsOpaque_F16Flag  = 1 << 0,
        kSrcIsSingle_F16Flag  = 1 << 1,
    };
    typedef void (*F16Proc)(SkBlendMode, uint64_t dst[], const SkPM4f src[], int count,
                            const SkAlpha coverage[]);
    static F16Proc GetF16Proc(SkBlendMode, uint32_t flags);

    enum LCDFlags {
        kSrcIsOpaque_LCDFlag    = 1 << 0,   // else src(s) may have alpha < 1
        kSrcIsSingle_LCDFlag    = 1 << 1,   // else src[count]
        kDstIsSRGB_LCDFlag      = 1 << 2,   // else l32 or f16
    };
    typedef void (*LCD32Proc)(uint32_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
    typedef void (*LCDF16Proc)(uint64_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
    static LCD32Proc GetLCD32Proc(uint32_t flags);
    static LCDF16Proc GetLCDF16Proc(uint32_t) { return nullptr; }

    virtual bool isArithmetic(SkArithmeticParams*) const { return false; }

protected:
    SkXfermode() {}
    /** The default implementation of xfer32/xfer16/xferA8 in turn call this
        method, 1 color at a time (upscaled to a SkPMColor). The default
        implementation of this method just returns dst. If performance is
        important, your subclass should override xfer32/xfer16/xferA8 directly.

        This method will not be called directly by the client, so it need not
        be implemented if your subclass has overridden xfer32/xfer16/xferA8
    */
    virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;

private:
    enum {
        kModeCount = kLastMode + 1
    };

    typedef SkFlattenable INHERITED;
};

#endif
