aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkXfermodePriv.h
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2016-11-15 16:44:34 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-16 15:38:11 +0000
commitd47067392848ba132d4e86ffbeebe2dcacda9534 (patch)
tree456bd4182524d55f19117d8e726bacca50059fa8 /src/core/SkXfermodePriv.h
parent988283c89458442f65d961f2746a9f271a39c31e (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/SkXfermodePriv.h')
-rw-r--r--src/core/SkXfermodePriv.h311
1 files changed, 311 insertions, 0 deletions
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