diff options
author | Mike Reed <reed@google.com> | 2016-11-15 16:44:34 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-16 15:38:11 +0000 |
commit | d47067392848ba132d4e86ffbeebe2dcacda9534 (patch) | |
tree | 456bd4182524d55f19117d8e726bacca50059fa8 /src/core | |
parent | 988283c89458442f65d961f2746a9f271a39c31e (diff) |
make SkXfermode.h go away
This is step one:
- make SkXfermode useless to public clients
- everything they should need is in SkBlendMode.h
Step two:
- remove SkXfermode.h entirely (since skia core will already be using SkXfermodePriv.h)
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4534
Change-Id: If2cea9f71df92430ed6644edb98dd306c5572cbc
Reviewed-on: https://skia-review.googlesource.com/4534
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBitmapProcShader.cpp | 2 | ||||
-rw-r--r-- | src/core/SkBlendModePriv.h | 2 | ||||
-rw-r--r-- | src/core/SkBlitter_A8.cpp | 2 | ||||
-rw-r--r-- | src/core/SkBlitter_ARGB32.cpp | 2 | ||||
-rw-r--r-- | src/core/SkBlitter_PM4f.cpp | 2 | ||||
-rw-r--r-- | src/core/SkBlitter_RGB16.cpp | 2 | ||||
-rw-r--r-- | src/core/SkCoreBlitters.h | 1 | ||||
-rw-r--r-- | src/core/SkLinearBitmapPipeline.h | 2 | ||||
-rw-r--r-- | src/core/SkOpts.h | 2 | ||||
-rw-r--r-- | src/core/SkPaintPriv.cpp | 1 | ||||
-rw-r--r-- | src/core/SkReadBuffer.h | 2 | ||||
-rw-r--r-- | src/core/SkSpriteBlitter4f.cpp | 2 | ||||
-rw-r--r-- | src/core/SkSpriteBlitter_ARGB32.cpp | 2 | ||||
-rw-r--r-- | src/core/SkXfermode.cpp | 4 | ||||
-rw-r--r-- | src/core/SkXfermode4f.cpp | 2 | ||||
-rw-r--r-- | src/core/SkXfermodeF16.cpp | 2 | ||||
-rw-r--r-- | src/core/SkXfermodePriv.h | 311 |
17 files changed, 331 insertions, 12 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index 218e919da3..b17d3e3dff 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -8,6 +8,7 @@ #include "SkBitmapProcShader.h" #include "SkBitmapProcState.h" #include "SkBitmapProvider.h" +#include "SkXfermodePriv.h" static bool only_scale_and_translate(const SkMatrix& matrix) { unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; @@ -102,7 +103,6 @@ private: /////////////////////////////////////////////////////////////////////////////////////////////////// #include "SkLinearBitmapPipeline.h" #include "SkPM4f.h" -#include "SkXfermode.h" class LinearPipelineContext : public BitmapProcInfoContext { public: diff --git a/src/core/SkBlendModePriv.h b/src/core/SkBlendModePriv.h index 29df639842..c4628fd927 100644 --- a/src/core/SkBlendModePriv.h +++ b/src/core/SkBlendModePriv.h @@ -15,6 +15,8 @@ bool SkBlendMode_SupportsCoverageAsAlpha(SkBlendMode); bool SkBlendMode_CanOverflow(SkBlendMode); bool SkBlendMode_AppendStages(SkBlendMode, SkRasterPipeline* = nullptr); +const char* SkBlendMode_Name(SkBlendMode); + #if SK_SUPPORT_GPU #include "GrXferProcessor.h" sk_sp<GrXPFactory> SkBlendMode_AsXPFactory(SkBlendMode); diff --git a/src/core/SkBlitter_A8.cpp b/src/core/SkBlitter_A8.cpp index cb7d718f54..1fd4d5f0d9 100644 --- a/src/core/SkBlitter_A8.cpp +++ b/src/core/SkBlitter_A8.cpp @@ -9,7 +9,7 @@ #include "SkCoreBlitters.h" #include "SkColorPriv.h" #include "SkShader.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" SkA8_Blitter::SkA8_Blitter(const SkPixmap& device, const SkPaint& paint) : INHERITED(device) { fSrcA = paint.getAlpha(); diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index ea0554d66e..958ad27970 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -9,7 +9,7 @@ #include "SkColorPriv.h" #include "SkShader.h" #include "SkUtils.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" #include "SkBlitMask.h" /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp index 2084972262..ce66580659 100644 --- a/src/core/SkBlitter_PM4f.cpp +++ b/src/core/SkBlitter_PM4f.cpp @@ -9,7 +9,7 @@ #include "SkColorPriv.h" #include "SkShader.h" #include "SkUtils.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" #include "SkBlitMask.h" #include "SkTemplates.h" #include "SkPM4f.h" diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp index 7860b7cb6c..015112a107 100644 --- a/src/core/SkBlitter_RGB16.cpp +++ b/src/core/SkBlitter_RGB16.cpp @@ -12,7 +12,7 @@ #include "SkShader.h" #include "SkUtils.h" #include "SkUtilsArm.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" #if defined(__mips_dsp) extern void blitmask_d565_opaque_mips(int width, int height, uint16_t* device, diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h index aa5deb21c1..23fca0f402 100644 --- a/src/core/SkCoreBlitters.h +++ b/src/core/SkCoreBlitters.h @@ -13,6 +13,7 @@ #include "SkBlitRow.h" #include "SkShader.h" #include "SkSmallAllocator.h" +#include "SkXfermodePriv.h" class SkRasterBlitter : public SkBlitter { public: diff --git a/src/core/SkLinearBitmapPipeline.h b/src/core/SkLinearBitmapPipeline.h index ea78489ed8..3e7be5c873 100644 --- a/src/core/SkLinearBitmapPipeline.h +++ b/src/core/SkLinearBitmapPipeline.h @@ -38,7 +38,7 @@ public: SkLinearBitmapPipeline( const SkLinearBitmapPipeline& pipeline, const SkPixmap& srcPixmap, - SkBlendMode blendMode, + SkBlendMode, const SkImageInfo& dstInfo); static bool ClonePipelineForBlitting( diff --git a/src/core/SkOpts.h b/src/core/SkOpts.h index ccd38acc5f..1d5e333729 100644 --- a/src/core/SkOpts.h +++ b/src/core/SkOpts.h @@ -11,7 +11,7 @@ #include "SkRasterPipeline.h" #include "SkTextureCompressor.h" #include "SkTypes.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" #include <functional> struct ProcCoeff; diff --git a/src/core/SkPaintPriv.cpp b/src/core/SkPaintPriv.cpp index cbe2558c2a..ffa818c6e8 100644 --- a/src/core/SkPaintPriv.cpp +++ b/src/core/SkPaintPriv.cpp @@ -11,6 +11,7 @@ #include "SkImage.h" #include "SkPaint.h" #include "SkShader.h" +#include "SkXfermodePriv.h" static bool changes_alpha(const SkPaint& paint) { SkColorFilter* cf = paint.getColorFilter(); diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h index c49b01c5fd..25928d1ba0 100644 --- a/src/core/SkReadBuffer.h +++ b/src/core/SkReadBuffer.h @@ -23,7 +23,7 @@ #include "SkShader.h" #include "SkTHash.h" #include "SkWriteBuffer.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" class SkBitmap; class SkImage; diff --git a/src/core/SkSpriteBlitter4f.cpp b/src/core/SkSpriteBlitter4f.cpp index ddf044e455..977a2647a9 100644 --- a/src/core/SkSpriteBlitter4f.cpp +++ b/src/core/SkSpriteBlitter4f.cpp @@ -8,7 +8,7 @@ #include "SkSpriteBlitter.h" #include "SkSpanProcs.h" #include "SkTemplates.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" class Sprite_4f : public SkSpriteBlitter { public: diff --git a/src/core/SkSpriteBlitter_ARGB32.cpp b/src/core/SkSpriteBlitter_ARGB32.cpp index 1a76b1b2fe..99856a14f9 100644 --- a/src/core/SkSpriteBlitter_ARGB32.cpp +++ b/src/core/SkSpriteBlitter_ARGB32.cpp @@ -11,7 +11,7 @@ #include "SkColorPriv.h" #include "SkTemplates.h" #include "SkUtils.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 64ce04d851..3f3927e742 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -1280,6 +1280,10 @@ const char* SkXfermode::ModeName(Mode mode) { static_assert(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, "mode_count"); } +const char* SkBlendMode_Name(SkBlendMode mode) { + return SkXfermode::ModeName((SkXfermode::Mode)mode); +} + #ifndef SK_IGNORE_TO_STRING void SkProcCoeffXfermode::toString(SkString* str) const { str->append("SkProcCoeffXfermode: "); diff --git a/src/core/SkXfermode4f.cpp b/src/core/SkXfermode4f.cpp index d5bdfe5251..e9d55905a7 100644 --- a/src/core/SkXfermode4f.cpp +++ b/src/core/SkXfermode4f.cpp @@ -7,7 +7,7 @@ #include "SkPM4fPriv.h" #include "SkUtils.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" #include "Sk4x4f.h" static SkPM4f rgba_to_pmcolor_order(const SkPM4f& x) { diff --git a/src/core/SkXfermodeF16.cpp b/src/core/SkXfermodeF16.cpp index 868ee087ca..ece4a097c3 100644 --- a/src/core/SkXfermodeF16.cpp +++ b/src/core/SkXfermodeF16.cpp @@ -8,7 +8,7 @@ #include "SkHalf.h" #include "SkPM4fPriv.h" #include "SkUtils.h" -#include "SkXfermode.h" +#include "SkXfermodePriv.h" static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCoverage) { return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f)); diff --git a/src/core/SkXfermodePriv.h b/src/core/SkXfermodePriv.h new file mode 100644 index 0000000000..b7d85ea98f --- /dev/null +++ b/src/core/SkXfermodePriv.h @@ -0,0 +1,311 @@ +/* + * 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 SkXfermodePriv_DEFINED +#define SkXfermodePriv_DEFINED + +#include "SkBlendMode.h" +#include "SkColor.h" +#include "SkFlattenable.h" + +#ifdef SK_SUPPORT_LEGACY_XFERMODE_IS_PUBLIC +#include "SkXfermode.h" +#else + +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 + +#endif |