aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapDevice.cpp2
-rw-r--r--src/core/SkBlendModePriv.h19
-rw-r--r--src/core/SkBlitter.cpp16
-rw-r--r--src/core/SkBlitter_A8.cpp9
-rw-r--r--src/core/SkBlitter_ARGB32.cpp4
-rw-r--r--src/core/SkBlitter_PM4f.cpp4
-rw-r--r--src/core/SkBlitter_RGB16.cpp14
-rw-r--r--src/core/SkBlitter_Sprite.cpp20
-rw-r--r--src/core/SkCanvas.cpp19
-rw-r--r--src/core/SkDraw.cpp21
-rw-r--r--src/core/SkGpuBlurUtils.cpp8
-rw-r--r--src/core/SkImageFilter.cpp2
-rw-r--r--src/core/SkMatrixImageFilter.cpp2
-rw-r--r--src/core/SkPaint.cpp96
-rw-r--r--src/core/SkPaintPriv.cpp2
-rw-r--r--src/core/SkPixmap.cpp2
-rw-r--r--src/core/SkRasterPipelineBlitter.cpp6
-rw-r--r--src/core/SkReadBuffer.h1
-rw-r--r--src/core/SkRecordDraw.cpp41
-rw-r--r--src/core/SkRecordOpts.cpp14
-rw-r--r--src/core/SkSpriteBlitter4f.cpp2
-rw-r--r--src/core/SkSpriteBlitter_ARGB32.cpp10
-rw-r--r--src/core/SkSpriteBlitter_RGB16.cpp2
-rw-r--r--src/core/SkXfermode.cpp61
-rw-r--r--src/core/SkXfermodeInterpretation.cpp25
25 files changed, 172 insertions, 230 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 26d253cf38..440de68345 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 ||
- !paint.isSrcOver())
+ !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode))
{
return true;
}
diff --git a/src/core/SkBlendModePriv.h b/src/core/SkBlendModePriv.h
deleted file mode 100644
index b5d9e751e6..0000000000
--- a/src/core/SkBlendModePriv.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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 ce689d7e84..db9fcda93b 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();
- SkBlendMode mode = origPaint.getBlendMode();
+ SkXfermode* mode = origPaint.getXfermode();
sk_sp<Sk3DShader> shader3D;
SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
@@ -823,12 +823,12 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
shader = shader3D.get();
}
- if (mode != SkBlendMode::kSrcOver) {
+ if (mode) {
bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType();
switch (SkInterpretXfermode(*paint, deviceIsOpaque)) {
case kSrcOver_SkXfermodeInterpretation:
- mode = SkBlendMode::kSrcOver;
- paint.writable()->setBlendMode(mode);
+ mode = nullptr;
+ paint.writable()->setXfermode(nullptr);
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 (mode == SkBlendMode::kClear) {
+ if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) {
SkPaint* p = paint.writable();
p->setShader(nullptr);
shader = nullptr;
p->setColorFilter(nullptr);
cf = nullptr;
- p->setBlendMode(mode = SkBlendMode::kSrc);
+ mode = p->setXfermodeMode(SkXfermode::kSrc_Mode);
p->setColor(0);
}
@@ -858,7 +858,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
}
if (nullptr == shader) {
- if (mode != SkBlendMode::kSrcOver) {
+ if (mode) {
// 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(paint->isSrcOver());
+ SkASSERT(nullptr == paint->getXfermode());
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 cb7d718f54..66976143c8 100644
--- a/src/core/SkBlitter_A8.cpp
+++ b/src/core/SkBlitter_A8.cpp
@@ -230,8 +230,10 @@ SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint&
SkShader::Context* shaderContext)
: INHERITED(device, paint, shaderContext)
{
- fXfermode = SkXfermode::Peek(paint.getBlendMode());
- SkASSERT(!fXfermode || fShaderContext);
+ if ((fXfermode = paint.getXfermode()) != nullptr) {
+ fXfermode->ref();
+ SkASSERT(fShaderContext);
+ }
int width = device.width();
fBuffer = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * (width + (SkAlign4(width) >> 2)));
@@ -239,6 +241,7 @@ SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint&
}
SkA8_Shader_Blitter::~SkA8_Shader_Blitter() {
+ if (fXfermode) SkSafeUnref(fXfermode);
sk_free(fBuffer);
}
@@ -352,7 +355,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(paint.isSrcOver());
+ SkASSERT(nullptr == paint.getXfermode());
SkASSERT(nullptr == paint.getColorFilter());
}
diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp
index ea0554d66e..aada0586a4 100644
--- a/src/core/SkBlitter_ARGB32.cpp
+++ b/src/core/SkBlitter_ARGB32.cpp
@@ -339,7 +339,8 @@ SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device,
{
fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
- fXfermode = SkXfermode::Peek(paint.getBlendMode());
+ fXfermode = paint.getXfermode();
+ SkSafeRef(fXfermode);
int flags = 0;
if (!(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
@@ -369,6 +370,7 @@ 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 d63e924e2c..455a97b95d 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 = SkXfermode::Peek(paint.getBlendMode());
+ fXfer = paint.getXfermode();
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 = SkXfermode::Peek(paint.getBlendMode());
+ bstate.fXfer = paint.getXfermode();
(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 7860b7cb6c..066ec616de 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.isSrcOver());
+ SkASSERT(paint.getXfermode() == nullptr);
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.isSrcOver());
+ SkASSERT(paint.getXfermode() == nullptr);
fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor));
@@ -809,8 +809,9 @@ SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter(
SkShader::Context* shaderContext)
: INHERITED(device, paint, shaderContext)
{
- fXfermode = SkXfermode::Peek(paint.getBlendMode());
+ fXfermode = paint.getXfermode();
SkASSERT(fXfermode);
+ fXfermode->ref();
int width = device.width();
fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * sizeof(SkPMColor));
@@ -818,6 +819,7 @@ SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter(
}
SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() {
+ fXfermode->unref();
sk_free(fBuffer);
}
@@ -895,14 +897,14 @@ SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint,
SkBlitter* blitter;
SkShader* shader = paint.getShader();
- bool is_srcover = paint.isSrcOver();
+ SkXfermode* mode = paint.getXfermode();
// we require a shader if there is an xfermode, handled by our caller
- SkASSERT(is_srcover || shader);
+ SkASSERT(nullptr == mode || shader);
if (shader) {
SkASSERT(shaderContext != nullptr);
- if (!is_srcover) {
+ if (mode) {
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 cef4cfaa2f..950f18791f 100644
--- a/src/core/SkBlitter_Sprite.cpp
+++ b/src/core/SkBlitter_Sprite.cpp
@@ -68,11 +68,14 @@ public:
if (0xFF != paint.getAlpha()) {
return false;
}
- SkBlendMode mode = paint.getBlendMode();
- if (SkBlendMode::kSrc == mode) {
+ SkXfermode::Mode mode;
+ if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) {
+ return false;
+ }
+ if (SkXfermode::kSrc_Mode == mode) {
return true;
}
- if (SkBlendMode::kSrcOver == mode && src.isOpaque()) {
+ if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) {
return true;
}
@@ -82,7 +85,7 @@ public:
return false;
}
- return SkBlendMode::kSrcOver == mode;
+ return SkXfermode::kSrcOver_Mode == mode;
}
SkSpriteBlitter_Src_SrcOver(const SkPixmap& src)
@@ -91,11 +94,14 @@ 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);
- SkBlendMode mode = paint.getBlendMode();
+ SkXfermode::Mode mode;
+ if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) {
+ SkFAIL("Should never happen.");
+ }
- SkASSERT(mode == SkBlendMode::kSrcOver || mode == SkBlendMode::kSrc);
+ SkASSERT(mode == SkXfermode::kSrcOver_Mode || mode == SkXfermode::kSrc_Mode);
- if (mode == SkBlendMode::kSrcOver && !fSource.isOpaque()) {
+ if (mode == SkXfermode::kSrcOver_Mode && !fSource.isOpaque()) {
fUseMemcpy = false;
}
}
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index cf3b5309c4..7db8601846 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -484,7 +484,7 @@ public:
*/
SkPaint tmp;
tmp.setImageFilter(fPaint->getImageFilter());
- tmp.setBlendMode(fPaint->getBlendMode());
+ tmp.setXfermode(sk_ref_sp(fPaint->getXfermode()));
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->setBlendMode(SkBlendMode::kSrcOver);
+ paint->setXfermode(nullptr);
}
if (fLooperContext && !fLooperContext->next(fCanvas, paint)) {
@@ -2634,7 +2634,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.isSrcOver())) {
+ (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) {
return;
}
@@ -2938,21 +2938,26 @@ 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, SkBlendMode mode) {
+void SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
+ SkXfermode::Mode mode) {
TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()");
SkPaint paint;
paint.setARGB(a, r, g, b);
- paint.setBlendMode(mode);
+ if (SkXfermode::kSrcOver_Mode != mode) {
+ paint.setXfermodeMode(mode);
+ }
this->drawPaint(paint);
}
-void SkCanvas::drawColor(SkColor c, SkBlendMode mode) {
+void SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) {
TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()");
SkPaint paint;
paint.setColor(c);
- paint.setBlendMode(mode);
+ if (SkXfermode::kSrcOver_Mode != mode) {
+ paint.setXfermodeMode(mode);
+ }
this->drawPaint(paint);
}
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 2a88781e48..53c8e5f0e8 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -7,7 +7,6 @@
#define __STDC_LIMIT_MACROS
#include "SkDraw.h"
-#include "SkBlendModePriv.h"
#include "SkBlitter.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
@@ -164,27 +163,31 @@ static BitmapXferProc ChooseBitmapXferProc(const SkPixmap& dst, const SkPaint& p
return nullptr;
}
- SkBlendMode mode = paint.getBlendMode();
+ SkXfermode::Mode mode;
+ if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) {
+ return nullptr;
+ }
+
SkColor color = paint.getColor();
// collaps modes based on color...
- if (SkBlendMode::kSrcOver == mode) {
+ if (SkXfermode::kSrcOver_Mode == mode) {
unsigned alpha = SkColorGetA(color);
if (0 == alpha) {
- mode = SkBlendMode::kDst;
+ mode = SkXfermode::kDst_Mode;
} else if (0xFF == alpha) {
- mode = SkBlendMode::kSrc;
+ mode = SkXfermode::kSrc_Mode;
}
}
switch (mode) {
- case SkBlendMode::kClear:
+ case SkXfermode::kClear_Mode:
// SkDebugf("--- D_Clear_BitmapXferProc\n");
return D_Clear_BitmapXferProc; // ignore data
- case SkBlendMode::kDst:
+ case SkXfermode::kDst_Mode:
// SkDebugf("--- D_Dst_BitmapXferProc\n");
return D_Dst_BitmapXferProc; // ignore data
- case SkBlendMode::kSrc: {
+ case SkXfermode::kSrc_Mode: {
/*
should I worry about dithering for the lower depths?
*/
@@ -1140,7 +1143,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 (SkBlendMode_SupportsCoverageAsAlpha(origPaint.getBlendMode())) {
+ } else if (SkXfermode::SupportsCoverageAsAlpha(origPaint.getXfermode())) {
U8CPU newAlpha;
#if 0
newAlpha = SkToU8(SkScalarRoundToInt(coverage *
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index ec3b0a9909..5b29884c25 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(SkBlendMode::kSrc);
+ paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
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(SkBlendMode::kSrc);
+ paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
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(SkBlendMode::kSrc);
+ paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
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(SkBlendMode::kSrc);
+ paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkIRect dstRect(srcRect);
scale_irect(&dstRect, scaleFactorX, scaleFactorY);
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 68183cc444..63095bc65d 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(SkBlendMode::kSrc);
+ paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
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 0a33280414..12efc64683 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.setBlendMode(SkBlendMode::kSrc);
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
paint.setFilterQuality(fFilterQuality);
input->draw(canvas, srcRect.x(), srcRect.y(), &paint);
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 1c5065e8c9..9d76a169b3 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -52,7 +52,6 @@ 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;
@@ -70,6 +69,7 @@ SkPaint::SkPaint(const SkPaint& src)
: COPY(fTypeface)
, COPY(fPathEffect)
, COPY(fShader)
+ , COPY(fXfermode)
, COPY(fMaskFilter)
, COPY(fColorFilter)
, COPY(fRasterizer)
@@ -81,7 +81,6 @@ SkPaint::SkPaint(const SkPaint& src)
, COPY(fColor)
, COPY(fWidth)
, COPY(fMiterLimit)
- , COPY(fBlendMode)
, COPY(fBitfields)
#undef COPY
{}
@@ -91,6 +90,7 @@ SkPaint::SkPaint(SkPaint&& src) {
MOVE(fTypeface);
MOVE(fPathEffect);
MOVE(fShader);
+ MOVE(fXfermode);
MOVE(fMaskFilter);
MOVE(fColorFilter);
MOVE(fRasterizer);
@@ -102,7 +102,6 @@ SkPaint::SkPaint(SkPaint&& src) {
MOVE(fColor);
MOVE(fWidth);
MOVE(fMiterLimit);
- MOVE(fBlendMode);
MOVE(fBitfields);
#undef MOVE
}
@@ -118,6 +117,7 @@ SkPaint& SkPaint::operator=(const SkPaint& src) {
ASSIGN(fTypeface);
ASSIGN(fPathEffect);
ASSIGN(fShader);
+ ASSIGN(fXfermode);
ASSIGN(fMaskFilter);
ASSIGN(fColorFilter);
ASSIGN(fRasterizer);
@@ -129,7 +129,6 @@ SkPaint& SkPaint::operator=(const SkPaint& src) {
ASSIGN(fColor);
ASSIGN(fWidth);
ASSIGN(fMiterLimit);
- ASSIGN(fBlendMode);
ASSIGN(fBitfields);
#undef ASSIGN
@@ -145,6 +144,7 @@ SkPaint& SkPaint::operator=(SkPaint&& src) {
MOVE(fTypeface);
MOVE(fPathEffect);
MOVE(fShader);
+ MOVE(fXfermode);
MOVE(fMaskFilter);
MOVE(fColorFilter);
MOVE(fRasterizer);
@@ -156,7 +156,6 @@ SkPaint& SkPaint::operator=(SkPaint&& src) {
MOVE(fColor);
MOVE(fWidth);
MOVE(fMiterLimit);
- MOVE(fBlendMode);
MOVE(fBitfields);
#undef MOVE
@@ -168,6 +167,7 @@ bool operator==(const SkPaint& a, const SkPaint& b) {
return EQUAL(fTypeface)
&& EQUAL(fPathEffect)
&& EQUAL(fShader)
+ && EQUAL(fXfermode)
&& EQUAL(fMaskFilter)
&& EQUAL(fColorFilter)
&& EQUAL(fRasterizer)
@@ -179,7 +179,6 @@ bool operator==(const SkPaint& a, const SkPaint& b) {
&& EQUAL(fColor)
&& EQUAL(fWidth)
&& EQUAL(fMiterLimit)
- && EQUAL(fBlendMode)
&& EQUAL(fBitfieldsUInt)
;
#undef EQUAL
@@ -361,6 +360,7 @@ MOVE_FIELD(Rasterizer)
MOVE_FIELD(ImageFilter)
MOVE_FIELD(Shader)
MOVE_FIELD(ColorFilter)
+MOVE_FIELD(Xfermode)
MOVE_FIELD(PathEffect)
MOVE_FIELD(MaskFilter)
MOVE_FIELD(DrawLooper)
@@ -386,10 +386,7 @@ SET_PTR(Shader)
SET_PTR(ColorFilter)
#endif
#ifdef SK_SUPPORT_LEGACY_XFERMODE_PTR
-SkXfermode* SkPaint::setXfermode(SkXfermode* xfer) {
- this->setBlendMode(xfer ? xfer->blend() : SkBlendMode::kSrcOver);
- return this->getXfermode();
-}
+SET_PTR(Xfermode)
#endif
#ifdef SK_SUPPORT_LEGACY_PATHEFFECT_PTR
SET_PTR(PathEffect)
@@ -406,18 +403,10 @@ 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) {
- this->setBlendMode((SkBlendMode)mode);
- return SkXfermode::Peek((SkBlendMode)mode);
+ fXfermode = SkXfermode::Make(mode);
+ return fXfermode.get(); // can/should we change this API to be void, like the other setters?
}
-#endif
///////////////////////////////////////////////////////////////////////////////
@@ -1915,6 +1904,7 @@ 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()) |
@@ -1933,8 +1923,7 @@ 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() << 4) | this->getTextEncoding(),
- fBlendMode));
+ this->getStyle(), this->getTextEncoding()));
// now we're done with ptr and the (pre)reserved space. If we need to write
// additional fields, use the buffer directly
@@ -1944,6 +1933,7 @@ 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());
@@ -1965,14 +1955,8 @@ 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));
- 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));
- }
+ this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
+ this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
if (flatFlags & kHasTypeface_FlatFlag) {
this->setTypeface(buffer.readTypeface());
@@ -1983,16 +1967,7 @@ void SkPaint::unflatten(SkReadBuffer& buffer) {
if (flatFlags & kHasEffects_FlatFlag) {
this->setPathEffect(buffer.readPathEffect());
this->setShader(buffer.readShader());
- 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->setXfermode(buffer.readXfermode());
this->setMaskFilter(buffer.readMaskFilter());
this->setColorFilter(buffer.readColorFilter());
this->setRasterizer(buffer.readRasterizer());
@@ -2011,6 +1986,7 @@ void SkPaint::unflatten(SkReadBuffer& buffer) {
} else {
this->setPathEffect(nullptr);
this->setShader(nullptr);
+ this->setXfermode(nullptr);
this->setMaskFilter(nullptr);
this->setColorFilter(nullptr);
this->setRasterizer(nullptr);
@@ -2140,8 +2116,11 @@ void SkPaint::toString(SkString* str) const {
str->append("</dd>");
}
- if (!this->isSrcOver()) {
- str->appendf("<dt>Xfermode:</dt><dd>%d</dd>", fBlendMode);
+ SkXfermode* xfer = this->getXfermode();
+ if (xfer) {
+ str->append("<dt>Xfermode:</dt><dd>");
+ xfer->toString(str);
+ str->append("</dd>");
}
SkMaskFilter* maskFilter = this->getMaskFilter();
@@ -2384,20 +2363,23 @@ bool SkPaint::nothingToDraw() const {
if (fDrawLooper) {
return false;
}
- 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;
+ 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;
+ }
}
return false;
}
@@ -2405,7 +2387,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) == 8 * sizeof(void*) + 7 * sizeof(uint32_t),
+ static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * 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 cbe2558c2a..6725cb49be 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->getBlendMode(), opacityType);
+ return SkXfermode::IsOpaque(paint->getXfermode(), opacityType);
}
bool SkPaintPriv::Overwrites(const SkBitmap& bitmap, const SkPaint* paint) {
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index 108c87757b..77498396b0 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.setBlendMode(SkBlendMode::kSrc);
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
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 91d60bee3a..1e8dcf59e0 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(SkXfermode::Peek(paint.getBlendMode()), &xfermode )) {
+ if (!append_effect_stages(paint.getColorFilter(), &colorFilter) ||
+ !append_effect_stages(paint.getXfermode(), &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.isSrcOver()) {
+ if (!paint.getXfermode()) {
blitter->fXfermode.append(SkRasterPipeline::srcover);
}
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index 4ac7973198..3e6742fde0 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -69,7 +69,6 @@ public:
kLightingShaderWritesInvNormRotation = 45,
kBlurMaskFilterWritesOccluder = 47,
kGradientShaderFloatColor_Version = 49,
- kXfermodeToBlendMode_Version = 50,
};
/**
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index dca19df100..ca9c1b6f78 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -341,27 +341,34 @@ private:
return true;
}
- // Unusual blendmodes require us to process a saved layer
+ // Unusual Xfermodes 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
- 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;
+ 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;
+ }
}
}
return false;
diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp
index a7feec1fb3..d46a6573b5 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->isSrcOver() || paint->getLooper()) {
+ if (paint->getXfermode() || 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->isSrcOver() ||
+ layerPaint->getXfermode() ||
layerPaint->getMaskFilter() ||
layerPaint->getColorFilter() ||
layerPaint->getRasterizer() ||
@@ -174,12 +174,16 @@ void SkRecordNoopSaveRestores(SkRecord* record) {
}
static bool effectively_srcover(const SkPaint* paint) {
- if (!paint || paint->isSrcOver()) {
+ if (!paint) {
+ return true;
+ }
+ SkXfermode* mode = paint->getXfermode();
+ if (SkXfermode::IsMode(mode, SkXfermode::kSrcOver_Mode)) {
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() && paint->getBlendMode() == SkBlendMode::kSrc;
+ 0xFF == paint->getAlpha() && SkXfermode::IsMode(mode, SkXfermode::kSrc_Mode);
}
// 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 38ec7394d7..a13edd9806 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 = SkXfermode::Peek(paint.getBlendMode());
+ fXfer = paint.getXfermode();
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 1a76b1b2fe..93885996ea 100644
--- a/src/core/SkSpriteBlitter_ARGB32.cpp
+++ b/src/core/SkSpriteBlitter_ARGB32.cpp
@@ -63,7 +63,8 @@ public:
fColorFilter = paint.getColorFilter();
SkSafeRef(fColorFilter);
- fXfermode = SkXfermode::Peek(paint.getBlendMode());
+ fXfermode = paint.getXfermode();
+ SkSafeRef(fXfermode);
fBufferSize = 0;
fBuffer = nullptr;
@@ -82,6 +83,7 @@ public:
virtual ~Sprite_D32_XferFilter() {
delete[] fBuffer;
+ SkSafeUnref(fXfermode);
SkSafeUnref(fColorFilter);
}
@@ -261,7 +263,7 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPain
}
U8CPU alpha = paint.getAlpha();
- bool isSrcOver = paint.isSrcOver();
+ SkXfermode* xfermode = paint.getXfermode();
SkColorFilter* filter = paint.getColorFilter();
SkSpriteBlitter* blitter = nullptr;
@@ -270,7 +272,7 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPain
if (alpha != 0xFF) {
return nullptr; // we only have opaque sprites
}
- if (!isSrcOver || filter) {
+ if (xfermode || filter) {
blitter = allocator->createT<Sprite_D32_S4444_XferFilter>(source, paint);
} else if (source.isOpaque()) {
blitter = allocator->createT<Sprite_D32_S4444_Opaque>(source);
@@ -279,7 +281,7 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPain
}
break;
case kN32_SkColorType:
- if (!isSrcOver || filter) {
+ if (xfermode || 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 9df7dab48c..6c5a7cb130 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.isSrcOver()) { // may add cases for this
+ if (paint.getXfermode() != nullptr) { // 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 226f2b8b43..2717fab7e9 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -1553,64 +1553,3 @@ 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 3a1da368d7..1b2c8e32e6 100644
--- a/src/core/SkXfermodeInterpretation.cpp
+++ b/src/core/SkXfermodeInterpretation.cpp
@@ -9,31 +9,38 @@
#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) {
- switch (paint.getBlendMode()) {
- case SkBlendMode::kSrcOver:
+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:
return kSrcOver_SkXfermodeInterpretation;
- case SkBlendMode::kSrc:
+ case SkXfermode::kSrc_Mode:
if (just_solid_color(paint)) {
return kSrcOver_SkXfermodeInterpretation;
}
return kNormal_SkXfermodeInterpretation;
- case SkBlendMode::kDst:
+ case SkXfermode::kDst_Mode:
return kSkipDrawing_SkXfermodeInterpretation;
- case SkBlendMode::kDstOver:
+ case SkXfermode::kDstOver_Mode:
if (dstIsOpaque) {
return kSkipDrawing_SkXfermodeInterpretation;
}
return kNormal_SkXfermodeInterpretation;
- case SkBlendMode::kSrcIn:
+ case SkXfermode::kSrcIn_Mode:
if (dstIsOpaque && just_solid_color(paint)) {
return kSrcOver_SkXfermodeInterpretation;
}
return kNormal_SkXfermodeInterpretation;
- case SkBlendMode::kDstIn:
+ case SkXfermode::kDstIn_Mode:
if (just_solid_color(paint)) {
return kSkipDrawing_SkXfermodeInterpretation;
}