Revert "replace SkXfermode obj with SkBlendMode enum in paints"
authorMike Reed <reed@google.com>
Mon, 3 Oct 2016 18:02:50 +0000 (18:02 +0000)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 3 Oct 2016 18:03:29 +0000 (18:03 +0000)
This reverts commit I4fb489ba6b3f77b458f7e4a99f79c7ad10859135.

Reason for revert: <INSERT REASONING HERE>

Original change's description:
> 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>
>

TBR=bsalomon@google.com,fmalita@chromium.org,fmalita@google.com,reed@google.com,reviews@skia.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Change-Id: I3e43f79ef5c1709929663fe63cc1f67cd78270b7
Reviewed-on: https://skia-review.googlesource.com/2871
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>

139 files changed:
bench/RectBench.cpp
bench/RotatedRectBench.cpp
bench/XfermodeBench.cpp
dm/DMSrcSink.cpp
fuzz/FilterFuzz.cpp
gm/aaclip.cpp
gm/aarectmodes.cpp
gm/aaxfermodes.cpp
gm/bitmaprect.cpp
gm/blurredclippedcircle.cpp
gm/colormatrix.cpp
gm/colortypexfermode.cpp
gm/drawatlas.cpp
gm/drawatlascolor.cpp
gm/dstreadshuffle.cpp
gm/gamma.cpp
gm/gm.cpp
gm/hairmodes.cpp
gm/imagefilters.cpp
gm/imagefiltersgraph.cpp
gm/imagefilterstransformed.cpp
gm/lcdblendmodes.cpp
gm/lcdoverlap.cpp
gm/lumafilter.cpp
gm/modecolorfilters.cpp
gm/picture.cpp
gm/plus.cpp
gm/srcmode.cpp
gm/textblobblockreordering.cpp
gm/textbloblooper.cpp
gm/texteffects.cpp
gm/texturedomaineffect.cpp
gm/verylargebitmap.cpp
gm/xfermodeimagefilter.cpp
gm/xfermodes.cpp
gm/xfermodes2.cpp
gm/xfermodes3.cpp
gyp/skia_for_android_framework_defines.gypi
include/core/SkBlendMode.h [deleted file]
include/core/SkCanvas.h
include/core/SkColorFilter.h
include/core/SkPaint.h
include/core/SkPicture.h
include/core/SkXfermode.h
include/effects/SkXfermodeImageFilter.h
include/gpu/GrPaint.h
include/gpu/effects/GrPorterDuffXferProcessor.h
public.bzl
samplecode/SampleAARectModes.cpp
samplecode/SampleAll.cpp
samplecode/SampleApp.cpp
samplecode/SampleColorFilter.cpp
samplecode/SampleFatBits.cpp
samplecode/SampleFilterFuzz.cpp
samplecode/SampleFuzz.cpp
samplecode/SampleHairModes.cpp
samplecode/SampleLayerMask.cpp
samplecode/SampleLayers.cpp
samplecode/SamplePathClip.cpp
samplecode/SampleQuadStroker.cpp
samplecode/SampleRegion.cpp
samplecode/SampleSlides.cpp
samplecode/SampleXfer.cpp
samplecode/SampleXfermodesBlur.cpp
src/c/sk_paint.cpp
src/core/SkBitmapDevice.cpp
src/core/SkBlendModePriv.h [deleted file]
src/core/SkBlitter.cpp
src/core/SkBlitter_A8.cpp
src/core/SkBlitter_ARGB32.cpp
src/core/SkBlitter_PM4f.cpp
src/core/SkBlitter_RGB16.cpp
src/core/SkBlitter_Sprite.cpp
src/core/SkCanvas.cpp
src/core/SkDraw.cpp
src/core/SkGpuBlurUtils.cpp
src/core/SkImageFilter.cpp
src/core/SkMatrixImageFilter.cpp
src/core/SkPaint.cpp
src/core/SkPaintPriv.cpp
src/core/SkPixmap.cpp
src/core/SkRasterPipelineBlitter.cpp
src/core/SkReadBuffer.h
src/core/SkRecordDraw.cpp
src/core/SkRecordOpts.cpp
src/core/SkSpriteBlitter4f.cpp
src/core/SkSpriteBlitter_ARGB32.cpp
src/core/SkSpriteBlitter_RGB16.cpp
src/core/SkXfermode.cpp
src/core/SkXfermodeInterpretation.cpp
src/effects/SkAlphaThresholdFilter.cpp
src/effects/SkColorFilterImageFilter.cpp
src/effects/SkDisplacementMapEffect.cpp
src/effects/SkDropShadowImageFilter.cpp
src/effects/SkImageSource.cpp
src/effects/SkLayerDrawLooper.cpp
src/effects/SkLightingImageFilter.cpp
src/effects/SkMergeImageFilter.cpp
src/effects/SkMorphologyImageFilter.cpp
src/effects/SkOffsetImageFilter.cpp
src/effects/SkTileImageFilter.cpp
src/effects/SkXfermodeImageFilter.cpp
src/gpu/GrContext.cpp
src/gpu/GrDrawContext.cpp
src/gpu/GrSWMaskHelper.cpp
src/gpu/GrTextureParamsAdjuster.cpp
src/gpu/GrTextureToYUVPlanes.cpp
src/gpu/GrYUVProvider.cpp
src/gpu/SkGr.cpp
src/gpu/effects/GrConfigConversionEffect.cpp
src/gpu/text/GrTextUtils.cpp
src/image/SkImage.cpp
src/pdf/SkPDFDevice.cpp
src/pdf/SkPDFDevice.h
src/pdf/SkPDFGraphicState.cpp
src/pdf/SkPDFGraphicState.h
src/pipe/SkPipeCanvas.cpp
src/pipe/SkPipeFormat.h
src/pipe/SkPipeReader.cpp
src/utils/SkDumpCanvas.cpp
src/utils/SkLua.cpp
src/utils/SkRGBAToYUV.cpp
src/xps/SkXPSDevice.cpp
tests/ApplyGammaTest.cpp
tests/ImageFilterTest.cpp
tests/ImageTest.cpp
tests/LayerDrawLooperTest.cpp
tests/PDFOpaqueSrcModeToSrcOverTest.cpp
tests/PaintTest.cpp
tests/ReadPixelsTest.cpp
tests/RecordDrawTest.cpp
tests/RecordOptsTest.cpp
tests/RecordingXfermodeTest.cpp
tests/SerializationTest.cpp
tests/WritePixelsTest.cpp
tools/debugger/SkDebugCanvas.cpp
tools/debugger/SkDrawCommand.cpp
tools/sk_tool_utils.cpp
tools/viewer/sk_app/mac/RasterWindowContext_mac.cpp

index 48764ca..46a515d 100644 (file)
@@ -85,7 +85,7 @@ private:
 class SrcModeRectBench : public RectBench {
 public:
     SrcModeRectBench() : INHERITED(1, 0) {
-        fMode = SkBlendMode::kSrc;
+        fMode = SkXfermode::Make(SkXfermode::kSrc_Mode);
     }
 
 protected:
@@ -93,7 +93,7 @@ protected:
         this->INHERITED::setupPaint(paint);
         // srcmode is most interesting when we're not opaque
         paint->setAlpha(0x80);
-        paint->setBlendMode(fMode);
+        paint->setXfermode(fMode);
     }
 
     const char* onGetName() override {
@@ -103,8 +103,8 @@ protected:
     }
 
 private:
-    SkString    fName;
-    SkBlendMode fMode;
+    SkString fName;
+    sk_sp<SkXfermode> fMode;
 
     typedef RectBench INHERITED;
 };
index f81bfb1..23e0443 100644 (file)
@@ -67,7 +67,7 @@ static SkString to_lower(const char* str) {
 
 class RotRectBench: public Benchmark {
 public:
-    RotRectBench(bool aa, ColorType ct, SkBlendMode mode)
+    RotRectBench(bool aa, ColorType ct, SkXfermode::Mode mode)
         : fAA(aa)
         , fColorType(ct)
         , fMode(mode) {
@@ -80,7 +80,7 @@ protected:
     void onDraw(int loops, SkCanvas* canvas) override {
         SkPaint paint;
         paint.setAntiAlias(fAA);
-        paint.setBlendMode(fMode);
+        paint.setXfermodeMode(fMode);
         SkColor color = start_color(fColorType);
 
         int w = this->getSize().x();
@@ -147,48 +147,48 @@ private:
         fName.appendf("_%s", to_lower(SkXfermode::ModeName(fMode)).c_str());
     }
 
-    bool        fAA;
-    ColorType   fColorType;
-    SkBlendMode fMode;
-    SkString    fName;
+    bool             fAA;
+    ColorType        fColorType;
+    SkXfermode::Mode fMode;
+    SkString         fName;
 
     typedef Benchmark INHERITED;
 };
 
 // Choose kSrcOver because it always allows coverage and alpha to be conflated. kSrc only allows
 // conflation when opaque, and kDarken because it isn't possilbe with standard GL blending.
-DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkBlendMode::kSrcOver);)
-DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkBlendMode::kSrcOver);)
-DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkBlendMode::kSrcOver);)
-DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkBlendMode::kSrcOver);)
-DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kSrcOver);)
-
-DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkBlendMode::kSrcOver);)
-DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkBlendMode::kSrcOver);)
-DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkBlendMode::kSrcOver);)
-DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkBlendMode::kSrcOver);)
-DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kSrcOver);)
-
-DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkBlendMode::kSrc);)
-DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkBlendMode::kSrc);)
-DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkBlendMode::kSrc);)
-DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkBlendMode::kSrc);)
-DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kSrc);)
-
-DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkBlendMode::kSrc);)
-DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkBlendMode::kSrc);)
-DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkBlendMode::kSrc);)
-DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkBlendMode::kSrc);)
-DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kSrc);)
-
-DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkBlendMode::kDarken);)
-DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkBlendMode::kDarken);)
-DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkBlendMode::kDarken);)
-DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkBlendMode::kDarken);)
-DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kDarken);)
-
-DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkBlendMode::kDarken);)
-DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkBlendMode::kDarken);)
-DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkBlendMode::kDarken);)
-DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkBlendMode::kDarken);)
-DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kDarken);)
+DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
+
+DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
+DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
+
+DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);)
+
+DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kSrc_Mode);)
+DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);)
+
+DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);)
+
+DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kDarken_Mode);)
+DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);)
index 9e148d4..60879d6 100644 (file)
 // Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode.
 class XfermodeBench : public Benchmark {
 public:
-    XfermodeBench(SkBlendMode mode, bool aa) : fBlendMode(mode) {
+    XfermodeBench(SkXfermode::Mode mode, bool aa) {
+        fXfermode = SkXfermode::Make(mode);
         fAA = aa;
+        SkASSERT(fXfermode.get() || SkXfermode::kSrcOver_Mode == mode);
         fName.printf("Xfermode_%s%s", SkXfermode::ModeName(mode), aa ? "_aa" : "");
     }
 
@@ -30,7 +32,7 @@ protected:
         SkRandom random;
         for (int i = 0; i < loops; ++i) {
             SkPaint paint;
-            paint.setBlendMode(fBlendMode);
+            paint.setXfermode(fXfermode);
             paint.setColor(random.nextU());
             if (fAA) {
                 // Draw text to exercise AA code paths.
@@ -59,48 +61,71 @@ protected:
     }
 
 private:
-    SkBlendMode fBlendMode;
-    SkString    fName;
-    bool        fAA;
+    sk_sp<SkXfermode>   fXfermode;
+    SkString            fName;
+    bool                fAA;
 
     typedef Benchmark INHERITED;
 };
 
+class XferCreateBench : public Benchmark {
+public:
+    bool isSuitableFor(Backend backend) override {
+        return backend == kNonRendering_Backend;
+    }
+
+protected:
+    const char* onGetName() override { return "xfermode_create"; }
+
+    void onDraw(int loops, SkCanvas* canvas) override {
+        for (int outer = 0; outer < loops * 10; ++outer) {
+            for (int i = 0; i <= SkXfermode::kLastMode; ++i) {
+                (void)SkXfermode::Make(SkXfermode::Mode(i));
+            }
+        }
+    }
+
+private:
+    typedef Benchmark INHERITED;
+};
+
 //////////////////////////////////////////////////////////////////////////////
 
 #define BENCH(...)                                             \
     DEF_BENCH( return new XfermodeBench(__VA_ARGS__, true); )  \
     DEF_BENCH( return new XfermodeBench(__VA_ARGS__, false); )
 
-BENCH(SkBlendMode::kClear)
-BENCH(SkBlendMode::kSrc)
-BENCH(SkBlendMode::kDst)
-BENCH(SkBlendMode::kSrcOver)
-BENCH(SkBlendMode::kDstOver)
-BENCH(SkBlendMode::kSrcIn)
-BENCH(SkBlendMode::kDstIn)
-BENCH(SkBlendMode::kSrcOut)
-BENCH(SkBlendMode::kDstOut)
-BENCH(SkBlendMode::kSrcATop)
-BENCH(SkBlendMode::kDstATop)
-BENCH(SkBlendMode::kXor)
-
-BENCH(SkBlendMode::kPlus)
-BENCH(SkBlendMode::kModulate)
-BENCH(SkBlendMode::kScreen)
-
-BENCH(SkBlendMode::kOverlay)
-BENCH(SkBlendMode::kDarken)
-BENCH(SkBlendMode::kLighten)
-BENCH(SkBlendMode::kColorDodge)
-BENCH(SkBlendMode::kColorBurn)
-BENCH(SkBlendMode::kHardLight)
-BENCH(SkBlendMode::kSoftLight)
-BENCH(SkBlendMode::kDifference)
-BENCH(SkBlendMode::kExclusion)
-BENCH(SkBlendMode::kMultiply)
-
-BENCH(SkBlendMode::kHue)
-BENCH(SkBlendMode::kSaturation)
-BENCH(SkBlendMode::kColor)
-BENCH(SkBlendMode::kLuminosity)
+BENCH(SkXfermode::kClear_Mode)
+BENCH(SkXfermode::kSrc_Mode)
+BENCH(SkXfermode::kDst_Mode)
+BENCH(SkXfermode::kSrcOver_Mode)
+BENCH(SkXfermode::kDstOver_Mode)
+BENCH(SkXfermode::kSrcIn_Mode)
+BENCH(SkXfermode::kDstIn_Mode)
+BENCH(SkXfermode::kSrcOut_Mode)
+BENCH(SkXfermode::kDstOut_Mode)
+BENCH(SkXfermode::kSrcATop_Mode)
+BENCH(SkXfermode::kDstATop_Mode)
+BENCH(SkXfermode::kXor_Mode)
+
+BENCH(SkXfermode::kPlus_Mode)
+BENCH(SkXfermode::kModulate_Mode)
+BENCH(SkXfermode::kScreen_Mode)
+
+BENCH(SkXfermode::kOverlay_Mode)
+BENCH(SkXfermode::kDarken_Mode)
+BENCH(SkXfermode::kLighten_Mode)
+BENCH(SkXfermode::kColorDodge_Mode)
+BENCH(SkXfermode::kColorBurn_Mode)
+BENCH(SkXfermode::kHardLight_Mode)
+BENCH(SkXfermode::kSoftLight_Mode)
+BENCH(SkXfermode::kDifference_Mode)
+BENCH(SkXfermode::kExclusion_Mode)
+BENCH(SkXfermode::kMultiply_Mode)
+
+BENCH(SkXfermode::kHue_Mode)
+BENCH(SkXfermode::kSaturation_Mode)
+BENCH(SkXfermode::kColor_Mode)
+BENCH(SkXfermode::kLuminosity_Mode)
+
+DEF_BENCH(return new XferCreateBench;)
index 585a51d..0565ee9 100644 (file)
@@ -1454,7 +1454,7 @@ Error ViaUpright::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkSt
     SkCanvas canvas(uprighted);
     canvas.concat(upright);
     SkPaint paint;
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     canvas.drawBitmap(*bitmap, 0, 0, &paint);
 
     *bitmap = uprighted;
index e6f9cb3..6b766a2 100644 (file)
@@ -154,8 +154,8 @@ static SkMatrix make_matrix() {
     return m;
 }
 
-static SkBlendMode make_blendmode() {
-    return static_cast<SkBlendMode>(R((int)SkBlendMode::kLastMode+1));
+static SkXfermode::Mode make_xfermode() {
+    return static_cast<SkXfermode::Mode>(R(SkXfermode::kLastMode+1));
 }
 
 static SkPaint::Align make_paint_align() {
@@ -369,7 +369,7 @@ static sk_sp<SkColorFilter> make_color_filter() {
             return SkTableColorFilter::MakeARGB(tableA, tableR, tableG, tableB);
         }
         case 3:
-            return SkColorFilter::MakeModeFilter(make_color(), (SkXfermode::Mode)make_blendmode());
+            return SkColorFilter::MakeModeFilter(make_color(), make_xfermode());
         case 4:
             return SkColorMatrixFilter::MakeLightingFilter(make_color(), make_color());
         case 5:
@@ -505,7 +505,7 @@ static SkPaint make_paint() {
     paint.setStrokeCap(make_paint_cap());
     paint.setStrokeJoin(make_paint_join());
     paint.setColorFilter(make_color_filter());
-    paint.setBlendMode(make_blendmode());
+    paint.setXfermodeMode(make_xfermode());
     paint.setPathEffect(make_path_effect());
     paint.setMaskFilter(make_mask_filter());
 
@@ -540,7 +540,7 @@ static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) {
     }
 
     enum { ALPHA_THRESHOLD, MERGE, COLOR, LUT3D, BLUR, MAGNIFIER,
-           BLENDMODE, OFFSET, MATRIX, MATRIX_CONVOLUTION, COMPOSE,
+           XFERMODE, OFFSET, MATRIX, MATRIX_CONVOLUTION, COMPOSE,
            DISTANT_LIGHT, POINT_LIGHT, SPOT_LIGHT, NOISE, DROP_SHADOW,
            MORPHOLOGY, BITMAP, DISPLACE, TILE, PICTURE, PAINT, NUM_FILTERS };
 
@@ -554,7 +554,7 @@ static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) {
     case MERGE:
         filter = SkMergeImageFilter::Make(make_image_filter(),
                                           make_image_filter(),
-                                          (SkXfermode::Mode)make_blendmode());
+                                          make_xfermode());
         break;
     case COLOR: {
         sk_sp<SkColorFilter> cf(make_color_filter());
@@ -580,8 +580,8 @@ static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) {
                                               make_scalar(true),
                                               make_image_filter());
         break;
-    case BLENDMODE:
-        filter = SkXfermodeImageFilter::Make(make_blendmode(),
+    case XFERMODE:
+        filter = SkXfermodeImageFilter::Make(SkXfermode::Make(make_xfermode()),
                                              make_image_filter(),
                                              make_image_filter(),
                                              nullptr);
index f00a4cd..26a25c1 100644 (file)
@@ -11,7 +11,7 @@
 
 static void do_draw(SkCanvas* canvas, const SkRect& r) {
     SkPaint paint;
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     paint.setColor(0x800000FF);
     canvas->drawRect(r, paint);
 }
index ebc47c2..6e9f4bf 100644 (file)
@@ -59,21 +59,21 @@ static void test4(SkCanvas* canvas) {
 }
 
 constexpr struct {
-    SkBlendMode fMode;
-    const char* fLabel;
+    SkXfermode::Mode  fMode;
+    const char*         fLabel;
 } gModes[] = {
-    { SkBlendMode::kClear,    "Clear"     },
-    { SkBlendMode::kSrc,      "Src"       },
-    { SkBlendMode::kDst,      "Dst"       },
-    { SkBlendMode::kSrcOver,  "SrcOver"   },
-    { SkBlendMode::kDstOver,  "DstOver"   },
-    { SkBlendMode::kSrcIn,    "SrcIn"     },
-    { SkBlendMode::kDstIn,    "DstIn"     },
-    { SkBlendMode::kSrcOut,   "SrcOut"    },
-    { SkBlendMode::kDstOut,   "DstOut"    },
-    { SkBlendMode::kSrcATop,  "SrcATop"   },
-    { SkBlendMode::kDstATop,  "DstATop"   },
-    { SkBlendMode::kXor,      "Xor"       },
+    { SkXfermode::kClear_Mode,    "Clear"     },
+    { SkXfermode::kSrc_Mode,      "Src"       },
+    { SkXfermode::kDst_Mode,      "Dst"       },
+    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
+    { SkXfermode::kDstOver_Mode,  "DstOver"   },
+    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
+    { SkXfermode::kDstIn_Mode,    "DstIn"     },
+    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
+    { SkXfermode::kDstOut_Mode,   "DstOut"    },
+    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
+    { SkXfermode::kDstATop_Mode,  "DstATop"   },
+    { SkXfermode::kXor_Mode,      "Xor"       },
 };
 
 const int gWidth = 64;
@@ -81,7 +81,7 @@ const int gHeight = 64;
 const SkScalar W = SkIntToScalar(gWidth);
 const SkScalar H = SkIntToScalar(gHeight);
 
-static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha a1) {
+static SkScalar drawCell(SkCanvas* canvas, sk_sp<SkXfermode> mode, SkAlpha a0, SkAlpha a1) {
 
     SkPaint paint;
     paint.setAntiAlias(true);
@@ -95,7 +95,7 @@ static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha
 
     paint.setColor(SK_ColorRED);
     paint.setAlpha(a1);
-    paint.setBlendMode(mode);
+    paint.setXfermode(std::move(mode));
 
     SkScalar offset = SK_Scalar1 / 3;
     SkRect rect = SkRect::MakeXYWH(W / 4 + offset,
@@ -155,7 +155,7 @@ namespace skiagm {
                     }
                     canvas->drawRect(bounds, fBGPaint);
                     canvas->saveLayer(&bounds, nullptr);
-                    SkScalar dy = drawCell(canvas, gModes[i].fMode,
+                    SkScalar dy = drawCell(canvas, SkXfermode::Make(gModes[i].fMode),
                                            gAlphaValue[alpha & 1],
                                            gAlphaValue[alpha & 2]);
                     canvas->restore();
index 7106ce8..678a837 100644 (file)
@@ -121,7 +121,7 @@ protected:
                 if (firstMode + m > SkXfermode::kLastMode) {
                     break;
                 }
-                SkBlendMode mode = static_cast<SkBlendMode>(firstMode + m);
+                SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(firstMode + m);
                 canvas->save();
 
                 if (kShape_Pass == drawingPass) {
@@ -144,7 +144,7 @@ protected:
                                         10);
                             } else {
                                 SkASSERT(kBackground_Pass == drawingPass);
-                                canvas->drawColor(kBGColor, SkBlendMode::kSrc);
+                                canvas->drawColor(kBGColor, SkXfermode::kSrc_Mode);
                             }
                             canvas->restore();
                         } else {
@@ -190,17 +190,18 @@ protected:
         canvas->restore();
     }
 
-    void drawModeName(SkCanvas* canvas, SkBlendMode mode) {
-        const char* modeName = SkXfermode::ModeName(mode);
+    void drawModeName(SkCanvas* canvas, SkXfermode::Mode mode) {
+        const char* modeName = mode <= SkXfermode::kLastMode ? SkXfermode::ModeName(mode)
+                                                             : "Arithmetic";
         fLabelPaint.setTextAlign(SkPaint::kRight_Align);
         canvas->drawText(modeName, strlen(modeName), kLabelSpacing - kShapeSize / 4,
                          fLabelPaint.getTextSize() / 4, fLabelPaint);
     }
 
-    void setupShapePaint(SkCanvas* canvas, GrColor color, SkBlendMode mode, SkPaint* paint) {
+    void setupShapePaint(SkCanvas* canvas, GrColor color, SkXfermode::Mode mode, SkPaint* paint) {
         paint->setColor(color);
 
-        if (mode == SkBlendMode::kPlus) {
+        if (mode == SkXfermode::kPlus_Mode) {
             // Check for overflow, otherwise we might get confusing AA artifacts.
             int maxSum = SkTMax(SkTMax(SkColorGetA(kBGColor) + SkColorGetA(color),
                                        SkColorGetR(kBGColor) + SkColorGetR(color)),
@@ -210,7 +211,7 @@ protected:
             if (maxSum > 255) {
                 SkPaint dimPaint;
                 dimPaint.setAntiAlias(false);
-                dimPaint.setBlendMode(SkBlendMode::kDstIn);
+                dimPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
                 if (255 != paint->getAlpha()) {
                     // Dim the src and dst colors.
                     dimPaint.setARGB(255 * 255 / maxSum, 0, 0, 0);
@@ -226,11 +227,11 @@ protected:
         }
     }
 
-    void drawShape(SkCanvas* canvas, Shape shape, const SkPaint& paint, SkBlendMode mode) {
-        SkASSERT(mode <= SkBlendMode::kLastMode);
+    void drawShape(SkCanvas* canvas, Shape shape, const SkPaint& paint, SkXfermode::Mode mode) {
+        SkASSERT(mode <= SkXfermode::kLastMode);
         SkPaint shapePaint(paint);
         shapePaint.setAntiAlias(kSquare_Shape != shape);
-        shapePaint.setBlendMode(mode);
+        shapePaint.setXfermodeMode(mode);
 
         switch (shape) {
             case kSquare_Shape:
@@ -248,7 +249,7 @@ protected:
 
             case kOval_Shape:
                 canvas->save();
-                canvas->rotate(static_cast<SkScalar>((511 * (int)mode + 257) % 360));
+                canvas->rotate(static_cast<SkScalar>((511 * mode + 257) % 360));
                 canvas->drawPath(fOval, shapePaint);
                 canvas->restore();
                 break;
index 06bf36a..2a81300 100644 (file)
@@ -201,7 +201,7 @@ protected:
     void onDraw(SkCanvas* canvas) override {
         SkPaint paint;
         paint.setAlpha(128);
-        paint.setBlendMode(SkBlendMode::kXor);
+        paint.setXfermode(SkXfermode::Make(SkXfermode::kXor_Mode));
 
         SkRect srcR1 = { 0.0f, 0.0f, 4096.0f, 2040.0f };
         SkRect dstR1 = { 10.1f, 10.1f, 629.9f, 400.9f };
index a0359c3..a087064 100644 (file)
@@ -34,7 +34,7 @@ protected:
     void onDraw(SkCanvas* canvas) override {
         SkPaint whitePaint;
         whitePaint.setColor(SK_ColorWHITE);
-        whitePaint.setBlendMode(SkBlendMode::kSrc);
+        whitePaint.setXfermode(SkXfermode::Make(SkXfermode::kSrc_Mode));
         whitePaint.setAntiAlias(true);
 
         // This scale exercises precision limits in the circle blur effect (crbug.com/560651)
index f6d51fc..202f72a 100644 (file)
@@ -77,7 +77,7 @@ protected:
         SkPaint paint;
         SkColorMatrix matrix;
 
-        paint.setBlendMode(SkBlendMode::kSrc);
+        paint.setXfermodeMode(SkXfermode::kSrc_Mode);
         const SkImage* bmps[] = { fSolidImg.get(), fTransparentImg.get() };
 
         for (size_t i = 0; i < SK_ARRAY_COUNT(bmps); ++i) {
index 9b715ef..554282f 100644 (file)
@@ -57,39 +57,39 @@ protected:
         canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
 
         const struct {
-            SkBlendMode fMode;
-            const char* fLabel;
+            SkXfermode::Mode  fMode;
+            const char*       fLabel;
         } gModes[] = {
-            { SkBlendMode::kClear,        "Clear"       },
-            { SkBlendMode::kSrc,          "Src"         },
-            { SkBlendMode::kDst,          "Dst"         },
-            { SkBlendMode::kSrcOver,      "SrcOver"     },
-            { SkBlendMode::kDstOver,      "DstOver"     },
-            { SkBlendMode::kSrcIn,        "SrcIn"       },
-            { SkBlendMode::kDstIn,        "DstIn"       },
-            { SkBlendMode::kSrcOut,       "SrcOut"      },
-            { SkBlendMode::kDstOut,       "DstOut"      },
-            { SkBlendMode::kSrcATop,      "SrcATop"     },
-            { SkBlendMode::kDstATop,      "DstATop"     },
-
-            { SkBlendMode::kXor,          "Xor"         },
-            { SkBlendMode::kPlus,         "Plus"        },
-            { SkBlendMode::kModulate,     "Modulate"    },
-            { SkBlendMode::kScreen,       "Screen"      },
-            { SkBlendMode::kOverlay,      "Overlay"     },
-            { SkBlendMode::kDarken,       "Darken"      },
-            { SkBlendMode::kLighten,      "Lighten"     },
-            { SkBlendMode::kColorDodge,   "ColorDodge"  },
-            { SkBlendMode::kColorBurn,    "ColorBurn"   },
-            { SkBlendMode::kHardLight,    "HardLight"   },
-            { SkBlendMode::kSoftLight,    "SoftLight"   },
-            { SkBlendMode::kDifference,   "Difference"  },
-            { SkBlendMode::kExclusion,    "Exclusion"   },
-            { SkBlendMode::kMultiply,     "Multiply"    },
-            { SkBlendMode::kHue,          "Hue"         },
-            { SkBlendMode::kSaturation,   "Saturation"  },
-            { SkBlendMode::kColor,        "Color"       },
-            { SkBlendMode::kLuminosity,   "Luminosity"  },
+            { SkXfermode::kClear_Mode,        "Clear"       },
+            { SkXfermode::kSrc_Mode,          "Src"         },
+            { SkXfermode::kDst_Mode,          "Dst"         },
+            { SkXfermode::kSrcOver_Mode,      "SrcOver"     },
+            { SkXfermode::kDstOver_Mode,      "DstOver"     },
+            { SkXfermode::kSrcIn_Mode,        "SrcIn"       },
+            { SkXfermode::kDstIn_Mode,        "DstIn"       },
+            { SkXfermode::kSrcOut_Mode,       "SrcOut"      },
+            { SkXfermode::kDstOut_Mode,       "DstOut"      },
+            { SkXfermode::kSrcATop_Mode,      "SrcATop"     },
+            { SkXfermode::kDstATop_Mode,      "DstATop"     },
+
+            { SkXfermode::kXor_Mode,          "Xor"         },
+            { SkXfermode::kPlus_Mode,         "Plus"        },
+            { SkXfermode::kModulate_Mode,     "Modulate"    },
+            { SkXfermode::kScreen_Mode,       "Screen"      },
+            { SkXfermode::kOverlay_Mode,      "Overlay"     },
+            { SkXfermode::kDarken_Mode,       "Darken"      },
+            { SkXfermode::kLighten_Mode,      "Lighten"     },
+            { SkXfermode::kColorDodge_Mode,   "ColorDodge"  },
+            { SkXfermode::kColorBurn_Mode,    "ColorBurn"   },
+            { SkXfermode::kHardLight_Mode,    "HardLight"   },
+            { SkXfermode::kSoftLight_Mode,    "SoftLight"   },
+            { SkXfermode::kDifference_Mode,   "Difference"  },
+            { SkXfermode::kExclusion_Mode,    "Exclusion"   },
+            { SkXfermode::kMultiply_Mode,     "Multiply"    },
+            { SkXfermode::kHue_Mode,          "Hue"         },
+            { SkXfermode::kSaturation_Mode,   "Saturation"  },
+            { SkXfermode::kColor_Mode,        "Color"       },
+            { SkXfermode::kLuminosity_Mode,   "Luminosity"  },
         };
 
         const SkScalar w = SkIntToScalar(W);
@@ -128,7 +128,7 @@ protected:
             p.setShader(nullptr);
             canvas->drawRect(r, p);
 
-            textP.setBlendMode(gModes[i].fMode);
+            textP.setXfermode(SkXfermode::Make(gModes[i].fMode));
             canvas->drawText("H", 1, x+ w/10.f, y + 7.f*h/8.f, textP);
 #if 1
             canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
index 43b103c..dd81628 100644 (file)
@@ -23,12 +23,12 @@ class DrawAtlasGM : public skiagm::GM {
         canvas->clear(SK_ColorRED);
 
         SkPaint paint;
-        paint.setBlendMode(SkBlendMode::kClear);
+        paint.setXfermodeMode(SkXfermode::kClear_Mode);
         SkRect r(target);
         r.inset(-1, -1);
         // zero out a place (with a 1-pixel border) to land our drawing.
         canvas->drawRect(r, paint);
-        paint.setBlendMode(SkBlendMode::kSrcOver);
+        paint.setXfermode(nullptr);
         paint.setColor(SK_ColorBLUE);
         paint.setAntiAlias(true);
         canvas->drawOval(target, paint);
index bf76c48..d7b973c 100644 (file)
@@ -26,7 +26,7 @@ static sk_sp<SkImage> make_atlas(SkCanvas* caller, int atlasSize) {
     SkCanvas* canvas = surface->getCanvas();
 
     SkPaint paint;
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermode(SkXfermode::Make(SkXfermode::kSrc_Mode));
 
     paint.setColor(SK_ColorWHITE);
     SkRect r = SkRect::MakeXYWH(0, 0,
index 72a68b1..47c7056 100644 (file)
@@ -159,8 +159,8 @@ protected:
                             p.setColor(color);
                             // In order to get some batching on the GPU backend we do 2 src over for
                             // each xfer mode which requires a dst read
-                            p.setBlendMode(r % 3 == 0 ? SkBlendMode::kLighten :
-                                                        SkBlendMode::kSrcOver);
+                            p.setXfermodeMode(r % 3 == 0 ? SkXfermode::kLighten_Mode :
+                                                           SkXfermode::kSrcOver_Mode);
                             SetStyle(&p, style, width);
                             canvas->save();
                             canvas->translate(x, y);
index 80209e5..f6b4a9c 100644 (file)
@@ -75,11 +75,11 @@ DEF_SIMPLE_GM(gamma, canvas, 850, 200) {
         advance();
     };
 
-    auto nextXferRect = [&](SkColor srcColor, SkBlendMode mode, SkColor dstColor) {
+    auto nextXferRect = [&](SkColor srcColor, SkXfermode::Mode mode, SkColor dstColor) {
         p.setColor(dstColor);
         canvas->drawRect(r, p);
         p.setColor(srcColor);
-        p.setBlendMode(mode);
+        p.setXfermodeMode(mode);
         canvas->drawRect(r, p);
 
         SkString srcText = SkStringPrintf("%08X", srcColor);
@@ -207,18 +207,18 @@ DEF_SIMPLE_GM(gamma, canvas, 850, 200) {
 
     canvas->saveLayer(nullptr, nullptr);
 
-    nextXferRect(0x7fffffff, SkBlendMode::kSrcOver, SK_ColorBLACK);
-    nextXferRect(0x7f000000, SkBlendMode::kSrcOver, SK_ColorWHITE);
+    nextXferRect(0x7fffffff, SkXfermode::kSrcOver_Mode, SK_ColorBLACK);
+    nextXferRect(0x7f000000, SkXfermode::kSrcOver_Mode, SK_ColorWHITE);
 
-    nextXferRect(SK_ColorBLACK, SkBlendMode::kDstOver, 0x7fffffff);
-    nextXferRect(SK_ColorWHITE, SkBlendMode::kSrcIn, 0x7fff00ff);
-    nextXferRect(0x7fff00ff, SkBlendMode::kDstIn, SK_ColorWHITE);
+    nextXferRect(SK_ColorBLACK, SkXfermode::kDstOver_Mode, 0x7fffffff);
+    nextXferRect(SK_ColorWHITE, SkXfermode::kSrcIn_Mode, 0x7fff00ff);
+    nextXferRect(0x7fff00ff, SkXfermode::kDstIn_Mode, SK_ColorWHITE);
 
     // 0x89 = 255 * linear_to_srgb(0.25)
-    nextXferRect(0xff898989, SkBlendMode::kPlus, 0xff898989);
+    nextXferRect(0xff898989, SkXfermode::kPlus_Mode, 0xff898989);
 
     // 0xDB = 255 * linear_to_srgb(sqrt(0.5))
-    nextXferRect(0xffdbdbdb, SkBlendMode::kModulate, 0xffdbdbdb);
+    nextXferRect(0xffdbdbdb, SkXfermode::kModulate_Mode, 0xffdbdbdb);
 
     canvas->restore();
 }
index 1b0598f..b6cac0c 100644 (file)
--- a/gm/gm.cpp
+++ b/gm/gm.cpp
@@ -58,7 +58,7 @@ bool GM::animate(const SkAnimTimer& timer) {
 /////////////////////////////////////////////////////////////////////////////////////////////
 
 void GM::onDrawBackground(SkCanvas* canvas) {
-    canvas->drawColor(fBGColor, SkBlendMode::kSrc);
+    canvas->drawColor(fBGColor, SkXfermode::kSrc_Mode);
 }
 
 void GM::drawSizeBounds(SkCanvas* canvas, SkColor color) {
index a628f4a..de937c4 100644 (file)
 #include "SkShader.h"
 
 constexpr struct {
-    SkBlendMode fMode;
-    const char* fLabel;
+    SkXfermode::Mode  fMode;
+    const char*         fLabel;
 } gModes[] = {
-    { SkBlendMode::kClear,    "Clear"     },
-    { SkBlendMode::kSrc,      "Src"       },
-    { SkBlendMode::kDst,      "Dst"       },
-    { SkBlendMode::kSrcOver,  "SrcOver"   },
-    { SkBlendMode::kDstOver,  "DstOver"   },
-    { SkBlendMode::kSrcIn,    "SrcIn"     },
-    { SkBlendMode::kDstIn,    "DstIn"     },
-    { SkBlendMode::kSrcOut,   "SrcOut"    },
-    { SkBlendMode::kDstOut,   "DstOut"    },
-    { SkBlendMode::kSrcATop,  "SrcATop"   },
-    { SkBlendMode::kDstATop,  "DstATop"   },
-    { SkBlendMode::kXor,      "Xor"       },
+    { SkXfermode::kClear_Mode,    "Clear"     },
+    { SkXfermode::kSrc_Mode,      "Src"       },
+    { SkXfermode::kDst_Mode,      "Dst"       },
+    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
+    { SkXfermode::kDstOver_Mode,  "DstOver"   },
+    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
+    { SkXfermode::kDstIn_Mode,    "DstIn"     },
+    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
+    { SkXfermode::kDstOut_Mode,   "DstOut"    },
+    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
+    { SkXfermode::kDstATop_Mode,  "DstATop"   },
+    { SkXfermode::kXor_Mode,      "Xor"       },
 };
 
 const int gWidth = 64;
@@ -33,7 +33,7 @@ const int gHeight = 64;
 const SkScalar W = SkIntToScalar(gWidth);
 const SkScalar H = SkIntToScalar(gHeight);
 
-static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha a1) {
+static SkScalar drawCell(SkCanvas* canvas, sk_sp<SkXfermode> mode, SkAlpha a0, SkAlpha a1) {
 
     SkPaint paint;
     paint.setAntiAlias(true);
@@ -47,7 +47,7 @@ static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha
 
     paint.setColor(SK_ColorRED);
     paint.setAlpha(a1);
-    paint.setBlendMode(mode);
+    paint.setXfermode(std::move(mode));
     for (int angle = 0; angle < 24; ++angle) {
         SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth;
         SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight;
@@ -104,7 +104,7 @@ namespace skiagm {
 
                     canvas->drawRect(bounds, fBGPaint);
                     canvas->saveLayer(&bounds, nullptr);
-                    SkScalar dy = drawCell(canvas, gModes[i].fMode,
+                    SkScalar dy = drawCell(canvas, SkXfermode::Make(gModes[i].fMode),
                                            gAlphaValue[alpha & 1],
                                            gAlphaValue[alpha & 2]);
                     canvas->restore();
index 27422b5..e9f54a3 100644 (file)
@@ -19,7 +19,7 @@
  *
  *  see https://bug.skia.org/3741
  */
-static void do_draw(SkCanvas* canvas, SkBlendMode mode, sk_sp<SkImageFilter> imf) {
+static void do_draw(SkCanvas* canvas, SkXfermode::Mode mode, sk_sp<SkImageFilter> imf) {
         SkAutoCanvasRestore acr(canvas, true);
         canvas->clipRect(SkRect::MakeWH(220, 220));
 
@@ -40,7 +40,7 @@ static void do_draw(SkCanvas* canvas, SkBlendMode mode, sk_sp<SkImageFilter> imf
 
         paint.setColor(0x660000FF);
         paint.setImageFilter(std::move(imf));
-        paint.setBlendMode(mode);
+        paint.setXfermodeMode(mode);
         canvas->drawOval(r1, paint);
 }
 
@@ -52,8 +52,8 @@ DEF_SIMPLE_GM(imagefilters_xfermodes, canvas, 480, 480) {
                                                                  kNone_SkFilterQuality,
                                                                  nullptr));
 
-        const SkBlendMode modes[] = {
-            SkBlendMode::kSrcATop, SkBlendMode::kDstIn
+        const SkXfermode::Mode modes[] = {
+            SkXfermode::kSrcATop_Mode, SkXfermode::kDstIn_Mode
         };
 
         for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) {
index 2d27728..9803989 100644 (file)
@@ -69,8 +69,9 @@ protected:
             sk_sp<SkImageFilter> colorMorph(SkColorFilterImageFilter::Make(std::move(matrixFilter),
                                                                            std::move(morph)));
             SkPaint paint;
-            paint.setImageFilter(SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver,
-                                                             std::move(colorMorph)));
+            paint.setImageFilter(SkXfermodeImageFilter::Make(
+                                        SkXfermode::Make(SkXfermode::kSrcOver_Mode),
+                                        std::move(colorMorph)));
 
             DrawClippedImage(canvas, fImage.get(), paint);
             canvas->translate(SkIntToScalar(100), 0);
@@ -104,8 +105,9 @@ protected:
             SkImageFilter::CropRect cropRect(SkRect::MakeWH(SkIntToScalar(95), SkIntToScalar(100)));
             SkPaint paint;
             paint.setImageFilter(
-                SkXfermodeImageFilter::Make(SkBlendMode::kSrcIn, std::move(blur), nullptr,
-                                            &cropRect));
+                SkXfermodeImageFilter::Make(SkXfermode::Make(SkXfermode::kSrcIn_Mode),
+                                            std::move(blur),
+                                            nullptr, &cropRect));
             DrawClippedImage(canvas, fImage.get(), paint);
             canvas->translate(SkIntToScalar(100), 0);
         }
index dc8257c..0906eb3 100644 (file)
@@ -127,7 +127,7 @@ DEF_SIMPLE_GM(rotate_imagefilter, canvas, 500, 500) {
     sk_sp<SkImageFilter> filters[] = {
         nullptr,
         SkBlurImageFilter::Make(6, 0, nullptr),
-        SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver, nullptr),
+        SkXfermodeImageFilter::Make(SkXfermode::Make(SkXfermode::kSrcOver_Mode), nullptr),
     };
 
     for (auto& filter : filters) {
index a16e219..537c4cb 100644 (file)
@@ -76,44 +76,44 @@ protected:
         this->drawColumn(surfCanvas, SK_ColorCYAN, SK_ColorMAGENTA, true);
 
         SkPaint surfPaint;
-        surfPaint.setBlendMode(SkBlendMode::kSrcOver);
+        surfPaint.setXfermode(SkXfermode::Make(SkXfermode::kSrcOver_Mode));
         surface->draw(canvas, 0, 0, &surfPaint);
     }
 
     void drawColumn(SkCanvas* canvas, SkColor backgroundColor, SkColor textColor, bool useGrad) {
         const struct {
-            SkBlendMode fMode;
-            const char* fLabel;
+            SkXfermode::Mode  fMode;
+            const char*       fLabel;
         } gModes[] = {
-            { SkBlendMode::kClear,        "Clear"       },
-            { SkBlendMode::kSrc,          "Src"         },
-            { SkBlendMode::kDst,          "Dst"         },
-            { SkBlendMode::kSrcOver,      "SrcOver"     },
-            { SkBlendMode::kDstOver,      "DstOver"     },
-            { SkBlendMode::kSrcIn,        "SrcIn"       },
-            { SkBlendMode::kDstIn,        "DstIn"       },
-            { SkBlendMode::kSrcOut,       "SrcOut"      },
-            { SkBlendMode::kDstOut,       "DstOut"      },
-            { SkBlendMode::kSrcATop,      "SrcATop"     },
-            { SkBlendMode::kDstATop,      "DstATop"     },
-            { SkBlendMode::kXor,          "Xor"         },
-            { SkBlendMode::kPlus,         "Plus"        },
-            { SkBlendMode::kModulate,     "Modulate"    },
-            { SkBlendMode::kScreen,       "Screen"      },
-            { SkBlendMode::kOverlay,      "Overlay"     },
-            { SkBlendMode::kDarken,       "Darken"      },
-            { SkBlendMode::kLighten,      "Lighten"     },
-            { SkBlendMode::kColorDodge,   "ColorDodge"  },
-            { SkBlendMode::kColorBurn,    "ColorBurn"   },
-            { SkBlendMode::kHardLight,    "HardLight"   },
-            { SkBlendMode::kSoftLight,    "SoftLight"   },
-            { SkBlendMode::kDifference,   "Difference"  },
-            { SkBlendMode::kExclusion,    "Exclusion"   },
-            { SkBlendMode::kMultiply,     "Multiply"    },
-            { SkBlendMode::kHue,          "Hue"         },
-            { SkBlendMode::kSaturation,   "Saturation"  },
-            { SkBlendMode::kColor,        "Color"       },
-            { SkBlendMode::kLuminosity,   "Luminosity"  },
+            { SkXfermode::kClear_Mode,        "Clear"       },
+            { SkXfermode::kSrc_Mode,          "Src"         },
+            { SkXfermode::kDst_Mode,          "Dst"         },
+            { SkXfermode::kSrcOver_Mode,      "SrcOver"     },
+            { SkXfermode::kDstOver_Mode,      "DstOver"     },
+            { SkXfermode::kSrcIn_Mode,        "SrcIn"       },
+            { SkXfermode::kDstIn_Mode,        "DstIn"       },
+            { SkXfermode::kSrcOut_Mode,       "SrcOut"      },
+            { SkXfermode::kDstOut_Mode,       "DstOut"      },
+            { SkXfermode::kSrcATop_Mode,      "SrcATop"     },
+            { SkXfermode::kDstATop_Mode,      "DstATop"     },
+            { SkXfermode::kXor_Mode,          "Xor"         },
+            { SkXfermode::kPlus_Mode,         "Plus"        },
+            { SkXfermode::kModulate_Mode,     "Modulate"    },
+            { SkXfermode::kScreen_Mode,       "Screen"      },
+            { SkXfermode::kOverlay_Mode,      "Overlay"     },
+            { SkXfermode::kDarken_Mode,       "Darken"      },
+            { SkXfermode::kLighten_Mode,      "Lighten"     },
+            { SkXfermode::kColorDodge_Mode,   "ColorDodge"  },
+            { SkXfermode::kColorBurn_Mode,    "ColorBurn"   },
+            { SkXfermode::kHardLight_Mode,    "HardLight"   },
+            { SkXfermode::kSoftLight_Mode,    "SoftLight"   },
+            { SkXfermode::kDifference_Mode,   "Difference"  },
+            { SkXfermode::kExclusion_Mode,    "Exclusion"   },
+            { SkXfermode::kMultiply_Mode,     "Multiply"    },
+            { SkXfermode::kHue_Mode,          "Hue"         },
+            { SkXfermode::kSaturation_Mode,   "Saturation"  },
+            { SkXfermode::kColor_Mode,        "Color"       },
+            { SkXfermode::kLuminosity_Mode,   "Luminosity"  },
         };
         // Draw background rect
         SkPaint backgroundPaint;
@@ -128,7 +128,7 @@ protected:
             paint.setSubpixelText(true);
             paint.setLCDRenderText(true);
             paint.setTextSize(fTextHeight);
-            paint.setBlendMode(gModes[m].fMode);
+            paint.setXfermode(SkXfermode::Make(gModes[m].fMode));
             sk_tool_utils::set_portable_typeface(&paint);
             if (useGrad) {
                 SkRect r;
index 3808785..623d746 100644 (file)
@@ -49,8 +49,8 @@ protected:
 
     SkISize onISize() override { return SkISize::Make(kWidth, kHeight); }
 
-    void drawTestCase(SkCanvas* canvas, SkScalar x, SkScalar y, SkBlendMode mode,
-                      SkBlendMode mode2) {
+    void drawTestCase(SkCanvas* canvas, SkScalar x, SkScalar y, SkXfermode::Mode mode,
+                      SkXfermode::Mode mode2) {
         const SkColor colors[] {
                 SK_ColorRED,
                 SK_ColorGREEN,
@@ -60,6 +60,8 @@ protected:
                 SK_ColorMAGENTA,
         };
 
+        sk_sp<SkXfermode> xfermode(SkXfermode::Make(mode));
+        sk_sp<SkXfermode> xfermode2(SkXfermode::Make(mode2));
         for (size_t i = 0; i < SK_ARRAY_COUNT(colors); i++) {
             canvas->save();
             canvas->translate(x, y);
@@ -68,7 +70,7 @@ protected:
 
             SkPaint textPaint;
             textPaint.setColor(colors[i]);
-            textPaint.setBlendMode(i % 2 == 0 ? mode : mode2);
+            textPaint.setXfermode(i % 2 == 0 ? xfermode : xfermode2);
             canvas->drawTextBlob(fBlob, 0, 0, textPaint);
             canvas->restore();
         }
@@ -77,11 +79,13 @@ protected:
     void onDraw(SkCanvas* canvas) override {
         SkScalar offsetX = kWidth / 4.0f;
         SkScalar offsetY = kHeight / 4.0f;
-        drawTestCase(canvas, offsetX, offsetY,  SkBlendMode::kSrc, SkBlendMode::kSrc);
-        drawTestCase(canvas, 3 * offsetX, offsetY,  SkBlendMode::kSrcOver, SkBlendMode::kSrcOver);
-        drawTestCase(canvas, offsetX, 3 * offsetY,  SkBlendMode::kHardLight,
-                     SkBlendMode::kLuminosity);
-        drawTestCase(canvas, 3 * offsetX, 3 * offsetY,  SkBlendMode::kSrcOver, SkBlendMode::kSrc);
+        drawTestCase(canvas, offsetX, offsetY,  SkXfermode::kSrc_Mode, SkXfermode::kSrc_Mode);
+        drawTestCase(canvas, 3 * offsetX, offsetY,  SkXfermode::kSrcOver_Mode,
+                     SkXfermode::kSrcOver_Mode);
+        drawTestCase(canvas, offsetX, 3 * offsetY,  SkXfermode::kHardLight_Mode,
+                     SkXfermode::kLuminosity_Mode);
+        drawTestCase(canvas, 3 * offsetX, 3 * offsetY,  SkXfermode::kSrcOver_Mode,
+                     SkXfermode::kSrc_Mode);
     }
 
 private:
index 3852d93..10eefab 100644 (file)
@@ -26,7 +26,7 @@ static void draw_label(SkCanvas* canvas, const char* label,
                      paint);
 }
 
-static void draw_scene(SkCanvas* canvas, const sk_sp<SkColorFilter>& filter, SkBlendMode mode,
+static void draw_scene(SkCanvas* canvas, const sk_sp<SkColorFilter>& filter, SkXfermode::Mode mode,
                        const sk_sp<SkShader>& s1, const sk_sp<SkShader>& s2) {
     SkPaint paint;
     paint.setAntiAlias(true);
@@ -53,7 +53,7 @@ static void draw_scene(SkCanvas* canvas, const sk_sp<SkColorFilter>& filter, SkB
     }
 
     SkPaint xferPaint;
-    xferPaint.setBlendMode(mode);
+    xferPaint.setXfermodeMode(mode);
     canvas->saveLayer(&bounds, &xferPaint);
 
     r = bounds;
@@ -101,14 +101,13 @@ protected:
     }
 
     void onDraw(SkCanvas* canvas) override {
-        SkBlendMode modes[] = {
-            SkBlendMode::kSrcOver,
-            SkBlendMode::kDstOver,
-            SkBlendMode::kSrcATop,
-            SkBlendMode::kDstATop,
-            SkBlendMode::kSrcIn,
-            SkBlendMode::kDstIn,
-        };
+        SkXfermode::Mode modes[] = { SkXfermode::kSrcOver_Mode,
+                                     SkXfermode::kDstOver_Mode,
+                                     SkXfermode::kSrcATop_Mode,
+                                     SkXfermode::kDstATop_Mode,
+                                     SkXfermode::kSrcIn_Mode,
+                                     SkXfermode::kDstIn_Mode,
+                                   };
         struct {
             const sk_sp<SkShader>& fShader1;
             const sk_sp<SkShader>& fShader2;
index ae926ef..50bb27f 100644 (file)
@@ -78,7 +78,7 @@ protected:
         }
         SkPaint bgPaint;
         bgPaint.setShader(fBmpShader);
-        bgPaint.setBlendMode(SkBlendMode::kSrc);
+        bgPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
 
         sk_sp<SkShader> shaders[] = {
             nullptr,                                   // use a paint color instead of a shader
index 72d4159..1ea8ada 100644 (file)
@@ -29,7 +29,7 @@ static sk_sp<SkPicture> make_picture() {
     canvas->drawPath(path, paint);
 
     paint.setColor(0x80FFFFFF);
-    paint.setBlendMode(SkBlendMode::kPlus);
+    paint.setXfermodeMode(SkXfermode::kPlus_Mode);
     canvas->drawRect(SkRect::MakeXYWH(25, 25, 50, 50), paint);
 
     return rec.finishRecordingAsPicture();
index 51ac2cb..6a5af61 100644 (file)
@@ -37,7 +37,7 @@ DEF_SIMPLE_GM(PlusMergesAA, canvas, 256, 256) {
 
     // Using Plus on the right should merge the AA of seam together completely covering the red.
     canvas->saveLayer(nullptr, nullptr);
-      p.setBlendMode(SkBlendMode::kPlus);
+      p.setXfermodeMode(SkXfermode::kPlus_Mode);
       canvas->translate(150, 0);
       canvas->drawPath(upperLeft, p);
       canvas->drawPath(bottomRight, p);
index d57b77c..0d02cdc 100644 (file)
@@ -82,8 +82,8 @@ protected:
             draw_hair, draw_thick, draw_rect, draw_oval, draw_text
         };
 
-        const SkBlendMode modes[] = {
-            SkBlendMode::kSrcOver, SkBlendMode::kSrc, SkBlendMode::kClear
+        const SkXfermode::Mode modes[] = {
+            SkXfermode::kSrcOver_Mode, SkXfermode::kSrc_Mode, SkXfermode::kClear_Mode
         };
 
         const PaintProc paintProcs[] = {
@@ -96,7 +96,7 @@ protected:
             for (size_t i = 0; i < SK_ARRAY_COUNT(paintProcs); ++i) {
                 paintProcs[i](&paint);
                 for (size_t x = 0; x < SK_ARRAY_COUNT(modes); ++x) {
-                    paint.setBlendMode(modes[x]);
+                    paint.setXfermodeMode(modes[x]);
                     canvas->save();
                     for (size_t y = 0; y < SK_ARRAY_COUNT(procs); ++y) {
                         procs[y](canvas, paint);
index c581e13..3974aca 100644 (file)
@@ -69,7 +69,7 @@ protected:
         redPaint.setColor(SK_ColorRED);
         canvas->drawRect(bounds, redPaint);
         SkPaint srcInPaint(paint);
-        srcInPaint.setBlendMode(SkBlendMode::kSrcIn);
+        srcInPaint.setXfermodeMode(SkXfermode::kSrcIn_Mode);
         canvas->drawTextBlob(fBlob, 0, 0, srcInPaint);
 
         canvas->translate(SkIntToScalar(xDelta), SkIntToScalar(yDelta));
index 37eae66..3adf349 100644 (file)
@@ -51,7 +51,7 @@ static void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const
 typedef void (*LooperProc)(SkPaint*);
 
 struct LooperSettings {
-    SkBlendMode      fMode;
+    SkXfermode::Mode fMode;
     SkColor          fColor;
     SkPaint::Style   fStyle;
     SkScalar         fWidth;
@@ -120,7 +120,7 @@ static sk_sp<SkDrawLooper> setupLooper(SkLayerDrawLooper::BitFlags bits,
     for (size_t i = 0; i < size; i++) {
         info.fOffset.set(settings[i].fOffset, settings[i].fOffset);
         SkPaint* paint = looperBuilder.addLayer(info);
-        paint->setBlendMode(settings[i].fMode);
+        paint->setXfermodeMode(settings[i].fMode);
         paint->setColor(settings[i].fColor);
         paint->setStyle(settings[i].fStyle);
         paint->setStrokeWidth(settings[i].fWidth);
@@ -152,37 +152,37 @@ protected:
 
         // create a looper which sandwhiches an effect in two normal draws
         LooperSettings looperSandwhich[] = {
-           { SkBlendMode::kSrc, SK_ColorMAGENTA, SkPaint::kFill_Style, 0, 0, 0, false },
-           { SkBlendMode::kSrcOver, 0x88000000, SkPaint::kFill_Style, 0, 10.f, 0, true },
-           { SkBlendMode::kSrcOver, 0x50FF00FF, SkPaint::kFill_Style, 0, 20.f, 0, false },
+           { SkXfermode::kSrc_Mode, SK_ColorMAGENTA, SkPaint::kFill_Style, 0, 0, 0, false },
+           { SkXfermode::kSrcOver_Mode, 0x88000000, SkPaint::kFill_Style, 0, 10.f, 0, true },
+           { SkXfermode::kSrcOver_Mode, 0x50FF00FF, SkPaint::kFill_Style, 0, 20.f, 0, false },
         };
 
         LooperSettings compound[] = {
-            { SkBlendMode::kSrc, SK_ColorWHITE, SkPaint::kStroke_Style, 1.f * 3/4, 0, 0, false },
-            { SkBlendMode::kSrc, SK_ColorRED, SkPaint::kStroke_Style, 4.f, 0, 0, false },
-            { SkBlendMode::kSrc, SK_ColorBLUE, SkPaint::kFill_Style, 0, 0, 0, false },
-            { SkBlendMode::kSrcOver, 0x88000000, SkPaint::kFill_Style, 0, 10.f, 0, true }
+            { SkXfermode::kSrc_Mode, SK_ColorWHITE, SkPaint::kStroke_Style, 1.f * 3/4, 0, 0, false },
+            { SkXfermode::kSrc_Mode, SK_ColorRED, SkPaint::kStroke_Style, 4.f, 0, 0, false },
+            { SkXfermode::kSrc_Mode, SK_ColorBLUE, SkPaint::kFill_Style, 0, 0, 0, false },
+            { SkXfermode::kSrcOver_Mode, 0x88000000, SkPaint::kFill_Style, 0, 10.f, 0, true }
         };
 
         LooperSettings xfermode[] = {
-            { SkBlendMode::kDifference, SK_ColorWHITE, SkPaint::kFill_Style, 0, 0, 0, false },
-            { SkBlendMode::kSrcOver, 0xFF000000, SkPaint::kFill_Style, 0, 1.f, 0, true },
-            { SkBlendMode::kSrcOver, 0x50FF00FF, SkPaint::kFill_Style, 0, 2.f, 0, false },
+            { SkXfermode::kDifference_Mode, SK_ColorWHITE, SkPaint::kFill_Style, 0, 0, 0, false },
+            { SkXfermode::kSrcOver_Mode, 0xFF000000, SkPaint::kFill_Style, 0, 1.f, 0, true },
+            { SkXfermode::kSrcOver_Mode, 0x50FF00FF, SkPaint::kFill_Style, 0, 2.f, 0, false },
         };
 
         // NOTE, this should be ignored by textblobs
         LooperSettings skew[] = {
-            { SkBlendMode::kSrc, SK_ColorRED, SkPaint::kFill_Style, 0, 0, -1.f, false },
-            { SkBlendMode::kSrc, SK_ColorGREEN, SkPaint::kFill_Style, 0, 10.f, -1.f, false },
-            { SkBlendMode::kSrc, SK_ColorBLUE, SkPaint::kFill_Style, 0, 20.f, -1.f, false },
+            { SkXfermode::kSrc_Mode, SK_ColorRED, SkPaint::kFill_Style, 0, 0, -1.f, false },
+            { SkXfermode::kSrc_Mode, SK_ColorGREEN, SkPaint::kFill_Style, 0, 10.f, -1.f, false },
+            { SkXfermode::kSrc_Mode, SK_ColorBLUE, SkPaint::kFill_Style, 0, 20.f, -1.f, false },
         };
 
         LooperSettings kitchenSink[] = {
-            { SkBlendMode::kSrc, SK_ColorWHITE, SkPaint::kStroke_Style, 1.f * 3/4, 0, 0, false },
-            { SkBlendMode::kSrc, SK_ColorBLACK, SkPaint::kFill_Style, 0, 0, 0, false },
-            { SkBlendMode::kDifference, SK_ColorWHITE, SkPaint::kFill_Style, 1.f, 10.f, 0, false },
-            { SkBlendMode::kSrc, SK_ColorWHITE, SkPaint::kFill_Style, 0, 10.f, 0, true },
-            { SkBlendMode::kSrcOver, 0x50FF00FF, SkPaint::kFill_Style, 0, 20.f, 0, false },
+            { SkXfermode::kSrc_Mode, SK_ColorWHITE, SkPaint::kStroke_Style, 1.f * 3/4, 0, 0, false },
+            { SkXfermode::kSrc_Mode, SK_ColorBLACK, SkPaint::kFill_Style, 0, 0, 0, false },
+            { SkXfermode::kDifference_Mode, SK_ColorWHITE, SkPaint::kFill_Style, 1.f, 10.f, 0, false },
+            { SkXfermode::kSrc_Mode, SK_ColorWHITE, SkPaint::kFill_Style, 0, 10.f, 0, true },
+            { SkXfermode::kSrcOver_Mode, 0x50FF00FF, SkPaint::kFill_Style, 0, 20.f, 0, false },
         };
 
         fLoopers.push_back(setupLooper(SkLayerDrawLooper::kMaskFilter_Bit |
index 453a555..6a5a9c1 100644 (file)
@@ -25,7 +25,7 @@ static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
 
     p.setAlpha(0x11);
     p.setStyle(SkPaint::kFill_Style);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -33,7 +33,7 @@ static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     rastBuilder->addLayer(p);
 
     p.setAlpha(0x40);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1*2);
     rastBuilder->addLayer(p);
@@ -46,7 +46,7 @@ static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
 
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1*3/2);
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -57,7 +57,7 @@ static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
 
     p.setAlpha(0x20);
     p.setStyle(SkPaint::kFill_Style);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -66,10 +66,10 @@ static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
 
     p.setAlpha(0xFF);
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
 
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     rastBuilder->addLayer(p);
 }
 
@@ -79,7 +79,7 @@ static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     rastBuilder->addLayer(p);
 
     p.setPathEffect(SkDiscretePathEffect::Make(SK_Scalar1*4, SK_Scalar1*3));
-    p.setBlendMode(SkBlendMode::kSrcOut);
+    p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -90,7 +90,7 @@ static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     SkLayerRasterizer::Builder rastBuilder2;
     r5(&rastBuilder2, p);
     p.setRasterizer(rastBuilder2.detach());
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -117,11 +117,11 @@ static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
     p.setPathEffect(MakeDotEffect(SK_Scalar1*2, lattice));
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 
     p.setPathEffect(nullptr);
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1);
     rastBuilder->addLayer(p);
@@ -134,11 +134,11 @@ static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
     lattice.postRotate(SkIntToScalar(30), 0, 0);
     p.setPathEffect(SkLine2DPathEffect::Make(SK_Scalar1*2, lattice));
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 
     p.setPathEffect(nullptr);
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1);
     rastBuilder->addLayer(p);
index b0d2ece..2dd340e 100644 (file)
@@ -57,14 +57,14 @@ protected:
         SkColor colors2[] = { SK_ColorMAGENTA, SK_ColorLTGRAY, SK_ColorYELLOW };
         paint.setShader(SkGradientShader::MakeSweep(45.f, 55.f, colors2, nullptr,
                                                     SK_ARRAY_COUNT(colors2)));
-        paint.setBlendMode(SkBlendMode::kDarken);
+        paint.setXfermodeMode(SkXfermode::kDarken_Mode);
         canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, fBmp.width() + 10.f, fBmp.height() + 10.f),
                         paint);
 
         SkColor colors3[] = { SK_ColorBLUE, SK_ColorLTGRAY, SK_ColorGREEN };
         paint.setShader(SkGradientShader::MakeSweep(25.f, 35.f, colors3, nullptr,
                                                     SK_ARRAY_COUNT(colors3)));
-        paint.setBlendMode(SkBlendMode::kLighten);
+        paint.setXfermodeMode(SkXfermode::kLighten_Mode);
         canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, fBmp.width() + 10.f, fBmp.height() + 10.f),
                         paint);
     }
index 9f1c05f..f257bf9 100644 (file)
@@ -18,7 +18,7 @@ static void draw(SkCanvas* canvas, int width, int height, SkColor colors[2]) {
     SkPaint paint;
     paint.setShader(SkGradientShader::MakeRadial(center, radius, colors, nullptr, 2,
                                                  SkShader::kMirror_TileMode));
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     canvas->drawPaint(paint);
 }
 
index 9190859..a0677c7 100644 (file)
@@ -48,45 +48,46 @@ protected:
         SkPaint paint;
 
         const struct {
-            SkBlendMode fMode;
-            const char* fLabel;
+            SkXfermode::Mode  fMode;
+            const char*         fLabel;
         } gModes[] = {
-            { SkBlendMode::kClear,    "Clear"     },
-            { SkBlendMode::kSrc,      "Src"       },
-            { SkBlendMode::kDst,      "Dst"       },
-            { SkBlendMode::kSrcOver,  "SrcOver"   },
-            { SkBlendMode::kDstOver,  "DstOver"   },
-            { SkBlendMode::kSrcIn,    "SrcIn"     },
-            { SkBlendMode::kDstIn,    "DstIn"     },
-            { SkBlendMode::kSrcOut,   "SrcOut"    },
-            { SkBlendMode::kDstOut,   "DstOut"    },
-            { SkBlendMode::kSrcATop,  "SrcATop"   },
-            { SkBlendMode::kDstATop,  "DstATop"   },
-            { SkBlendMode::kXor,      "Xor"       },
-
-            { SkBlendMode::kPlus,         "Plus"          },
-            { SkBlendMode::kModulate,     "Modulate"      },
-            { SkBlendMode::kScreen,       "Screen"        },
-            { SkBlendMode::kOverlay,      "Overlay"       },
-            { SkBlendMode::kDarken,       "Darken"        },
-            { SkBlendMode::kLighten,      "Lighten"       },
-            { SkBlendMode::kColorDodge,   "ColorDodge"    },
-            { SkBlendMode::kColorBurn,    "ColorBurn"     },
-            { SkBlendMode::kHardLight,    "HardLight"     },
-            { SkBlendMode::kSoftLight,    "SoftLight"     },
-            { SkBlendMode::kDifference,   "Difference"    },
-            { SkBlendMode::kExclusion,    "Exclusion"     },
-            { SkBlendMode::kMultiply,     "Multiply"      },
-            { SkBlendMode::kHue,          "Hue"           },
-            { SkBlendMode::kSaturation,   "Saturation"    },
-            { SkBlendMode::kColor,        "Color"         },
-            { SkBlendMode::kLuminosity,   "Luminosity"    },
+            { SkXfermode::kClear_Mode,    "Clear"     },
+            { SkXfermode::kSrc_Mode,      "Src"       },
+            { SkXfermode::kDst_Mode,      "Dst"       },
+            { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
+            { SkXfermode::kDstOver_Mode,  "DstOver"   },
+            { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
+            { SkXfermode::kDstIn_Mode,    "DstIn"     },
+            { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
+            { SkXfermode::kDstOut_Mode,   "DstOut"    },
+            { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
+            { SkXfermode::kDstATop_Mode,  "DstATop"   },
+            { SkXfermode::kXor_Mode,      "Xor"       },
+
+            { SkXfermode::kPlus_Mode,         "Plus"          },
+            { SkXfermode::kModulate_Mode,     "Modulate"      },
+            { SkXfermode::kScreen_Mode,       "Screen"        },
+            { SkXfermode::kOverlay_Mode,      "Overlay"       },
+            { SkXfermode::kDarken_Mode,       "Darken"        },
+            { SkXfermode::kLighten_Mode,      "Lighten"       },
+            { SkXfermode::kColorDodge_Mode,   "ColorDodge"    },
+            { SkXfermode::kColorBurn_Mode,    "ColorBurn"     },
+            { SkXfermode::kHardLight_Mode,    "HardLight"     },
+            { SkXfermode::kSoftLight_Mode,    "SoftLight"     },
+            { SkXfermode::kDifference_Mode,   "Difference"    },
+            { SkXfermode::kExclusion_Mode,    "Exclusion"     },
+            { SkXfermode::kMultiply_Mode,     "Multiply"      },
+            { SkXfermode::kHue_Mode,          "Hue"           },
+            { SkXfermode::kSaturation_Mode,   "Saturation"    },
+            { SkXfermode::kColor_Mode,        "Color"         },
+            { SkXfermode::kLuminosity_Mode,   "Luminosity"    },
         };
 
         int x = 0, y = 0;
         sk_sp<SkImageFilter> background(SkImageSource::Make(fCheckerboard));
         for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
-            paint.setImageFilter(SkXfermodeImageFilter::Make(gModes[i].fMode, background));
+            paint.setImageFilter(SkXfermodeImageFilter::Make(SkXfermode::Make(gModes[i].fMode),
+                                                             background));
             DrawClippedBitmap(canvas, fBitmap, paint, x, y);
             x += fBitmap.width() + MARGIN;
             if (x + fBitmap.width() > WIDTH) {
@@ -103,7 +104,7 @@ protected:
             y += fBitmap.height() + MARGIN;
         }
         // Test nullptr mode
-        paint.setImageFilter(SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver, background));
+        paint.setImageFilter(SkXfermodeImageFilter::Make(nullptr, background));
         DrawClippedBitmap(canvas, fBitmap, paint, x, y);
         x += fBitmap.width() + MARGIN;
         if (x + fBitmap.width() > WIDTH) {
@@ -121,10 +122,11 @@ protected:
         sk_sp<SkImageFilter> offsetBackground(SkOffsetImageFilter::Make(SkIntToScalar(4),
                                                                         SkIntToScalar(4),
                                                                         background));
-        paint.setImageFilter(SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver,
-                                                         offsetBackground,
-                                                         offsetForeground,
-                                                         nullptr));
+        paint.setImageFilter(SkXfermodeImageFilter::Make(
+                                                     SkXfermode::Make(SkXfermode::kSrcOver_Mode),
+                                                     offsetBackground,
+                                                     offsetForeground,
+                                                     nullptr));
         DrawClippedPaint(canvas, clipRect, paint, x, y);
         x += fBitmap.width() + MARGIN;
         if (x + fBitmap.width() > WIDTH) {
@@ -132,7 +134,7 @@ protected:
             y += fBitmap.height() + MARGIN;
         }
         // Test offsets on Darken (uses shader blend)
-        paint.setImageFilter(SkXfermodeImageFilter::Make(SkBlendMode::kDarken,
+        paint.setImageFilter(SkXfermodeImageFilter::Make(SkXfermode::Make(SkXfermode::kDarken_Mode),
                                                          offsetBackground,
                                                          offsetForeground,
                                                          nullptr));
@@ -144,9 +146,9 @@ protected:
         }
         // Test cropping
         constexpr size_t nbSamples = 3;
-        const SkBlendMode sampledModes[nbSamples] = {
-            SkBlendMode::kOverlay, SkBlendMode::kSrcOver, SkBlendMode::kPlus
-        };
+        SkXfermode::Mode sampledModes[nbSamples] = {SkXfermode::kOverlay_Mode,
+                                                    SkXfermode::kSrcOver_Mode,
+                                                    SkXfermode::kPlus_Mode};
         int offsets[nbSamples][4] = {{ 10,  10, -16, -16},
                                      { 10,  10,  10,  10},
                                      {-10, -10,  -6,  -6}};
@@ -156,7 +158,7 @@ protected:
                                                  fBitmap.width()  + offsets[i][2],
                                                  fBitmap.height() + offsets[i][3]);
             SkImageFilter::CropRect rect(SkRect::Make(cropRect));
-            paint.setImageFilter(SkXfermodeImageFilter::Make(sampledModes[i],
+            paint.setImageFilter(SkXfermodeImageFilter::Make(SkXfermode::Make(sampledModes[i]),
                                                              offsetBackground,
                                                              offsetForeground,
                                                              &rect));
@@ -168,7 +170,7 @@ protected:
             }
         }
         // Test small bg, large fg with Screen (uses shader blend)
-        SkBlendMode mode = SkBlendMode::kScreen;
+        auto mode = SkXfermode::Make(SkXfermode::kScreen_Mode);
         SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(10, 10, 60, 60));
         sk_sp<SkImageFilter> cropped(SkOffsetImageFilter::Make(0, 0, foreground, &cropRect));
         paint.setImageFilter(SkXfermodeImageFilter::Make(mode, cropped, background, nullptr));
@@ -189,7 +191,7 @@ protected:
         // Test small fg, large bg with SrcIn with a crop that forces it to full size.
         // This tests that SkXfermodeImageFilter correctly applies the compositing mode to
         // the region outside the foreground.
-        mode = SkBlendMode::kSrcIn;
+        mode = SkXfermode::Make(SkXfermode::kSrcIn_Mode);
         SkImageFilter::CropRect cropRectFull(SkRect::MakeXYWH(0, 0, 80, 80));
         paint.setImageFilter(SkXfermodeImageFilter::Make(mode, background,
                                                          cropped, &cropRectFull));
index 604a767..8fbbdbe 100644 (file)
@@ -34,45 +34,45 @@ enum SrcType {
 };
 
 const struct {
-    SkBlendMode fMode;
-    const char* fLabel;
-    int         fSourceTypeMask;  // The source types to use this
+    SkXfermode::Mode  fMode;
+    const char*       fLabel;
+    int               fSourceTypeMask;  // The source types to use this
     // mode with. See draw_mode for
     // an explanation of each type.
     // PDF has to play some tricks
     // to support the base modes,
     // test those more extensively.
 } gModes[] = {
-    { SkBlendMode::kClear,        "Clear",        kAll_SrcType   },
-    { SkBlendMode::kSrc,          "Src",          kAll_SrcType   },
-    { SkBlendMode::kDst,          "Dst",          kAll_SrcType   },
-    { SkBlendMode::kSrcOver,      "SrcOver",      kAll_SrcType   },
-    { SkBlendMode::kDstOver,      "DstOver",      kAll_SrcType   },
-    { SkBlendMode::kSrcIn,        "SrcIn",        kAll_SrcType   },
-    { SkBlendMode::kDstIn,        "DstIn",        kAll_SrcType   },
-    { SkBlendMode::kSrcOut,       "SrcOut",       kAll_SrcType   },
-    { SkBlendMode::kDstOut,       "DstOut",       kAll_SrcType   },
-    { SkBlendMode::kSrcATop,      "SrcATop",      kAll_SrcType   },
-    { SkBlendMode::kDstATop,      "DstATop",      kAll_SrcType   },
-
-    { SkBlendMode::kXor,          "Xor",          kBasic_SrcType },
-    { SkBlendMode::kPlus,         "Plus",         kBasic_SrcType },
-    { SkBlendMode::kModulate,     "Modulate",     kAll_SrcType   },
-    { SkBlendMode::kScreen,       "Screen",       kBasic_SrcType },
-    { SkBlendMode::kOverlay,      "Overlay",      kBasic_SrcType },
-    { SkBlendMode::kDarken,       "Darken",       kBasic_SrcType },
-    { SkBlendMode::kLighten,      "Lighten",      kBasic_SrcType },
-    { SkBlendMode::kColorDodge,   "ColorDodge",   kBasic_SrcType },
-    { SkBlendMode::kColorBurn,    "ColorBurn",    kBasic_SrcType },
-    { SkBlendMode::kHardLight,    "HardLight",    kBasic_SrcType },
-    { SkBlendMode::kSoftLight,    "SoftLight",    kBasic_SrcType },
-    { SkBlendMode::kDifference,   "Difference",   kBasic_SrcType },
-    { SkBlendMode::kExclusion,    "Exclusion",    kBasic_SrcType },
-    { SkBlendMode::kMultiply,     "Multiply",     kAll_SrcType   },
-    { SkBlendMode::kHue,          "Hue",          kBasic_SrcType },
-    { SkBlendMode::kSaturation,   "Saturation",   kBasic_SrcType },
-    { SkBlendMode::kColor,        "Color",        kBasic_SrcType },
-    { SkBlendMode::kLuminosity,   "Luminosity",   kBasic_SrcType },
+    { SkXfermode::kClear_Mode,        "Clear",        kAll_SrcType   },
+    { SkXfermode::kSrc_Mode,          "Src",          kAll_SrcType   },
+    { SkXfermode::kDst_Mode,          "Dst",          kAll_SrcType   },
+    { SkXfermode::kSrcOver_Mode,      "SrcOver",      kAll_SrcType   },
+    { SkXfermode::kDstOver_Mode,      "DstOver",      kAll_SrcType   },
+    { SkXfermode::kSrcIn_Mode,        "SrcIn",        kAll_SrcType   },
+    { SkXfermode::kDstIn_Mode,        "DstIn",        kAll_SrcType   },
+    { SkXfermode::kSrcOut_Mode,       "SrcOut",       kAll_SrcType   },
+    { SkXfermode::kDstOut_Mode,       "DstOut",       kAll_SrcType   },
+    { SkXfermode::kSrcATop_Mode,      "SrcATop",      kAll_SrcType   },
+    { SkXfermode::kDstATop_Mode,      "DstATop",      kAll_SrcType   },
+
+    { SkXfermode::kXor_Mode,          "Xor",          kBasic_SrcType },
+    { SkXfermode::kPlus_Mode,         "Plus",         kBasic_SrcType },
+    { SkXfermode::kModulate_Mode,     "Modulate",     kAll_SrcType   },
+    { SkXfermode::kScreen_Mode,       "Screen",       kBasic_SrcType },
+    { SkXfermode::kOverlay_Mode,      "Overlay",      kBasic_SrcType },
+    { SkXfermode::kDarken_Mode,       "Darken",       kBasic_SrcType },
+    { SkXfermode::kLighten_Mode,      "Lighten",      kBasic_SrcType },
+    { SkXfermode::kColorDodge_Mode,   "ColorDodge",   kBasic_SrcType },
+    { SkXfermode::kColorBurn_Mode,    "ColorBurn",    kBasic_SrcType },
+    { SkXfermode::kHardLight_Mode,    "HardLight",    kBasic_SrcType },
+    { SkXfermode::kSoftLight_Mode,    "SoftLight",    kBasic_SrcType },
+    { SkXfermode::kDifference_Mode,   "Difference",   kBasic_SrcType },
+    { SkXfermode::kExclusion_Mode,    "Exclusion",    kBasic_SrcType },
+    { SkXfermode::kMultiply_Mode,     "Multiply",     kAll_SrcType   },
+    { SkXfermode::kHue_Mode,          "Hue",          kBasic_SrcType },
+    { SkXfermode::kSaturation_Mode,   "Saturation",   kBasic_SrcType },
+    { SkXfermode::kColor_Mode,        "Color",        kBasic_SrcType },
+    { SkXfermode::kLuminosity_Mode,   "Luminosity",   kBasic_SrcType },
 };
 
 static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst,
@@ -118,14 +118,15 @@ class XfermodesGM : public skiagm::GM {
      * uses the implied shape of the drawing command and these modes
      * demonstrate that.
      */
-    void draw_mode(SkCanvas* canvas, SkBlendMode mode, SrcType srcType, SkScalar x, SkScalar y) {
+    void draw_mode(SkCanvas* canvas, SkXfermode::Mode mode, SrcType srcType,
+                   SkScalar x, SkScalar y) {
         SkPaint p;
         SkMatrix m;
         bool restoreNeeded = false;
         m.setTranslate(x, y);
 
         canvas->drawBitmap(fSrcB, x, y, &p);
-        p.setBlendMode(mode);
+        p.setXfermodeMode(mode);
         switch (srcType) {
             case kSmallTransparentImage_SrcType: {
                 m.postScale(SK_ScalarHalf, SK_ScalarHalf, x, y);
@@ -140,7 +141,7 @@ class XfermodesGM : public skiagm::GM {
                                                  SkIntToScalar(H));
                 canvas->saveLayer(&bounds, &p);
                 restoreNeeded = true;
-                p.setBlendMode(SkBlendMode::kSrcOver);
+                p.setXfermodeMode(SkXfermode::kSrcOver_Mode);
                 // Fall through.
             }
             case kQuarterClear_SrcType: {
index 03da0d3..6f7d054 100644 (file)
@@ -40,7 +40,7 @@ protected:
 
         SkScalar x = 0, y = 0;
         for (size_t m = 0; m <= SkXfermode::kLastMode; m++) {
-            SkBlendMode mode = static_cast<SkBlendMode>(m);
+            SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(m);
 
             canvas->save();
 
@@ -57,7 +57,7 @@ protected:
             p.setShader(fDst);
             canvas->drawRect(r, p);
             p.setShader(fSrc);
-            p.setBlendMode(mode);
+            p.setXfermode(SkXfermode::Make(mode));
             canvas->drawRect(r, p);
 
             canvas->restore();
@@ -65,7 +65,7 @@ protected:
             r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
             p.setStyle(SkPaint::kStroke_Style);
             p.setShader(nullptr);
-            p.setBlendMode(SkBlendMode::kSrcOver);
+            p.setXfermode(nullptr);
             canvas->drawRect(r, p);
 
             canvas->restore();
index 36702bf..300b78f 100644 (file)
@@ -69,7 +69,7 @@ protected:
         };
         for (size_t s = 0; s < SK_ARRAY_COUNT(kStrokes); ++s) {
             for (size_t m = 0; m <= SkXfermode::kLastMode; ++m) {
-                SkBlendMode mode = static_cast<SkBlendMode>(m);
+                SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(m);
                 canvas->drawText(SkXfermode::ModeName(mode),
                                  strlen(SkXfermode::ModeName(mode)),
                                  SkIntToScalar(x),
@@ -77,7 +77,7 @@ protected:
                                  labelP);
                 for (size_t c = 0; c < SK_ARRAY_COUNT(kSolidColors); ++c) {
                     SkPaint modePaint;
-                    modePaint.setBlendMode(mode);
+                    modePaint.setXfermodeMode(mode);
                     modePaint.setColor(kSolidColors[c]);
                     modePaint.setStyle(kStrokes[s].fStyle);
                     modePaint.setStrokeWidth(kStrokes[s].fWidth);
@@ -93,7 +93,7 @@ protected:
                 }
                 for (size_t a = 0; a < SK_ARRAY_COUNT(kBmpAlphas); ++a) {
                     SkPaint modePaint;
-                    modePaint.setBlendMode(mode);
+                    modePaint.setXfermodeMode(mode);
                     modePaint.setAlpha(kBmpAlphas[a]);
                     modePaint.setShader(fBmpShader);
                     modePaint.setStyle(kStrokes[s].fStyle);
index 2c24e75..de2f541 100644 (file)
@@ -33,7 +33,6 @@
       'SK_SUPPORT_LEGACY_STREAM_DATA',
       'SK_SUPPORT_LEGACY_CLIP_REGIONOPS',
       'SK_SUPPORT_LEGACY_SHADER_ISABITMAP',
-      'SK_SUPPORT_LEGACY_XFERMODE_OBJECT',
     ],
   },
 }
diff --git a/include/core/SkBlendMode.h b/include/core/SkBlendMode.h
deleted file mode 100644 (file)
index eb3469f..0000000
+++ /dev/null
@@ -1,51 +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 SkBlendMode_DEFINED
-#define SkBlendMode_DEFINED
-
-enum class SkBlendMode {
-    kClear,    //!< [0, 0]
-    kSrc,      //!< [Sa, Sc]
-    kDst,      //!< [Da, Dc]
-    kSrcOver,  //!< [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)]
-    kDstOver,  //!< [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)]
-    kSrcIn,    //!< [Sa * Da, Sc * Da]
-    kDstIn,    //!< [Da * Sa, Dc * Sa]
-    kSrcOut,   //!< [Sa * (1 - Da), Sc * (1 - Da)]
-    kDstOut,   //!< [Da * (1 - Sa), Dc * (1 - Sa)]
-    kSrcATop,  //!< [Da, Sc * Da + Dc * (1 - Sa)]
-    kDstATop,  //!< [Sa, Dc * Sa + Sc * (1 - Da)]
-    kXor,      //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)]
-    kPlus,     //!< [Sa + Da, Sc + Dc]
-    kModulate, // multiplies all components (= alpha and color)
-
-    // Following blend modes are defined in the CSS Compositing standard:
-    // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending
-    kScreen,
-    kLastCoeffMode = kScreen,
-
-    kOverlay,
-    kDarken,
-    kLighten,
-    kColorDodge,
-    kColorBurn,
-    kHardLight,
-    kSoftLight,
-    kDifference,
-    kExclusion,
-    kMultiply,
-    kLastSeparableMode = kMultiply,
-
-    kHue,
-    kSaturation,
-    kColor,
-    kLuminosity,
-    kLastMode = kLuminosity
-};
-
-#endif
index 5078f42..8d98e50 100644 (file)
@@ -9,7 +9,6 @@
 #define SkCanvas_DEFINED
 
 #include "SkTypes.h"
-#include "SkBlendMode.h"
 #include "SkBitmap.h"
 #include "SkClipOp.h"
 #include "SkDeque.h"
@@ -596,31 +595,22 @@ public:
         @param b    the blue component (0..255) of the color to fill the canvas
         @param mode the mode to apply the color in (defaults to SrcOver)
     */
-    void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkBlendMode mode = SkBlendMode::kSrcOver);
-#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
-    void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkXfermode::Mode mode) {
-        this->drawARGB(a, r, g, b, (SkBlendMode)mode);
-    }
-#endif
+    void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
+                  SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
 
     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
         specified color and mode.
         @param color    the color to draw with
         @param mode the mode to apply the color in (defaults to SrcOver)
     */
-    void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver);
-#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
-    void drawColor(SkColor color, SkXfermode::Mode mode) {
-        this->drawColor(color, (SkBlendMode)mode);
-    }
-#endif
+    void drawColor(SkColor color, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
 
     /**
      *  Helper method for drawing a color in SRC mode, completely replacing all the pixels
      *  in the current clip with this color.
      */
     void clear(SkColor color) {
-        this->drawColor(color, SkBlendMode::kSrc);
+        this->drawColor(color, SkXfermode::kSrc_Mode);
     }
 
     /**
index 5a23a34..609550f 100644 (file)
@@ -115,9 +115,6 @@ public:
                     or NULL if the mode will have no effect.
     */
     static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkXfermode::Mode mode);
-    static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkBlendMode mode) {
-        return MakeModeFilter(c, (SkXfermode::Mode)mode);
-    }
 
     /** Construct a colorfilter whose effect is to first apply the inner filter and then apply
      *  the outer filter to the result of the inner's.
index ddc90ae..e28d2fc 100644 (file)
@@ -8,14 +8,11 @@
 #ifndef SkPaint_DEFINED
 #define SkPaint_DEFINED
 
-#include "SkBlendMode.h"
 #include "SkColor.h"
 #include "SkFilterQuality.h"
 #include "SkMatrix.h"
 #include "SkXfermode.h"
 
-//#define SK_SUPPORT_LEGACY_XFERMODE_OBJECT
-
 class SkAutoDescriptor;
 class SkAutoGlyphCache;
 class SkColorFilter;
@@ -528,13 +525,12 @@ public:
 #endif
     void setColorFilter(sk_sp<SkColorFilter>);
 
-#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
     /** Get the paint's xfermode object.
         <p />
       The xfermode's reference count is not affected.
         @return the paint's xfermode (or NULL)
     */
-    SkXfermode* getXfermode() const;
+    SkXfermode* getXfermode() const { return fXfermode.get(); }
 
     /** Set or clear the xfermode object.
         <p />
@@ -556,11 +552,6 @@ public:
         the paint's xfermode is set to null.
      */
     SkXfermode* setXfermodeMode(SkXfermode::Mode);
-#endif
-
-    SkBlendMode getBlendMode() const { return (SkBlendMode)fBlendMode; }
-    bool isSrcOver() const { return (SkBlendMode)fBlendMode == SkBlendMode::kSrcOver; }
-    void setBlendMode(SkBlendMode mode) { fBlendMode = (unsigned)mode; }
 
     /** Get the paint's patheffect object.
         <p />
@@ -1099,6 +1090,7 @@ private:
     sk_sp<SkTypeface>     fTypeface;
     sk_sp<SkPathEffect>   fPathEffect;
     sk_sp<SkShader>       fShader;
+    sk_sp<SkXfermode>     fXfermode;
     sk_sp<SkMaskFilter>   fMaskFilter;
     sk_sp<SkColorFilter>  fColorFilter;
     sk_sp<SkRasterizer>   fRasterizer;
@@ -1111,7 +1103,6 @@ private:
     SkColor         fColor;
     SkScalar        fWidth;
     SkScalar        fMiterLimit;
-    uint32_t        fBlendMode; // just need 5-6 bits for SkXfermode::Mode
     union {
         struct {
             // all of these bitfields should add up to 32
index c2d05f9..c398d3a 100644 (file)
@@ -224,11 +224,10 @@ private:
     // V47: Add occluder rect to SkBlurMaskFilter
     // V48: Read and write extended SkTextBlobs.
     // V49: Gradients serialized as SkColor4f + SkColorSpace
-    // V50: SkXfermode -> SkBlendMode
 
     // Only SKPs within the min/current picture version range (inclusive) can be read.
     static const uint32_t     MIN_PICTURE_VERSION = 35;     // Produced by Chrome M39.
-    static const uint32_t CURRENT_PICTURE_VERSION = 50;
+    static const uint32_t CURRENT_PICTURE_VERSION = 49;
 
     static_assert(MIN_PICTURE_VERSION <= 41,
                   "Remove kFontFileName and related code from SkFontDescriptor.cpp.");
index 8319ad6..2d12b3c 100644 (file)
@@ -8,9 +8,8 @@
 #ifndef SkXfermode_DEFINED
 #define SkXfermode_DEFINED
 
-#include "SkBlendMode.h"
-#include "SkColor.h"
 #include "SkFlattenable.h"
+#include "SkColor.h"
 
 class GrFragmentProcessor;
 class GrTexture;
@@ -113,9 +112,6 @@ public:
      * Gets the name of the Mode as a string.
      */
     static const char* ModeName(Mode);
-    static const char* ModeName(SkBlendMode mode) {
-        return ModeName(Mode(mode));
-    }
 
     /**
      *  If the xfermode is one of the modes in the Mode enum, then asMode()
@@ -161,31 +157,6 @@ public:
     }
 #endif
 
-    /**
-     *  Skia maintains global xfermode objects corresponding to each BlendMode. This returns a
-     *  ptr to that global xfermode (or null if the mode is srcover). Thus the caller may use
-     *  the returned ptr, but it should leave its refcnt untouched.
-     */
-    static SkXfermode* Peek(SkBlendMode mode) {
-        sk_sp<SkXfermode> xfer = Make(mode);
-        if (!xfer) {
-            SkASSERT(SkBlendMode::kSrcOver == mode);
-            return nullptr;
-        }
-        SkASSERT(!xfer->unique());
-        return xfer.get();
-    }
-
-    static sk_sp<SkXfermode> Make(SkBlendMode bm) {
-        return Make((Mode)bm);
-    }
-
-    SkBlendMode blend() const {
-        Mode mode;
-        SkAssertResult(this->asMode(&mode));
-        return (SkBlendMode)mode;
-    }
-
     /** Return a function pointer to a routine that applies the specified
         porter-duff transfer mode.
      */
@@ -244,7 +215,6 @@ public:
     static bool IsOpaque(const sk_sp<SkXfermode>& xfer, SrcColorOpacity opacityType) {
         return IsOpaque(xfer.get(), opacityType);
     }
-    static bool IsOpaque(SkBlendMode, SrcColorOpacity);
 
 #if SK_SUPPORT_GPU
     /** Used by the SkXfermodeImageFilter to blend two colors via a GrFragmentProcessor.
index fa9c857..6066b8d 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef SkXfermodeImageFilter_DEFINED
 #define SkXfermodeImageFilter_DEFINED
 
-#include "SkBlendMode.h"
 #include "SkImageFilter.h"
 
 class SkXfermode;
@@ -20,11 +19,11 @@ class SkXfermode;
  */
 class SK_API SkXfermodeImageFilter {
 public:
-    static sk_sp<SkImageFilter> Make(SkBlendMode, sk_sp<SkImageFilter> background,
+    static sk_sp<SkImageFilter> Make(sk_sp<SkXfermode> mode, sk_sp<SkImageFilter> background,
                                      sk_sp<SkImageFilter> foreground,
                                      const SkImageFilter::CropRect* cropRect);
-    static sk_sp<SkImageFilter> Make(SkBlendMode mode, sk_sp<SkImageFilter> background) {
-        return Make(mode, std::move(background), nullptr, nullptr);
+    static sk_sp<SkImageFilter> Make(sk_sp<SkXfermode> mode, sk_sp<SkImageFilter> background) {
+        return Make(std::move(mode), std::move(background), nullptr, nullptr);
     }
 
     static sk_sp<SkImageFilter> MakeArithmetic(float k1, float k2, float k3, float k4,
@@ -39,16 +38,6 @@ public:
                               nullptr, nullptr);
     }
 
-#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
-    static sk_sp<SkImageFilter> Make(sk_sp<SkXfermode> mode, sk_sp<SkImageFilter> background,
-                                     sk_sp<SkImageFilter> foreground,
-                                     const SkImageFilter::CropRect* cropRect);
-    static sk_sp<SkImageFilter> Make(sk_sp<SkXfermode> mode, sk_sp<SkImageFilter> background) {
-        return Make(std::move(mode), std::move(background), nullptr, nullptr);
-    }
-
-#endif
-
 #ifdef SK_SUPPORT_LEGACY_XFERMODE_PTR
     static SkImageFilter* Create(SkXfermode* mode, SkImageFilter* background,
                                  SkImageFilter* foreground = NULL,
index a8af3c2..6120348 100644 (file)
@@ -16,9 +16,9 @@
 #include "effects/GrPorterDuffXferProcessor.h"
 #include "GrFragmentProcessor.h"
 
-#include "SkBlendMode.h"
 #include "SkRefCnt.h"
 #include "SkRegion.h"
+#include "SkXfermode.h"
 
 /**
  * The paint describes how color and coverage are computed at each pixel by GrContext draw
@@ -95,10 +95,6 @@ public:
         fXPFactory = std::move(xpFactory);
     }
 
-    void setPorterDuffXPFactory(SkBlendMode mode) {
-        fXPFactory = GrPorterDuffXPFactory::Make((SkXfermode::Mode)mode);
-    }
-
     void setPorterDuffXPFactory(SkXfermode::Mode mode) {
         fXPFactory = GrPorterDuffXPFactory::Make(mode);
     }
index 6777d76..8399d58 100644 (file)
@@ -17,9 +17,6 @@ class GrProcOptInfo;
 class GrPorterDuffXPFactory : public GrXPFactory {
 public:
     static sk_sp<GrXPFactory> Make(SkXfermode::Mode mode);
-    static sk_sp<GrXPFactory> Make(SkBlendMode mode) {
-        return Make((SkXfermode::Mode)mode);
-    }
 
     void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
                                   GrXPFactory::InvariantBlendedColor*) const override;
index 0e7a065..a34f76e 100644 (file)
@@ -618,7 +618,6 @@ DEFINES_ALL = [
     "SK_SUPPORT_LEGACY_TEXTBLOB_BUILDER",
     "SK_SUPPORT_LEGACY_CLIP_REGIONOPS",
     "SK_SUPPORT_LEGACY_SHADER_ISABITMAP",
-    "SK_SUPPORT_LEGACY_XFERMODE_OBJECT",
 ]
 
 ################################################################################
index 0a50303..65b1da1 100644 (file)
 #include "SkShader.h"
 
 static const struct {
-    SkBlendMode fMode;
-    const char* fLabel;
+    SkXfermode::Mode  fMode;
+    const char*         fLabel;
 } gModes[] = {
-    { SkBlendMode::kClear,    "Clear"     },
-    { SkBlendMode::kSrc,      "Src"       },
-    { SkBlendMode::kDst,      "Dst"       },
-    { SkBlendMode::kSrcOver,  "SrcOver"   },
-    { SkBlendMode::kDstOver,  "DstOver"   },
-    { SkBlendMode::kSrcIn,    "SrcIn"     },
-    { SkBlendMode::kDstIn,    "DstIn"     },
-    { SkBlendMode::kSrcOut,   "SrcOut"    },
-    { SkBlendMode::kDstOut,   "DstOut"    },
-    { SkBlendMode::kSrcATop,  "SrcATop"   },
-    { SkBlendMode::kDstATop,  "DstATop"   },
-    { SkBlendMode::kXor,      "Xor"       },
+    { SkXfermode::kClear_Mode,    "Clear"     },
+    { SkXfermode::kSrc_Mode,      "Src"       },
+    { SkXfermode::kDst_Mode,      "Dst"       },
+    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
+    { SkXfermode::kDstOver_Mode,  "DstOver"   },
+    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
+    { SkXfermode::kDstIn_Mode,    "DstIn"     },
+    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
+    { SkXfermode::kDstOut_Mode,   "DstOut"    },
+    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
+    { SkXfermode::kDstATop_Mode,  "DstATop"   },
+    { SkXfermode::kXor_Mode,      "Xor"       },
 };
 
 const int gWidth = 64;
@@ -34,7 +34,7 @@ const int gHeight = 64;
 const SkScalar W = SkIntToScalar(gWidth);
 const SkScalar H = SkIntToScalar(gHeight);
 
-static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha a1) {
+static SkScalar drawCell(SkCanvas* canvas, const sk_sp<SkXfermode>& mode, SkAlpha a0, SkAlpha a1) {
     SkPaint paint;
     paint.setAntiAlias(true);
 
@@ -47,7 +47,7 @@ static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha
 
     paint.setColor(SK_ColorRED);
     paint.setAlpha(a1);
-    paint.setBlendMode(mode);
+    paint.setXfermode(mode);
 
     SkScalar offset = SK_Scalar1 / 3;
     SkRect rect = SkRect::MakeXYWH(W / 4 + offset,
@@ -106,10 +106,11 @@ protected:
                     canvas->translate(W * 5, 0);
                     canvas->save();
                 }
+                sk_sp<SkXfermode> mode = SkXfermode::Make(gModes[i].fMode);
 
                 canvas->drawRect(bounds, fBGPaint);
                 canvas->saveLayer(&bounds, nullptr);
-                SkScalar dy = drawCell(canvas, gModes[i].fMode, gAlphaValue[alpha & 1],
+                SkScalar dy = drawCell(canvas, mode, gAlphaValue[alpha & 1],
                                        gAlphaValue[alpha & 2]);
                 canvas->restore();
 
index 8c1ace5..29b5c66 100644 (file)
@@ -89,7 +89,7 @@ static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
 
     p.setAlpha(0x11);
     p.setStyle(SkPaint::kFill_Style);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -97,7 +97,7 @@ static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     rastBuilder->addLayer(p);
 
     p.setAlpha(0x40);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1*2);
     rastBuilder->addLayer(p);
@@ -110,7 +110,7 @@ static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
 
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1*3/2);
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -121,7 +121,7 @@ static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
 
     p.setAlpha(0x20);
     p.setStyle(SkPaint::kFill_Style);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -130,10 +130,10 @@ static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
 
     p.setAlpha(0xFF);
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
 
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     rastBuilder->addLayer(p);
 }
 
@@ -141,7 +141,7 @@ static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     rastBuilder->addLayer(p);
 
     p.setPathEffect(SkDiscretePathEffect::Make(SK_Scalar1*4, SK_Scalar1*3));
-    p.setBlendMode(SkBlendMode::kSrcOut);
+    p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -152,7 +152,7 @@ static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     SkLayerRasterizer::Builder rastBuilder2;
     r5(&rastBuilder2, p);
     p.setRasterizer(rastBuilder2.detach());
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -194,11 +194,11 @@ static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
     p.setPathEffect(sk_make_sp<Dot2DPathEffect>(SK_Scalar1*2, lattice));
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 
     p.setPathEffect(nullptr);
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1);
     rastBuilder->addLayer(p);
@@ -211,11 +211,11 @@ static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
     lattice.postRotate(SkIntToScalar(30), 0, 0);
     p.setPathEffect(SkLine2DPathEffect::Make(SK_Scalar1*2, lattice));
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 
     p.setPathEffect(nullptr);
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1);
     rastBuilder->addLayer(p);
@@ -401,10 +401,10 @@ protected:
         paint.setColor(SK_ColorGREEN);
         paint.setStrokeWidth(SkIntToScalar(10));
         paint.setStyle(SkPaint::kStroke_Style);
-        paint.setBlendMode(SkBlendMode::kXor);
+        paint.setXfermode(SkXfermode::Make(SkXfermode::kXor_Mode));
         paint.setColorFilter(lightingFilter);
         canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
-        paint.setBlendMode(SkBlendMode::kSrcOver);
+        paint.setXfermode(nullptr);
         paint.setColorFilter(nullptr);
 
         // rectangle
index d2374f5..233306c 100644 (file)
@@ -351,7 +351,7 @@ public:
             bool doGamma = (fActualColorBits == 30) && SkImageInfoIsGammaCorrect(win->info());
 
             SkPaint gammaPaint;
-            gammaPaint.setBlendMode(SkBlendMode::kSrc);
+            gammaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
             if (doGamma) {
                 gammaPaint.setColorFilter(SkGammaColorFilter::Make(1.0f / 2.2f));
             }
index 67c7b2e..3da77a4 100644 (file)
@@ -100,7 +100,7 @@ static SkBitmap createBitmap(int n) {
     canvas.drawOval(r, paint);
 
     r.inset(SK_Scalar1*n/4, SK_Scalar1*n/4);
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     paint.setColor(0x800000FF);
     canvas.drawOval(r, paint);
 
index 82eb25f..8da6058 100644 (file)
@@ -163,7 +163,7 @@ private:
         canvas->restore();
 
         SkPaint paint;
-        paint.setBlendMode(SkBlendMode::kClear);
+        paint.setXfermodeMode(SkXfermode::kClear_Mode);
         for (int iy = 1; iy < fH; ++iy) {
             SkScalar y = SkIntToScalar(iy * fZoom);
             canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
index 28aa5f4..755e8fb 100644 (file)
@@ -157,8 +157,8 @@ static SkMatrix make_matrix() {
     return m;
 }
 
-static SkBlendMode make_xfermode() {
-    return static_cast<SkBlendMode>(R(SkXfermode::kLastMode+1));
+static SkXfermode::Mode make_xfermode() {
+    return static_cast<SkXfermode::Mode>(R(SkXfermode::kLastMode+1));
 }
 
 static SkPaint::Align make_paint_align() {
@@ -508,7 +508,7 @@ static SkPaint make_paint() {
     paint.setStrokeCap(make_paint_cap());
     paint.setStrokeJoin(make_paint_join());
     paint.setColorFilter(make_color_filter());
-    paint.setBlendMode(make_xfermode());
+    paint.setXfermodeMode(make_xfermode());
     paint.setPathEffect(make_path_effect());
     paint.setMaskFilter(make_mask_filter());
 
@@ -558,7 +558,7 @@ static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) {
     case MERGE:
         filter = SkMergeImageFilter::Make(make_image_filter(),
                                           make_image_filter(),
-                                          (SkXfermode::Mode)make_xfermode());
+                                          make_xfermode());
         break;
     case COLOR: {
         sk_sp<SkColorFilter> cf(make_color_filter());
@@ -585,7 +585,7 @@ static sk_sp<SkImageFilter> make_image_filter(bool canBeNull) {
                                               make_image_filter());
         break;
     case XFERMODE:
-        filter = SkXfermodeImageFilter::Make(make_xfermode(),
+        filter = SkXfermodeImageFilter::Make(SkXfermode::Make(make_xfermode()),
                                              make_image_filter(),
                                              make_image_filter(),
                                              nullptr);
index c7d0578..76420f0 100644 (file)
@@ -153,15 +153,15 @@ static void do_fuzz(SkCanvas* canvas) {
       break;
 
       case 2: {
-          SkBlendMode mode;
+          SkXfermode::Mode mode;
           switch (R(3)) {
-            case 0: mode = SkBlendMode::kSrc; break;
-            case 1: mode = SkBlendMode::kXor; break;
+            case 0: mode = SkXfermode::kSrc_Mode; break;
+            case 1: mode = SkXfermode::kXor_Mode; break;
             case 2:
             default:  // silence warning
-              mode = SkBlendMode::kSrcOver; break;
+              mode = SkXfermode::kSrcOver_Mode; break;
           }
-          paint.setBlendMode(mode);
+          paint.setXfermodeMode(mode);
       }
       break;
 
index 5eeb6cb..26037d7 100644 (file)
 #include "SkShader.h"
 
 static const struct {
-    SkBlendMode fMode;
-    const char* fLabel;
+    SkXfermode::Mode  fMode;
+    const char*         fLabel;
 } gModes[] = {
-    { SkBlendMode::kClear,    "Clear"     },
-    { SkBlendMode::kSrc,      "Src"       },
-    { SkBlendMode::kDst,      "Dst"       },
-    { SkBlendMode::kSrcOver,  "SrcOver"   },
-    { SkBlendMode::kDstOver,  "DstOver"   },
-    { SkBlendMode::kSrcIn,    "SrcIn"     },
-    { SkBlendMode::kDstIn,    "DstIn"     },
-    { SkBlendMode::kSrcOut,   "SrcOut"    },
-    { SkBlendMode::kDstOut,   "DstOut"    },
-    { SkBlendMode::kSrcATop,  "SrcATop"   },
-    { SkBlendMode::kDstATop,  "DstATop"   },
-    { SkBlendMode::kXor,      "Xor"       },
+    { SkXfermode::kClear_Mode,    "Clear"     },
+    { SkXfermode::kSrc_Mode,      "Src"       },
+    { SkXfermode::kDst_Mode,      "Dst"       },
+    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
+    { SkXfermode::kDstOver_Mode,  "DstOver"   },
+    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
+    { SkXfermode::kDstIn_Mode,    "DstIn"     },
+    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
+    { SkXfermode::kDstOut_Mode,   "DstOut"    },
+    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
+    { SkXfermode::kDstATop_Mode,  "DstATop"   },
+    { SkXfermode::kXor_Mode,      "Xor"       },
 };
 
 const int gWidth = 64;
@@ -34,7 +34,7 @@ const int gHeight = 64;
 const SkScalar W = SkIntToScalar(gWidth);
 const SkScalar H = SkIntToScalar(gHeight);
 
-static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha a1) {
+static SkScalar drawCell(SkCanvas* canvas, sk_sp<SkXfermode> mode, SkAlpha a0, SkAlpha a1) {
     SkPaint paint;
     paint.setAntiAlias(true);
 
@@ -47,7 +47,7 @@ static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha
 
     paint.setColor(SK_ColorRED);
     paint.setAlpha(a1);
-    paint.setBlendMode(mode);
+    paint.setXfermode(mode);
     for (int angle = 0; angle < 24; ++angle) {
         SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth;
         SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight;
@@ -105,7 +105,7 @@ protected:
                 }
                 canvas->drawRect(bounds, fBGPaint);
                 canvas->saveLayer(&bounds, nullptr);
-                SkScalar dy = drawCell(canvas, gModes[i].fMode,
+                SkScalar dy = drawCell(canvas, SkXfermode::Make(gModes[i].fMode),
                                        gAlphaValue[alpha & 1],
                                        gAlphaValue[alpha & 2]);
                 canvas->restore();
index f0c6a40..5fce85c 100644 (file)
@@ -44,13 +44,13 @@ protected:
             bounds.offset(-bounds.fLeft, -bounds.fTop);
             c.drawOval(bounds, paint);
 
-            paint.setBlendMode(SkBlendMode::kDstIn);
+            paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
             canvas->drawBitmap(mask, r.fLeft, r.fTop, &paint);
         } else {
             SkPath p;
             p.addOval(r);
             p.setFillType(SkPath::kInverseWinding_FillType);
-            paint.setBlendMode(SkBlendMode::kDstOut);
+            paint.setXfermodeMode(SkXfermode::kDstOut_Mode);
             canvas->drawPath(p, paint);
         }
     }
index 71b2e8b..52e6593 100644 (file)
@@ -31,7 +31,7 @@ static void make_paint(SkPaint* paint, const SkMatrix& localMatrix) {
     SkPoint pts[] = { { 0, 0 }, { 0, SK_Scalar1*20 } };
     paint->setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
                                                   SkShader::kClamp_TileMode, 0, &localMatrix));
-    paint->setBlendMode(SkBlendMode::kDstIn);
+    paint->setXfermodeMode(SkXfermode::kDstIn_Mode);
 }
 
 // test drawing with strips of fading gradient above and below
@@ -141,7 +141,7 @@ protected:
             canvas->saveLayer(&r, &p);
             canvas->drawColor(0xFFFF0000);
             p.setAlpha(0);  // or 0
-            p.setBlendMode(SkBlendMode::kSrc);
+            p.setXfermodeMode(SkXfermode::kSrc_Mode);
             canvas->drawOval(r, p);
             canvas->restore();
             return;
index af9608f..a53fe71 100644 (file)
@@ -225,7 +225,7 @@ protected:
         // We use a layer, so we can PLUS the different edge-colors, showing where two edges
         // canceled each other out.
         canvas->saveLayer(nullptr, nullptr);
-        p.setBlendMode(SkBlendMode::kPlus);
+        p.setXfermodeMode(SkXfermode::kPlus_Mode);
         for (int i = 0; i < N; ++i) {
             const int j = (i + 1) % N;
             p.setColor(fEdgeColor[i]);
index 30b8603..ab65ff6 100644 (file)
@@ -248,7 +248,7 @@ protected:
         canvas->restore();
 
         SkPaint paint;
-        paint.setBlendMode(SkBlendMode::kClear);
+        paint.setXfermodeMode(SkXfermode::kClear_Mode);
         for (int iy = 1; iy < fH; ++iy) {
             SkScalar y = SkIntToScalar(iy * fZoom);
             canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
index 082ff22..1934dc7 100644 (file)
@@ -80,7 +80,7 @@ static void drawFadingText(SkCanvas* canvas,
 
     SkPaint p;
     p.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 3, SkShader::kClamp_TileMode));
-    p.setBlendMode(SkBlendMode::kDstIn);
+    p.setXfermodeMode(SkXfermode::kDstIn_Mode);
     canvas->drawRect(bounds, p);
 
     canvas->restore();
index 521e9f6..5858d26 100644 (file)
@@ -472,7 +472,7 @@ static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
 
     p.setAlpha(0x11);
     p.setStyle(SkPaint::kFill_Style);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -481,7 +481,7 @@ static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
     rastBuilder->addLayer(p);
 
     p.setAlpha(0x40);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1*2);
     rastBuilder->addLayer(p);
@@ -495,7 +495,7 @@ static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
 
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1*3/2);
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -507,7 +507,7 @@ static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
 
     p.setAlpha(0x20);
     p.setStyle(SkPaint::kFill_Style);
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -517,10 +517,10 @@ static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
     rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
 
     p.setAlpha(0xFF);
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
 
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     rastBuilder->addLayer(p);
 }
 
@@ -531,7 +531,7 @@ static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
     rastBuilder->addLayer(p);
 
     p.setPathEffect(SkDiscretePathEffect::Make(SK_Scalar1*4, SK_Scalar1*3));
-    p.setBlendMode(SkBlendMode::kSrcOut);
+    p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -543,7 +543,7 @@ static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
     SkLayerRasterizer::Builder rastBuilder2;
     r5(&rastBuilder2, p);
     p.setRasterizer(rastBuilder2.detach());
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 }
 
@@ -572,11 +572,11 @@ static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
     p.setPathEffect(MakeDotEffect(SK_Scalar1*2, lattice));
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 
     p.setPathEffect(nullptr);
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1);
     rastBuilder->addLayer(p);
@@ -590,11 +590,11 @@ static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p)
     lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
     lattice.postRotate(SkIntToScalar(30), 0, 0);
     p.setPathEffect(SkLine2DPathEffect::Make(SK_Scalar1*2, lattice));
-    p.setBlendMode(SkBlendMode::kClear);
+    p.setXfermodeMode(SkXfermode::kClear_Mode);
     rastBuilder->addLayer(p);
 
     p.setPathEffect(nullptr);
-    p.setBlendMode(SkBlendMode::kSrcOver);
+    p.setXfermode(nullptr);
     p.setStyle(SkPaint::kStroke_Style);
     p.setStrokeWidth(SK_Scalar1);
     rastBuilder->addLayer(p);
index c0ad000..6aaffe5 100644 (file)
 #include "SkGradientShader.h"
 
 const struct {
-    SkBlendMode fMode;
-    const char* fName;
+    SkXfermode::Mode fMode;
+    const char*      fName;
 } gModes[] = {
-    { SkBlendMode::kSrcOver, "src-over" },
-    { SkBlendMode::kSrc,     "src" },
-    { SkBlendMode::kSrcIn,   "src-in" },
-    { SkBlendMode::kSrcOut,  "src-out" },
-    { SkBlendMode::kSrcATop, "src-atop" },
-    { SkBlendMode::kDstOver, "dst-over" },
-    { SkBlendMode::kDstIn,   "dst-in" },
-    { SkBlendMode::kDstOut,  "dst-out" },
-    { SkBlendMode::kDstATop, "dst-atop" },
+    { SkXfermode::kSrcOver_Mode, "src-over" },
+    { SkXfermode::kSrc_Mode,     "src" },
+    { SkXfermode::kSrcIn_Mode,   "src-in" },
+    { SkXfermode::kSrcOut_Mode,  "src-out" },
+    { SkXfermode::kSrcATop_Mode, "src-atop" },
+    { SkXfermode::kDstOver_Mode, "dst-over" },
+    { SkXfermode::kDstIn_Mode,   "dst-in" },
+    { SkXfermode::kDstOut_Mode,  "dst-out" },
+    { SkXfermode::kDstATop_Mode, "dst-atop" },
 };
 const int N_Modes = SK_ARRAY_COUNT(gModes);
 
@@ -109,10 +109,10 @@ private:
 
 class ModeDrawable : public SkDrawable {
 public:
-    ModeDrawable() : fMode(SkBlendMode::kSrcOver), fLoc(SkPoint::Make(0, 0)) {}
+    ModeDrawable() : fMode(SkXfermode::kSrcOver_Mode), fLoc(SkPoint::Make(0, 0)) {}
 
-    SkBlendMode fMode;
-    SkPoint     fLoc;
+    SkXfermode::Mode fMode;
+    SkPoint          fLoc;
 
     bool hitTest(SkScalar x, SkScalar y) {
         SkRect target = SkRect::MakeXYWH(x - fLoc.x() - 1, y - fLoc.y() - 1, 3, 3);
@@ -139,7 +139,7 @@ protected:
     }
 
     void onDraw(SkCanvas* canvas) override {
-        fPaint.setBlendMode(fMode);
+        fPaint.setXfermodeMode(fMode);
         canvas->save();
         canvas->translate(fLoc.x(), fLoc.y());
         canvas->drawOval(fBounds, fPaint);
@@ -160,7 +160,7 @@ class XferDemo : public SampleView {
         SkScalar x = 10;
         SkScalar y = 10;
         for (int i = 0; i < N_Modes; ++i) {
-            SkAutoTUnref<SkView> v(new PushButtonWig(gModes[i].fName, (int)gModes[i].fMode));
+            SkAutoTUnref<SkView> v(new PushButtonWig(gModes[i].fName, gModes[i].fMode));
             v->setSize(70, 25);
             v->setLoc(x, y);
             v->setVisibleP(true);
@@ -178,7 +178,7 @@ public:
         for (int i = 0; i < N; ++i) {
             fDrs[i].reset(new CircDrawable(200, colors[i]));
             fDrs[i]->fLoc.set(100.f + i * 100, 100.f + i * 100);
-            fDrs[i]->fMode = SkBlendMode::kSrcOver;
+            fDrs[i]->fMode = SkXfermode::kSrcOver_Mode;
         }
         fSelected = nullptr;
 
@@ -189,7 +189,7 @@ protected:
     bool onEvent(const SkEvent& evt) override {
         if (evt.isType("push-button")) {
             if (fSelected) {
-                fSelected->fMode = (SkBlendMode)evt.getFast32();
+                fSelected->fMode = (SkXfermode::Mode)evt.getFast32();
                 this->inval(nullptr);
             }
             return true;
index fe07c9b..ef25114 100644 (file)
@@ -37,7 +37,8 @@ class XfermodesBlurView : public SampleView {
     SkBitmap    fBG;
     SkBitmap    fSrcB, fDstB;
 
-    void draw_mode(SkCanvas* canvas, SkBlendMode mode, int alpha, SkScalar x, SkScalar y) {
+    void draw_mode(SkCanvas* canvas, sk_sp<SkXfermode> mode, int alpha,
+                   SkScalar x, SkScalar y) {
         SkPaint p;
         p.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
                                                SkBlurMask::ConvertRadiusToSigma(5),
@@ -54,7 +55,7 @@ class XfermodesBlurView : public SampleView {
         r.offset(x, y);
         canvas->drawOval(r, p);
 
-        p.setBlendMode(mode);
+        p.setXfermode(std::move(mode));
 
         // draw a square overlapping the circle
         // in the lower right of the canvas
@@ -109,23 +110,34 @@ protected:
         }
 
         const struct {
-            SkBlendMode fMode;
-            const char* fLabel;
+            SkXfermode::Mode  fMode;
+            const char*         fLabel;
         } gModes[] = {
-            { SkBlendMode::kClear,    "Clear"     },
-            { SkBlendMode::kSrc,      "Src"       },
-            { SkBlendMode::kDst,      "Dst"       },
-            { SkBlendMode::kSrcOver,  "SrcOver"   },
-            { SkBlendMode::kDstOver,  "DstOver"   },
-            { SkBlendMode::kSrcIn,    "SrcIn"     },
-            { SkBlendMode::kDstIn,    "DstIn"     },
-            { SkBlendMode::kSrcOut,   "SrcOut"    },
-            { SkBlendMode::kDstOut,   "DstOut"    },
-            { SkBlendMode::kSrcATop,  "SrcATop"   },
-            { SkBlendMode::kDstATop,  "DstATop"   },
-            { SkBlendMode::kXor,      "Xor"       },
-
-            { SkBlendMode::kPlus,     "Plus"          },
+            { SkXfermode::kClear_Mode,    "Clear"     },
+            { SkXfermode::kSrc_Mode,      "Src"       },
+            { SkXfermode::kDst_Mode,      "Dst"       },
+            { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
+            { SkXfermode::kDstOver_Mode,  "DstOver"   },
+            { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
+            { SkXfermode::kDstIn_Mode,    "DstIn"     },
+            { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
+            { SkXfermode::kDstOut_Mode,   "DstOut"    },
+            { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
+            { SkXfermode::kDstATop_Mode,  "DstATop"   },
+            { SkXfermode::kXor_Mode,      "Xor"       },
+
+            { SkXfermode::kPlus_Mode,         "Plus"          },
+            /*{ SkXfermode::kModulate_Mode,     "Modulate"      },
+            { SkXfermode::kScreen_Mode,       "Screen"        },
+            { SkXfermode::kOverlay_Mode,      "Overlay"       },
+            { SkXfermode::kDarken_Mode,       "Darken"        },
+            { SkXfermode::kLighten_Mode,      "Lighten"       },
+            { SkXfermode::kColorDodge_Mode,   "ColorDodge"    },
+            { SkXfermode::kColorBurn_Mode,    "ColorBurn"     },
+            { SkXfermode::kHardLight_Mode,    "HardLight"     },
+            { SkXfermode::kSoftLight_Mode,    "SoftLight"     },
+            { SkXfermode::kDifference_Mode,   "Difference"    },
+            { SkXfermode::kExclusion_Mode,    "Exclusion"     },*/
         };
 
         const SkScalar w = SkIntToScalar(W);
@@ -156,7 +168,8 @@ protected:
                 canvas->drawRect(r, p);
 
                 canvas->saveLayer(&r, nullptr);
-                draw_mode(canvas, gModes[i].fMode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop);
+                draw_mode(canvas, SkXfermode::Make(gModes[i].fMode),
+                          twice ? 0x88 : 0xFF, r.fLeft, r.fTop);
                 canvas->restore();
 
                 r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
index 126170c..f82cd81 100644 (file)
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkBlendMode.h"
 #include "SkMaskFilter.h"
 #include "SkPaint.h"
 #include "SkShader.h"
@@ -133,41 +132,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);
-    SkBlendMode skmode;
+    SkXfermode::Mode skmode;
     switch (mode) {
         #define MAP(X, Y) case (X): skmode = (Y); break
-        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 );
+        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 );
         #undef MAP
         default:
             return;
     }
-    AsPaint(paint)->setBlendMode(skmode);
+    AsPaint(paint)->setXfermodeMode(skmode);
 }
index 26d253c..440de68 100644 (file)
@@ -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 (file)
index b5d9e75..0000000
+++ /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
index ce689d7..db9fcda 100644 (file)
@@ -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);
index cb7d718..6697614 100644 (file)
@@ -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());
 }
 
index ea0554d..aada058 100644 (file)
@@ -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);
 }
 
index d63e924..455a97b 100644 (file)
@@ -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);
index 7860b7c..066ec61 100644 (file)
@@ -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 {
index cef4cfa..950f187 100644 (file)
@@ -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;
         }
     }
index ce47d5c..c55ca10 100644 (file)
@@ -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)) {
@@ -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.isSrcOver())) {
+        (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) {
         return;
     }
 
@@ -2994,21 +2994,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);
 }
 
index c6c5cf3..34c7d73 100644 (file)
@@ -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 *
index ec3b0a9..5b29884 100644 (file)
@@ -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);
index 68183cc..63095bc 100644 (file)
@@ -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());
index 0a33280..12efc64 100644 (file)
@@ -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);
index 83e45c0..9d76a16 100644 (file)
@@ -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)
@@ -385,6 +385,9 @@ 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
@@ -400,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
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -1909,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()) |
@@ -1927,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
@@ -1938,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());
@@ -1959,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());
@@ -1977,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());
@@ -2005,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);
@@ -2134,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();
@@ -2378,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;
 }
@@ -2399,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));
index cbe2558..6725cb4 100644 (file)
@@ -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) {
index 108c877..7749839 100644 (file)
@@ -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;
index 91d60be..1e8dcf5 100644 (file)
@@ -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);
     }
 
index 4ac7973..3e6742f 100644 (file)
@@ -69,7 +69,6 @@ public:
         kLightingShaderWritesInvNormRotation = 45,
         kBlurMaskFilterWritesOccluder      = 47,
         kGradientShaderFloatColor_Version  = 49,
-        kXfermodeToBlendMode_Version       = 50,
     };
 
     /**
index dca19df..ca9c1b6 100644 (file)
@@ -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;
index a7feec1..d46a657 100644 (file)
@@ -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
index 38ec739..a13edd9 100644 (file)
@@ -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());
index 1a76b1b..9388599 100644 (file)
@@ -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);
index 9df7dab..6c5a7cb 100644 (file)
@@ -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
index 226f2b8..2717fab 100644 (file)
@@ -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
index 3a1da36..1b2c8e3 100644 (file)
@@ -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;
             }
index bbae2e1..515e05b 100644 (file)
@@ -107,7 +107,7 @@ sk_sp<GrTexture> SkAlphaThresholdFilterImpl::createMaskTexture(GrContext* contex
     }
 
     GrPaint grPaint;
-    grPaint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+    grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
     SkRegion::Iterator iter(fRegion);
     drawContext->clear(nullptr, 0x0, true);
 
index 507a805..d6b23d5 100644 (file)
@@ -89,7 +89,7 @@ sk_sp<SkSpecialImage> SkColorFilterImageFilter::onFilterImage(SkSpecialImage* so
 
     SkPaint paint;
 
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     paint.setColorFilter(fColorFilter);
 
     // TODO: it may not be necessary to clear or drawPaint inside the input bounds
index 6c779b7..4f6386d 100644 (file)
@@ -343,7 +343,7 @@ sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* sou
                                           offsetMatrix,
                                           colorTexture.get(),
                                           SkISize::Make(color->width(), color->height())));
-        paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+        paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
         SkMatrix matrix;
         matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y()));
 
index cc43db7..b4b8cac 100644 (file)
@@ -95,6 +95,7 @@ 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);
index f96a4a1..f434de4 100644 (file)
@@ -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.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     // FIXME: this probably shouldn't be necessary, but drawImageRect asserts
     // None filtering when it's translate-only
     paint.setFilterQuality(
index 784228f..d8f7744 100644 (file)
@@ -104,7 +104,7 @@ void SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo(
         dst->setColorFilter(sk_ref_sp(src.getColorFilter()));
     }
     if (bits & kXfermode_Bit) {
-        dst->setBlendMode(src.getBlendMode());
+        dst->setXfermode(sk_ref_sp(src.getXfermode()));
     }
 
     // we don't override these
index 057ef24..5627574 100644 (file)
@@ -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(SkBlendMode::kSrc);
+    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
     drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
 }
 
index 9830669..cc7e336 100755 (executable)
@@ -131,7 +131,7 @@ sk_sp<SkSpecialImage> SkMergeImageFilter::onFilterImage(SkSpecialImage* source,
 
         SkPaint paint;
         if (fModes) {
-            paint.setBlendMode((SkBlendMode)fModes[i]);
+            paint.setXfermodeMode((SkXfermode::Mode)fModes[i]);
         }
 
         inputs[i]->draw(canvas,
index 2bd7928..82e47c5 100644 (file)
@@ -401,7 +401,7 @@ static void apply_morphology_rect(GrDrawContext* drawContext,
                                                              radius,
                                                              morphType,
                                                              bounds));
-    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
     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(SkBlendMode::kSrc);
+    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
     drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
                                 SkRect::Make(srcRect));
 }
index 2e8b0d9..1c99154 100644 (file)
@@ -61,7 +61,7 @@ sk_sp<SkSpecialImage> SkOffsetImageFilter::onFilterImage(SkSpecialImage* source,
         canvas->clear(0x0);
 
         SkPaint paint;
-        paint.setBlendMode(SkBlendMode::kSrc);
+        paint.setXfermodeMode(SkXfermode::kSrc_Mode);
         canvas->translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
                           SkIntToScalar(srcOffset.fY - bounds.fTop));
 
index a140db2..46c4d9a 100644 (file)
@@ -87,7 +87,7 @@ sk_sp<SkSpecialImage> SkTileImageFilter::onFilterImage(SkSpecialImage* source,
         SkASSERT(canvas);
 
         SkPaint paint;
-        paint.setBlendMode(SkBlendMode::kSrc);
+        paint.setXfermodeMode(SkXfermode::kSrc_Mode);
 
         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.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     paint.setShader(subset->makeShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
     canvas->translate(-dstRect.fLeft, -dstRect.fTop);
     canvas->drawRect(dstRect, paint);
index 2335a76..952ce97 100644 (file)
@@ -27,7 +27,7 @@
 
 class SkXfermodeImageFilter_Base : public SkImageFilter {
 public:
-    SkXfermodeImageFilter_Base(SkBlendMode mode, sk_sp<SkImageFilter> inputs[2],
+    SkXfermodeImageFilter_Base(sk_sp<SkXfermode> mode, sk_sp<SkImageFilter> inputs[2],
                                const CropRect* cropRect);
 
     SK_TO_STRING_OVERRIDE()
@@ -55,7 +55,7 @@ protected:
 #endif
 
 private:
-    SkBlendMode fMode;
+    sk_sp<SkXfermode> fMode;
 
     friend class SkXfermodeImageFilter;
 
@@ -64,7 +64,7 @@ private:
 
 ///////////////////////////////////////////////////////////////////////////////
 
-sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(SkBlendMode mode,
+sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode,
                                                  sk_sp<SkImageFilter> background,
                                                  sk_sp<SkImageFilter> foreground,
                                                  const SkImageFilter::CropRect* cropRect) {
@@ -72,36 +72,23 @@ sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(SkBlendMode mode,
     return sk_sp<SkImageFilter>(new SkXfermodeImageFilter_Base(mode, inputs, cropRect));
 }
 
-#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)
+SkXfermodeImageFilter_Base::SkXfermodeImageFilter_Base(sk_sp<SkXfermode> mode,
+                                             sk_sp<SkImageFilter> inputs[2],
+                                             const CropRect* cropRect)
     : INHERITED(inputs, 2, cropRect)
-    , fMode(mode)
-{}
+    , fMode(std::move(mode)) {
+}
 
 sk_sp<SkFlattenable> SkXfermodeImageFilter_Base::CreateProc(SkReadBuffer& buffer) {
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
-    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),
+    sk_sp<SkXfermode> mode(buffer.readXfermode());
+    return SkXfermodeImageFilter::Make(std::move(mode), common.getInput(0), common.getInput(1),
                                        &common.cropRect());
 }
 
 void SkXfermodeImageFilter_Base::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-    buffer.write32((unsigned)fMode);
+    buffer.writeFlattenable(fMode.get());
 }
 
 sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage* source,
@@ -160,7 +147,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage*
 
     if (background) {
         SkPaint paint;
-        paint.setBlendMode(SkBlendMode::kSrc);
+        paint.setXfermodeMode(SkXfermode::kSrc_Mode);
         background->draw(canvas,
                          SkIntToScalar(backgroundOffset.fX), SkIntToScalar(backgroundOffset.fY),
                          &paint);
@@ -174,7 +161,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage*
 void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage* img,
                                                 const SkIRect& fgBounds) const {
     SkPaint paint;
-    paint.setBlendMode(fMode);
+    paint.setXfermode(fMode);
     if (img) {
         img->draw(canvas, SkIntToScalar(fgBounds.fLeft), SkIntToScalar(fgBounds.fTop), &paint);
     }
@@ -188,7 +175,11 @@ void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage
 #ifndef SK_IGNORE_TO_STRING
 void SkXfermodeImageFilter_Base::toString(SkString* str) const {
     str->appendf("SkXfermodeImageFilter: (");
-    str->appendf("blendmode: (%d)", fMode);
+    str->appendf("xfermode: (");
+    if (fMode) {
+        fMode->toString(str);
+    }
+    str->append(")");
     if (this->getInput(0)) {
         str->appendf("foreground: (");
         this->getInput(0)->toString(str);
@@ -275,7 +266,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::filterImageGPU(
         paint.addColorFragmentProcessor(std::move(bgFP));
     }
 
-    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
 
     sk_sp<GrDrawContext> drawContext(
         context->makeDrawContext(SkBackingFit::kApprox, bounds.width(), bounds.height(),
@@ -299,9 +290,8 @@ 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).
-    SkXfermode* xfer = SkXfermode::Peek(fMode);
-    sk_sp<SkXfermode> srcover;
-    if (!xfer) {
+    SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get()));
+    if (!mode) {
         // 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.
@@ -309,11 +299,9 @@ SkXfermodeImageFilter_Base::makeFGFrag(sk_sp<GrFragmentProcessor> bgFP) const {
         rec.fProc = SkXfermode::GetProc(SkXfermode::kSrcOver_Mode);
         SkXfermode::ModeAsCoeff(SkXfermode::kSrcOver_Mode, &rec.fSC, &rec.fDC);
 
-        srcover.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode));
-        xfer = srcover.get();
-
+        mode.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode));
     }
-    return xfer->makeFragmentProcessorForImageFilter(std::move(bgFP));
+    return mode->makeFragmentProcessorForImageFilter(std::move(bgFP));
 }
 
 #endif
@@ -324,8 +312,7 @@ 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)
-        // need to pass a blendmode to our inherited constructor, but we ignore it
-        : SkXfermodeImageFilter_Base(SkBlendMode::kSrcOver, inputs, cropRect)
+        : SkXfermodeImageFilter_Base(nullptr, inputs, cropRect)
         , fK{ k1, k2, k3, k4 }
         , fEnforcePMColor(enforcePMColor)
     {}
@@ -360,8 +347,8 @@ sk_sp<SkFlattenable> SkArithmeticImageFilter::CreateProc(SkReadBuffer& buffer) {
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
 
     // skip the mode (srcover) our parent-class wrote
-    SkDEBUGCODE(uint32_t mode =) buffer.read32();
-    SkASSERT((unsigned)SkBlendMode::kSrcOver == mode);
+    sk_sp<SkXfermode> mode(buffer.readXfermode());
+    SkASSERT(nullptr == mode);
 
     float k[4];
     for (int i = 0; i < 4; ++i) {
@@ -488,16 +475,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 = (int)SkBlendMode::kSrc;
+        mode = SkXfermode::kSrc_Mode;
     } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) &&
                SkScalarNearlyEqual(k3, SK_Scalar1) && SkScalarNearlyZero(k4)) {
-        mode = (int)SkBlendMode::kDst;
+        mode = SkXfermode::kDst_Mode;
     } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) &&
                SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) {
-        mode = (int)SkBlendMode::kClear;
+        mode = SkXfermode::kClear_Mode;
     }
     if (mode >= 0) {
-        return SkXfermodeImageFilter::Make((SkBlendMode)mode,
+        return SkXfermodeImageFilter::Make(SkXfermode::Make((SkXfermode::Mode)mode),
                                            std::move(background), std::move(foreground), crop);
     }
 
index 176d5da..6cec1da 100644 (file)
@@ -356,7 +356,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
             }
             GrPaint paint;
             paint.addColorFragmentProcessor(std::move(fp));
-            paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+            paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
             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(SkBlendMode::kSrc);
+                paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
                 paint.setAllowSRGBInputs(true);
                 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
                 tempDC->drawRect(GrNoClip(), paint, SkMatrix::I(), rect, nullptr);
index 42d6795..e9a9619 100644 (file)
@@ -241,7 +241,7 @@ void GrDrawContext::internalClear(const GrFixedClip& clip,
 
         GrPaint paint;
         paint.setColor4f(GrColor4f::FromGrColor(color));
-        paint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::Mode::kSrc_Mode));
+        paint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSrc_Mode));
 
         this->drawRect(clip, paint, SkMatrix::I(), clearRect);
     } else if (isFull) {
index 747b757..a20eacb 100644 (file)
 /*
  * Convert a boolean operation into a transfer mode code
  */
-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
+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
     };
 
     return modeMap[op];
@@ -42,7 +42,7 @@ void GrSWMaskHelper::drawRect(const SkRect& rect, SkRegion::Op op,
                               bool antiAlias, uint8_t alpha) {
     SkPaint paint;
 
-    paint.setBlendMode(op_to_mode(op));
+    paint.setXfermode(SkXfermode::Make(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.setBlendMode(op_to_mode(op));
+        paint.setXfermodeMode(op_to_mode(op));
         paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
         fDraw.drawPath(path, paint);
     }
index f51cc54..3ca90f5 100644 (file)
@@ -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(SkBlendMode::kSrc);
+    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
 
     SkRect localRect;
     if (subset) {
index 93a62d2..5e7dafe 100644 (file)
@@ -41,7 +41,7 @@ static bool convert_texture(GrTexture* src, GrDrawContext* dst, int dstW, int ds
         return false;
     }
     GrPaint paint;
-    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
     paint.addColorFragmentProcessor(std::move(fp));
     dst->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::MakeIWH(dstW, dstH));
     return true;
index db58e0a..b187ec3 100644 (file)
@@ -142,7 +142,7 @@ sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx,
         }
     }
 
-    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
     const SkRect r = SkRect::MakeIWH(yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth,
             yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
 
index ee4e40a..d4db461 100644 (file)
@@ -20,7 +20,6 @@
 #include "GrXferProcessor.h"
 #include "GrYUVProvider.h"
 
-#include "SkBlendModePriv.h"
 #include "SkColorFilter.h"
 #include "SkConfig8888.h"
 #include "SkCanvas.h"
@@ -681,8 +680,9 @@ 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());
-    if (!skPaint.isSrcOver()) {
-        grPaint->setXPFactory(SkBlendMode_AsXPFactory(skPaint.getBlendMode()));
+    SkXfermode* xfermode = skPaint.getXfermode();
+    if (xfermode) {
+        grPaint->setXPFactory(xfermode->asXPFactory());
     }
 
 #ifndef SK_IGNORE_GPU_DITHER
index 80a0314..4eb7a11 100644 (file)
@@ -229,19 +229,19 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
                 tempDC->asTexture().get(), GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I()));
 
         paint1.addColorFragmentProcessor(std::move(pmToUPM1));
-        paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
+        paint1.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
 
         readDC->fillRectToRect(GrNoClip(), paint1, SkMatrix::I(), kDstRect, kSrcRect);
 
         readDC->asTexture()->readPixels(0, 0, kSize, kSize, kConfig, firstRead);
 
         paint2.addColorFragmentProcessor(std::move(upmToPM));
-        paint2.setPorterDuffXPFactory(SkBlendMode::kSrc);
+        paint2.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
 
         tempDC->fillRectToRect(GrNoClip(), paint2, SkMatrix::I(), kDstRect, kSrcRect);
 
         paint3.addColorFragmentProcessor(std::move(pmToUPM2));
-        paint3.setPorterDuffXPFactory(SkBlendMode::kSrc);
+        paint3.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
 
         readDC->fillRectToRect(GrNoClip(), paint3, SkMatrix::I(), kDstRect, kSrcRect);
 
index a5685f0..56d4ec1 100644 (file)
@@ -547,7 +547,8 @@ void GrTextUtils::DrawPosTextAsPath(GrContext* context,
 }
 
 bool GrTextUtils::ShouldDisableLCD(const SkPaint& paint) {
-    return paint.getMaskFilter() ||
+    return !SkXfermode::AsMode(paint.getXfermode(), nullptr) ||
+           paint.getMaskFilter() ||
            paint.getRasterizer() ||
            paint.getPathEffect() ||
            paint.isFakeBoldText() ||
index 67779ba..2870f31 100644 (file)
@@ -259,7 +259,7 @@ bool SkImage_Base::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, siz
     SkCanvas canvas(bm);
 
     SkPaint paint;
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     canvas.drawImage(this, -SkIntToScalar(srcX), -SkIntToScalar(srcY), &paint);
 
     return true;
index a874284..a002120 100644 (file)
 
 // Utility functions
 
-// If the paint will definitely draw opaquely, replace kSrc with
-// kSrcOver.  http://crbug.com/473572
+// If the paint will definitely draw opaquely, replace kSrc_Mode with
+// kSrcOver_Mode.  http://crbug.com/473572
 static void replace_srcmode_on_opaque_paint(SkPaint* paint) {
-    if (kSrcOver_SkXfermodeInterpretation == SkInterpretXfermode(*paint, false)) {
-        paint->setBlendMode(SkBlendMode::kSrcOver);
+    if (kSrcOver_SkXfermodeInterpretation
+        == SkInterpretXfermode(*paint, false)) {
+        paint->setXfermode(nullptr);
     }
 }
 
@@ -391,7 +392,7 @@ public:
                        const SkPaint& paint, bool hasText = false)
         : fDevice(device),
           fContentEntry(nullptr),
-          fBlendMode(SkBlendMode::kSrcOver),
+          fXfermode(SkXfermode::kSrcOver_Mode),
           fDstFormXObject(nullptr) {
         init(draw.fClipStack, draw.fRC->bwRgn(), *draw.fMatrix, paint, hasText);
     }
@@ -400,7 +401,7 @@ public:
                        const SkPaint& paint, bool hasText = false)
         : fDevice(device),
           fContentEntry(nullptr),
-          fBlendMode(SkBlendMode::kSrcOver),
+          fXfermode(SkXfermode::kSrcOver_Mode),
           fDstFormXObject(nullptr) {
         init(clipStack, clipRegion, matrix, paint, hasText);
     }
@@ -411,7 +412,7 @@ public:
             if (shape->isEmpty()) {
                 shape = nullptr;
             }
-            fDevice->finishContentEntry(fBlendMode, std::move(fDstFormXObject), shape);
+            fDevice->finishContentEntry(fXfermode, std::move(fDstFormXObject), shape);
         }
     }
 
@@ -419,16 +420,16 @@ public:
 
     /* Returns true when we explicitly need the shape of the drawing. */
     bool needShape() {
-        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:
+        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:
                 return true;
             default:
                 return false;
@@ -437,7 +438,7 @@ public:
 
     /* Returns true unless we only need the shape of the drawing. */
     bool needSource() {
-        if (fBlendMode == SkBlendMode::kClear) {
+        if (fXfermode == SkXfermode::kClear_Mode) {
             return false;
         }
         return true;
@@ -454,7 +455,7 @@ public:
 private:
     SkPDFDevice* fDevice;
     SkPDFDevice::ContentEntry* fContentEntry;
-    SkBlendMode fBlendMode;
+    SkXfermode::Mode fXfermode;
     sk_sp<SkPDFObject> fDstFormXObject;
     SkPath fShape;
 
@@ -465,7 +466,9 @@ private:
             NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
             return;
         }
-        fBlendMode = paint.getBlendMode();
+        if (paint.getXfermode()) {
+            paint.getXfermode()->asMode(&fXfermode);
+        }
         fContentEntry = fDevice->setUpContentEntry(clipStack, clipRegion,
                                                    matrix, paint, hasText,
                                                    &fDstFormXObject);
@@ -1705,7 +1708,7 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
                                           sk_sp<SkPDFObject> mask,
                                           const SkClipStack* clipStack,
                                           const SkRegion& clipRegion,
-                                          SkBlendMode mode,
+                                          SkXfermode::Mode mode,
                                           bool invertClip) {
     if (clipRegion.isEmpty() && !invertClip) {
         return;
@@ -1718,7 +1721,7 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
     SkMatrix identity;
     identity.reset();
     SkPaint paint;
-    paint.setBlendMode(mode);
+    paint.setXfermodeMode(mode);
     ScopedContentEntry content(this, clipStack, clipRegion, identity, paint);
     if (!content.entry()) {
         return;
@@ -1764,24 +1767,27 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli
         }
     }
 
-    SkBlendMode blendMode = paint.getBlendMode();
+    SkXfermode::Mode xfermode = SkXfermode::kSrcOver_Mode;
+    if (paint.getXfermode()) {
+        paint.getXfermode()->asMode(&xfermode);
+    }
 
     // For the following modes, we want to handle source and destination
     // separately, so make an object of what's already there.
-    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 (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 (!isContentEmpty()) {
             *dst = this->makeFormXObjectFromDevice();
             SkASSERT(isContentEmpty());
-        } else if (blendMode != SkBlendMode::kSrc &&
-                   blendMode != SkBlendMode::kSrcOut) {
+        } else if (xfermode != SkXfermode::kSrc_Mode &&
+                   xfermode != SkXfermode::kSrcOut_Mode) {
             // Except for Src and SrcOut, if there isn't anything already there,
             // then we're done.
             return nullptr;
@@ -1791,14 +1797,14 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli
     // Xor, Plus.
 
     // Dst xfer mode doesn't draw source at all.
-    if (blendMode == SkBlendMode::kDst) {
+    if (xfermode == SkXfermode::kDst_Mode) {
         return nullptr;
     }
 
     SkPDFDevice::ContentEntry* entry;
     if (fContentEntries.back() && fContentEntries.back()->fContent.getOffset() == 0) {
         entry = fContentEntries.back();
-    } else if (blendMode != SkBlendMode::kDstOver) {
+    } else if (xfermode != SkXfermode::kDstOver_Mode) {
         entry = fContentEntries.emplace_back();
     } else {
         entry = fContentEntries.emplace_front();
@@ -1808,23 +1814,23 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli
     return entry;
 }
 
-void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
+void SkPDFDevice::finishContentEntry(SkXfermode::Mode xfermode,
                                      sk_sp<SkPDFObject> dst,
                                      SkPath* shape) {
-    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) {
+    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) {
         SkASSERT(!dst);
         return;
     }
-    if (blendMode == SkBlendMode::kDstOver) {
+    if (xfermode == SkXfermode::kDstOver_Mode) {
         SkASSERT(!dst);
         if (fContentEntries.front()->fContent.getOffset() == 0) {
             // For DstOver, an empty content entry was inserted before the rest
@@ -1835,8 +1841,8 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
         return;
     }
     if (!dst) {
-        SkASSERT(blendMode == SkBlendMode::kSrc ||
-                 blendMode == SkBlendMode::kSrcOut);
+        SkASSERT(xfermode == SkXfermode::kSrc_Mode ||
+                 xfermode == SkXfermode::kSrcOut_Mode);
         return;
     }
 
@@ -1861,8 +1867,8 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
         // 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 || blendMode == SkBlendMode::kDstOut ||
-                blendMode == SkBlendMode::kSrcATop) {
+        if (shape == nullptr || xfermode == SkXfermode::kDstOut_Mode ||
+                xfermode == SkXfermode::kSrcATop_Mode) {
             ScopedContentEntry content(this, &fExistingClipStack,
                                        fExistingClipRegion, identity,
                                        stockPaint);
@@ -1871,7 +1877,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
                                         &content.entry()->fContent);
             return;
         } else {
-            blendMode = SkBlendMode::kClear;
+            xfermode = SkXfermode::kClear_Mode;
         }
     } else {
         SkASSERT(fContentEntries.count() == 1);
@@ -1880,14 +1886,14 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
 
     // TODO(vandebo) srcFormXObject may contain alpha, but here we want it
     // without alpha.
-    if (blendMode == SkBlendMode::kSrcATop) {
+    if (xfermode == SkXfermode::kSrcATop_Mode) {
         // 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,
-                                SkBlendMode::kSrcOver, true);
+                                SkXfermode::kSrcOver_Mode, true);
     } else {
         if (shape != nullptr) {
             // Draw shape into a form-xobject.
@@ -1903,19 +1909,19 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
             drawFormXObjectWithMask(addXObjectResource(dst.get()),
                                     this->makeFormXObjectFromDevice(),
                                     &fExistingClipStack, fExistingClipRegion,
-                                    SkBlendMode::kSrcOver, true);
+                                    SkXfermode::kSrcOver_Mode, true);
 
         } else {
             drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObject,
                                     &fExistingClipStack, fExistingClipRegion,
-                                    SkBlendMode::kSrcOver, true);
+                                    SkXfermode::kSrcOver_Mode, true);
         }
     }
 
-    if (blendMode == SkBlendMode::kClear) {
+    if (xfermode == SkXfermode::kClear_Mode) {
         return;
-    } else if (blendMode == SkBlendMode::kSrc ||
-            blendMode == SkBlendMode::kDstATop) {
+    } else if (xfermode == SkXfermode::kSrc_Mode ||
+            xfermode == SkXfermode::kDstATop_Mode) {
         ScopedContentEntry content(this, &fExistingClipStack,
                                    fExistingClipRegion, identity, stockPaint);
         if (content.entry()) {
@@ -1923,10 +1929,10 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
                     this->addXObjectResource(srcFormXObject.get()),
                     &content.entry()->fContent);
         }
-        if (blendMode == SkBlendMode::kSrc) {
+        if (xfermode == SkXfermode::kSrc_Mode) {
             return;
         }
-    } else if (blendMode == SkBlendMode::kSrcATop) {
+    } else if (xfermode == SkXfermode::kSrcATop_Mode) {
         ScopedContentEntry content(this, &fExistingClipStack,
                                    fExistingClipRegion, identity, stockPaint);
         if (content.entry()) {
@@ -1935,36 +1941,36 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
         }
     }
 
-    SkASSERT(blendMode == SkBlendMode::kSrcIn   ||
-             blendMode == SkBlendMode::kDstIn   ||
-             blendMode == SkBlendMode::kSrcOut  ||
-             blendMode == SkBlendMode::kDstOut  ||
-             blendMode == SkBlendMode::kSrcATop ||
-             blendMode == SkBlendMode::kDstATop ||
-             blendMode == SkBlendMode::kModulate);
+    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);
 
-    if (blendMode == SkBlendMode::kSrcIn ||
-            blendMode == SkBlendMode::kSrcOut ||
-            blendMode == SkBlendMode::kSrcATop) {
+    if (xfermode == SkXfermode::kSrcIn_Mode ||
+            xfermode == SkXfermode::kSrcOut_Mode ||
+            xfermode == SkXfermode::kSrcATop_Mode) {
         drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
                                 std::move(dst),
                                 &fExistingClipStack, fExistingClipRegion,
-                                SkBlendMode::kSrcOver,
-                                blendMode == SkBlendMode::kSrcOut);
+                                SkXfermode::kSrcOver_Mode,
+                                xfermode == SkXfermode::kSrcOut_Mode);
         return;
     } else {
-        SkBlendMode mode = SkBlendMode::kSrcOver;
+        SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
         int resourceID = addXObjectResource(dst.get());
-        if (blendMode == SkBlendMode::kModulate) {
+        if (xfermode == SkXfermode::kModulate_Mode) {
             drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
                                     std::move(dst), &fExistingClipStack,
                                     fExistingClipRegion,
-                                    SkBlendMode::kSrcOver, false);
-            mode = SkBlendMode::kMultiply;
+                                    SkXfermode::kSrcOver_Mode, false);
+            mode = SkXfermode::kMultiply_Mode;
         }
         drawFormXObjectWithMask(resourceID, std::move(srcFormXObject),
                                 &fExistingClipStack, fExistingClipRegion, mode,
-                                blendMode == SkBlendMode::kDstOut);
+                                xfermode == SkXfermode::kDstOut_Mode);
         return;
     }
 }
index 7d207e7..be0a277 100644 (file)
@@ -246,7 +246,7 @@ private:
                                  sk_sp<SkPDFObject> mask,
                                  const SkClipStack* clipStack,
                                  const SkRegion& clipRegion,
-                                 SkBlendMode,
+                                 SkXfermode::Mode mode,
                                  bool invertClip);
 
     // If the paint or clip is such that we shouldn't draw anything, this
@@ -259,7 +259,9 @@ private:
                                     const SkPaint& paint,
                                     bool hasText,
                                     sk_sp<SkPDFObject>* dst);
-    void finishContentEntry(SkBlendMode, sk_sp<SkPDFObject> dst, SkPath* shape);
+    void finishContentEntry(SkXfermode::Mode xfermode,
+                            sk_sp<SkPDFObject> dst,
+                            SkPath* shape);
     bool isContentEmpty();
 
     void populateGraphicStateEntryFromPaint(const SkMatrix& matrix,
index d60526c..a78c4c5 100644 (file)
 #include "SkPDFGraphicState.h"
 #include "SkPDFUtils.h"
 
-static const char* as_blend_mode(SkBlendMode mode) {
+static const char* as_blend_mode(SkXfermode::Mode mode) {
     switch (mode) {
-        case SkBlendMode::kSrcOver:
+        case SkXfermode::kSrcOver_Mode:
             return "Normal";
-        case SkBlendMode::kMultiply:
+        case SkXfermode::kMultiply_Mode:
             return "Multiply";
-        case SkBlendMode::kScreen:
+        case SkXfermode::kScreen_Mode:
             return "Screen";
-        case SkBlendMode::kOverlay:
+        case SkXfermode::kOverlay_Mode:
             return "Overlay";
-        case SkBlendMode::kDarken:
+        case SkXfermode::kDarken_Mode:
             return "Darken";
-        case SkBlendMode::kLighten:
+        case SkXfermode::kLighten_Mode:
             return "Lighten";
-        case SkBlendMode::kColorDodge:
+        case SkXfermode::kColorDodge_Mode:
             return "ColorDodge";
-        case SkBlendMode::kColorBurn:
+        case SkXfermode::kColorBurn_Mode:
             return "ColorBurn";
-        case SkBlendMode::kHardLight:
+        case SkXfermode::kHardLight_Mode:
             return "HardLight";
-        case SkBlendMode::kSoftLight:
+        case SkXfermode::kSoftLight_Mode:
             return "SoftLight";
-        case SkBlendMode::kDifference:
+        case SkXfermode::kDifference_Mode:
             return "Difference";
-        case SkBlendMode::kExclusion:
+        case SkXfermode::kExclusion_Mode:
             return "Exclusion";
-        case SkBlendMode::kHue:
+        case SkXfermode::kHue_Mode:
             return "Hue";
-        case SkBlendMode::kSaturation:
+        case SkXfermode::kSaturation_Mode:
             return "Saturation";
-        case SkBlendMode::kColor:
+        case SkXfermode::kColor_Mode:
             return "Color";
-        case SkBlendMode::kLuminosity:
+        case SkXfermode::kLuminosity_Mode:
             return "Luminosity";
 
         // These are handled in SkPDFDevice::setUpContentEntry.
-        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:
+        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:
             return "Normal";
 
         // TODO(vandebo): Figure out if we can support more of these modes.
-        case SkBlendMode::kXor:
-        case SkBlendMode::kPlus:
+        case SkXfermode::kXor_Mode:
+        case SkXfermode::kPlus_Mode:
             return nullptr;
     }
     return nullptr;
@@ -71,28 +71,32 @@ static const char* as_blend_mode(SkBlendMode mode) {
 
 // If a SkXfermode is unsupported in PDF, this function returns
 // SrcOver, otherwise, it returns that Xfermode as a Mode.
-static SkBlendMode mode_for_pdf(SkBlendMode mode) {
+static SkXfermode::Mode mode_for_pdf(const SkXfermode* xfermode) {
+    SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
+    if (xfermode) {
+        xfermode->asMode(&mode);
+    }
     switch (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:
+        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:
             // Mode is suppported and handled by pdf graphics state.
             return mode;
         default:
-            return SkBlendMode::kSrcOver;  // Default mode.
+            return SkXfermode::kSrcOver_Mode;  // Default mode.
     }
 }
 
@@ -102,7 +106,7 @@ SkPDFGraphicState::SkPDFGraphicState(const SkPaint& p)
     , fAlpha(p.getAlpha())
     , fStrokeCap(SkToU8(p.getStrokeCap()))
     , fStrokeJoin(SkToU8(p.getStrokeJoin()))
-    , fMode(SkToU8((unsigned)mode_for_pdf(p.getBlendMode()))) {}
+    , fMode(SkToU8(mode_for_pdf(p.getXfermode()))) {}
 
 // static
 SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint(
@@ -182,6 +186,7 @@ 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");
@@ -200,6 +205,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((SkBlendMode)fMode));
+    dict->insertName("BM", as_blend_mode(xferMode));
     dict->emitObject(stream, objNumMap);
 }
index 8ee6728..0c2e4a0 100644 (file)
@@ -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;        // SkBlendMode
+    const uint8_t fMode;        // SkXfermode::Mode
 
     SkPDFGraphicState(const SkPaint&);
 
index 3b636a2..a01237f 100644 (file)
@@ -81,6 +81,7 @@ 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);
@@ -149,8 +150,15 @@ 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)paint.getBlendMode() << 8) | pad);
+    writer.write32((nondef << 16) | ((unsigned)mode << 8) | pad);
 
     CHECK_WRITE_SCALAR(writer, nondef, paint, TextSize);
     CHECK_WRITE_SCALAR(writer, nondef, paint, TextScaleX);
@@ -171,6 +179,7 @@ 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);
index 9a1d30c..8f5c828 100644 (file)
@@ -94,11 +94,12 @@ enum {
     kTypeface_NonDef    = 1 << 6,
     kPathEffect_NonDef  = 1 << 7,
     kShader_NonDef      = 1 << 8,
-    kMaskFilter_NonDef  = 1 << 9,
-    kColorFilter_NonDef = 1 << 10,
-    kRasterizer_NonDef  = 1 << 11,
-    kImageFilter_NonDef = 1 << 12,
-    kDrawLooper_NonDef  = 1 << 13,
+    kXfermode_NonDef    = 1 << 9,
+    kMaskFilter_NonDef  = 1 << 10,
+    kColorFilter_NonDef = 1 << 11,
+    kRasterizer_NonDef  = 1 << 12,
+    kImageFilter_NonDef = 1 << 13,
+    kDrawLooper_NonDef  = 1 << 14,
 };
 
 enum {
index 47d4072..8840da1 100644 (file)
@@ -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;
-    paint.setBlendMode(SkBlendMode((extra >> 8) & 0xFF));
-    SkASSERT((extra & 0xFF) == 0);  // zero pad byte
+    SkXfermode::Mode mode = (SkXfermode::Mode)((extra >> 8) & 0xFF);
+    SkASSERT((extra & 0xFF) == 0);
+
+    SkPaint paint;
 
     packedFlags >>= 2;  // currently unused
     paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3));    packedFlags >>= 2;
@@ -180,12 +180,17 @@ 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;
 }
 
index 68bd13e..fcb24d2 100644 (file)
@@ -209,8 +209,8 @@ SkCanvas::SaveLayerStrategy SkDumpCanvas::getSaveLayerStrategy(const SaveLayerRe
         if (paint->getAlpha() != 0xFF) {
             str.appendf(" alpha:0x%02X", paint->getAlpha());
         }
-        if (!paint->isSrcOver()) {
-            str.appendf(" blendmode:%d", paint->getBlendMode());
+        if (paint->getXfermode()) {
+            str.appendf(" xfermode:%p", paint->getXfermode());
         }
     }
     this->dump(kSave_Verb, paint, str.c_str());
@@ -540,10 +540,8 @@ 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");
index ba311af..e80708c 100644 (file)
@@ -28,6 +28,7 @@
 #include "SkSurface.h"
 #include "SkTextBlob.h"
 #include "SkTypeface.h"
+#include "SkXfermode.h"
 
 extern "C" {
     #include "lua.h"
@@ -58,6 +59,7 @@ 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));
@@ -1071,9 +1073,26 @@ 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();
@@ -1198,6 +1217,8 @@ 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 },
@@ -1320,6 +1341,24 @@ 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;
@@ -2139,6 +2178,7 @@ 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);
index 0528b14..63d9152 100644 (file)
@@ -45,7 +45,7 @@ bool SkRGBAToYUV(const SkImage* image, const SkISize sizes[3], void* const plane
         }
         SkPaint paint;
         paint.setFilterQuality(kLow_SkFilterQuality);
-        paint.setBlendMode(SkBlendMode::kSrc);
+        paint.setXfermodeMode(SkXfermode::kSrc_Mode);
         int rowStartIdx = 5 * i;
         const SkScalar* row = kYUVColorSpaceInvMatrices[colorSpace] + rowStartIdx;
         paint.setColorFilter(
index 5db644c..7757cb8 100644 (file)
@@ -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.isSrcOver())) {
+        (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) {
         return;
     }
 
@@ -1536,7 +1536,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
 
     // nothing to draw
     if (d.fRC->isEmpty() ||
-        (paint->getAlpha() == 0 && paint->isSrcOver())) {
+        (paint->getAlpha() == 0 && paint->getXfermode() == nullptr)) {
         return;
     }
 
index ec790f5..6e6e23a 100644 (file)
@@ -112,7 +112,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ApplyGamma, reporter, ctxInfo) {
             dstCanvas->flush();
 
             SkPaint gammaPaint;
-            gammaPaint.setBlendMode(SkBlendMode::kSrc);
+            gammaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
             gammaPaint.setColorFilter(SkGammaColorFilter::Make(gamma));
 
             dstCanvas->drawImage(src, 0, 0, &gammaPaint);
index 668ae5a..fd83a6c 100644 (file)
@@ -261,8 +261,8 @@ public:
                                                                       std::move(paintFilter),
                                                                       cropRect));
         }
-        this->addFilter("xfermode", SkXfermodeImageFilter::Make(SkBlendMode::kSrc, input, input,
-                                                                cropRect));
+        this->addFilter("xfermode", SkXfermodeImageFilter::Make(
+            SkXfermode::Make(SkXfermode::kSrc_Mode), input, input, cropRect));
     }
     int count() const { return fFilters.count(); }
     SkImageFilter* getFilter(int index) const { return fFilters[index].fFilter.get(); }
@@ -938,14 +938,14 @@ DEF_TEST(ImageFilterUnionBounds, reporter) {
     // Regardless of which order they appear in, the image filter bounds should
     // be combined correctly.
     {
-        sk_sp<SkImageFilter> composite(SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver, offset));
+        sk_sp<SkImageFilter> composite(SkXfermodeImageFilter::Make(nullptr, offset));
         SkRect bounds = SkRect::MakeWH(100, 100);
         // Intentionally aliasing here, as that's what the real callers do.
         bounds = composite->computeFastBounds(bounds);
         REPORTER_ASSERT(reporter, bounds == SkRect::MakeWH(150, 100));
     }
     {
-        sk_sp<SkImageFilter> composite(SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver, nullptr,
+        sk_sp<SkImageFilter> composite(SkXfermodeImageFilter::Make(nullptr, nullptr,
                                                                    offset, nullptr));
         SkRect bounds = SkRect::MakeWH(100, 100);
         // Intentionally aliasing here, as that's what the real callers do.
@@ -1432,7 +1432,7 @@ static void test_xfermode_cropped_input(SkCanvas* canvas, skiatest::Reporter* re
 
     // Check that an xfermode image filter whose input has been cropped out still draws the other
     // input. Also check that drawing with both inputs cropped out doesn't cause a GPU warning.
-    SkBlendMode mode = SkBlendMode::kSrcOver;
+    sk_sp<SkXfermode> mode(SkXfermode::Make(SkXfermode::kSrcOver_Mode));
     sk_sp<SkImageFilter> xfermodeNoFg(SkXfermodeImageFilter::Make(mode, greenFilter,
                                                                   croppedOut, nullptr));
     sk_sp<SkImageFilter> xfermodeNoBg(SkXfermodeImageFilter::Make(mode, croppedOut,
index 74dd532..993c3fa 100644 (file)
@@ -351,7 +351,7 @@ DEF_TEST(Image_RetainSnapshot, reporter) {
     }
 
     SkPaint paint;
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     paint.setColor(SK_ColorRED);
 
     surface->getCanvas()->drawRect(SkRect::MakeXYWH(1, 1, 1, 1), paint);
index 4897fd2..8ba290f 100644 (file)
@@ -53,7 +53,7 @@ static void test_frontToBack(skiatest::Reporter* reporter) {
     layerInfo.fOffset.set(10.0f, 20.0f);
     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
     SkPaint* layerPaint = looperBuilder.addLayer(layerInfo);
-    layerPaint->setBlendMode(SkBlendMode::kSrc);
+    layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
 
     FakeDevice device;
     SkCanvas canvas(&device);
@@ -65,7 +65,7 @@ static void test_frontToBack(skiatest::Reporter* reporter) {
 
     // The back layer should come first.
     REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
-    REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
+    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
     REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
@@ -73,7 +73,7 @@ static void test_frontToBack(skiatest::Reporter* reporter) {
 
     // Then the front layer.
     REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
-    REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
+    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
@@ -93,7 +93,7 @@ static void test_backToFront(skiatest::Reporter* reporter) {
     layerInfo.fOffset.set(10.0f, 20.0f);
     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
     SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
-    layerPaint->setBlendMode(SkBlendMode::kSrc);
+    layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
 
     FakeDevice device;
     SkCanvas canvas(&device);
@@ -105,7 +105,7 @@ static void test_backToFront(skiatest::Reporter* reporter) {
 
     // The back layer should come first.
     REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
-    REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
+    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
@@ -113,7 +113,7 @@ static void test_backToFront(skiatest::Reporter* reporter) {
 
     // Then the front layer.
     REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
-    REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
+    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
     REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
@@ -133,7 +133,7 @@ static void test_mixed(skiatest::Reporter* reporter) {
     layerInfo.fOffset.set(10.0f, 20.0f);
     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
     SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
-    layerPaint->setBlendMode(SkBlendMode::kSrc);
+    layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
 
     FakeDevice device;
     SkCanvas canvas(&device);
@@ -145,7 +145,7 @@ static void test_mixed(skiatest::Reporter* reporter) {
 
     // The back layer should come first.
     REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
-    REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
+    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
@@ -153,7 +153,7 @@ static void test_mixed(skiatest::Reporter* reporter) {
 
     // Then the front layer.
     REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
-    REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
+    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
     REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
index e15234d..76796f5 100644 (file)
@@ -9,14 +9,14 @@
 #include "SkStream.h"
 #include "Test.h"
 
-static void run_test(SkWStream* out, SkBlendMode mode, U8CPU alpha) {
+static void run_test(SkWStream* out, SkXfermode::Mode mode, U8CPU alpha) {
     sk_sp<SkDocument> pdfDoc(SkDocument::MakePDF(out));
     SkCanvas* c = pdfDoc->beginPage(612.0f, 792.0f);
     SkPaint black;
     SkPaint background;
     background.setColor(SK_ColorWHITE);
     background.setAlpha(alpha);
-    background.setBlendMode(mode);
+    background.setXfermodeMode(mode);
     c->drawRect(SkRect::MakeWH(612.0f, 792.0f), background);
     c->drawRect(SkRect::MakeXYWH(36.0f, 36.0f, 9.0f, 9.0f), black);
     c->drawRect(SkRect::MakeXYWH(72.0f, 72.0f, 468.0f, 648.0f), background);
@@ -31,8 +31,8 @@ DEF_TEST(SkPDF_OpaqueSrcModeToSrcOver, r) {
     SkDynamicMemoryWStream srcOverMode;
 
     U8CPU alpha = SK_AlphaOPAQUE;
-    run_test(&srcMode, SkBlendMode::kSrc, alpha);
-    run_test(&srcOverMode, SkBlendMode::kSrcOver, alpha);
+    run_test(&srcMode, SkXfermode::kSrc_Mode, alpha);
+    run_test(&srcOverMode, SkXfermode::kSrcOver_Mode, alpha);
     REPORTER_ASSERT(r, srcMode.getOffset() == srcOverMode.getOffset());
     // The two PDFs should be equal because they have an opaque alpha.
 
@@ -40,8 +40,8 @@ DEF_TEST(SkPDF_OpaqueSrcModeToSrcOver, r) {
     srcOverMode.reset();
 
     alpha = 0x80;
-    run_test(&srcMode, SkBlendMode::kSrc, alpha);
-    run_test(&srcOverMode, SkBlendMode::kSrcOver, alpha);
+    run_test(&srcMode, SkXfermode::kSrc_Mode, alpha);
+    run_test(&srcOverMode, SkXfermode::kSrcOver_Mode, alpha);
     REPORTER_ASSERT(r, srcMode.getOffset() > srcOverMode.getOffset());
     // The two PDFs should not be equal because they have a non-opaque alpha.
 }
index 9cd9cfc..f507467 100644 (file)
@@ -292,7 +292,7 @@ DEF_TEST(Paint_MoreFlattening, r) {
     paint.setColor(0x00AABBCC);
     paint.setTextScaleX(1.0f);  // Default value, ignored.
     paint.setTextSize(19);
-    paint.setBlendMode(SkBlendMode::kModulate);
+    paint.setXfermode(SkXfermode::Make(SkXfermode::kModulate_Mode));
     paint.setLooper(nullptr);  // Default value, ignored.
 
     SkBinaryWriteBuffer writer;
@@ -311,7 +311,12 @@ DEF_TEST(Paint_MoreFlattening, r) {
     ASSERT(other.getTextScaleX() == paint.getTextScaleX());
     ASSERT(other.getTextSize()   == paint.getTextSize());
     ASSERT(other.getLooper()     == paint.getLooper());
-    ASSERT(other.getBlendMode()  == paint.getBlendMode());
+
+    // We have to be a little looser and compare just the modes.  Pointers might not be the same.
+    SkXfermode::Mode otherMode, paintMode;
+    ASSERT(other.getXfermode()->asMode(&otherMode));
+    ASSERT(paint.getXfermode()->asMode(&paintMode));
+    ASSERT(otherMode == paintMode);
 }
 
 DEF_TEST(Paint_getHash, r) {
@@ -350,11 +355,11 @@ DEF_TEST(Paint_nothingToDraw, r) {
     REPORTER_ASSERT(r, paint.nothingToDraw());
 
     paint.setAlpha(0xFF);
-    paint.setBlendMode(SkBlendMode::kDst);
+    paint.setXfermodeMode(SkXfermode::kDst_Mode);
     REPORTER_ASSERT(r, paint.nothingToDraw());
 
     paint.setAlpha(0);
-    paint.setBlendMode(SkBlendMode::kSrcOver);
+    paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
 
     SkColorMatrix cm;
     cm.setIdentity();   // does not change alpha
index 008781c..5fbaf9b 100644 (file)
@@ -113,7 +113,7 @@ static void fill_src_canvas(SkCanvas* canvas) {
     canvas->setMatrix(SkMatrix::I());
     canvas->clipRect(DEV_RECT_S, SkCanvas::kReplace_Op);
     SkPaint paint;
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     canvas->drawBitmap(make_src_bitmap(), 0, 0, &paint);
     canvas->restore();
 }
index 1dbd945..cf8141a 100644 (file)
@@ -240,7 +240,7 @@ DEF_TEST(RecordDraw_SaveLayerBoundsAffectsClipBounds, r) {
     SkRecorder recorder(&record, 50, 50);
 
     SkPaint p;
-    p.setBlendMode(SkBlendMode::kSrc);
+    p.setXfermodeMode(SkXfermode::kSrc_Mode);
 
     SkRect layerBounds = SkRect::MakeLTRB(10, 10, 40, 40);
     recorder.saveLayer(&layerBounds, &p);
index b7c9ae9..4567a01 100644 (file)
@@ -140,7 +140,7 @@ DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
     SkPaint alphaOnlyLayerPaint, translucentLayerPaint, xfermodeLayerPaint;
     alphaOnlyLayerPaint.setColor(0x03000000);  // Only alpha.
     translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
-    xfermodeLayerPaint.setBlendMode(SkBlendMode::kDstIn);  // Any effect will do.
+    xfermodeLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);  // Any effect will do.
 
     SkPaint opaqueDrawPaint, translucentDrawPaint;
     opaqueDrawPaint.setColor(0xFF020202);  // Opaque.
@@ -222,10 +222,10 @@ DEF_TEST(RecordOpts_MergeSvgOpacityAndFilterLayers, r) {
     SkPaint translucentLayerPaint;
     translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
     SkPaint xfermodePaint;
-    xfermodePaint.setBlendMode(SkBlendMode::kDstIn);
+    xfermodePaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
     SkPaint colorFilterPaint;
     colorFilterPaint.setColorFilter(
-        SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
+        SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkXfermode::kSrcIn_Mode));
 
     SkPaint opaqueFilterLayerPaint;
     opaqueFilterLayerPaint.setColor(0xFF020202);  // Opaque.
@@ -353,7 +353,7 @@ static void do_draw(SkCanvas* canvas, SkColor color, bool doLayer) {
 
     if (doLayer) {
         canvas->saveLayer(nullptr, nullptr);
-        p.setBlendMode(SkBlendMode::kSrc);
+        p.setXfermodeMode(SkXfermode::kSrc_Mode);
         canvas->drawPaint(p);
         canvas->restore();
     } else {
index 32aec36..0f91aea 100644 (file)
@@ -34,7 +34,7 @@ class Drawer {
 
     const SkImageInfo& imageInfo() const { return fImageInfo; }
 
-    void draw(SkCanvas* canvas, const SkRect& clipRect, SkBlendMode mode) const {
+    void draw(SkCanvas* canvas, const SkRect& clipRect, SkXfermode::Mode mode) const {
         SkPaint greenPaint;
         greenPaint.setColor(0xff008000);
         SkPaint blackPaint;
@@ -43,7 +43,7 @@ class Drawer {
         whitePaint.setColor(0xffffffff);
         SkPaint layerPaint;
         layerPaint.setColor(0xff000000);
-        layerPaint.setBlendMode(mode);
+        layerPaint.setXfermodeMode(mode);
         SkRect canvasRect(SkRect::MakeWH(SkIntToScalar(fImageInfo.width()),
                                          SkIntToScalar(fImageInfo.height())));
 
@@ -68,7 +68,7 @@ class RecordingStrategy {
     virtual ~RecordingStrategy() {}
     virtual const SkBitmap& recordAndReplay(const Drawer& drawer,
                                             const SkRect& intoClip,
-                                            SkBlendMode) = 0;
+                                            SkXfermode::Mode) = 0;
 };
 
 class BitmapBackedCanvasStrategy : public RecordingStrategy {
@@ -78,8 +78,9 @@ class BitmapBackedCanvasStrategy : public RecordingStrategy {
         fBitmap.allocPixels(imageInfo);
     }
 
-    const SkBitmap& recordAndReplay(const Drawer& drawer, const SkRect& intoClip,
-                                    SkBlendMode mode) override {
+    virtual const SkBitmap& recordAndReplay(const Drawer& drawer,
+                                            const SkRect& intoClip,
+                                            SkXfermode::Mode mode) {
         SkCanvas canvas(fBitmap);
         canvas.clear(0xffffffff);
         // Note that the scene is drawn just into the clipped region!
@@ -103,8 +104,9 @@ class PictureStrategy : public RecordingStrategy {
         fHeight = imageInfo.height();
     }
 
-    const SkBitmap& recordAndReplay(const Drawer& drawer, const SkRect& intoClip,
-                                    SkBlendMode mode) override {
+    virtual const SkBitmap& recordAndReplay(const Drawer& drawer,
+                                            const SkRect& intoClip,
+                                            SkXfermode::Mode mode) {
         SkRTreeFactory factory;
         SkPictureRecorder recorder;
         SkRect canvasRect(SkRect::MakeWH(SkIntToScalar(fWidth),SkIntToScalar(fHeight)));
@@ -142,9 +144,9 @@ DEF_TEST(SkRecordingAccuracyXfermode, reporter) {
     SkString errors;
 #endif
 
-    for (int iMode = 0; iMode < int(SkBlendMode::kLastMode); iMode++) {
+    for (int iMode = 0; iMode < int(SkXfermode::kLastMode); iMode++) {
         const SkRect& clip = SkRect::MakeXYWH(100, 0, 100, 100);
-        SkBlendMode mode = SkBlendMode(iMode);
+        SkXfermode::Mode mode = SkXfermode::Mode(iMode);
 
         const SkBitmap& goldenBM = golden.recordAndReplay(drawer, clip, mode);
         const SkBitmap& pictureBM = picture.recordAndReplay(drawer, clip, mode);
index 26a2da4..9e40701 100644 (file)
@@ -260,7 +260,7 @@ static void TestBitmapSerialization(const SkBitmap& validBitmap,
     sk_sp<SkImage> invalidImage(SkImage::MakeFromBitmap(invalidBitmap));
     sk_sp<SkImageFilter> invalidBitmapSource(SkImageSource::Make(std::move(invalidImage)));
     sk_sp<SkImageFilter> xfermodeImageFilter(
-        SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver,
+        SkXfermodeImageFilter::Make(SkXfermode::Make(SkXfermode::kSrcOver_Mode),
                                     std::move(invalidBitmapSource),
                                     std::move(validBitmapSource), nullptr));
 
index 77038d4..c59aa2d 100644 (file)
@@ -122,7 +122,7 @@ static void fill_canvas(SkCanvas* canvas) {
     canvas->setMatrix(SkMatrix::I());
     canvas->clipRect(DEV_RECT_S, SkCanvas::kReplace_Op);
     SkPaint paint;
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     canvas->drawBitmap(bmp, 0, 0, &paint);
     canvas->restore();
 }
index 1da995b..f15c68c 100644 (file)
@@ -42,8 +42,7 @@ protected:
         if (*paint) {
             if (nullptr != fOverdrawXfermode.get()) {
                 paint->writable()->setAntiAlias(false);
-                // TODO: replace overdraw mode with something else
-//                paint->writable()->setXfermode(fOverdrawXfermode);
+                paint->writable()->setXfermode(fOverdrawXfermode);
             }
 
             if (fOverrideFilterQuality) {
index 156ca4f..ba6302c 100644 (file)
@@ -1116,6 +1116,16 @@ static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
     }
 }
 
+static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target,
+                                 UrlDataManager& urlDataManager) {
+    SkFlattenable* xfermode = paint.getXfermode();
+    if (xfermode != nullptr) {
+        Json::Value jsonXfermode;
+        SkDrawCommand::flatten(xfermode, &jsonXfermode, urlDataManager);
+        (*target)[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode;
+    }
+}
+
 static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
                                     UrlDataManager& urlDataManager) {
     SkFlattenable* imageFilter = paint.getImageFilter();
@@ -1167,6 +1177,7 @@ Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& u
     apply_paint_patheffect(paint, &result, urlDataManager);
     apply_paint_maskfilter(paint, &result, urlDataManager);
     apply_paint_shader(paint, &result, urlDataManager);
+    apply_paint_xfermode(paint, &result, urlDataManager);
     apply_paint_looper(paint, &result, urlDataManager);
     apply_paint_imagefilter(paint, &result, urlDataManager);
     apply_paint_colorfilter(paint, &result, urlDataManager);
@@ -1235,6 +1246,17 @@ static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManage
     }
 }
 
+static void extract_json_paint_xfermode(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
+                                        SkPaint* target) {
+    if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_XFERMODE)) {
+        Json::Value jsonXfermode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE];
+        sk_sp<SkXfermode> xfermode((SkXfermode*) load_flattenable(jsonXfermode, urlDataManager));
+        if (xfermode != nullptr) {
+            target->setXfermode(xfermode);
+        }
+    }
+}
+
 static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
                                       SkPaint* target) {
     if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
@@ -1481,6 +1503,7 @@ static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManage
     extract_json_paint_patheffect(paint, urlDataManager, result);
     extract_json_paint_maskfilter(paint, urlDataManager, result);
     extract_json_paint_colorfilter(paint, urlDataManager, result);
+    extract_json_paint_xfermode(paint, urlDataManager, result);
     extract_json_paint_looper(paint, urlDataManager, result);
     extract_json_paint_imagefilter(paint, urlDataManager, result);
     extract_json_paint_typeface(paint, urlDataManager, result);
index c84d452..72d1af5 100644 (file)
@@ -220,7 +220,7 @@ SkBitmap create_checkerboard_bitmap(int w, int h, SkColor c1, SkColor c2, int ch
 void draw_checkerboard(SkCanvas* canvas, SkColor c1, SkColor c2, int size) {
     SkPaint paint;
     paint.setShader(create_checkerboard_shader(c1, c2, size));
-    paint.setBlendMode(SkBlendMode::kSrc);
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     canvas->drawPaint(paint);
 }
 
index fd2f2ef..47f349b 100644 (file)
@@ -121,7 +121,7 @@ void RasterWindowContext_mac::onSwapBuffers() {
                        (fDisplayParams.fColorSpace != nullptr ||
                         kRGBA_F16_SkColorType == fDisplayParams.fColorType);
         SkPaint gammaPaint;
-        gammaPaint.setBlendMode(SkBlendMode::kSrc);
+        gammaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
         if (doGamma) {
             gammaPaint.setColorFilter(SkGammaColorFilter::Make(1.0f / 2.2f));
         }