diff options
author | Mike Reed <reed@google.com> | 2016-10-03 12:57:32 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-10-03 17:17:10 +0000 |
commit | 0591897548c8fcb7d53cc94053e01702e58f1ac5 (patch) | |
tree | 099bf31c7bf4bd3062d2e7a8b4268a89f1fd61a2 /src | |
parent | a224bb7027f022cf78376cb7afa2fff83d59153e (diff) |
replace SkXfermode obj with SkBlendMode enum in paints
BUG=skia:5814
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2714
Change-Id: I4fb489ba6b3f77b458f7e4a99f79c7ad10859135
Reviewed-on: https://skia-review.googlesource.com/2714
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src')
59 files changed, 488 insertions, 490 deletions
diff --git a/src/c/sk_paint.cpp b/src/c/sk_paint.cpp index f82cd815c1..126170ca4c 100644 --- a/src/c/sk_paint.cpp +++ b/src/c/sk_paint.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "SkBlendMode.h" #include "SkMaskFilter.h" #include "SkPaint.h" #include "SkShader.h" @@ -132,41 +133,41 @@ void sk_paint_set_stroke_join(sk_paint_t* cpaint, sk_stroke_join_t cjoin) { void sk_paint_set_xfermode_mode(sk_paint_t* paint, sk_xfermode_mode_t mode) { SkASSERT(paint); - SkXfermode::Mode skmode; + SkBlendMode skmode; switch (mode) { #define MAP(X, Y) case (X): skmode = (Y); break - MAP( CLEAR_SK_XFERMODE_MODE, SkXfermode::kClear_Mode ); - MAP( SRC_SK_XFERMODE_MODE, SkXfermode::kSrc_Mode ); - MAP( DST_SK_XFERMODE_MODE, SkXfermode::kDst_Mode ); - MAP( SRCOVER_SK_XFERMODE_MODE, SkXfermode::kSrcOver_Mode ); - MAP( DSTOVER_SK_XFERMODE_MODE, SkXfermode::kDstOver_Mode ); - MAP( SRCIN_SK_XFERMODE_MODE, SkXfermode::kSrcIn_Mode ); - MAP( DSTIN_SK_XFERMODE_MODE, SkXfermode::kDstIn_Mode ); - MAP( SRCOUT_SK_XFERMODE_MODE, SkXfermode::kSrcOut_Mode ); - MAP( DSTOUT_SK_XFERMODE_MODE, SkXfermode::kDstOut_Mode ); - MAP( SRCATOP_SK_XFERMODE_MODE, SkXfermode::kSrcATop_Mode ); - MAP( DSTATOP_SK_XFERMODE_MODE, SkXfermode::kDstATop_Mode ); - MAP( XOR_SK_XFERMODE_MODE, SkXfermode::kXor_Mode ); - MAP( PLUS_SK_XFERMODE_MODE, SkXfermode::kPlus_Mode ); - MAP( MODULATE_SK_XFERMODE_MODE, SkXfermode::kModulate_Mode ); - MAP( SCREEN_SK_XFERMODE_MODE, SkXfermode::kScreen_Mode ); - MAP( OVERLAY_SK_XFERMODE_MODE, SkXfermode::kOverlay_Mode ); - MAP( DARKEN_SK_XFERMODE_MODE, SkXfermode::kDarken_Mode ); - MAP( LIGHTEN_SK_XFERMODE_MODE, SkXfermode::kLighten_Mode ); - MAP( COLORDODGE_SK_XFERMODE_MODE, SkXfermode::kColorDodge_Mode ); - MAP( COLORBURN_SK_XFERMODE_MODE, SkXfermode::kColorBurn_Mode ); - MAP( HARDLIGHT_SK_XFERMODE_MODE, SkXfermode::kHardLight_Mode ); - MAP( SOFTLIGHT_SK_XFERMODE_MODE, SkXfermode::kSoftLight_Mode ); - MAP( DIFFERENCE_SK_XFERMODE_MODE, SkXfermode::kDifference_Mode ); - MAP( EXCLUSION_SK_XFERMODE_MODE, SkXfermode::kExclusion_Mode ); - MAP( MULTIPLY_SK_XFERMODE_MODE, SkXfermode::kMultiply_Mode ); - MAP( HUE_SK_XFERMODE_MODE, SkXfermode::kHue_Mode ); - MAP( SATURATION_SK_XFERMODE_MODE, SkXfermode::kSaturation_Mode ); - MAP( COLOR_SK_XFERMODE_MODE, SkXfermode::kColor_Mode ); - MAP( LUMINOSITY_SK_XFERMODE_MODE, SkXfermode::kLuminosity_Mode ); + MAP( CLEAR_SK_XFERMODE_MODE, SkBlendMode::kClear ); + MAP( SRC_SK_XFERMODE_MODE, SkBlendMode::kSrc ); + MAP( DST_SK_XFERMODE_MODE, SkBlendMode::kDst ); + MAP( SRCOVER_SK_XFERMODE_MODE, SkBlendMode::kSrcOver ); + MAP( DSTOVER_SK_XFERMODE_MODE, SkBlendMode::kDstOver ); + MAP( SRCIN_SK_XFERMODE_MODE, SkBlendMode::kSrcIn ); + MAP( DSTIN_SK_XFERMODE_MODE, SkBlendMode::kDstIn ); + MAP( SRCOUT_SK_XFERMODE_MODE, SkBlendMode::kSrcOut ); + MAP( DSTOUT_SK_XFERMODE_MODE, SkBlendMode::kDstOut ); + MAP( SRCATOP_SK_XFERMODE_MODE, SkBlendMode::kSrcATop ); + MAP( DSTATOP_SK_XFERMODE_MODE, SkBlendMode::kDstATop ); + MAP( XOR_SK_XFERMODE_MODE, SkBlendMode::kXor ); + MAP( PLUS_SK_XFERMODE_MODE, SkBlendMode::kPlus ); + MAP( MODULATE_SK_XFERMODE_MODE, SkBlendMode::kModulate ); + MAP( SCREEN_SK_XFERMODE_MODE, SkBlendMode::kScreen ); + MAP( OVERLAY_SK_XFERMODE_MODE, SkBlendMode::kOverlay ); + MAP( DARKEN_SK_XFERMODE_MODE, SkBlendMode::kDarken ); + MAP( LIGHTEN_SK_XFERMODE_MODE, SkBlendMode::kLighten ); + MAP( COLORDODGE_SK_XFERMODE_MODE, SkBlendMode::kColorDodge ); + MAP( COLORBURN_SK_XFERMODE_MODE, SkBlendMode::kColorBurn ); + MAP( HARDLIGHT_SK_XFERMODE_MODE, SkBlendMode::kHardLight ); + MAP( SOFTLIGHT_SK_XFERMODE_MODE, SkBlendMode::kSoftLight ); + MAP( DIFFERENCE_SK_XFERMODE_MODE, SkBlendMode::kDifference ); + MAP( EXCLUSION_SK_XFERMODE_MODE, SkBlendMode::kExclusion ); + MAP( MULTIPLY_SK_XFERMODE_MODE, SkBlendMode::kMultiply ); + MAP( HUE_SK_XFERMODE_MODE, SkBlendMode::kHue ); + MAP( SATURATION_SK_XFERMODE_MODE, SkBlendMode::kSaturation ); + MAP( COLOR_SK_XFERMODE_MODE, SkBlendMode::kColor ); + MAP( LUMINOSITY_SK_XFERMODE_MODE, SkBlendMode::kLuminosity ); #undef MAP default: return; } - AsPaint(paint)->setXfermodeMode(skmode); + AsPaint(paint)->setBlendMode(skmode); } diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp index 440de68345..26d253cf38 100644 --- a/src/core/SkBitmapDevice.cpp +++ b/src/core/SkBitmapDevice.cpp @@ -446,7 +446,7 @@ bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const { paint.getPathEffect() || paint.isFakeBoldText() || paint.getStyle() != SkPaint::kFill_Style || - !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)) + !paint.isSrcOver()) { return true; } diff --git a/src/core/SkBlendModePriv.h b/src/core/SkBlendModePriv.h new file mode 100644 index 0000000000..b5d9e751e6 --- /dev/null +++ b/src/core/SkBlendModePriv.h @@ -0,0 +1,19 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBlendModePriv_DEFINED +#define SkBlendModePriv_DEFINED + +#include "SkBlendMode.h" + +bool SkBlendMode_SupportsCoverageAsAlpha(SkBlendMode); + +#if SK_SUPPORT_GPU +sk_sp<GrXPFactory> SkBlendMode_AsXPFactory(SkBlendMode); +#endif + +#endif diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index db9fcda93b..ce689d7e84 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -810,7 +810,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, SkShader* shader = origPaint.getShader(); SkColorFilter* cf = origPaint.getColorFilter(); - SkXfermode* mode = origPaint.getXfermode(); + SkBlendMode mode = origPaint.getBlendMode(); sk_sp<Sk3DShader> shader3D; SkTCopyOnFirstWrite<SkPaint> paint(origPaint); @@ -823,12 +823,12 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, shader = shader3D.get(); } - if (mode) { + if (mode != SkBlendMode::kSrcOver) { bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType(); switch (SkInterpretXfermode(*paint, deviceIsOpaque)) { case kSrcOver_SkXfermodeInterpretation: - mode = nullptr; - paint.writable()->setXfermode(nullptr); + mode = SkBlendMode::kSrcOver; + paint.writable()->setBlendMode(mode); break; case kSkipDrawing_SkXfermodeInterpretation:{ return allocator->createT<SkNullBlitter>(); @@ -843,13 +843,13 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, * color/shader/colorfilter, and just pretend we're SRC + color==0. This * will fall into our optimizations for SRC mode. */ - if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) { + if (mode == SkBlendMode::kClear) { SkPaint* p = paint.writable(); p->setShader(nullptr); shader = nullptr; p->setColorFilter(nullptr); cf = nullptr; - mode = p->setXfermodeMode(SkXfermode::kSrc_Mode); + p->setBlendMode(mode = SkBlendMode::kSrc); p->setColor(0); } @@ -858,7 +858,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, } if (nullptr == shader) { - if (mode) { + if (mode != SkBlendMode::kSrcOver) { // xfermodes (and filters) require shaders for our current blitters paint.writable()->setShader(SkShader::MakeColorShader(paint->getColor())); paint.writable()->setAlpha(0xFF); @@ -909,7 +909,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, case kAlpha_8_SkColorType: if (drawCoverage) { SkASSERT(nullptr == shader); - SkASSERT(nullptr == paint->getXfermode()); + SkASSERT(paint->isSrcOver()); blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint); } else if (shader) { blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint, shaderContext); diff --git a/src/core/SkBlitter_A8.cpp b/src/core/SkBlitter_A8.cpp index 66976143c8..cb7d718f54 100644 --- a/src/core/SkBlitter_A8.cpp +++ b/src/core/SkBlitter_A8.cpp @@ -230,10 +230,8 @@ SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint& SkShader::Context* shaderContext) : INHERITED(device, paint, shaderContext) { - if ((fXfermode = paint.getXfermode()) != nullptr) { - fXfermode->ref(); - SkASSERT(fShaderContext); - } + fXfermode = SkXfermode::Peek(paint.getBlendMode()); + SkASSERT(!fXfermode || fShaderContext); int width = device.width(); fBuffer = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * (width + (SkAlign4(width) >> 2))); @@ -241,7 +239,6 @@ SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint& } SkA8_Shader_Blitter::~SkA8_Shader_Blitter() { - if (fXfermode) SkSafeUnref(fXfermode); sk_free(fBuffer); } @@ -355,7 +352,7 @@ void SkA8_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) { SkA8_Coverage_Blitter::SkA8_Coverage_Blitter(const SkPixmap& device, const SkPaint& paint) : SkRasterBlitter(device) { SkASSERT(nullptr == paint.getShader()); - SkASSERT(nullptr == paint.getXfermode()); + SkASSERT(paint.isSrcOver()); SkASSERT(nullptr == paint.getColorFilter()); } diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index aada0586a4..ea0554d66e 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -339,8 +339,7 @@ SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, { fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor))); - fXfermode = paint.getXfermode(); - SkSafeRef(fXfermode); + fXfermode = SkXfermode::Peek(paint.getBlendMode()); int flags = 0; if (!(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) { @@ -370,7 +369,6 @@ SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, } SkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() { - SkSafeUnref(fXfermode); sk_free(fBuffer); } diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp index 455a97b95d..d63e924e2c 100644 --- a/src/core/SkBlitter_PM4f.cpp +++ b/src/core/SkBlitter_PM4f.cpp @@ -325,7 +325,7 @@ static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderConte struct State4f { State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) { - fXfer = paint.getXfermode(); + fXfer = SkXfermode::Peek(paint.getBlendMode()); if (shaderContext) { fBuffer.reset(info.width()); } else { @@ -410,7 +410,7 @@ template <typename State> SkBlitter* create(const SkPixmap& device, const SkPain SkShader::Context::BlitState bstate; sk_bzero(&bstate, sizeof(bstate)); bstate.fCtx = shaderContext; - bstate.fXfer = paint.getXfermode(); + bstate.fXfer = SkXfermode::Peek(paint.getBlendMode()); (void)shaderContext->chooseBlitProcs(device.info(), &bstate); return allocator->createT<SkState_Shader_Blitter<State>>(device, paint, bstate); diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp index 066ec616de..7860b7cb6c 100644 --- a/src/core/SkBlitter_RGB16.cpp +++ b/src/core/SkBlitter_RGB16.cpp @@ -160,7 +160,7 @@ SkRGB16_Black_Blitter::SkRGB16_Black_Blitter(const SkPixmap& device, const SkPai : INHERITED(device, paint) { SkASSERT(paint.getShader() == nullptr); SkASSERT(paint.getColorFilter() == nullptr); - SkASSERT(paint.getXfermode() == nullptr); + SkASSERT(paint.isSrcOver()); SkASSERT(paint.getColor() == SK_ColorBLACK); } @@ -683,7 +683,7 @@ SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkPixmap& device, SkShader::Context* shaderContext) : INHERITED(device, paint, shaderContext) { - SkASSERT(paint.getXfermode() == nullptr); + SkASSERT(paint.isSrcOver()); fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); @@ -809,9 +809,8 @@ SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( SkShader::Context* shaderContext) : INHERITED(device, paint, shaderContext) { - fXfermode = paint.getXfermode(); + fXfermode = SkXfermode::Peek(paint.getBlendMode()); SkASSERT(fXfermode); - fXfermode->ref(); int width = device.width(); fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * sizeof(SkPMColor)); @@ -819,7 +818,6 @@ SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( } SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() { - fXfermode->unref(); sk_free(fBuffer); } @@ -897,14 +895,14 @@ SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint, SkBlitter* blitter; SkShader* shader = paint.getShader(); - SkXfermode* mode = paint.getXfermode(); + bool is_srcover = paint.isSrcOver(); // we require a shader if there is an xfermode, handled by our caller - SkASSERT(nullptr == mode || shader); + SkASSERT(is_srcover || shader); if (shader) { SkASSERT(shaderContext != nullptr); - if (mode) { + if (!is_srcover) { blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device, paint, shaderContext); } else { diff --git a/src/core/SkBlitter_Sprite.cpp b/src/core/SkBlitter_Sprite.cpp index 950f18791f..cef4cfaa2f 100644 --- a/src/core/SkBlitter_Sprite.cpp +++ b/src/core/SkBlitter_Sprite.cpp @@ -68,14 +68,11 @@ public: if (0xFF != paint.getAlpha()) { return false; } - SkXfermode::Mode mode; - if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { - return false; - } - if (SkXfermode::kSrc_Mode == mode) { + SkBlendMode mode = paint.getBlendMode(); + if (SkBlendMode::kSrc == mode) { return true; } - if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) { + if (SkBlendMode::kSrcOver == mode && src.isOpaque()) { return true; } @@ -85,7 +82,7 @@ public: return false; } - return SkXfermode::kSrcOver_Mode == mode; + return SkBlendMode::kSrcOver == mode; } SkSpriteBlitter_Src_SrcOver(const SkPixmap& src) @@ -94,14 +91,11 @@ public: void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override { SkASSERT(Supports(dst, fSource, paint)); this->INHERITED::setup(dst, left, top, paint); - SkXfermode::Mode mode; - if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { - SkFAIL("Should never happen."); - } + SkBlendMode mode = paint.getBlendMode(); - SkASSERT(mode == SkXfermode::kSrcOver_Mode || mode == SkXfermode::kSrc_Mode); + SkASSERT(mode == SkBlendMode::kSrcOver || mode == SkBlendMode::kSrc); - if (mode == SkXfermode::kSrcOver_Mode && !fSource.isOpaque()) { + if (mode == SkBlendMode::kSrcOver && !fSource.isOpaque()) { fUseMemcpy = false; } } diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 7597c7a07a..38ec770fb2 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -484,7 +484,7 @@ public: */ SkPaint tmp; tmp.setImageFilter(fPaint->getImageFilter()); - tmp.setXfermode(sk_ref_sp(fPaint->getXfermode())); + tmp.setBlendMode(fPaint->getBlendMode()); SkRect storage; if (rawBounds) { // Make rawBounds include all paint outsets except for those due to image filters. @@ -558,7 +558,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { if (fTempLayerForImageFilter) { paint->setImageFilter(nullptr); - paint->setXfermode(nullptr); + paint->setBlendMode(SkBlendMode::kSrcOver); } if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { @@ -2690,7 +2690,7 @@ void SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, // nothing to draw if (text == nullptr || byteLength == 0 || draw.fRC->isEmpty() || - (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) { + (paint.getAlpha() == 0 && paint.isSrcOver())) { return; } @@ -2999,26 +2999,21 @@ void SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* va // methods, rather than actually drawing themselves. ////////////////////////////////////////////////////////////////////////////// -void SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, - SkXfermode::Mode mode) { +void SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkBlendMode mode) { TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); SkPaint paint; paint.setARGB(a, r, g, b); - if (SkXfermode::kSrcOver_Mode != mode) { - paint.setXfermodeMode(mode); - } + paint.setBlendMode(mode); this->drawPaint(paint); } -void SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { +void SkCanvas::drawColor(SkColor c, SkBlendMode mode) { TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); SkPaint paint; paint.setColor(c); - if (SkXfermode::kSrcOver_Mode != mode) { - paint.setXfermodeMode(mode); - } + paint.setBlendMode(mode); this->drawPaint(paint); } diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 34c7d73b3e..c6c5cf3c81 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -7,6 +7,7 @@ #define __STDC_LIMIT_MACROS #include "SkDraw.h" +#include "SkBlendModePriv.h" #include "SkBlitter.h" #include "SkCanvas.h" #include "SkColorPriv.h" @@ -163,31 +164,27 @@ static BitmapXferProc ChooseBitmapXferProc(const SkPixmap& dst, const SkPaint& p return nullptr; } - SkXfermode::Mode mode; - if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { - return nullptr; - } - + SkBlendMode mode = paint.getBlendMode(); SkColor color = paint.getColor(); // collaps modes based on color... - if (SkXfermode::kSrcOver_Mode == mode) { + if (SkBlendMode::kSrcOver == mode) { unsigned alpha = SkColorGetA(color); if (0 == alpha) { - mode = SkXfermode::kDst_Mode; + mode = SkBlendMode::kDst; } else if (0xFF == alpha) { - mode = SkXfermode::kSrc_Mode; + mode = SkBlendMode::kSrc; } } switch (mode) { - case SkXfermode::kClear_Mode: + case SkBlendMode::kClear: // SkDebugf("--- D_Clear_BitmapXferProc\n"); return D_Clear_BitmapXferProc; // ignore data - case SkXfermode::kDst_Mode: + case SkBlendMode::kDst: // SkDebugf("--- D_Dst_BitmapXferProc\n"); return D_Dst_BitmapXferProc; // ignore data - case SkXfermode::kSrc_Mode: { + case SkBlendMode::kSrc: { /* should I worry about dithering for the lower depths? */ @@ -1143,7 +1140,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint, if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) { if (SK_Scalar1 == coverage) { paint.writable()->setStrokeWidth(0); - } else if (SkXfermode::SupportsCoverageAsAlpha(origPaint.getXfermode())) { + } else if (SkBlendMode_SupportsCoverageAsAlpha(origPaint.getBlendMode())) { U8CPU newAlpha; #if 0 newAlpha = SkToU8(SkScalarRoundToInt(coverage * diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp index 5b29884c25..ec3b0a9909 100644 --- a/src/core/SkGpuBlurUtils.cpp +++ b/src/core/SkGpuBlurUtils.cpp @@ -80,7 +80,7 @@ static void convolve_gaussian_1d(GrDrawContext* drawContext, sk_sp<GrFragmentProcessor> conv(GrConvolutionEffect::MakeGaussian( texture, direction, radius, sigma, useBounds, bounds)); paint.addColorFragmentProcessor(std::move(conv)); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()), -SkIntToScalar(srcOffset.y())); drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), @@ -110,7 +110,7 @@ static void convolve_gaussian_2d(GrDrawContext* drawContext, srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_Mode, true, sigmaX, sigmaY)); paint.addColorFragmentProcessor(std::move(conv)); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), SkRect::Make(dstRect), localMatrix); } @@ -285,7 +285,7 @@ sk_sp<GrDrawContext> GaussianBlur(GrContext* context, GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); paint.addColorTextureProcessor(srcTexture.get(), nullptr, matrix, params); } - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); shrink_irect_by_2(&dstRect, i < scaleFactorX, i < scaleFactorY); dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), @@ -361,7 +361,7 @@ sk_sp<GrDrawContext> GaussianBlur(GrContext* context, GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); sk_sp<GrTexture> tex(srcDrawContext->asTexture()); paint.addColorTextureProcessor(tex.get(), nullptr, matrix, params); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); SkIRect dstRect(srcRect); scale_irect(&dstRect, scaleFactorX, scaleFactorY); diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index 63095bc65d..68183cc444 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -281,7 +281,7 @@ sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context, const OutputProperties& outputProperties) { GrPaint paint; paint.addColorFragmentProcessor(std::move(fp)); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); sk_sp<SkColorSpace> colorSpace = sk_ref_sp(outputProperties.colorSpace()); GrPixelConfig config = GrRenderableConfigForColorSpace(colorSpace.get()); diff --git a/src/core/SkMatrixImageFilter.cpp b/src/core/SkMatrixImageFilter.cpp index 12efc64683..0a33280414 100644 --- a/src/core/SkMatrixImageFilter.cpp +++ b/src/core/SkMatrixImageFilter.cpp @@ -85,7 +85,7 @@ sk_sp<SkSpecialImage> SkMatrixImageFilter::onFilterImage(SkSpecialImage* source, SkPaint paint; paint.setAntiAlias(true); - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); paint.setFilterQuality(fFilterQuality); input->draw(canvas, srcRect.x(), srcRect.y(), &paint); diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 9d76a169b3..83e45c058d 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -52,6 +52,7 @@ SkPaint::SkPaint() { fColor = SK_ColorBLACK; fWidth = 0; fMiterLimit = SkPaintDefaults_MiterLimit; + fBlendMode = (unsigned)SkBlendMode::kSrcOver; // Zero all bitfields, then set some non-zero defaults. fBitfieldsUInt = 0; @@ -69,7 +70,6 @@ SkPaint::SkPaint(const SkPaint& src) : COPY(fTypeface) , COPY(fPathEffect) , COPY(fShader) - , COPY(fXfermode) , COPY(fMaskFilter) , COPY(fColorFilter) , COPY(fRasterizer) @@ -81,6 +81,7 @@ SkPaint::SkPaint(const SkPaint& src) , COPY(fColor) , COPY(fWidth) , COPY(fMiterLimit) + , COPY(fBlendMode) , COPY(fBitfields) #undef COPY {} @@ -90,7 +91,6 @@ SkPaint::SkPaint(SkPaint&& src) { MOVE(fTypeface); MOVE(fPathEffect); MOVE(fShader); - MOVE(fXfermode); MOVE(fMaskFilter); MOVE(fColorFilter); MOVE(fRasterizer); @@ -102,6 +102,7 @@ SkPaint::SkPaint(SkPaint&& src) { MOVE(fColor); MOVE(fWidth); MOVE(fMiterLimit); + MOVE(fBlendMode); MOVE(fBitfields); #undef MOVE } @@ -117,7 +118,6 @@ SkPaint& SkPaint::operator=(const SkPaint& src) { ASSIGN(fTypeface); ASSIGN(fPathEffect); ASSIGN(fShader); - ASSIGN(fXfermode); ASSIGN(fMaskFilter); ASSIGN(fColorFilter); ASSIGN(fRasterizer); @@ -129,6 +129,7 @@ SkPaint& SkPaint::operator=(const SkPaint& src) { ASSIGN(fColor); ASSIGN(fWidth); ASSIGN(fMiterLimit); + ASSIGN(fBlendMode); ASSIGN(fBitfields); #undef ASSIGN @@ -144,7 +145,6 @@ SkPaint& SkPaint::operator=(SkPaint&& src) { MOVE(fTypeface); MOVE(fPathEffect); MOVE(fShader); - MOVE(fXfermode); MOVE(fMaskFilter); MOVE(fColorFilter); MOVE(fRasterizer); @@ -156,6 +156,7 @@ SkPaint& SkPaint::operator=(SkPaint&& src) { MOVE(fColor); MOVE(fWidth); MOVE(fMiterLimit); + MOVE(fBlendMode); MOVE(fBitfields); #undef MOVE @@ -167,7 +168,6 @@ bool operator==(const SkPaint& a, const SkPaint& b) { return EQUAL(fTypeface) && EQUAL(fPathEffect) && EQUAL(fShader) - && EQUAL(fXfermode) && EQUAL(fMaskFilter) && EQUAL(fColorFilter) && EQUAL(fRasterizer) @@ -179,6 +179,7 @@ bool operator==(const SkPaint& a, const SkPaint& b) { && EQUAL(fColor) && EQUAL(fWidth) && EQUAL(fMiterLimit) + && EQUAL(fBlendMode) && EQUAL(fBitfieldsUInt) ; #undef EQUAL @@ -360,7 +361,6 @@ MOVE_FIELD(Rasterizer) MOVE_FIELD(ImageFilter) MOVE_FIELD(Shader) MOVE_FIELD(ColorFilter) -MOVE_FIELD(Xfermode) MOVE_FIELD(PathEffect) MOVE_FIELD(MaskFilter) MOVE_FIELD(DrawLooper) @@ -385,9 +385,6 @@ SET_PTR(Shader) #ifdef SK_SUPPORT_LEGACY_COLORFILTER_PTR SET_PTR(ColorFilter) #endif -#ifdef SK_SUPPORT_LEGACY_XFERMODE_PTR -SET_PTR(Xfermode) -#endif #ifdef SK_SUPPORT_LEGACY_PATHEFFECT_PTR SET_PTR(PathEffect) #endif @@ -403,10 +400,18 @@ SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { } #endif +#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT +void SkPaint::setXfermode(sk_sp<SkXfermode> mode) { + this->setBlendMode(mode ? mode->blend() : SkBlendMode::kSrcOver); +} +SkXfermode* SkPaint::getXfermode() const { + return SkXfermode::Peek((SkBlendMode)fBlendMode); +} SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { - fXfermode = SkXfermode::Make(mode); - return fXfermode.get(); // can/should we change this API to be void, like the other setters? + this->setBlendMode((SkBlendMode)mode); + return SkXfermode::Peek((SkBlendMode)mode); } +#endif /////////////////////////////////////////////////////////////////////////////// @@ -1904,7 +1909,6 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const { } if (asint(this->getPathEffect()) | asint(this->getShader()) | - asint(this->getXfermode()) | asint(this->getMaskFilter()) | asint(this->getColorFilter()) | asint(this->getRasterizer()) | @@ -1923,7 +1927,8 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const { buffer.writeUInt(pack_paint_flags(this->getFlags(), this->getHinting(), this->getTextAlign(), this->getFilterQuality(), flatFlags)); buffer.writeUInt(pack_4(this->getStrokeCap(), this->getStrokeJoin(), - this->getStyle(), this->getTextEncoding())); + (this->getStyle() << 4) | this->getTextEncoding(), + fBlendMode)); // now we're done with ptr and the (pre)reserved space. If we need to write // additional fields, use the buffer directly @@ -1933,7 +1938,6 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const { if (flatFlags & kHasEffects_FlatFlag) { buffer.writeFlattenable(this->getPathEffect()); buffer.writeFlattenable(this->getShader()); - buffer.writeFlattenable(this->getXfermode()); buffer.writeFlattenable(this->getMaskFilter()); buffer.writeFlattenable(this->getColorFilter()); buffer.writeFlattenable(this->getRasterizer()); @@ -1955,8 +1959,14 @@ void SkPaint::unflatten(SkReadBuffer& buffer) { uint32_t tmp = buffer.readUInt(); this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); - this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); - this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); + if (buffer.isVersionLT(SkReadBuffer::kXfermodeToBlendMode_Version)) { + this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); + this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); + } else { + this->setStyle(static_cast<Style>((tmp >> 12) & 0xF)); + this->setTextEncoding(static_cast<TextEncoding>((tmp >> 8) & 0xF)); + this->setBlendMode((SkBlendMode)(tmp & 0xFF)); + } if (flatFlags & kHasTypeface_FlatFlag) { this->setTypeface(buffer.readTypeface()); @@ -1967,7 +1977,16 @@ void SkPaint::unflatten(SkReadBuffer& buffer) { if (flatFlags & kHasEffects_FlatFlag) { this->setPathEffect(buffer.readPathEffect()); this->setShader(buffer.readShader()); - this->setXfermode(buffer.readXfermode()); + if (buffer.isVersionLT(SkReadBuffer::kXfermodeToBlendMode_Version)) { + sk_sp<SkXfermode> xfer = buffer.readXfermode(); + if (xfer) { + SkXfermode::Mode mode; + if (!xfer->asMode(&mode)) { + mode = SkXfermode::kSrcOver_Mode; + } + this->setBlendMode((SkBlendMode)mode); + } + } this->setMaskFilter(buffer.readMaskFilter()); this->setColorFilter(buffer.readColorFilter()); this->setRasterizer(buffer.readRasterizer()); @@ -1986,7 +2005,6 @@ void SkPaint::unflatten(SkReadBuffer& buffer) { } else { this->setPathEffect(nullptr); this->setShader(nullptr); - this->setXfermode(nullptr); this->setMaskFilter(nullptr); this->setColorFilter(nullptr); this->setRasterizer(nullptr); @@ -2116,11 +2134,8 @@ void SkPaint::toString(SkString* str) const { str->append("</dd>"); } - SkXfermode* xfer = this->getXfermode(); - if (xfer) { - str->append("<dt>Xfermode:</dt><dd>"); - xfer->toString(str); - str->append("</dd>"); + if (!this->isSrcOver()) { + str->appendf("<dt>Xfermode:</dt><dd>%d</dd>", fBlendMode); } SkMaskFilter* maskFilter = this->getMaskFilter(); @@ -2363,23 +2378,20 @@ bool SkPaint::nothingToDraw() const { if (fDrawLooper) { return false; } - SkXfermode::Mode mode; - if (SkXfermode::AsMode(fXfermode.get(), &mode)) { - switch (mode) { - case SkXfermode::kSrcOver_Mode: - case SkXfermode::kSrcATop_Mode: - case SkXfermode::kDstOut_Mode: - case SkXfermode::kDstOver_Mode: - case SkXfermode::kPlus_Mode: - if (0 == this->getAlpha()) { - return !affects_alpha(fColorFilter.get()) && !affects_alpha(fImageFilter.get()); - } - break; - case SkXfermode::kDst_Mode: - return true; - default: - break; - } + switch ((SkBlendMode)fBlendMode) { + case SkBlendMode::kSrcOver: + case SkBlendMode::kSrcATop: + case SkBlendMode::kDstOut: + case SkBlendMode::kDstOver: + case SkBlendMode::kPlus: + if (0 == this->getAlpha()) { + return !affects_alpha(fColorFilter.get()) && !affects_alpha(fImageFilter.get()); + } + break; + case SkBlendMode::kDst: + return true; + default: + break; } return false; } @@ -2387,7 +2399,7 @@ bool SkPaint::nothingToDraw() const { uint32_t SkPaint::getHash() const { // We're going to hash 10 pointers and 7 32-bit values, finishing up with fBitfields, // so fBitfields should be 10 pointers and 6 32-bit values from the start. - static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * sizeof(uint32_t), + static_assert(offsetof(SkPaint, fBitfields) == 8 * sizeof(void*) + 7 * sizeof(uint32_t), "SkPaint_notPackedTightly"); return SkOpts::hash(reinterpret_cast<const uint32_t*>(this), offsetof(SkPaint, fBitfields) + sizeof(fBitfields)); diff --git a/src/core/SkPaintPriv.cpp b/src/core/SkPaintPriv.cpp index 6725cb49be..cbe2558c2a 100644 --- a/src/core/SkPaintPriv.cpp +++ b/src/core/SkPaintPriv.cpp @@ -41,7 +41,7 @@ bool SkPaintPriv::Overwrites(const SkPaint* paint, ShaderOverrideOpacity overrid } } - return SkXfermode::IsOpaque(paint->getXfermode(), opacityType); + return SkXfermode::IsOpaque(paint->getBlendMode(), opacityType); } bool SkPaintPriv::Overwrites(const SkBitmap& bitmap, const SkPaint* paint) { diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp index 77498396b0..108c87757b 100644 --- a/src/core/SkPixmap.cpp +++ b/src/core/SkPixmap.cpp @@ -267,7 +267,7 @@ bool SkPixmap::scalePixels(const SkPixmap& dst, SkFilterQuality quality) const { SkPaint paint; paint.setFilterQuality(quality); - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); surface->getCanvas()->drawBitmapRect(bitmap, SkRect::MakeIWH(dst.width(), dst.height()), &paint); return true; diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp index 1e8dcf59e0..91d60bee3a 100644 --- a/src/core/SkRasterPipelineBlitter.cpp +++ b/src/core/SkRasterPipelineBlitter.cpp @@ -82,8 +82,8 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, } SkRasterPipeline shader, colorFilter, xfermode; - if (!append_effect_stages(paint.getColorFilter(), &colorFilter) || - !append_effect_stages(paint.getXfermode(), &xfermode )) { + if (!append_effect_stages(paint.getColorFilter(), &colorFilter) || + !append_effect_stages(SkXfermode::Peek(paint.getBlendMode()), &xfermode )) { return nullptr; } @@ -104,7 +104,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, if (!paint.getShader()) { blitter->fShader.append(SkRasterPipeline::constant_color, &blitter->fPaintColor); } - if (!paint.getXfermode()) { + if (paint.isSrcOver()) { blitter->fXfermode.append(SkRasterPipeline::srcover); } diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h index 3e6742fde0..4ac7973198 100644 --- a/src/core/SkReadBuffer.h +++ b/src/core/SkReadBuffer.h @@ -69,6 +69,7 @@ public: kLightingShaderWritesInvNormRotation = 45, kBlurMaskFilterWritesOccluder = 47, kGradientShaderFloatColor_Version = 49, + kXfermodeToBlendMode_Version = 50, }; /** diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index ca9c1b6f78..dca19df100 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -341,34 +341,27 @@ private: return true; } - // Unusual Xfermodes require us to process a saved layer + // Unusual blendmodes require us to process a saved layer // even with operations outisde the clip. // For example, DstIn is used by masking layers. // https://code.google.com/p/skia/issues/detail?id=1291 // https://crbug.com/401593 - SkXfermode* xfermode = paint->getXfermode(); - SkXfermode::Mode mode; - // SrcOver is ok, and is also the common case with a nullptr xfermode. - // So we should make that the fast path and bypass the mode extraction - // and test. - if (xfermode && xfermode->asMode(&mode)) { - switch (mode) { - // For each of the following transfer modes, if the source - // alpha is zero (our transparent black), the resulting - // blended alpha is not necessarily equal to the original - // destination alpha. - case SkXfermode::kClear_Mode: - case SkXfermode::kSrc_Mode: - case SkXfermode::kSrcIn_Mode: - case SkXfermode::kDstIn_Mode: - case SkXfermode::kSrcOut_Mode: - case SkXfermode::kDstATop_Mode: - case SkXfermode::kModulate_Mode: - return true; - break; - default: - break; - } + switch (paint->getBlendMode()) { + // For each of the following transfer modes, if the source + // alpha is zero (our transparent black), the resulting + // blended alpha is not necessarily equal to the original + // destination alpha. + case SkBlendMode::kClear: + case SkBlendMode::kSrc: + case SkBlendMode::kSrcIn: + case SkBlendMode::kDstIn: + case SkBlendMode::kSrcOut: + case SkBlendMode::kDstATop: + case SkBlendMode::kModulate: + return true; + break; + default: + break; } } return false; diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp index d46a6573b5..a7feec1fb3 100644 --- a/src/core/SkRecordOpts.cpp +++ b/src/core/SkRecordOpts.cpp @@ -98,7 +98,7 @@ static bool fold_opacity_layer_color_to_paint(const SkPaint* layerPaint, // looper drawing unmodulated filter layer twice and then modulating the result produces // different image to drawing modulated filter layer twice. // TODO: most likely the looper and only some xfer modes are the hard constraints - if (paint->getXfermode() || paint->getLooper()) { + if (!paint->isSrcOver() || paint->getLooper()) { return false; } @@ -129,9 +129,9 @@ static bool fold_opacity_layer_color_to_paint(const SkPaint* layerPaint, } // The layer paint can not have any effects. - if (layerPaint->getPathEffect() || + if (layerPaint->getPathEffect() || layerPaint->getShader() || - layerPaint->getXfermode() || + !layerPaint->isSrcOver() || layerPaint->getMaskFilter() || layerPaint->getColorFilter() || layerPaint->getRasterizer() || @@ -174,16 +174,12 @@ void SkRecordNoopSaveRestores(SkRecord* record) { } static bool effectively_srcover(const SkPaint* paint) { - if (!paint) { - return true; - } - SkXfermode* mode = paint->getXfermode(); - if (SkXfermode::IsMode(mode, SkXfermode::kSrcOver_Mode)) { + if (!paint || paint->isSrcOver()) { return true; } // src-mode with opaque and no effects (which might change opaqueness) is ok too. return !paint->getShader() && !paint->getColorFilter() && !paint->getImageFilter() && - 0xFF == paint->getAlpha() && SkXfermode::IsMode(mode, SkXfermode::kSrc_Mode); + 0xFF == paint->getAlpha() && paint->getBlendMode() == SkBlendMode::kSrc; } // For some SaveLayer-[drawing command]-Restore patterns, merge the SaveLayer's alpha into the diff --git a/src/core/SkSpriteBlitter4f.cpp b/src/core/SkSpriteBlitter4f.cpp index a13edd9806..38ec7394d7 100644 --- a/src/core/SkSpriteBlitter4f.cpp +++ b/src/core/SkSpriteBlitter4f.cpp @@ -13,7 +13,7 @@ class Sprite_4f : public SkSpriteBlitter { public: Sprite_4f(const SkPixmap& src, const SkPaint& paint) : INHERITED(src) { - fXfer = paint.getXfermode(); + fXfer = SkXfermode::Peek(paint.getBlendMode()); fLoader = SkLoadSpanProc_Choose(src.info()); fFilter = SkFilterSpanProc_Choose(paint); fBuffer.reset(src.width()); diff --git a/src/core/SkSpriteBlitter_ARGB32.cpp b/src/core/SkSpriteBlitter_ARGB32.cpp index 93885996ea..1a76b1b2fe 100644 --- a/src/core/SkSpriteBlitter_ARGB32.cpp +++ b/src/core/SkSpriteBlitter_ARGB32.cpp @@ -63,8 +63,7 @@ public: fColorFilter = paint.getColorFilter(); SkSafeRef(fColorFilter); - fXfermode = paint.getXfermode(); - SkSafeRef(fXfermode); + fXfermode = SkXfermode::Peek(paint.getBlendMode()); fBufferSize = 0; fBuffer = nullptr; @@ -83,7 +82,6 @@ public: virtual ~Sprite_D32_XferFilter() { delete[] fBuffer; - SkSafeUnref(fXfermode); SkSafeUnref(fColorFilter); } @@ -263,7 +261,7 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPain } U8CPU alpha = paint.getAlpha(); - SkXfermode* xfermode = paint.getXfermode(); + bool isSrcOver = paint.isSrcOver(); SkColorFilter* filter = paint.getColorFilter(); SkSpriteBlitter* blitter = nullptr; @@ -272,7 +270,7 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPain if (alpha != 0xFF) { return nullptr; // we only have opaque sprites } - if (xfermode || filter) { + if (!isSrcOver || filter) { blitter = allocator->createT<Sprite_D32_S4444_XferFilter>(source, paint); } else if (source.isOpaque()) { blitter = allocator->createT<Sprite_D32_S4444_Opaque>(source); @@ -281,7 +279,7 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPain } break; case kN32_SkColorType: - if (xfermode || filter) { + if (!isSrcOver || filter) { if (255 == alpha) { // this can handle xfermode or filter, but not alpha blitter = allocator->createT<Sprite_D32_S32A_XferFilter>(source, paint); diff --git a/src/core/SkSpriteBlitter_RGB16.cpp b/src/core/SkSpriteBlitter_RGB16.cpp index 6c5a7cb130..9df7dab48c 100644 --- a/src/core/SkSpriteBlitter_RGB16.cpp +++ b/src/core/SkSpriteBlitter_RGB16.cpp @@ -307,7 +307,7 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkPixmap& source, const SkPain if (paint.getMaskFilter() != nullptr) { // may add cases for this return nullptr; } - if (paint.getXfermode() != nullptr) { // may add cases for this + if (!paint.isSrcOver()) { // may add cases for this return nullptr; } if (paint.getColorFilter() != nullptr) { // may add cases for this diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 2717fab7e9..226f2b8b43 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -1553,3 +1553,64 @@ bool SkProcCoeffXfermode::onAppendStages(SkRasterPipeline* p) const { } return false; } + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +bool SkBlendMode_SupportsCoverageAsAlpha(SkBlendMode mode) { + switch (mode) { + case SkBlendMode::kDst: + case SkBlendMode::kSrcOver: + case SkBlendMode::kDstOver: + case SkBlendMode::kDstOut: + case SkBlendMode::kSrcATop: + case SkBlendMode::kXor: + case SkBlendMode::kPlus: + return true; + default: + break; + } + return false; +} + +bool SkXfermode::IsOpaque(SkBlendMode mode, SrcColorOpacity opacityType) { + const ProcCoeff rec = gProcCoeffs[(int)mode]; + + switch (rec.fSC) { + case kDA_Coeff: + case kDC_Coeff: + case kIDA_Coeff: + case kIDC_Coeff: + return false; + default: + break; + } + + switch (rec.fDC) { + case kZero_Coeff: + return true; + case kISA_Coeff: + return kOpaque_SrcColorOpacity == opacityType; + case kSA_Coeff: + return kTransparentBlack_SrcColorOpacity == opacityType || + kTransparentAlpha_SrcColorOpacity == opacityType; + case kSC_Coeff: + return kTransparentBlack_SrcColorOpacity == opacityType; + default: + return false; + } + return false; +} + +#if SK_SUPPORT_GPU +sk_sp<GrXPFactory> SkBlendMode_AsXPFactory(SkBlendMode mode) { + const ProcCoeff rec = gProcCoeffs[(int)mode]; + if (CANNOT_USE_COEFF != rec.fSC) { + sk_sp<GrXPFactory> result(GrPorterDuffXPFactory::Make(mode)); + SkASSERT(result); + return result; + } + + SkASSERT(GrCustomXfermode::IsSupportedMode((SkXfermode::Mode)mode)); + return GrCustomXfermode::MakeXPFactory((SkXfermode::Mode)mode); +} +#endif diff --git a/src/core/SkXfermodeInterpretation.cpp b/src/core/SkXfermodeInterpretation.cpp index 1b2c8e32e6..3a1da368d7 100644 --- a/src/core/SkXfermodeInterpretation.cpp +++ b/src/core/SkXfermodeInterpretation.cpp @@ -9,38 +9,31 @@ #include "SkPaint.h" static bool just_solid_color(const SkPaint& p) { - return SK_AlphaOPAQUE == p.getAlpha() - && !p.getColorFilter() && !p.getShader(); + return SK_AlphaOPAQUE == p.getAlpha() && !p.getColorFilter() && !p.getShader(); } -SkXfermodeInterpretation SkInterpretXfermode(const SkPaint& paint, - bool dstIsOpaque) { - const SkXfermode* xfer = paint.getXfermode(); - SkXfermode::Mode mode; - if (!SkXfermode::AsMode(xfer, &mode)) { - return kNormal_SkXfermodeInterpretation; - } - switch (mode) { - case SkXfermode::kSrcOver_Mode: +SkXfermodeInterpretation SkInterpretXfermode(const SkPaint& paint, bool dstIsOpaque) { + switch (paint.getBlendMode()) { + case SkBlendMode::kSrcOver: return kSrcOver_SkXfermodeInterpretation; - case SkXfermode::kSrc_Mode: + case SkBlendMode::kSrc: if (just_solid_color(paint)) { return kSrcOver_SkXfermodeInterpretation; } return kNormal_SkXfermodeInterpretation; - case SkXfermode::kDst_Mode: + case SkBlendMode::kDst: return kSkipDrawing_SkXfermodeInterpretation; - case SkXfermode::kDstOver_Mode: + case SkBlendMode::kDstOver: if (dstIsOpaque) { return kSkipDrawing_SkXfermodeInterpretation; } return kNormal_SkXfermodeInterpretation; - case SkXfermode::kSrcIn_Mode: + case SkBlendMode::kSrcIn: if (dstIsOpaque && just_solid_color(paint)) { return kSrcOver_SkXfermodeInterpretation; } return kNormal_SkXfermodeInterpretation; - case SkXfermode::kDstIn_Mode: + case SkBlendMode::kDstIn: if (just_solid_color(paint)) { return kSkipDrawing_SkXfermodeInterpretation; } diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp index 1d92aa51a6..47a2d3d127 100644 --- a/src/effects/SkAlphaThresholdFilter.cpp +++ b/src/effects/SkAlphaThresholdFilter.cpp @@ -107,7 +107,7 @@ sk_sp<GrTexture> SkAlphaThresholdFilterImpl::createMaskTexture(GrContext* contex } GrPaint grPaint; - grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + grPaint.setPorterDuffXPFactory(SkBlendMode::kSrc); SkRegion::Iterator iter(fRegion); drawContext->clear(nullptr, 0x0, true); diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp index d6b23d5038..507a80580f 100644 --- a/src/effects/SkColorFilterImageFilter.cpp +++ b/src/effects/SkColorFilterImageFilter.cpp @@ -89,7 +89,7 @@ sk_sp<SkSpecialImage> SkColorFilterImageFilter::onFilterImage(SkSpecialImage* so SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); paint.setColorFilter(fColorFilter); // TODO: it may not be necessary to clear or drawPaint inside the input bounds diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index 4f6386d92e..6c779b74fd 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -343,7 +343,7 @@ sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* sou offsetMatrix, colorTexture.get(), SkISize::Make(color->width(), color->height()))); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); SkMatrix matrix; matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y())); diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp index b4b8cac4f0..cc43db7f08 100644 --- a/src/effects/SkDropShadowImageFilter.cpp +++ b/src/effects/SkDropShadowImageFilter.cpp @@ -95,7 +95,6 @@ sk_sp<SkSpecialImage> SkDropShadowImageFilter::onFilterImage(SkSpecialImage* sou SkPaint paint; paint.setImageFilter(SkBlurImageFilter::Make(sigma.fX, sigma.fY, nullptr)); paint.setColorFilter(SkColorFilter::MakeModeFilter(fColor, SkXfermode::kSrcIn_Mode)); - paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); SkVector offsetVec = SkVector::Make(fDx, fDy); ctx.ctm().mapVectors(&offsetVec, 1); diff --git a/src/effects/SkImageSource.cpp b/src/effects/SkImageSource.cpp index f434de4aa0..f96a4a1676 100644 --- a/src/effects/SkImageSource.cpp +++ b/src/effects/SkImageSource.cpp @@ -108,7 +108,7 @@ sk_sp<SkSpecialImage> SkImageSource::onFilterImage(SkSpecialImage* source, const // Subtract off the integer component of the translation (will be applied in offset, below). dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop)); - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); // FIXME: this probably shouldn't be necessary, but drawImageRect asserts // None filtering when it's translate-only paint.setFilterQuality( diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp index d8f774437e..784228fa8b 100644 --- a/src/effects/SkLayerDrawLooper.cpp +++ b/src/effects/SkLayerDrawLooper.cpp @@ -104,7 +104,7 @@ void SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo( dst->setColorFilter(sk_ref_sp(src.getColorFilter())); } if (bits & kXfermode_Bit) { - dst->setXfermode(sk_ref_sp(src.getXfermode())); + dst->setBlendMode(src.getBlendMode()); } // we don't override these diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index 56275743d7..057ef24e95 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -396,7 +396,7 @@ void SkLightingImageFilterInternal::drawRect(GrDrawContext* drawContext, sk_sp<GrFragmentProcessor> fp(this->makeFragmentProcessor(src, matrix, srcBounds, boundaryMode)); paint.addColorFragmentProcessor(std::move(fp)); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect); } diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp index cc7e336a3d..9830669f04 100755 --- a/src/effects/SkMergeImageFilter.cpp +++ b/src/effects/SkMergeImageFilter.cpp @@ -131,7 +131,7 @@ sk_sp<SkSpecialImage> SkMergeImageFilter::onFilterImage(SkSpecialImage* source, SkPaint paint; if (fModes) { - paint.setXfermodeMode((SkXfermode::Mode)fModes[i]); + paint.setBlendMode((SkBlendMode)fModes[i]); } inputs[i]->draw(canvas, diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 82e47c5081..2bd792860b 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -401,7 +401,7 @@ static void apply_morphology_rect(GrDrawContext* drawContext, radius, morphType, bounds)); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect), SkRect::Make(srcRect)); } @@ -418,7 +418,7 @@ static void apply_morphology_rect_no_bounds(GrDrawContext* drawContext, paint.setGammaCorrect(drawContext->isGammaCorrect()); paint.addColorFragmentProcessor(GrMorphologyEffect::Make(texture, direction, radius, morphType)); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect), SkRect::Make(srcRect)); } diff --git a/src/effects/SkOffsetImageFilter.cpp b/src/effects/SkOffsetImageFilter.cpp index 1c99154f16..2e8b0d916d 100644 --- a/src/effects/SkOffsetImageFilter.cpp +++ b/src/effects/SkOffsetImageFilter.cpp @@ -61,7 +61,7 @@ sk_sp<SkSpecialImage> SkOffsetImageFilter::onFilterImage(SkSpecialImage* source, canvas->clear(0x0); SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); canvas->translate(SkIntToScalar(srcOffset.fX - bounds.fLeft), SkIntToScalar(srcOffset.fY - bounds.fTop)); diff --git a/src/effects/SkTileImageFilter.cpp b/src/effects/SkTileImageFilter.cpp index 46c4d9af67..a140db216b 100644 --- a/src/effects/SkTileImageFilter.cpp +++ b/src/effects/SkTileImageFilter.cpp @@ -87,7 +87,7 @@ sk_sp<SkSpecialImage> SkTileImageFilter::onFilterImage(SkSpecialImage* source, SkASSERT(canvas); SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); input->draw(canvas, SkIntToScalar(inputOffset.x()), SkIntToScalar(inputOffset.y()), @@ -107,7 +107,7 @@ sk_sp<SkSpecialImage> SkTileImageFilter::onFilterImage(SkSpecialImage* source, SkASSERT(canvas); SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); paint.setShader(subset->makeShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode)); canvas->translate(-dstRect.fLeft, -dstRect.fTop); canvas->drawRect(dstRect, paint); diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index 952ce977aa..2335a760fb 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -27,7 +27,7 @@ class SkXfermodeImageFilter_Base : public SkImageFilter { public: - SkXfermodeImageFilter_Base(sk_sp<SkXfermode> mode, sk_sp<SkImageFilter> inputs[2], + SkXfermodeImageFilter_Base(SkBlendMode mode, sk_sp<SkImageFilter> inputs[2], const CropRect* cropRect); SK_TO_STRING_OVERRIDE() @@ -55,7 +55,7 @@ protected: #endif private: - sk_sp<SkXfermode> fMode; + SkBlendMode fMode; friend class SkXfermodeImageFilter; @@ -64,7 +64,7 @@ private: /////////////////////////////////////////////////////////////////////////////// -sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode, +sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(SkBlendMode mode, sk_sp<SkImageFilter> background, sk_sp<SkImageFilter> foreground, const SkImageFilter::CropRect* cropRect) { @@ -72,23 +72,36 @@ sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode, return sk_sp<SkImageFilter>(new SkXfermodeImageFilter_Base(mode, inputs, cropRect)); } -SkXfermodeImageFilter_Base::SkXfermodeImageFilter_Base(sk_sp<SkXfermode> mode, - sk_sp<SkImageFilter> inputs[2], - const CropRect* cropRect) - : INHERITED(inputs, 2, cropRect) - , fMode(std::move(mode)) { +#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT +sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode, + sk_sp<SkImageFilter> background, + sk_sp<SkImageFilter> foreground, + const SkImageFilter::CropRect* cropRect) { + return Make(mode ? mode->blend() : SkBlendMode::kSrcOver, + std::move(background), std::move(foreground), cropRect); } +#endif + +SkXfermodeImageFilter_Base::SkXfermodeImageFilter_Base(SkBlendMode mode, + sk_sp<SkImageFilter> inputs[2], + const CropRect* cropRect) + : INHERITED(inputs, 2, cropRect) + , fMode(mode) +{} sk_sp<SkFlattenable> SkXfermodeImageFilter_Base::CreateProc(SkReadBuffer& buffer) { SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); - sk_sp<SkXfermode> mode(buffer.readXfermode()); - return SkXfermodeImageFilter::Make(std::move(mode), common.getInput(0), common.getInput(1), + uint32_t mode = buffer.read32(); + if (!buffer.validate(mode <= (unsigned)SkBlendMode::kLastMode)) { + return nullptr; + } + return SkXfermodeImageFilter::Make((SkBlendMode)mode, common.getInput(0), common.getInput(1), &common.cropRect()); } void SkXfermodeImageFilter_Base::flatten(SkWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); - buffer.writeFlattenable(fMode.get()); + buffer.write32((unsigned)fMode); } sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage* source, @@ -147,7 +160,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage* if (background) { SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); background->draw(canvas, SkIntToScalar(backgroundOffset.fX), SkIntToScalar(backgroundOffset.fY), &paint); @@ -161,7 +174,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage* void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage* img, const SkIRect& fgBounds) const { SkPaint paint; - paint.setXfermode(fMode); + paint.setBlendMode(fMode); if (img) { img->draw(canvas, SkIntToScalar(fgBounds.fLeft), SkIntToScalar(fgBounds.fTop), &paint); } @@ -175,11 +188,7 @@ void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage #ifndef SK_IGNORE_TO_STRING void SkXfermodeImageFilter_Base::toString(SkString* str) const { str->appendf("SkXfermodeImageFilter: ("); - str->appendf("xfermode: ("); - if (fMode) { - fMode->toString(str); - } - str->append(")"); + str->appendf("blendmode: (%d)", fMode); if (this->getInput(0)) { str->appendf("foreground: ("); this->getInput(0)->toString(str); @@ -266,7 +275,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::filterImageGPU( paint.addColorFragmentProcessor(std::move(bgFP)); } - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); sk_sp<GrDrawContext> drawContext( context->makeDrawContext(SkBackingFit::kApprox, bounds.width(), bounds.height(), @@ -290,8 +299,9 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::filterImageGPU( sk_sp<GrFragmentProcessor> SkXfermodeImageFilter_Base::makeFGFrag(sk_sp<GrFragmentProcessor> bgFP) const { // A null fMode is interpreted to mean kSrcOver_Mode (to match raster). - SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get())); - if (!mode) { + SkXfermode* xfer = SkXfermode::Peek(fMode); + sk_sp<SkXfermode> srcover; + if (!xfer) { // It would be awesome to use SkXfermode::Create here but it knows better // than us and won't return a kSrcOver_Mode SkXfermode. That means we // have to get one the hard way. @@ -299,9 +309,11 @@ SkXfermodeImageFilter_Base::makeFGFrag(sk_sp<GrFragmentProcessor> bgFP) const { rec.fProc = SkXfermode::GetProc(SkXfermode::kSrcOver_Mode); SkXfermode::ModeAsCoeff(SkXfermode::kSrcOver_Mode, &rec.fSC, &rec.fDC); - mode.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode)); + srcover.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode)); + xfer = srcover.get(); + } - return mode->makeFragmentProcessorForImageFilter(std::move(bgFP)); + return xfer->makeFragmentProcessorForImageFilter(std::move(bgFP)); } #endif @@ -312,7 +324,8 @@ class SkArithmeticImageFilter : public SkXfermodeImageFilter_Base { public: SkArithmeticImageFilter(float k1, float k2, float k3, float k4, bool enforcePMColor, sk_sp<SkImageFilter> inputs[2], const CropRect* cropRect) - : SkXfermodeImageFilter_Base(nullptr, inputs, cropRect) + // need to pass a blendmode to our inherited constructor, but we ignore it + : SkXfermodeImageFilter_Base(SkBlendMode::kSrcOver, inputs, cropRect) , fK{ k1, k2, k3, k4 } , fEnforcePMColor(enforcePMColor) {} @@ -347,8 +360,8 @@ sk_sp<SkFlattenable> SkArithmeticImageFilter::CreateProc(SkReadBuffer& buffer) { SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); // skip the mode (srcover) our parent-class wrote - sk_sp<SkXfermode> mode(buffer.readXfermode()); - SkASSERT(nullptr == mode); + SkDEBUGCODE(uint32_t mode =) buffer.read32(); + SkASSERT((unsigned)SkBlendMode::kSrcOver == mode); float k[4]; for (int i = 0; i < 4; ++i) { @@ -475,16 +488,16 @@ sk_sp<SkImageFilter> SkXfermodeImageFilter::MakeArithmetic(float k1, float k2, f int mode = -1; // illegal mode if (SkScalarNearlyZero(k1) && SkScalarNearlyEqual(k2, SK_Scalar1) && SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) { - mode = SkXfermode::kSrc_Mode; + mode = (int)SkBlendMode::kSrc; } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) && SkScalarNearlyEqual(k3, SK_Scalar1) && SkScalarNearlyZero(k4)) { - mode = SkXfermode::kDst_Mode; + mode = (int)SkBlendMode::kDst; } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) && SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) { - mode = SkXfermode::kClear_Mode; + mode = (int)SkBlendMode::kClear; } if (mode >= 0) { - return SkXfermodeImageFilter::Make(SkXfermode::Make((SkXfermode::Mode)mode), + return SkXfermodeImageFilter::Make((SkBlendMode)mode, std::move(background), std::move(foreground), crop); } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 6cec1da86b..176d5da59b 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -356,7 +356,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, } GrPaint paint; paint.addColorFragmentProcessor(std::move(fp)); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); paint.setAllowSRGBInputs(true); SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); drawContext->drawRect(GrNoClip(), paint, matrix, rect, nullptr); @@ -471,7 +471,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, if (fp) { GrPaint paint; paint.addColorFragmentProcessor(std::move(fp)); - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); paint.setAllowSRGBInputs(true); SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); tempDC->drawRect(GrNoClip(), paint, SkMatrix::I(), rect, nullptr); diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index e9a9619da5..42d6795903 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -241,7 +241,7 @@ void GrDrawContext::internalClear(const GrFixedClip& clip, GrPaint paint; paint.setColor4f(GrColor4f::FromGrColor(color)); - paint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSrc_Mode)); + paint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::Mode::kSrc_Mode)); this->drawRect(clip, paint, SkMatrix::I(), clearRect); } else if (isFull) { diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index a20eacb75c..747b7574be 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -21,15 +21,15 @@ /* * Convert a boolean operation into a transfer mode code */ -static SkXfermode::Mode op_to_mode(SkRegion::Op op) { - - static const SkXfermode::Mode modeMap[] = { - SkXfermode::kDstOut_Mode, // kDifference_Op - SkXfermode::kModulate_Mode, // kIntersect_Op - SkXfermode::kSrcOver_Mode, // kUnion_Op - SkXfermode::kXor_Mode, // kXOR_Op - SkXfermode::kClear_Mode, // kReverseDifference_Op - SkXfermode::kSrc_Mode, // kReplace_Op +static SkBlendMode op_to_mode(SkRegion::Op op) { + + static const SkBlendMode modeMap[] = { + SkBlendMode::kDstOut, // kDifference_Op + SkBlendMode::kModulate, // kIntersect_Op + SkBlendMode::kSrcOver, // kUnion_Op + SkBlendMode::kXor, // kXOR_Op + SkBlendMode::kClear, // kReverseDifference_Op + SkBlendMode::kSrc, // kReplace_Op }; return modeMap[op]; @@ -42,7 +42,7 @@ void GrSWMaskHelper::drawRect(const SkRect& rect, SkRegion::Op op, bool antiAlias, uint8_t alpha) { SkPaint paint; - paint.setXfermode(SkXfermode::Make(op_to_mode(op))); + paint.setBlendMode(op_to_mode(op)); paint.setAntiAlias(antiAlias); paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); @@ -65,7 +65,7 @@ void GrSWMaskHelper::drawShape(const GrShape& shape, SkRegion::Op op, bool antiA SkASSERT(0xFF == paint.getAlpha()); fDraw.drawPathCoverage(path, paint); } else { - paint.setXfermodeMode(op_to_mode(op)); + paint.setBlendMode(op_to_mode(op)); paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); fDraw.drawPath(path, paint); } diff --git a/src/gpu/GrTextureParamsAdjuster.cpp b/src/gpu/GrTextureParamsAdjuster.cpp index 3ca90f5adb..f51cc54aba 100644 --- a/src/gpu/GrTextureParamsAdjuster.cpp +++ b/src/gpu/GrTextureParamsAdjuster.cpp @@ -72,7 +72,7 @@ static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset, GrTextureParams params(SkShader::kClamp_TileMode, copyParams.fFilter); paint.addColorTextureProcessor(inputTexture, nullptr, SkMatrix::I(), params); } - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); SkRect localRect; if (subset) { diff --git a/src/gpu/GrTextureToYUVPlanes.cpp b/src/gpu/GrTextureToYUVPlanes.cpp index 5e7dafecf3..93a62d2643 100644 --- a/src/gpu/GrTextureToYUVPlanes.cpp +++ b/src/gpu/GrTextureToYUVPlanes.cpp @@ -41,7 +41,7 @@ static bool convert_texture(GrTexture* src, GrDrawContext* dst, int dstW, int ds return false; } GrPaint paint; - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); paint.addColorFragmentProcessor(std::move(fp)); dst->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::MakeIWH(dstW, dstH)); return true; diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp index b187ec3888..db58e0afed 100644 --- a/src/gpu/GrYUVProvider.cpp +++ b/src/gpu/GrYUVProvider.cpp @@ -142,7 +142,7 @@ sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx, } } - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint.setPorterDuffXPFactory(SkBlendMode::kSrc); const SkRect r = SkRect::MakeIWH(yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth, yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight); diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index d4db461c57..ee4e40a642 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -20,6 +20,7 @@ #include "GrXferProcessor.h" #include "GrYUVProvider.h" +#include "SkBlendModePriv.h" #include "SkColorFilter.h" #include "SkConfig8888.h" #include "SkCanvas.h" @@ -680,9 +681,8 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context, // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on // the GrPaint to also be null (also kSrcOver). SkASSERT(!grPaint->getXPFactory()); - SkXfermode* xfermode = skPaint.getXfermode(); - if (xfermode) { - grPaint->setXPFactory(xfermode->asXPFactory()); + if (!skPaint.isSrcOver()) { + grPaint->setXPFactory(SkBlendMode_AsXPFactory(skPaint.getBlendMode())); } #ifndef SK_IGNORE_GPU_DITHER diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index 4eb7a11c76..80a0314ac2 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -229,19 +229,19 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context tempDC->asTexture().get(), GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I())); paint1.addColorFragmentProcessor(std::move(pmToUPM1)); - paint1.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint1.setPorterDuffXPFactory(SkBlendMode::kSrc); readDC->fillRectToRect(GrNoClip(), paint1, SkMatrix::I(), kDstRect, kSrcRect); readDC->asTexture()->readPixels(0, 0, kSize, kSize, kConfig, firstRead); paint2.addColorFragmentProcessor(std::move(upmToPM)); - paint2.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint2.setPorterDuffXPFactory(SkBlendMode::kSrc); tempDC->fillRectToRect(GrNoClip(), paint2, SkMatrix::I(), kDstRect, kSrcRect); paint3.addColorFragmentProcessor(std::move(pmToUPM2)); - paint3.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); + paint3.setPorterDuffXPFactory(SkBlendMode::kSrc); readDC->fillRectToRect(GrNoClip(), paint3, SkMatrix::I(), kDstRect, kSrcRect); diff --git a/src/gpu/text/GrTextUtils.cpp b/src/gpu/text/GrTextUtils.cpp index 56d4ec1c00..a5685f0381 100644 --- a/src/gpu/text/GrTextUtils.cpp +++ b/src/gpu/text/GrTextUtils.cpp @@ -547,8 +547,7 @@ void GrTextUtils::DrawPosTextAsPath(GrContext* context, } bool GrTextUtils::ShouldDisableLCD(const SkPaint& paint) { - return !SkXfermode::AsMode(paint.getXfermode(), nullptr) || - paint.getMaskFilter() || + return paint.getMaskFilter() || paint.getRasterizer() || paint.getPathEffect() || paint.isFakeBoldText() || diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 2870f31ef1..67779ba146 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -259,7 +259,7 @@ bool SkImage_Base::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, siz SkCanvas canvas(bm); SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); canvas.drawImage(this, -SkIntToScalar(srcX), -SkIntToScalar(srcY), &paint); return true; diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp index a002120738..a87428456d 100644 --- a/src/pdf/SkPDFDevice.cpp +++ b/src/pdf/SkPDFDevice.cpp @@ -47,12 +47,11 @@ // Utility functions -// If the paint will definitely draw opaquely, replace kSrc_Mode with -// kSrcOver_Mode. http://crbug.com/473572 +// If the paint will definitely draw opaquely, replace kSrc with +// kSrcOver. http://crbug.com/473572 static void replace_srcmode_on_opaque_paint(SkPaint* paint) { - if (kSrcOver_SkXfermodeInterpretation - == SkInterpretXfermode(*paint, false)) { - paint->setXfermode(nullptr); + if (kSrcOver_SkXfermodeInterpretation == SkInterpretXfermode(*paint, false)) { + paint->setBlendMode(SkBlendMode::kSrcOver); } } @@ -392,7 +391,7 @@ public: const SkPaint& paint, bool hasText = false) : fDevice(device), fContentEntry(nullptr), - fXfermode(SkXfermode::kSrcOver_Mode), + fBlendMode(SkBlendMode::kSrcOver), fDstFormXObject(nullptr) { init(draw.fClipStack, draw.fRC->bwRgn(), *draw.fMatrix, paint, hasText); } @@ -401,7 +400,7 @@ public: const SkPaint& paint, bool hasText = false) : fDevice(device), fContentEntry(nullptr), - fXfermode(SkXfermode::kSrcOver_Mode), + fBlendMode(SkBlendMode::kSrcOver), fDstFormXObject(nullptr) { init(clipStack, clipRegion, matrix, paint, hasText); } @@ -412,7 +411,7 @@ public: if (shape->isEmpty()) { shape = nullptr; } - fDevice->finishContentEntry(fXfermode, std::move(fDstFormXObject), shape); + fDevice->finishContentEntry(fBlendMode, std::move(fDstFormXObject), shape); } } @@ -420,16 +419,16 @@ public: /* Returns true when we explicitly need the shape of the drawing. */ bool needShape() { - switch (fXfermode) { - case SkXfermode::kClear_Mode: - case SkXfermode::kSrc_Mode: - case SkXfermode::kSrcIn_Mode: - case SkXfermode::kSrcOut_Mode: - case SkXfermode::kDstIn_Mode: - case SkXfermode::kDstOut_Mode: - case SkXfermode::kSrcATop_Mode: - case SkXfermode::kDstATop_Mode: - case SkXfermode::kModulate_Mode: + switch (fBlendMode) { + case SkBlendMode::kClear: + case SkBlendMode::kSrc: + case SkBlendMode::kSrcIn: + case SkBlendMode::kSrcOut: + case SkBlendMode::kDstIn: + case SkBlendMode::kDstOut: + case SkBlendMode::kSrcATop: + case SkBlendMode::kDstATop: + case SkBlendMode::kModulate: return true; default: return false; @@ -438,7 +437,7 @@ public: /* Returns true unless we only need the shape of the drawing. */ bool needSource() { - if (fXfermode == SkXfermode::kClear_Mode) { + if (fBlendMode == SkBlendMode::kClear) { return false; } return true; @@ -455,7 +454,7 @@ public: private: SkPDFDevice* fDevice; SkPDFDevice::ContentEntry* fContentEntry; - SkXfermode::Mode fXfermode; + SkBlendMode fBlendMode; sk_sp<SkPDFObject> fDstFormXObject; SkPath fShape; @@ -466,9 +465,7 @@ private: NOT_IMPLEMENTED(!matrix.hasPerspective(), false); return; } - if (paint.getXfermode()) { - paint.getXfermode()->asMode(&fXfermode); - } + fBlendMode = paint.getBlendMode(); fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion, matrix, paint, hasText, &fDstFormXObject); @@ -1708,7 +1705,7 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, sk_sp<SkPDFObject> mask, const SkClipStack* clipStack, const SkRegion& clipRegion, - SkXfermode::Mode mode, + SkBlendMode mode, bool invertClip) { if (clipRegion.isEmpty() && !invertClip) { return; @@ -1721,7 +1718,7 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex, SkMatrix identity; identity.reset(); SkPaint paint; - paint.setXfermodeMode(mode); + paint.setBlendMode(mode); ScopedContentEntry content(this, clipStack, clipRegion, identity, paint); if (!content.entry()) { return; @@ -1767,27 +1764,24 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli } } - SkXfermode::Mode xfermode = SkXfermode::kSrcOver_Mode; - if (paint.getXfermode()) { - paint.getXfermode()->asMode(&xfermode); - } + SkBlendMode blendMode = paint.getBlendMode(); // For the following modes, we want to handle source and destination // separately, so make an object of what's already there. - if (xfermode == SkXfermode::kClear_Mode || - xfermode == SkXfermode::kSrc_Mode || - xfermode == SkXfermode::kSrcIn_Mode || - xfermode == SkXfermode::kDstIn_Mode || - xfermode == SkXfermode::kSrcOut_Mode || - xfermode == SkXfermode::kDstOut_Mode || - xfermode == SkXfermode::kSrcATop_Mode || - xfermode == SkXfermode::kDstATop_Mode || - xfermode == SkXfermode::kModulate_Mode) { + if (blendMode == SkBlendMode::kClear || + blendMode == SkBlendMode::kSrc || + blendMode == SkBlendMode::kSrcIn || + blendMode == SkBlendMode::kDstIn || + blendMode == SkBlendMode::kSrcOut || + blendMode == SkBlendMode::kDstOut || + blendMode == SkBlendMode::kSrcATop || + blendMode == SkBlendMode::kDstATop || + blendMode == SkBlendMode::kModulate) { if (!isContentEmpty()) { *dst = this->makeFormXObjectFromDevice(); SkASSERT(isContentEmpty()); - } else if (xfermode != SkXfermode::kSrc_Mode && - xfermode != SkXfermode::kSrcOut_Mode) { + } else if (blendMode != SkBlendMode::kSrc && + blendMode != SkBlendMode::kSrcOut) { // Except for Src and SrcOut, if there isn't anything already there, // then we're done. return nullptr; @@ -1797,14 +1791,14 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli // Xor, Plus. // Dst xfer mode doesn't draw source at all. - if (xfermode == SkXfermode::kDst_Mode) { + if (blendMode == SkBlendMode::kDst) { return nullptr; } SkPDFDevice::ContentEntry* entry; if (fContentEntries.back() && fContentEntries.back()->fContent.getOffset() == 0) { entry = fContentEntries.back(); - } else if (xfermode != SkXfermode::kDstOver_Mode) { + } else if (blendMode != SkBlendMode::kDstOver) { entry = fContentEntries.emplace_back(); } else { entry = fContentEntries.emplace_front(); @@ -1814,23 +1808,23 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli return entry; } -void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, +void SkPDFDevice::finishContentEntry(SkBlendMode blendMode, sk_sp<SkPDFObject> dst, SkPath* shape) { - if (xfermode != SkXfermode::kClear_Mode && - xfermode != SkXfermode::kSrc_Mode && - xfermode != SkXfermode::kDstOver_Mode && - xfermode != SkXfermode::kSrcIn_Mode && - xfermode != SkXfermode::kDstIn_Mode && - xfermode != SkXfermode::kSrcOut_Mode && - xfermode != SkXfermode::kDstOut_Mode && - xfermode != SkXfermode::kSrcATop_Mode && - xfermode != SkXfermode::kDstATop_Mode && - xfermode != SkXfermode::kModulate_Mode) { + if (blendMode != SkBlendMode::kClear && + blendMode != SkBlendMode::kSrc && + blendMode != SkBlendMode::kDstOver && + blendMode != SkBlendMode::kSrcIn && + blendMode != SkBlendMode::kDstIn && + blendMode != SkBlendMode::kSrcOut && + blendMode != SkBlendMode::kDstOut && + blendMode != SkBlendMode::kSrcATop && + blendMode != SkBlendMode::kDstATop && + blendMode != SkBlendMode::kModulate) { SkASSERT(!dst); return; } - if (xfermode == SkXfermode::kDstOver_Mode) { + if (blendMode == SkBlendMode::kDstOver) { SkASSERT(!dst); if (fContentEntries.front()->fContent.getOffset() == 0) { // For DstOver, an empty content entry was inserted before the rest @@ -1841,8 +1835,8 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, return; } if (!dst) { - SkASSERT(xfermode == SkXfermode::kSrc_Mode || - xfermode == SkXfermode::kSrcOut_Mode); + SkASSERT(blendMode == SkBlendMode::kSrc || + blendMode == SkBlendMode::kSrcOut); return; } @@ -1867,8 +1861,8 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, // If there is shape, then an empty source with Src, SrcIn, SrcOut, // DstIn, DstAtop or Modulate reduces to Clear and DstOut or SrcAtop // reduces to Dst. - if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode || - xfermode == SkXfermode::kSrcATop_Mode) { + if (shape == nullptr || blendMode == SkBlendMode::kDstOut || + blendMode == SkBlendMode::kSrcATop) { ScopedContentEntry content(this, &fExistingClipStack, fExistingClipRegion, identity, stockPaint); @@ -1877,7 +1871,7 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, &content.entry()->fContent); return; } else { - xfermode = SkXfermode::kClear_Mode; + blendMode = SkBlendMode::kClear; } } else { SkASSERT(fContentEntries.count() == 1); @@ -1886,14 +1880,14 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, // TODO(vandebo) srcFormXObject may contain alpha, but here we want it // without alpha. - if (xfermode == SkXfermode::kSrcATop_Mode) { + if (blendMode == SkBlendMode::kSrcATop) { // TODO(vandebo): In order to properly support SrcATop we have to track // the shape of what's been drawn at all times. It's the intersection of // the non-transparent parts of the device and the outlines (shape) of // all images and devices drawn. drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst, &fExistingClipStack, fExistingClipRegion, - SkXfermode::kSrcOver_Mode, true); + SkBlendMode::kSrcOver, true); } else { if (shape != nullptr) { // Draw shape into a form-xobject. @@ -1909,19 +1903,19 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, drawFormXObjectWithMask(addXObjectResource(dst.get()), this->makeFormXObjectFromDevice(), &fExistingClipStack, fExistingClipRegion, - SkXfermode::kSrcOver_Mode, true); + SkBlendMode::kSrcOver, true); } else { drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObject, &fExistingClipStack, fExistingClipRegion, - SkXfermode::kSrcOver_Mode, true); + SkBlendMode::kSrcOver, true); } } - if (xfermode == SkXfermode::kClear_Mode) { + if (blendMode == SkBlendMode::kClear) { return; - } else if (xfermode == SkXfermode::kSrc_Mode || - xfermode == SkXfermode::kDstATop_Mode) { + } else if (blendMode == SkBlendMode::kSrc || + blendMode == SkBlendMode::kDstATop) { ScopedContentEntry content(this, &fExistingClipStack, fExistingClipRegion, identity, stockPaint); if (content.entry()) { @@ -1929,10 +1923,10 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, this->addXObjectResource(srcFormXObject.get()), &content.entry()->fContent); } - if (xfermode == SkXfermode::kSrc_Mode) { + if (blendMode == SkBlendMode::kSrc) { return; } - } else if (xfermode == SkXfermode::kSrcATop_Mode) { + } else if (blendMode == SkBlendMode::kSrcATop) { ScopedContentEntry content(this, &fExistingClipStack, fExistingClipRegion, identity, stockPaint); if (content.entry()) { @@ -1941,36 +1935,36 @@ void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode, } } - SkASSERT(xfermode == SkXfermode::kSrcIn_Mode || - xfermode == SkXfermode::kDstIn_Mode || - xfermode == SkXfermode::kSrcOut_Mode || - xfermode == SkXfermode::kDstOut_Mode || - xfermode == SkXfermode::kSrcATop_Mode || - xfermode == SkXfermode::kDstATop_Mode || - xfermode == SkXfermode::kModulate_Mode); + SkASSERT(blendMode == SkBlendMode::kSrcIn || + blendMode == SkBlendMode::kDstIn || + blendMode == SkBlendMode::kSrcOut || + blendMode == SkBlendMode::kDstOut || + blendMode == SkBlendMode::kSrcATop || + blendMode == SkBlendMode::kDstATop || + blendMode == SkBlendMode::kModulate); - if (xfermode == SkXfermode::kSrcIn_Mode || - xfermode == SkXfermode::kSrcOut_Mode || - xfermode == SkXfermode::kSrcATop_Mode) { + if (blendMode == SkBlendMode::kSrcIn || + blendMode == SkBlendMode::kSrcOut || + blendMode == SkBlendMode::kSrcATop) { drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), std::move(dst), &fExistingClipStack, fExistingClipRegion, - SkXfermode::kSrcOver_Mode, - xfermode == SkXfermode::kSrcOut_Mode); + SkBlendMode::kSrcOver, + blendMode == SkBlendMode::kSrcOut); return; } else { - SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode; + SkBlendMode mode = SkBlendMode::kSrcOver; int resourceID = addXObjectResource(dst.get()); - if (xfermode == SkXfermode::kModulate_Mode) { + if (blendMode == SkBlendMode::kModulate) { drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), std::move(dst), &fExistingClipStack, fExistingClipRegion, - SkXfermode::kSrcOver_Mode, false); - mode = SkXfermode::kMultiply_Mode; + SkBlendMode::kSrcOver, false); + mode = SkBlendMode::kMultiply; } drawFormXObjectWithMask(resourceID, std::move(srcFormXObject), &fExistingClipStack, fExistingClipRegion, mode, - xfermode == SkXfermode::kDstOut_Mode); + blendMode == SkBlendMode::kDstOut); return; } } diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h index be0a277ff5..7d207e7cf9 100644 --- a/src/pdf/SkPDFDevice.h +++ b/src/pdf/SkPDFDevice.h @@ -246,7 +246,7 @@ private: sk_sp<SkPDFObject> mask, const SkClipStack* clipStack, const SkRegion& clipRegion, - SkXfermode::Mode mode, + SkBlendMode, bool invertClip); // If the paint or clip is such that we shouldn't draw anything, this @@ -259,9 +259,7 @@ private: const SkPaint& paint, bool hasText, sk_sp<SkPDFObject>* dst); - void finishContentEntry(SkXfermode::Mode xfermode, - sk_sp<SkPDFObject> dst, - SkPath* shape); + void finishContentEntry(SkBlendMode, sk_sp<SkPDFObject> dst, SkPath* shape); bool isContentEmpty(); void populateGraphicStateEntryFromPaint(const SkMatrix& matrix, diff --git a/src/pdf/SkPDFGraphicState.cpp b/src/pdf/SkPDFGraphicState.cpp index a78c4c51b5..d60526c11a 100644 --- a/src/pdf/SkPDFGraphicState.cpp +++ b/src/pdf/SkPDFGraphicState.cpp @@ -12,58 +12,58 @@ #include "SkPDFGraphicState.h" #include "SkPDFUtils.h" -static const char* as_blend_mode(SkXfermode::Mode mode) { +static const char* as_blend_mode(SkBlendMode mode) { switch (mode) { - case SkXfermode::kSrcOver_Mode: + case SkBlendMode::kSrcOver: return "Normal"; - case SkXfermode::kMultiply_Mode: + case SkBlendMode::kMultiply: return "Multiply"; - case SkXfermode::kScreen_Mode: + case SkBlendMode::kScreen: return "Screen"; - case SkXfermode::kOverlay_Mode: + case SkBlendMode::kOverlay: return "Overlay"; - case SkXfermode::kDarken_Mode: + case SkBlendMode::kDarken: return "Darken"; - case SkXfermode::kLighten_Mode: + case SkBlendMode::kLighten: return "Lighten"; - case SkXfermode::kColorDodge_Mode: + case SkBlendMode::kColorDodge: return "ColorDodge"; - case SkXfermode::kColorBurn_Mode: + case SkBlendMode::kColorBurn: return "ColorBurn"; - case SkXfermode::kHardLight_Mode: + case SkBlendMode::kHardLight: return "HardLight"; - case SkXfermode::kSoftLight_Mode: + case SkBlendMode::kSoftLight: return "SoftLight"; - case SkXfermode::kDifference_Mode: + case SkBlendMode::kDifference: return "Difference"; - case SkXfermode::kExclusion_Mode: + case SkBlendMode::kExclusion: return "Exclusion"; - case SkXfermode::kHue_Mode: + case SkBlendMode::kHue: return "Hue"; - case SkXfermode::kSaturation_Mode: + case SkBlendMode::kSaturation: return "Saturation"; - case SkXfermode::kColor_Mode: + case SkBlendMode::kColor: return "Color"; - case SkXfermode::kLuminosity_Mode: + case SkBlendMode::kLuminosity: return "Luminosity"; // These are handled in SkPDFDevice::setUpContentEntry. - case SkXfermode::kClear_Mode: - case SkXfermode::kSrc_Mode: - case SkXfermode::kDst_Mode: - case SkXfermode::kDstOver_Mode: - case SkXfermode::kSrcIn_Mode: - case SkXfermode::kDstIn_Mode: - case SkXfermode::kSrcOut_Mode: - case SkXfermode::kDstOut_Mode: - case SkXfermode::kSrcATop_Mode: - case SkXfermode::kDstATop_Mode: - case SkXfermode::kModulate_Mode: + case SkBlendMode::kClear: + case SkBlendMode::kSrc: + case SkBlendMode::kDst: + case SkBlendMode::kDstOver: + case SkBlendMode::kSrcIn: + case SkBlendMode::kDstIn: + case SkBlendMode::kSrcOut: + case SkBlendMode::kDstOut: + case SkBlendMode::kSrcATop: + case SkBlendMode::kDstATop: + case SkBlendMode::kModulate: return "Normal"; // TODO(vandebo): Figure out if we can support more of these modes. - case SkXfermode::kXor_Mode: - case SkXfermode::kPlus_Mode: + case SkBlendMode::kXor: + case SkBlendMode::kPlus: return nullptr; } return nullptr; @@ -71,32 +71,28 @@ static const char* as_blend_mode(SkXfermode::Mode mode) { // If a SkXfermode is unsupported in PDF, this function returns // SrcOver, otherwise, it returns that Xfermode as a Mode. -static SkXfermode::Mode mode_for_pdf(const SkXfermode* xfermode) { - SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode; - if (xfermode) { - xfermode->asMode(&mode); - } +static SkBlendMode mode_for_pdf(SkBlendMode mode) { switch (mode) { - case SkXfermode::kSrcOver_Mode: - case SkXfermode::kMultiply_Mode: - case SkXfermode::kScreen_Mode: - case SkXfermode::kOverlay_Mode: - case SkXfermode::kDarken_Mode: - case SkXfermode::kLighten_Mode: - case SkXfermode::kColorDodge_Mode: - case SkXfermode::kColorBurn_Mode: - case SkXfermode::kHardLight_Mode: - case SkXfermode::kSoftLight_Mode: - case SkXfermode::kDifference_Mode: - case SkXfermode::kExclusion_Mode: - case SkXfermode::kHue_Mode: - case SkXfermode::kSaturation_Mode: - case SkXfermode::kColor_Mode: - case SkXfermode::kLuminosity_Mode: + case SkBlendMode::kSrcOver: + case SkBlendMode::kMultiply: + case SkBlendMode::kScreen: + case SkBlendMode::kOverlay: + case SkBlendMode::kDarken: + case SkBlendMode::kLighten: + case SkBlendMode::kColorDodge: + case SkBlendMode::kColorBurn: + case SkBlendMode::kHardLight: + case SkBlendMode::kSoftLight: + case SkBlendMode::kDifference: + case SkBlendMode::kExclusion: + case SkBlendMode::kHue: + case SkBlendMode::kSaturation: + case SkBlendMode::kColor: + case SkBlendMode::kLuminosity: // Mode is suppported and handled by pdf graphics state. return mode; default: - return SkXfermode::kSrcOver_Mode; // Default mode. + return SkBlendMode::kSrcOver; // Default mode. } } @@ -106,7 +102,7 @@ SkPDFGraphicState::SkPDFGraphicState(const SkPaint& p) , fAlpha(p.getAlpha()) , fStrokeCap(SkToU8(p.getStrokeCap())) , fStrokeJoin(SkToU8(p.getStrokeJoin())) - , fMode(SkToU8(mode_for_pdf(p.getXfermode()))) {} + , fMode(SkToU8((unsigned)mode_for_pdf(p.getBlendMode()))) {} // static SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint( @@ -186,7 +182,6 @@ void SkPDFGraphicState::emitObject( SkPaint::Cap strokeCap = (SkPaint::Cap)fStrokeCap; SkPaint::Join strokeJoin = (SkPaint::Join)fStrokeJoin; - SkXfermode::Mode xferMode = (SkXfermode::Mode)fMode; static_assert(SkPaint::kButt_Cap == 0, "paint_cap_mismatch"); static_assert(SkPaint::kRound_Cap == 1, "paint_cap_mismatch"); @@ -205,6 +200,6 @@ void SkPDFGraphicState::emitObject( dict->insertScalar("LW", fStrokeWidth); dict->insertScalar("ML", fStrokeMiter); dict->insertBool("SA", true); // SA = Auto stroke adjustment. - dict->insertName("BM", as_blend_mode(xferMode)); + dict->insertName("BM", as_blend_mode((SkBlendMode)fMode)); dict->emitObject(stream, objNumMap); } diff --git a/src/pdf/SkPDFGraphicState.h b/src/pdf/SkPDFGraphicState.h index 0c2e4a0f49..8ee6728f56 100644 --- a/src/pdf/SkPDFGraphicState.h +++ b/src/pdf/SkPDFGraphicState.h @@ -70,7 +70,7 @@ private: const uint8_t fAlpha; const uint8_t fStrokeCap; // SkPaint::Cap const uint8_t fStrokeJoin; // SkPaint::Join - const uint8_t fMode; // SkXfermode::Mode + const uint8_t fMode; // SkBlendMode SkPDFGraphicState(const SkPaint&); diff --git a/src/pipe/SkPipeCanvas.cpp b/src/pipe/SkPipeCanvas.cpp index a01237fbbb..3b636a23c0 100644 --- a/src/pipe/SkPipeCanvas.cpp +++ b/src/pipe/SkPipeCanvas.cpp @@ -81,7 +81,6 @@ static uint16_t compute_nondef(const SkPaint& paint, PaintUsage usage) { bits |= (paint.getMaskFilter() ? kMaskFilter_NonDef : 0); } - bits |= (paint.getXfermode() ? kXfermode_NonDef : 0); bits |= (paint.getColorFilter() ? kColorFilter_NonDef : 0); bits |= (paint.getImageFilter() ? kImageFilter_NonDef : 0); bits |= (paint.getDrawLooper() ? kDrawLooper_NonDef : 0); @@ -150,15 +149,8 @@ static void write_paint(SkWriteBuffer& writer, const SkPaint& paint, unsigned us writer.write32(packedFlags); unsigned nondef = compute_nondef(paint, (PaintUsage)usage); - SkXfermode::Mode mode; - if (SkXfermode::AsMode(paint.getXfermode(), &mode)) { - nondef &= ~kXfermode_NonDef; // don't need to store a pointer since we have an enum - } else { - SkASSERT(nondef & kXfermode_NonDef); - mode = (SkXfermode::Mode)0; - } const uint8_t pad = 0; - writer.write32((nondef << 16) | ((unsigned)mode << 8) | pad); + writer.write32((nondef << 16) | ((unsigned)paint.getBlendMode() << 8) | pad); CHECK_WRITE_SCALAR(writer, nondef, paint, TextSize); CHECK_WRITE_SCALAR(writer, nondef, paint, TextScaleX); @@ -179,7 +171,6 @@ static void write_paint(SkWriteBuffer& writer, const SkPaint& paint, unsigned us CHECK_WRITE_FLATTENABLE(writer, nondef, paint, PathEffect); CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Shader); - CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Xfermode); CHECK_WRITE_FLATTENABLE(writer, nondef, paint, MaskFilter); CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ColorFilter); CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Rasterizer); diff --git a/src/pipe/SkPipeFormat.h b/src/pipe/SkPipeFormat.h index 8f5c8282e4..9a1d30c7be 100644 --- a/src/pipe/SkPipeFormat.h +++ b/src/pipe/SkPipeFormat.h @@ -94,12 +94,11 @@ enum { kTypeface_NonDef = 1 << 6, kPathEffect_NonDef = 1 << 7, kShader_NonDef = 1 << 8, - kXfermode_NonDef = 1 << 9, - kMaskFilter_NonDef = 1 << 10, - kColorFilter_NonDef = 1 << 11, - kRasterizer_NonDef = 1 << 12, - kImageFilter_NonDef = 1 << 13, - kDrawLooper_NonDef = 1 << 14, + kMaskFilter_NonDef = 1 << 9, + kColorFilter_NonDef = 1 << 10, + kRasterizer_NonDef = 1 << 11, + kImageFilter_NonDef = 1 << 12, + kDrawLooper_NonDef = 1 << 13, }; enum { diff --git a/src/pipe/SkPipeReader.cpp b/src/pipe/SkPipeReader.cpp index 8840da1c83..47d4072d06 100644 --- a/src/pipe/SkPipeReader.cpp +++ b/src/pipe/SkPipeReader.cpp @@ -149,13 +149,13 @@ static SkMatrix read_sparse_matrix(SkReadBuffer& reader, SkMatrix::TypeMask tm) * pad zeros : 8 */ static SkPaint read_paint(SkReadBuffer& reader) { + SkPaint paint; + uint32_t packedFlags = reader.read32(); uint32_t extra = reader.read32(); unsigned nondef = extra >> 16; - SkXfermode::Mode mode = (SkXfermode::Mode)((extra >> 8) & 0xFF); - SkASSERT((extra & 0xFF) == 0); - - SkPaint paint; + paint.setBlendMode(SkBlendMode((extra >> 8) & 0xFF)); + SkASSERT((extra & 0xFF) == 0); // zero pad byte packedFlags >>= 2; // currently unused paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3)); packedFlags >>= 2; @@ -180,17 +180,12 @@ static SkPaint read_paint(SkReadBuffer& reader) { CHECK_SET_FLATTENABLE(Typeface); CHECK_SET_FLATTENABLE(PathEffect); CHECK_SET_FLATTENABLE(Shader); - CHECK_SET_FLATTENABLE(Xfermode); CHECK_SET_FLATTENABLE(MaskFilter); CHECK_SET_FLATTENABLE(ColorFilter); CHECK_SET_FLATTENABLE(Rasterizer); CHECK_SET_FLATTENABLE(ImageFilter); CHECK_SET_FLATTENABLE(DrawLooper); - if (!(nondef & kXfermode_NonDef)) { - paint.setXfermodeMode(mode); - } - return paint; } diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp index fcb24d28c4..68bd13eccb 100644 --- a/src/utils/SkDumpCanvas.cpp +++ b/src/utils/SkDumpCanvas.cpp @@ -209,8 +209,8 @@ SkCanvas::SaveLayerStrategy SkDumpCanvas::getSaveLayerStrategy(const SaveLayerRe if (paint->getAlpha() != 0xFF) { str.appendf(" alpha:0x%02X", paint->getAlpha()); } - if (paint->getXfermode()) { - str.appendf(" xfermode:%p", paint->getXfermode()); + if (!paint->isSrcOver()) { + str.appendf(" blendmode:%d", paint->getBlendMode()); } } this->dump(kSave_Verb, paint, str.c_str()); @@ -540,8 +540,10 @@ void SkFormatDumper::dump(SkDumpCanvas* canvas, SkDumpCanvas::Verb verb, if (p) { msg.appendf(" color:0x%08X flags:%X", p->getColor(), p->getFlags()); + if (!p->isSrcOver()) { + msg.appendf(" blendmode:%d", p->getBlendMode()); + } appendFlattenable(&msg, p->getShader(), "shader"); - appendFlattenable(&msg, p->getXfermode(), "xfermode"); appendFlattenable(&msg, p->getPathEffect(), "pathEffect"); appendFlattenable(&msg, p->getMaskFilter(), "maskFilter"); appendFlattenable(&msg, p->getPathEffect(), "pathEffect"); diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp index e80708c71c..ba311af61c 100644 --- a/src/utils/SkLua.cpp +++ b/src/utils/SkLua.cpp @@ -28,7 +28,6 @@ #include "SkSurface.h" #include "SkTextBlob.h" #include "SkTypeface.h" -#include "SkXfermode.h" extern "C" { #include "lua.h" @@ -59,7 +58,6 @@ DEF_MTNAME(SkShader) DEF_MTNAME(SkSurface) DEF_MTNAME(SkTextBlob) DEF_MTNAME(SkTypeface) -DEF_MTNAME(SkXfermode) template <typename T> T* push_new(lua_State* L) { T* addr = (T*)lua_newuserdata(L, sizeof(T)); @@ -1073,26 +1071,9 @@ static int lpaint_getEffects(lua_State* L) { setfield_bool_if(L, "shader", !!paint->getShader()); setfield_bool_if(L, "colorFilter", !!paint->getColorFilter()); setfield_bool_if(L, "imageFilter", !!paint->getImageFilter()); - setfield_bool_if(L, "xfermode", !!paint->getXfermode()); return 1; } -static int lpaint_getXfermode(lua_State* L) { - const SkPaint* paint = get_obj<SkPaint>(L, 1); - SkXfermode* xfermode = paint->getXfermode(); - if (xfermode) { - push_ref(L, xfermode); - return 1; - } - return 0; -} - -static int lpaint_setXfermode(lua_State* L) { - SkPaint* paint = get_obj<SkPaint>(L, 1); - paint->setXfermode(sk_ref_sp(get_ref<SkXfermode>(L, 2))); - return 0; -} - static int lpaint_getColorFilter(lua_State* L) { const SkPaint* paint = get_obj<SkPaint>(L, 1); SkColorFilter* cf = paint->getColorFilter(); @@ -1217,8 +1198,6 @@ static const struct luaL_Reg gSkPaint_Methods[] = { { "setColorFilter", lpaint_setColorFilter }, { "getImageFilter", lpaint_getImageFilter }, { "setImageFilter", lpaint_setImageFilter }, - { "getXfermode", lpaint_getXfermode }, - { "setXfermode", lpaint_setXfermode }, { "getShader", lpaint_getShader }, { "setShader", lpaint_setShader }, { "getPathEffect", lpaint_getPathEffect }, @@ -1341,24 +1320,6 @@ static const struct luaL_Reg gSkPathEffect_Methods[] = { /////////////////////////////////////////////////////////////////////////////// -static int lpxfermode_getTypeName(lua_State* L) { - lua_pushstring(L, get_ref<SkXfermode>(L, 1)->getTypeName()); - return 1; -} - -static int lpxfermode_gc(lua_State* L) { - get_ref<SkXfermode>(L, 1)->unref(); - return 0; -} - -static const struct luaL_Reg gSkXfermode_Methods[] = { - { "getTypeName", lpxfermode_getTypeName }, - { "__gc", lpxfermode_gc }, - { nullptr, nullptr } -}; - -/////////////////////////////////////////////////////////////////////////////// - static int lpcolorfilter_gc(lua_State* L) { get_ref<SkColorFilter>(L, 1)->unref(); return 0; @@ -2178,7 +2139,6 @@ void SkLua::Load(lua_State* L) { REG_CLASS(L, SkSurface); REG_CLASS(L, SkTextBlob); REG_CLASS(L, SkTypeface); - REG_CLASS(L, SkXfermode); } extern "C" int luaopen_skia(lua_State* L); diff --git a/src/utils/SkRGBAToYUV.cpp b/src/utils/SkRGBAToYUV.cpp index 63d9152362..0528b144f0 100644 --- a/src/utils/SkRGBAToYUV.cpp +++ b/src/utils/SkRGBAToYUV.cpp @@ -45,7 +45,7 @@ bool SkRGBAToYUV(const SkImage* image, const SkISize sizes[3], void* const plane } SkPaint paint; paint.setFilterQuality(kLow_SkFilterQuality); - paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setBlendMode(SkBlendMode::kSrc); int rowStartIdx = 5 * i; const SkScalar* row = kYUVColorSpaceInvMatrices[colorSpace] + rowStartIdx; paint.setColorFilter( diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp index 7757cb8774..5db644c30a 100644 --- a/src/xps/SkXPSDevice.cpp +++ b/src/xps/SkXPSDevice.cpp @@ -1220,7 +1220,7 @@ void SkXPSDevice::internalDrawRect(const SkDraw& d, const SkPaint& paint) { //Exit early if there is nothing to draw. if (d.fRC->isEmpty() || - (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) { + (paint.getAlpha() == 0 && paint.isSrcOver())) { return; } @@ -1536,7 +1536,7 @@ void SkXPSDevice::drawPath(const SkDraw& d, // nothing to draw if (d.fRC->isEmpty() || - (paint->getAlpha() == 0 && paint->getXfermode() == nullptr)) { + (paint->getAlpha() == 0 && paint->isSrcOver())) { return; } |