aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2016-10-04 10:06:20 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-10-04 20:09:34 +0000
commit1834242ec6e3cd62669227d394bc79e1cd66dcfb (patch)
treec956e75f272619b5901ca0beab31dbf4a50d9974 /src/core
parent6942442ef7cc018ac136dd379ad6a30902a060e5 (diff)
Revert[4] "replace SkXfermode obj with SkBlendMode enum in paints"
This reverts commit 2cbcd12281ee807214df094964c584c78932e10b. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2924 Change-Id: I0fa5c58af428f3da8565465d1219a34ef8417d9a Reviewed-on: https://skia-review.googlesource.com/2924 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Reed <reed@google.com>
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, 230 insertions, 172 deletions
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 b57bd43ad0..3643e66760 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -815,7 +815,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);
@@ -828,12 +828,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>();
@@ -848,13 +848,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);
}
@@ -863,7 +863,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);
@@ -914,7 +914,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 7db8601846..cf3b5309c4 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)) {
@@ -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.getXfermode() == nullptr)) {
+ (paint.getAlpha() == 0 && paint.isSrcOver())) {
return;
}
@@ -2938,26 +2938,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 53c8e5f0e8..2a88781e48 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..1c5065e8c9 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)
@@ -386,7 +386,10 @@ SET_PTR(Shader)
SET_PTR(ColorFilter)
#endif
#ifdef SK_SUPPORT_LEGACY_XFERMODE_PTR
-SET_PTR(Xfermode)
+SkXfermode* SkPaint::setXfermode(SkXfermode* xfer) {
+ this->setBlendMode(xfer ? xfer->blend() : SkBlendMode::kSrcOver);
+ return this->getXfermode();
+}
#endif
#ifdef SK_SUPPORT_LEGACY_PATHEFFECT_PTR
SET_PTR(PathEffect)
@@ -403,10 +406,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 +1915,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 +1933,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 +1944,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 +1965,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 +1983,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 +2011,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 +2140,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 +2384,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 +2405,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 8a3b7bac88..6b0d332e0f 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 58c557805b..38a160870e 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -1472,3 +1472,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;
}