LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkXfermodePriv.h (source / functions) Hit Total Coverage
Test: output.info Lines: 5 20 25.0 %
Date: 2017-07-14 16:53:18 Functions: 1 11 9.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13