1d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed/* 2d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * Copyright 2006 The Android Open Source Project 3d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * 4d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * Use of this source code is governed by a BSD-style license that can be 5d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * found in the LICENSE file. 6d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 7d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 8d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#ifndef SkXfermodePriv_DEFINED 9d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#define SkXfermodePriv_DEFINED 10d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 11d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#include "SkBlendMode.h" 12d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#include "SkColor.h" 13d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#include "SkFlattenable.h" 14d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 15d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedclass GrFragmentProcessor; 16d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedclass GrTexture; 17d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedclass GrXPFactory; 18d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedclass SkRasterPipeline; 19d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedclass SkString; 20d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 21d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedstruct SkArithmeticParams; 22d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 23d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedstruct SkPM4f; 24d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedtypedef SkPM4f (*SkXfermodeProc4f)(const SkPM4f& src, const SkPM4f& dst); 25d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 26d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed/** \class SkXfermode 27d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * 28d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * SkXfermode is the base class for objects that are called to implement custom 29d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * "transfer-modes" in the drawing pipeline. The static function Create(Modes) 30d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * can be called to return an instance of any of the predefined subclasses as 31d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * specified in the Modes enum. When an SkXfermode is assigned to an SkPaint, 32d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * then objects drawn with that paint have the xfermode applied. 33d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * 34d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * All subclasses are required to be reentrant-safe : it must be legal to share 35d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * the same instance between several threads. 36d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 37d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedclass SK_API SkXfermode : public SkFlattenable { 38d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedpublic: 39d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, 40d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed const SkAlpha aa[]) const; 41d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, 42d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed const SkAlpha aa[]) const; 43d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count, 44d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed const SkAlpha aa[]) const; 45d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 46d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** Enum of possible coefficients to describe some xfermodes 47d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 48d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed enum Coeff { 49d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kZero_Coeff, /** 0 */ 50d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kOne_Coeff, /** 1 */ 51d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSC_Coeff, /** src color */ 52d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kISC_Coeff, /** inverse src color (i.e. 1 - sc) */ 53d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDC_Coeff, /** dst color */ 54d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kIDC_Coeff, /** inverse dst color (i.e. 1 - dc) */ 55d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSA_Coeff, /** src alpha */ 56d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kISA_Coeff, /** inverse src alpha (i.e. 1 - sa) */ 57d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDA_Coeff, /** dst alpha */ 58d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kIDA_Coeff, /** inverse dst alpha (i.e. 1 - da) */ 59d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 60d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kCoeffCount 61d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed }; 62d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 63d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** List of predefined xfermodes. 64d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed The algebra for the modes uses the following symbols: 65d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed Sa, Sc - source alpha and color 66d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed Da, Dc - destination alpha and color (before compositing) 67d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed [a, c] - Resulting (alpha, color) values 68d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed For these equations, the colors are in premultiplied state. 69d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed If no xfermode is specified, kSrcOver is assumed. 70d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed The modes are ordered by those that can be expressed as a pair of Coeffs, followed by those 71d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed that aren't Coeffs but have separable r,g,b computations, and finally 72d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed those that are not separable. 73d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 74d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed enum Mode { 75d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kClear_Mode, //!< [0, 0] 76d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrc_Mode, //!< [Sa, Sc] 77d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDst_Mode, //!< [Da, Dc] 78d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcOver_Mode, //!< [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)] 79d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDstOver_Mode, //!< [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)] 80d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 81d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDstIn_Mode, //!< [Da * Sa, Dc * Sa] 82d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 83d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 84d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcATop_Mode, //!< [Da, Sc * Da + Dc * (1 - Sa)] 85d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDstATop_Mode, //!< [Sa, Dc * Sa + Sc * (1 - Da)] 86d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)] 87d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kPlus_Mode, //!< [Sa + Da, Sc + Dc] 88d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kModulate_Mode, // multiplies all components (= alpha and color) 89d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 90d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed // Following blend modes are defined in the CSS Compositing standard: 91d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending 92d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kScreen_Mode, 93d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kLastCoeffMode = kScreen_Mode, 94d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 95d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kOverlay_Mode, 96d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDarken_Mode, 97d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kLighten_Mode, 98d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kColorDodge_Mode, 99d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kColorBurn_Mode, 100d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kHardLight_Mode, 101d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSoftLight_Mode, 102d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDifference_Mode, 103d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kExclusion_Mode, 104d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kMultiply_Mode, 105d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kLastSeparableMode = kMultiply_Mode, 106d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 107d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kHue_Mode, 108d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSaturation_Mode, 109d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kColor_Mode, 110d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kLuminosity_Mode, 111d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kLastMode = kLuminosity_Mode 112d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed }; 113d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 114d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 115d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * Gets the name of the Mode as a string. 116d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 117d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static const char* ModeName(Mode); 118d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static const char* ModeName(SkBlendMode mode) { 119d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return ModeName(Mode(mode)); 120d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 121d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 122d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 123d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * If the xfermode is one of the modes in the Mode enum, then asMode() 124d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * returns true and sets (if not null) mode accordingly. Otherwise it 125d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * returns false and ignores the mode parameter. 126d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 127d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual bool asMode(Mode* mode) const; 128d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 129d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 130d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * The same as calling xfermode->asMode(mode), except that this also checks 131d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * if the xfermode is NULL, and if so, treats it as kSrcOver_Mode. 132d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 133d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool AsMode(const SkXfermode*, Mode* mode); 134d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool AsMode(const sk_sp<SkXfermode>& xfer, Mode* mode) { 135d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return AsMode(xfer.get(), mode); 136d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 137d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 138d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 139d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * Returns true if the xfermode claims to be the specified Mode. This works 140d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus 141d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * you can say this without checking for a null... 142d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * 143d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * If (SkXfermode::IsMode(paint.getXfermode(), 144d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * SkXfermode::kDstOver_Mode)) { 145d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * ... 146d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * } 147d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 148d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool IsMode(const SkXfermode* xfer, Mode mode); 149d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool IsMode(const sk_sp<SkXfermode>& xfer, Mode mode) { 150d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return IsMode(xfer.get(), mode); 151d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 152d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 153d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** Return an SkXfermode object for the specified mode. 154d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 155d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static sk_sp<SkXfermode> Make(SkBlendMode); 156d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static sk_sp<SkXfermode> Make(Mode m) { return Make((SkBlendMode)m); } 157d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 158d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 159d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * Skia maintains global xfermode objects corresponding to each BlendMode. This returns a 160d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * ptr to that global xfermode (or null if the mode is srcover). Thus the caller may use 161d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * the returned ptr, but it should leave its refcnt untouched. 162d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 163d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static SkXfermode* Peek(SkBlendMode mode) { 164d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed sk_sp<SkXfermode> xfer = Make(mode); 165d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed if (!xfer) { 166d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed SkASSERT(SkBlendMode::kSrcOver == mode); 167d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return nullptr; 168d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 169d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed SkASSERT(!xfer->unique()); 170d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return xfer.get(); 171d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 172d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 173d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed SkBlendMode blend() const { 174d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed Mode mode; 175d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed SkAssertResult(this->asMode(&mode)); 176d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return (SkBlendMode)mode; 177d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 178d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 179d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static SkXfermodeProc GetProc(SkBlendMode); 180d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static SkXfermodeProc4f GetProc4f(SkBlendMode); 181d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 182d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 183d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * If the specified mode can be represented by a pair of Coeff, then return 184d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * true and set (if not NULL) the corresponding coeffs. If the mode is 185d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * not representable as a pair of Coeffs, return false and ignore the 186d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * src and dst parameters. 187d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 188d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst); 189d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool ModeAsCoeff(SkBlendMode mode, Coeff* src, Coeff* dst) { 190d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return ModeAsCoeff((Mode)mode, src, dst); 191d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 192d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 193d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 194d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * Returns whether or not the xfer mode can support treating coverage as alpha 195d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 196d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual bool supportsCoverageAsAlpha() const; 197d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 198d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 199d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * The same as calling xfermode->supportsCoverageAsAlpha(), except that this also checks if 200d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * the xfermode is NULL, and if so, treats it as kSrcOver_Mode. 201d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 202d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool SupportsCoverageAsAlpha(const SkXfermode* xfer); 203d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool SupportsCoverageAsAlpha(const sk_sp<SkXfermode>& xfer) { 204d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return SupportsCoverageAsAlpha(xfer.get()); 205d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 206d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 207d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed enum SrcColorOpacity { 208d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed // The src color is known to be opaque (alpha == 255) 209d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kOpaque_SrcColorOpacity = 0, 210d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed // The src color is known to be fully transparent (color == 0) 211d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kTransparentBlack_SrcColorOpacity = 1, 212d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed // The src alpha is known to be fully transparent (alpha == 0) 213d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kTransparentAlpha_SrcColorOpacity = 2, 214d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed // The src color opacity is unknown 215d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kUnknown_SrcColorOpacity = 3 216d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed }; 217d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 218d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 219d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * Returns whether or not the result of the draw with the xfer mode will be opaque or not. The 220d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * input to this call is an enum describing known information about the opacity of the src color 221d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * that will be given to the xfer mode. 222d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 223d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual bool isOpaque(SrcColorOpacity opacityType) const; 224d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 225d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** 226d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * The same as calling xfermode->isOpaque(...), except that this also checks if 227d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed * the xfermode is NULL, and if so, treats it as kSrcOver_Mode. 228d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 229d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType); 230d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool IsOpaque(const sk_sp<SkXfermode>& xfer, SrcColorOpacity opacityType) { 231d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed return IsOpaque(xfer.get(), opacityType); 232d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed } 233d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static bool IsOpaque(SkBlendMode, SrcColorOpacity); 234d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 235d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#if SK_SUPPORT_GPU 236d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** Used by the SkXfermodeImageFilter to blend two colors via a GrFragmentProcessor. 237d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed The input to the returned FP is the src color. The dst color is 238d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed provided by the dst param which becomes a child FP of the returned FP. 239d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed It is legal for the function to return a null output. This indicates that 240d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed the output of the blend is simply the src color. 241d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 242d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual sk_sp<GrFragmentProcessor> makeFragmentProcessorForImageFilter( 243d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed sk_sp<GrFragmentProcessor> dst) const; 244d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 245d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** A subclass must implement this factory function to work with the GPU backend. 246d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed The xfermode will return a factory for which the caller will get a ref. It is up 247d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed to the caller to install it. XferProcessors cannot use a background texture. 248d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 249a16339297859f37df69230e64f05624cef511ad3Brian Salomon virtual const GrXPFactory* asXPFactory() const; 250d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#endif 251d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 252d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed SK_TO_STRING_PUREVIRT() 253d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() 254d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed SK_DEFINE_FLATTENABLE_TYPE(SkXfermode) 255d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 256d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed enum D32Flags { 257d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcIsOpaque_D32Flag = 1 << 0, 258d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcIsSingle_D32Flag = 1 << 1, 259d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDstIsSRGB_D32Flag = 1 << 2, 260d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed }; 261d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed typedef void (*D32Proc)(SkBlendMode, uint32_t dst[], const SkPM4f src[], 262d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed int count, const SkAlpha coverage[]); 263d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static D32Proc GetD32Proc(SkBlendMode, uint32_t flags); 264d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 265d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed enum F16Flags { 266d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcIsOpaque_F16Flag = 1 << 0, 267d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcIsSingle_F16Flag = 1 << 1, 268d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed }; 269d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed typedef void (*F16Proc)(SkBlendMode, uint64_t dst[], const SkPM4f src[], int count, 270d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed const SkAlpha coverage[]); 271d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static F16Proc GetF16Proc(SkBlendMode, uint32_t flags); 272d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 273d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed enum LCDFlags { 274d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcIsOpaque_LCDFlag = 1 << 0, // else src(s) may have alpha < 1 275d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kSrcIsSingle_LCDFlag = 1 << 1, // else src[count] 276d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kDstIsSRGB_LCDFlag = 1 << 2, // else l32 or f16 277d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed }; 278d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed typedef void (*LCD32Proc)(uint32_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]); 279d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed typedef void (*LCDF16Proc)(uint64_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]); 280d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static LCD32Proc GetLCD32Proc(uint32_t flags); 281d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed static LCDF16Proc GetLCDF16Proc(uint32_t) { return nullptr; } 282d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 283d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual bool isArithmetic(SkArithmeticParams*) const { return false; } 284d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 285d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedprotected: 286d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed SkXfermode() {} 287d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed /** The default implementation of xfer32/xfer16/xferA8 in turn call this 288d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed method, 1 color at a time (upscaled to a SkPMColor). The default 289d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed implementation of this method just returns dst. If performance is 290d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed important, your subclass should override xfer32/xfer16/xferA8 directly. 291d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 292d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed This method will not be called directly by the client, so it need not 293d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed be implemented if your subclass has overridden xfer32/xfer16/xferA8 294d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed */ 295d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const; 296d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 297d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reedprivate: 298d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed enum { 299d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed kModeCount = kLastMode + 1 300d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed }; 301d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 302d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed typedef SkFlattenable INHERITED; 303d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed}; 304d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed 305d47067392848ba132d4e86ffbeebe2dcacda9534Mike Reed#endif 306