1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkXfermode_DEFINED
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkXfermode_DEFINED
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFlattenable.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColor.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
16b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrFragmentProcessor;
1786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.orgclass GrTexture;
18378092f3d10b1dd62967f419c35cfefec7c10ee7egdanielclass GrXPFactory;
19b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comclass SkString;
20b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com
21dd9ffea9ce051a49dbc6544e6aa3cb68fe987f47reedstruct SkPM4f;
22dd9ffea9ce051a49dbc6544e6aa3cb68fe987f47reedtypedef SkPM4f (*SkXfermodeProc4f)(const SkPM4f& src, const SkPM4f& dst);
23dd9ffea9ce051a49dbc6544e6aa3cb68fe987f47reed
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkXfermode
25fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *
26fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *  SkXfermode is the base class for objects that are called to implement custom
27fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *  "transfer-modes" in the drawing pipeline. The static function Create(Modes)
28fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *  can be called to return an instance of any of the predefined subclasses as
29fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *  specified in the Modes enum. When an SkXfermode is assigned to an SkPaint,
30fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *  then objects drawn with that paint have the xfermode applied.
31fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *
32fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *  All subclasses are required to be reentrant-safe : it must be legal to share
33fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com *  the same instance between several threads.
34fb6deed66c20f86c86c105f41dbbf3f3c4a47e4creed@google.com */
357ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkXfermode : public SkFlattenable {
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
3830da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com                        const SkAlpha aa[]) const;
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
4030da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com                        const SkAlpha aa[]) const;
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
4230da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com                        const SkAlpha aa[]) const;
431447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
44d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    /** Enum of possible coefficients to describe some xfermodes
45d252db03d9650013b545ef9781fe993c07f8f314reed@android.com     */
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    enum Coeff {
47d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kZero_Coeff,    /** 0 */
48d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kOne_Coeff,     /** 1 */
49d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kSC_Coeff,      /** src color */
50d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kISC_Coeff,     /** inverse src color (i.e. 1 - sc) */
51d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kDC_Coeff,      /** dst color */
52d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kIDC_Coeff,     /** inverse dst color (i.e. 1 - dc) */
53d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kSA_Coeff,      /** src alpha */
54d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kISA_Coeff,     /** inverse src alpha (i.e. 1 - sa) */
55d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kDA_Coeff,      /** dst alpha */
56d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        kIDA_Coeff,     /** inverse dst alpha (i.e. 1 - da) */
571447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kCoeffCount
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
601447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
61a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    /** List of predefined xfermodes.
62a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        The algebra for the modes uses the following symbols:
63a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        Sa, Sc  - source alpha and color
64a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        Da, Dc - destination alpha and color (before compositing)
65a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        [a, c] - Resulting (alpha, color) values
66a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        For these equations, the colors are in premultiplied state.
67a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        If no xfermode is specified, kSrcOver is assumed.
688da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com        The modes are ordered by those that can be expressed as a pair of Coeffs, followed by those
698da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com        that aren't Coeffs but have separable r,g,b computations, and finally
708da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com        those that are not separable.
71a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com     */
72a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    enum Mode {
73a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kClear_Mode,    //!< [0, 0]
74a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kSrc_Mode,      //!< [Sa, Sc]
75a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kDst_Mode,      //!< [Da, Dc]
76129319ff55f4be826419ffa04e772e21c6b12400pkasting        kSrcOver_Mode,  //!< [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)]
77129319ff55f4be826419ffa04e772e21c6b12400pkasting        kDstOver_Mode,  //!< [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)]
78a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kSrcIn_Mode,    //!< [Sa * Da, Sc * Da]
79129319ff55f4be826419ffa04e772e21c6b12400pkasting        kDstIn_Mode,    //!< [Da * Sa, Dc * Sa]
80a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kSrcOut_Mode,   //!< [Sa * (1 - Da), Sc * (1 - Da)]
81a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kDstOut_Mode,   //!< [Da * (1 - Sa), Dc * (1 - Sa)]
82129319ff55f4be826419ffa04e772e21c6b12400pkasting        kSrcATop_Mode,  //!< [Da, Sc * Da + Dc * (1 - Sa)]
83129319ff55f4be826419ffa04e772e21c6b12400pkasting        kDstATop_Mode,  //!< [Sa, Dc * Sa + Sc * (1 - Da)]
84129319ff55f4be826419ffa04e772e21c6b12400pkasting        kXor_Mode,      //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)]
85b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org        kPlus_Mode,     //!< [Sa + Da, Sc + Dc]
868d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com        kModulate_Mode, // multiplies all components (= alpha and color)
87fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
8864334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com        // Following blend modes are defined in the CSS Compositing standard:
89b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org        // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending
90b0091b8382970c28dba57adc170e27b2e3d7394absalomon@google.com        kScreen_Mode,
918da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com        kLastCoeffMode = kScreen_Mode,
928da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com
938da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com        kOverlay_Mode,
94a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kDarken_Mode,
95a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kLighten_Mode,
96a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kColorDodge_Mode,
97a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kColorBurn_Mode,
98a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kHardLight_Mode,
99a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kSoftLight_Mode,
100a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kDifference_Mode,
101a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kExclusion_Mode,
10225cfa693420b6da4182bda42ba15970999b840ddreed@google.com        kMultiply_Mode,
1038da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com        kLastSeparableMode = kMultiply_Mode,
104a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
105b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org        kHue_Mode,
106b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org        kSaturation_Mode,
107b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org        kColor_Mode,
108b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org        kLuminosity_Mode,
109b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org        kLastMode = kLuminosity_Mode
110a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    };
11105a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com
112d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org    /**
113d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org     * Gets the name of the Mode as a string.
114d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org     */
115d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org    static const char* ModeName(Mode);
116a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
117c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com    /**
118c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com     *  If the xfermode is one of the modes in the Mode enum, then asMode()
119c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com     *  returns true and sets (if not null) mode accordingly. Otherwise it
120c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com     *  returns false and ignores the mode parameter.
12148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org     */
12230da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com    virtual bool asMode(Mode* mode) const;
12348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org
12443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    /**
12543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com     *  The same as calling xfermode->asMode(mode), except that this also checks
126f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com     *  if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
12743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com     */
12830da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com    static bool AsMode(const SkXfermode*, Mode* mode);
12943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
130e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org    /**
131e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     *  Returns true if the xfermode claims to be the specified Mode. This works
132e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     *  correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus
133e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     *  you can say this without checking for a null...
134e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     *
135e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     *  If (SkXfermode::IsMode(paint.getXfermode(),
136e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     *                         SkXfermode::kDstOver_Mode)) {
137e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     *      ...
138e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     *  }
139e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org     */
14030da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com    static bool IsMode(const SkXfermode* xfer, Mode mode);
141e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org
142a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    /** Return an SkXfermode object for the specified mode.
143a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com     */
144a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    static SkXfermode* Create(Mode mode);
145a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
146a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    /** Return a function pointer to a routine that applies the specified
147a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        porter-duff transfer mode.
148a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com     */
149a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    static SkXfermodeProc GetProc(Mode mode);
1503125565804054691b110b4731bc5a32070fab780reed    static SkXfermodeProc4f GetProc4f(Mode);
151a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
152129ed1cd6d792f3f6cf563aefa9756fc6308289dreed    virtual SkXfermodeProc4f getProc4f() const;
153129ed1cd6d792f3f6cf563aefa9756fc6308289dreed
154c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com    /**
15543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com     *  If the specified mode can be represented by a pair of Coeff, then return
15643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com     *  true and set (if not NULL) the corresponding coeffs. If the mode is
15743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com     *  not representable as a pair of Coeffs, return false and ignore the
15843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com     *  src and dst parameters.
159a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com     */
16043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst);
161a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
1624469938e92d779dff05e745559e67907bbf21e78reed@google.com    SK_ATTR_DEPRECATED("use AsMode(...)")
16330da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com    static bool IsMode(const SkXfermode* xfer, Mode* mode) {
16443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        return AsMode(xfer, mode);
16543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    }
1661447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
167dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    /**
168dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     * Returns whether or not the xfer mode can support treating coverage as alpha
1692766c00fc0b6a07d46e5f74cdad45da2ef625237mtklein     */
170dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    virtual bool supportsCoverageAsAlpha() const;
171dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel
172dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    /**
173dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     *  The same as calling xfermode->supportsCoverageAsAlpha(), except that this also checks if
174dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     *  the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
175dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     */
176dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    static bool SupportsCoverageAsAlpha(const SkXfermode* xfer);
177dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel
178dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    enum SrcColorOpacity {
179dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel        // The src color is known to be opaque (alpha == 255)
180dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel        kOpaque_SrcColorOpacity = 0,
181dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel        // The src color is known to be fully transparent (color == 0)
182dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel        kTransparentBlack_SrcColorOpacity = 1,
183dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel        // The src alpha is known to be fully transparent (alpha == 0)
184dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel        kTransparentAlpha_SrcColorOpacity = 2,
185dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel        // The src color opacity is unknown
186dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel        kUnknown_SrcColorOpacity = 3
187dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    };
188dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel
189dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    /**
190dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     * Returns whether or not the result of the draw with the xfer mode will be opaque or not. The
191dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     * input to this call is an enum describing known information about the opacity of the src color
192dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     * that will be given to the xfer mode.
193dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     */
194dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    virtual bool isOpaque(SrcColorOpacity opacityType) const;
195dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel
196dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    /**
197dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     *  The same as calling xfermode->isOpaque(...), except that this also checks if
198dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     *  the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
199dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel     */
200dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel    static bool IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType);
201dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel
2024f0379444db31421894d2fce7c85889fe5eaa01arobertphillips#if SK_SUPPORT_GPU
2034f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    /** Used by the SkXfermodeImageFilter to blend two colors via a GrFragmentProcessor.
2044f0379444db31421894d2fce7c85889fe5eaa01arobertphillips        The input to the returned FP is the src color. The dst color is
2054f0379444db31421894d2fce7c85889fe5eaa01arobertphillips        provided by the dst param which becomes a child FP of the returned FP.
2064f0379444db31421894d2fce7c85889fe5eaa01arobertphillips        It is legal for the function to return a null output. This indicates that
207ae4738f677c70f4ec7687422e1510ee3d80d810ebsalomon        the output of the blend is simply the src color.
208f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com     */
2094f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    virtual const GrFragmentProcessor* getFragmentProcessorForImageFilter(
2104f0379444db31421894d2fce7c85889fe5eaa01arobertphillips                                                            const GrFragmentProcessor* dst) const;
211378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel
2124f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    /** A subclass must implement this factory function to work with the GPU backend.
2134f0379444db31421894d2fce7c85889fe5eaa01arobertphillips        The xfermode will return a factory for which the caller will get a ref. It is up
2144f0379444db31421894d2fce7c85889fe5eaa01arobertphillips        to the caller to install it. XferProcessors cannot use a background texture.
215c4b72720e75313079212e69e46a5ef7c474b2305egdaniel      */
2164f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    virtual GrXPFactory* asXPFactory() const;
2174f0379444db31421894d2fce7c85889fe5eaa01arobertphillips#endif
218f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com
2190f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org    SK_TO_STRING_PUREVIRT()
220a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
221c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    SK_DEFINE_FLATTENABLE_TYPE(SkXfermode)
222c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org
2238f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed    enum D32Flags {
2248f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed        kSrcIsOpaque_D32Flag  = 1 << 0,
2258f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed        kSrcIsSingle_D32Flag  = 1 << 1,
2268f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed        kDstIsSRGB_D32Flag    = 1 << 2,
227395eabeb0e72334c45324874c6e009b54634df21reed    };
2288f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed    typedef void (*D32Proc)(const SkXfermode*, uint32_t dst[], const SkPM4f src[],
2298f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed                            int count, const SkAlpha coverage[]);
2308f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed    static D32Proc GetD32Proc(SkXfermode*, uint32_t flags);
2318f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed
2328f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed    enum D64Flags {
2338f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed        kSrcIsOpaque_D64Flag  = 1 << 0,
2348f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed        kSrcIsSingle_D64Flag  = 1 << 1,
2358f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed        kDstIsFloat16_D64Flag = 1 << 2, // else U16 bit components
236395eabeb0e72334c45324874c6e009b54634df21reed    };
2378f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed    typedef void (*D64Proc)(const SkXfermode*, uint64_t dst[], const SkPM4f src[], int count,
2388f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed                            const SkAlpha coverage[]);
2398f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed    static D64Proc GetD64Proc(SkXfermode*, uint32_t flags);
240d2ed622a2fc574288b312ec1ff94c77ed6e70476reed
2414528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed    enum LCDFlags {
2424528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed        kSrcIsOpaque_LCDFlag    = 1 << 0,   // else src(s) may have alpha < 1
2434528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed        kSrcIsSingle_LCDFlag    = 1 << 1,   // else src[count]
2444528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed        kDstIsLinearInt_LCDFlag = 1 << 2,   // else srgb/half-float
2454528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed    };
2464528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed    typedef void (*LCD32Proc)(uint32_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
2474528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed    typedef void (*LCD64Proc)(uint64_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
2484528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed    static LCD32Proc GetLCD32Proc(uint32_t flags);
2494528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed    static LCD64Proc GetLCD64Proc(uint32_t) { return nullptr; }
2504528c867c4ba65fdf5cfd6de35ea4c36a16c73f6reed
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
252bd0be25074e53a6d1abc284562568c9745191984commit-bot@chromium.org    SkXfermode() {}
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** The default implementation of xfer32/xfer16/xferA8 in turn call this
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        method, 1 color at a time (upscaled to a SkPMColor). The default
255ae4738f677c70f4ec7687422e1510ee3d80d810ebsalomon        implementation of this method just returns dst. If performance is
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        important, your subclass should override xfer32/xfer16/xferA8 directly.
2571447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        This method will not be called directly by the client, so it need not
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        be implemented if your subclass has overridden xfer32/xfer16/xferA8
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
26130da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com    virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2638f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed    virtual D32Proc onGetD32Proc(uint32_t flags) const;
2648f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed    virtual D64Proc onGetD64Proc(uint32_t flags) const;
2658f7b0b2d809510d4af4e6ff6f731bac78eded6c4reed
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
267a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    enum {
268a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com        kModeCount = kLastMode + 1
269a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    };
27086490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkFlattenable INHERITED;
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
275