make SkXfermode.h go away
authorMike Reed <reed@google.com>
Tue, 15 Nov 2016 21:44:34 +0000 (16:44 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 16 Nov 2016 15:38:11 +0000 (15:38 +0000)
This is step one:
- make SkXfermode useless to public clients
- everything they should need is in SkBlendMode.h

Step two:
- remove SkXfermode.h entirely (since skia core will already be using SkXfermodePriv.h)

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4534

Change-Id: If2cea9f71df92430ed6644edb98dd306c5572cbc
Reviewed-on: https://skia-review.googlesource.com/4534
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
45 files changed:
bench/RotatedRectBench.cpp
bench/Xfer4fBench.cpp
bench/XferF16Bench.cpp
bench/XfermodeBench.cpp
gm/SkLinearBitmapPipelineGM.cpp
gm/aaxfermodes.cpp
gm/gamma.cpp
gm/lumafilter.cpp
gm/xfermodes2.cpp
gm/xfermodes3.cpp
gn/android_framework_defines.gni
gn/core.gni
gn/tests.gni
include/core/SkMaskFilter.h
include/core/SkXfermode.h
include/gpu/GrProcessorUnitTest.h
include/gpu/effects/GrCustomXfermode.h
public.bzl
samplecode/SampleFilterFuzz.cpp
src/core/SkBitmapProcShader.cpp
src/core/SkBlendModePriv.h
src/core/SkBlitter_A8.cpp
src/core/SkBlitter_ARGB32.cpp
src/core/SkBlitter_PM4f.cpp
src/core/SkBlitter_RGB16.cpp
src/core/SkCoreBlitters.h
src/core/SkLinearBitmapPipeline.h
src/core/SkOpts.h
src/core/SkPaintPriv.cpp
src/core/SkReadBuffer.h
src/core/SkSpriteBlitter4f.cpp
src/core/SkSpriteBlitter_ARGB32.cpp
src/core/SkXfermode.cpp
src/core/SkXfermode4f.cpp
src/core/SkXfermodeF16.cpp
src/core/SkXfermodePriv.h [new file with mode: 0644]
src/effects/SkArithmeticModePriv.h
src/gpu/SkGrPriv.h
src/gpu/effects/GrCustomXfermode.cpp
src/gpu/effects/GrPorterDuffXferProcessor.cpp
src/gpu/glsl/GrGLSLBlend.cpp
tests/BlendTest.cpp
tests/RecordingXfermodeTest.cpp
tests/SkColor4fTest.cpp
tests/XfermodeTest.cpp [deleted file]

index f81bfb1d1010300eb1e79882824bb6796ca5099b..d9ee5823bfd9957cfad57eb6eaf4b09eb4324931 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "Benchmark.h"
+#include "SkBlendModePriv.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 
@@ -144,7 +145,7 @@ private:
                 fName.append("_alternating_transparent_and_opaque");
                 break;
         }
-        fName.appendf("_%s", to_lower(SkXfermode::ModeName(fMode)).c_str());
+        fName.appendf("_%s", to_lower(SkBlendMode_Name(fMode)).c_str());
     }
 
     bool        fAA;
index 0e99c8c3f2848355d90ecdd618b3bdfb8db7e764..5e679a826e8338d6cef8775a899c06deeb6c2b2e 100644 (file)
@@ -8,7 +8,7 @@
 #include "Benchmark.h"
 #include "SkPM4f.h"
 #include "SkString.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 #define USE_AA      (1 << 31)   // merge with Xfermode::PMFlags w/o conflict
 
index 14505fd6bf653aa013bbe033529baecfa9db4c1e..bd44effd0597d3d4f340bb05cc57cae60f324406 100644 (file)
@@ -8,7 +8,7 @@
 #include "Benchmark.h"
 #include "SkPM4f.h"
 #include "SkString.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 #define USE_AA      (1 << 31)   // merge with Xfermode::PMFlags w/o conflict
 
index 9e148d43177aeaf991948b8832692c45bf8a09fd..605d167296c0fe809dc19e14016653c83e54b6ea 100644 (file)
@@ -6,18 +6,18 @@
  */
 
 #include "Benchmark.h"
+#include "SkBlendModePriv.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 #include "SkRandom.h"
 #include "SkString.h"
-#include "SkXfermode.h"
 
 // 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) {
         fAA = aa;
-        fName.printf("Xfermode_%s%s", SkXfermode::ModeName(mode), aa ? "_aa" : "");
+        fName.printf("Xfermode_%s%s", SkBlendMode_Name(mode), aa ? "_aa" : "");
     }
 
 protected:
index f6f7c9e215877a27d5c1e5f5cb30cdb57cc970fe..13f600429ff2eef2e841cc46fdb0c0125385c984 100644 (file)
@@ -12,7 +12,7 @@
 #include "SkImage.h"
 #include "SkImageInfo.h"
 #include "SkLinearBitmapPipeline.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 #include "SkPM4fPriv.h"
 #include "SkShader.h"
 
index 7106ce817409afe06e21d7e8a9aa97b8517932a1..df09a0bc9dd3996340c97ba009a582e53be61ec4 100644 (file)
@@ -4,14 +4,15 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "gm.h"
 #include "SkArithmeticMode.h"
+#include "SkBlendModePriv.h"
 #include "SkPath.h"
 #include "SkShader.h"
-#include "SkXfermode.h"
 
 enum {
-    kXfermodeCount = SkXfermode::kLastMode + 2, // All xfermodes plus arithmetic mode.
+    kXfermodeCount = (int)SkBlendMode::kLastMode + 1 + 1,   // extra for arith
     kShapeSize = 22,
     kShapeSpacing = 36,
     kShapeTypeSpacing = 4 * kShapeSpacing / 3,
@@ -62,7 +63,7 @@ protected:
         return SkISize::Make(2 * kMargin + 2 * kXfermodeTypeSpacing -
                              (kXfermodeTypeSpacing - (kLabelSpacing + 2 * kPaintSpacing)),
                              2 * kMargin + kTitleSpacing + kSubtitleSpacing +
-                             (1 + SkXfermode::kLastCoeffMode) * kShapeSpacing);
+                             (1 + (int)SkBlendMode::kLastCoeffMode) * kShapeSpacing);
     }
 
     void onOnceBeforeDraw() override {
@@ -101,7 +102,7 @@ protected:
         canvas->translate(0, kTitleSpacing);
 
         for (size_t xfermodeSet = 0; xfermodeSet < 2; xfermodeSet++) {
-            size_t firstMode = (SkXfermode::kLastCoeffMode + 1) * xfermodeSet;
+            size_t firstMode = ((size_t)SkBlendMode::kLastCoeffMode + 1) * xfermodeSet;
             canvas->save();
 
             if (kShape_Pass == drawingPass) {
@@ -117,8 +118,8 @@ protected:
 
             canvas->translate(0, kSubtitleSpacing + kShapeSpacing/2);
 
-            for (size_t m = 0; m <= SkXfermode::kLastCoeffMode; m++) {
-                if (firstMode + m > SkXfermode::kLastMode) {
+            for (size_t m = 0; m <= (size_t)SkBlendMode::kLastCoeffMode; m++) {
+                if (firstMode + m > (size_t)SkBlendMode::kLastMode) {
                     break;
                 }
                 SkBlendMode mode = static_cast<SkBlendMode>(firstMode + m);
@@ -191,7 +192,7 @@ protected:
     }
 
     void drawModeName(SkCanvas* canvas, SkBlendMode mode) {
-        const char* modeName = SkXfermode::ModeName(mode);
+        const char* modeName = SkBlendMode_Name(mode);
         fLabelPaint.setTextAlign(SkPaint::kRight_Align);
         canvas->drawText(modeName, strlen(modeName), kLabelSpacing - kShapeSize / 4,
                          fLabelPaint.getTextSize() / 4, fLabelPaint);
index 4e80bbf3b0db7bbd7c67edbc45a19acfef28e7aa..09f80dd3270c67678d69244a131c4a32fee59669 100644 (file)
@@ -8,6 +8,7 @@
 #include "gm.h"
 
 #include "Resources.h"
+#include "SkBlendModePriv.h"
 #include "SkGradientShader.h"
 #include "SkPM4fPriv.h"
 
@@ -86,7 +87,7 @@ DEF_SIMPLE_GM(gamma, canvas, 850, 200) {
         SkString dstText = SkStringPrintf("%08X", dstColor);
         canvas->drawText(srcText.c_str(), srcText.size(), 0, sz + textPaint.getFontSpacing(),
                          textPaint);
-        const char* modeName = SkXfermode::ModeName(mode);
+        const char* modeName = SkBlendMode_Name(mode);
         canvas->drawText(modeName, strlen(modeName), 0, sz + 2 * textPaint.getFontSpacing(),
                          textPaint);
         canvas->drawText(dstText.c_str(), dstText.size(), 0, sz + 3 * textPaint.getFontSpacing(),
index 3852d9385f8c62a9b1ad14078698c9c311f29332..abce994c20a1ae5893ed953ed3bdc4d15992a38e 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "gm.h"
+#include "SkBlendModePriv.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkLumaColorFilter.h"
@@ -121,7 +122,7 @@ protected:
 
         SkScalar gridStep = kSize + 2 * kInset;
         for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) {
-            draw_label(canvas, SkXfermode::ModeName(modes[i]),
+            draw_label(canvas, SkBlendMode_Name(modes[i]),
                        SkPoint::Make(gridStep * (0.5f + i), 20));
         }
 
index 03da0d33173058366f1d3da1488691c6816342ba..4d6b5e7fe936b29ed3d881ea31f010442bd0b409 100644 (file)
@@ -7,7 +7,7 @@
 #include "gm.h"
 #include "SkBitmap.h"
 #include "SkShader.h"
-#include "SkXfermode.h"
+#include "SkBlendModePriv.h"
 #include "SkColorPriv.h"
 
 namespace skiagm {
@@ -39,7 +39,7 @@ protected:
         const int W = 6;
 
         SkScalar x = 0, y = 0;
-        for (size_t m = 0; m <= SkXfermode::kLastMode; m++) {
+        for (size_t m = 0; m <= (size_t)SkBlendMode::kLastMode; m++) {
             SkBlendMode mode = static_cast<SkBlendMode>(m);
 
             canvas->save();
@@ -71,7 +71,7 @@ protected:
             canvas->restore();
 
 #if 1
-            canvas->drawText(SkXfermode::ModeName(mode), strlen(SkXfermode::ModeName(mode)),
+            canvas->drawText(SkBlendMode_Name(mode), strlen(SkBlendMode_Name(mode)),
                              x + w/2, y - labelP.getTextSize()/2, labelP);
 #endif
             x += w + SkIntToScalar(10);
index 36702bf70e996e1aa2ede5a4ad27fa8093b88064..e6ee7508ad02908ba8dbbf792f99a287392d9f11 100644 (file)
@@ -9,7 +9,7 @@
 #include "SkBitmap.h"
 #include "SkGradientShader.h"
 #include "SkSurface.h"
-#include "SkXfermode.h"
+#include "SkBlendModePriv.h"
 #include "SkColorPriv.h"
 
 #if SK_SUPPORT_GPU
@@ -68,10 +68,10 @@ protected:
             {SkPaint::kStroke_Style, SkIntToScalar(kSize) / 2},
         };
         for (size_t s = 0; s < SK_ARRAY_COUNT(kStrokes); ++s) {
-            for (size_t m = 0; m <= SkXfermode::kLastMode; ++m) {
+            for (size_t m = 0; m <= (size_t)SkBlendMode::kLastMode; ++m) {
                 SkBlendMode mode = static_cast<SkBlendMode>(m);
-                canvas->drawText(SkXfermode::ModeName(mode),
-                                 strlen(SkXfermode::ModeName(mode)),
+                canvas->drawText(SkBlendMode_Name(mode),
+                                 strlen(SkBlendMode_Name(mode)),
                                  SkIntToScalar(x),
                                  SkIntToScalar(y + kSize + 3) + labelP.getTextSize(),
                                  labelP);
index 90fea2fb25fd39dead2c02a6cce6b1c91444961c..1e61d377b3b88ff9889e04ce0411fad643f80b94 100644 (file)
@@ -15,4 +15,5 @@ android_framework_defines = [
   "SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT",
   "SK_SUPPORT_LEGACY_CLIP_REGIONOPS",
   "SK_SUPPORT_LEGACY_SHADER_ISABITMAP",
+  "SK_SUPPORT_LEGACY_XFERMODE_IS_PUBLIC",
 ]
index 60c7761ef56c183aae0db6f49961605bb16d9000..d7f11569a87314107e6aba916e70ab70b9cef29a 100644 (file)
@@ -442,7 +442,6 @@ skia_core_sources = [
   "$_include/core/SkTypes.h",
   "$_include/core/SkUnPreMultiply.h",
   "$_include/core/SkWriter32.h",
-  "$_include/core/SkXfermode.h",
 
   # private
   "$_include/private/SkAtomics.h",
index d828297b5b0339d8002daf1c05fe7754027a5ad6..d888c6a15269ee1ff38a96bcdb0239e667e5519f 100644 (file)
@@ -245,7 +245,6 @@ tests_sources = [
   "$_tests/WindowRectanglesTest.cpp",
   "$_tests/WritePixelsTest.cpp",
   "$_tests/Writer32Test.cpp",
-  "$_tests/XfermodeTest.cpp",
   "$_tests/YUVCacheTest.cpp",
   "$_tests/YUVTest.cpp",
 ]
index 34989354cda42ae5af66b7ca0d5b7dd3b614ee62..2d0047757b0164f8a6c27c96a2bf353998626e10 100644 (file)
@@ -20,7 +20,9 @@ class GrClip;
 class GrContext;
 class GrRenderTargetContext;
 class GrPaint;
+class GrFragmentProcessor;
 class GrRenderTarget;
+class GrTexture;
 class GrTextureProvider;
 class SkBitmap;
 class SkBlitter;
index e865e66456ae74c491866a866daf1f19566e0a80..59f205848a03617b3ddc5685bb8a54d5b85ce131 100644 (file)
@@ -12,6 +12,8 @@
 #include "SkColor.h"
 #include "SkFlattenable.h"
 
+#ifdef SK_SUPPORT_LEGACY_XFERMODE_IS_PUBLIC
+
 class GrFragmentProcessor;
 class GrTexture;
 class GrXPFactory;
@@ -303,3 +305,5 @@ private:
 };
 
 #endif
+
+#endif
index 075581f6c1f25af427f3eac7aada9dfb1ac4b157..3e9fe5e44bfa092f4e8abf1553702241ac34be40 100644 (file)
@@ -17,6 +17,7 @@ class GrCaps;
 class GrContext;
 class GrRenderTargetContext;
 struct GrProcessorTestData;
+class GrTexture;
 
 namespace GrProcessorUnitTest {
 
index 8632093074b21c3f060a02d5835f96f25ceccafc..a8c868e0348e5e5f2fec044830a20edb8fcb39e0 100644 (file)
@@ -8,9 +8,11 @@
 #ifndef GrCustomXfermode_DEFINED
 #define GrCustomXfermode_DEFINED
 
-#include "SkXfermode.h"
+#include "SkBlendMode.h"
+#include "SkRefCnt.h"
 
 class GrTexture;
+class GrXPFactory;
 
 /**
  * Custom Xfer modes are used for blending when the blend mode cannot be represented using blend
index 4e100122a1eda7c7c049f6f621529875f73a44db..dee0fb8dedf3263834a5d210b6c0277e6c5b0914 100644 (file)
@@ -602,6 +602,7 @@ DEFINES_ALL = [
     "SK_SUPPORT_LEGACY_ACCESSBITMAP",
     "SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT",
     "SK_SUPPORT_LEGACY_CLIP_REGIONOPS",
+    "SK_SUPPORT_LEGACY_XFERMODE_IS_PUBLIC",
     # Temporarily Disable analytic AA for Google3
     "SK_NO_ANALYTIC_AA",
 ]
index 5f65c9fabc5159a2d3351bf4bf0ddb5f488dd681..682db9220e151265b7494e64c3bcd0b7e0b5049e 100644 (file)
@@ -158,7 +158,7 @@ static SkMatrix make_matrix() {
 }
 
 static SkBlendMode make_xfermode() {
-    return static_cast<SkBlendMode>(R(SkXfermode::kLastMode+1));
+    return static_cast<SkBlendMode>(R((int)SkBlendMode::kLastMode+1));
 }
 
 static SkPaint::Align make_paint_align() {
index 218e919da3537048ebf8c996b0ec5a8444381e64..b17d3e3dffb56aa600920ef2cc1c92ec861ace9f 100644 (file)
@@ -8,6 +8,7 @@
 #include "SkBitmapProcShader.h"
 #include "SkBitmapProcState.h"
 #include "SkBitmapProvider.h"
+#include "SkXfermodePriv.h"
 
 static bool only_scale_and_translate(const SkMatrix& matrix) {
     unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
@@ -102,7 +103,6 @@ private:
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 #include "SkLinearBitmapPipeline.h"
 #include "SkPM4f.h"
-#include "SkXfermode.h"
 
 class LinearPipelineContext : public BitmapProcInfoContext {
 public:
index 29df639842531c6cfa6c1d4a955b93a52cf09f84..c4628fd9276f79dea4712d9ce109c5f0cf7fb543 100644 (file)
@@ -15,6 +15,8 @@ bool SkBlendMode_SupportsCoverageAsAlpha(SkBlendMode);
 bool SkBlendMode_CanOverflow(SkBlendMode);
 bool SkBlendMode_AppendStages(SkBlendMode, SkRasterPipeline* = nullptr);
 
+const char* SkBlendMode_Name(SkBlendMode);
+
 #if SK_SUPPORT_GPU
 #include "GrXferProcessor.h"
 sk_sp<GrXPFactory> SkBlendMode_AsXPFactory(SkBlendMode);
index cb7d718f54009c254ba33d1c6d7f3688b9806faf..1fd4d5f0d9729f75f5d2ae83fba23d7f5ead1687 100644 (file)
@@ -9,7 +9,7 @@
 #include "SkCoreBlitters.h"
 #include "SkColorPriv.h"
 #include "SkShader.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 SkA8_Blitter::SkA8_Blitter(const SkPixmap& device, const SkPaint& paint) : INHERITED(device) {
     fSrcA = paint.getAlpha();
index ea0554d66eaaa8aac3f1c9788732da837641e74a..958ad27970f089016f8c2193a8f6abfe9d1cd34a 100644 (file)
@@ -9,7 +9,7 @@
 #include "SkColorPriv.h"
 #include "SkShader.h"
 #include "SkUtils.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 #include "SkBlitMask.h"
 
 ///////////////////////////////////////////////////////////////////////////////
index 208497226237afc0bbc275fab472e50b4c948e1b..ce665806596344a6f892e440937776299615554d 100644 (file)
@@ -9,7 +9,7 @@
 #include "SkColorPriv.h"
 #include "SkShader.h"
 #include "SkUtils.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 #include "SkBlitMask.h"
 #include "SkTemplates.h"
 #include "SkPM4f.h"
index 7860b7cb6c03c82f27b888071b411eec760b72a4..015112a107195e889858b497765153cc87662287 100644 (file)
@@ -12,7 +12,7 @@
 #include "SkShader.h"
 #include "SkUtils.h"
 #include "SkUtilsArm.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 #if defined(__mips_dsp)
 extern void blitmask_d565_opaque_mips(int width, int height, uint16_t* device,
index aa5deb21c178b5cf8509ca593d5a3b0a22b6c155..23fca0f402fb0682d459d1f50810f1a37e778582 100644 (file)
@@ -13,6 +13,7 @@
 #include "SkBlitRow.h"
 #include "SkShader.h"
 #include "SkSmallAllocator.h"
+#include "SkXfermodePriv.h"
 
 class SkRasterBlitter : public SkBlitter {
 public:
index ea78489ed83961622d6fe9179801e321f1f43f3c..3e7be5c873062f852513b4bb54d5eff817d60359 100644 (file)
@@ -38,7 +38,7 @@ public:
     SkLinearBitmapPipeline(
         const SkLinearBitmapPipeline& pipeline,
         const SkPixmap& srcPixmap,
-        SkBlendMode blendMode,
+        SkBlendMode,
         const SkImageInfo& dstInfo);
 
     static bool ClonePipelineForBlitting(
index ccd38acc5fb8f10fda940868d498986142adb11f..1d5e3337298a67cb9e907bbdbaf025c72ca2509e 100644 (file)
@@ -11,7 +11,7 @@
 #include "SkRasterPipeline.h"
 #include "SkTextureCompressor.h"
 #include "SkTypes.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 #include <functional>
 
 struct ProcCoeff;
index cbe2558c2a82aecba3943116711c30386e6f8aae..ffa818c6e87089a8e71217cc0389344731dc7433 100644 (file)
@@ -11,6 +11,7 @@
 #include "SkImage.h"
 #include "SkPaint.h"
 #include "SkShader.h"
+#include "SkXfermodePriv.h"
 
 static bool changes_alpha(const SkPaint& paint) {
     SkColorFilter* cf = paint.getColorFilter();
index c49b01c5fd5b119b47ce958c6ed6ebbb40f2961c..25928d1ba0a6874532a2a3dfefa62ce3e8f22571 100644 (file)
@@ -23,7 +23,7 @@
 #include "SkShader.h"
 #include "SkTHash.h"
 #include "SkWriteBuffer.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 class SkBitmap;
 class SkImage;
index ddf044e455b21075a0c3e3e3a2adadde0835f4aa..977a2647a9418f997d7925e4988607cc03ec595e 100644 (file)
@@ -8,7 +8,7 @@
 #include "SkSpriteBlitter.h"
 #include "SkSpanProcs.h"
 #include "SkTemplates.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 class Sprite_4f : public SkSpriteBlitter {
 public:
index 1a76b1b2fe1511c8c153370aaf56a8ea3603e9b0..99856a14f9e3dacb8463525d06632a7feaea5f97 100644 (file)
@@ -11,7 +11,7 @@
 #include "SkColorPriv.h"
 #include "SkTemplates.h"
 #include "SkUtils.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 
index 64ce04d851192443d703d45ef1b0c7327bb56da3..3f3927e742ee0fcf95cff59e94e99335ec31c725 100644 (file)
@@ -1280,6 +1280,10 @@ const char* SkXfermode::ModeName(Mode mode) {
     static_assert(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, "mode_count");
 }
 
+const char* SkBlendMode_Name(SkBlendMode mode) {
+    return SkXfermode::ModeName((SkXfermode::Mode)mode);
+}
+
 #ifndef SK_IGNORE_TO_STRING
 void SkProcCoeffXfermode::toString(SkString* str) const {
     str->append("SkProcCoeffXfermode: ");
index d5bdfe5251fa4450f313bf6fccfbaf4e1efda975..e9d55905a71544cc7b5cc0fce474bb629beb1f2f 100644 (file)
@@ -7,7 +7,7 @@
 
 #include "SkPM4fPriv.h"
 #include "SkUtils.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 #include "Sk4x4f.h"
 
 static SkPM4f rgba_to_pmcolor_order(const SkPM4f& x) {
index 868ee087ca4d3b43d31d62a43ef9a4cda17b8d04..ece4a097c37fc346413d8fff262b81387e155933 100644 (file)
@@ -8,7 +8,7 @@
 #include "SkHalf.h"
 #include "SkPM4fPriv.h"
 #include "SkUtils.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCoverage) {
     return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f));
diff --git a/src/core/SkXfermodePriv.h b/src/core/SkXfermodePriv.h
new file mode 100644 (file)
index 0000000..b7d85ea
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkXfermodePriv_DEFINED
+#define SkXfermodePriv_DEFINED
+
+#include "SkBlendMode.h"
+#include "SkColor.h"
+#include "SkFlattenable.h"
+
+#ifdef SK_SUPPORT_LEGACY_XFERMODE_IS_PUBLIC
+#include "SkXfermode.h"
+#else
+
+class GrFragmentProcessor;
+class GrTexture;
+class GrXPFactory;
+class SkRasterPipeline;
+class SkString;
+
+struct SkArithmeticParams;
+
+struct SkPM4f;
+typedef SkPM4f (*SkXfermodeProc4f)(const SkPM4f& src, const SkPM4f& dst);
+
+/** \class SkXfermode
+ *
+ *  SkXfermode is the base class for objects that are called to implement custom
+ *  "transfer-modes" in the drawing pipeline. The static function Create(Modes)
+ *  can be called to return an instance of any of the predefined subclasses as
+ *  specified in the Modes enum. When an SkXfermode is assigned to an SkPaint,
+ *  then objects drawn with that paint have the xfermode applied.
+ *
+ *  All subclasses are required to be reentrant-safe : it must be legal to share
+ *  the same instance between several threads.
+ */
+class SK_API SkXfermode : public SkFlattenable {
+public:
+    virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+                        const SkAlpha aa[]) const;
+    virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+                        const SkAlpha aa[]) const;
+    virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+                        const SkAlpha aa[]) const;
+
+    /** Enum of possible coefficients to describe some xfermodes
+     */
+    enum Coeff {
+        kZero_Coeff,    /** 0 */
+        kOne_Coeff,     /** 1 */
+        kSC_Coeff,      /** src color */
+        kISC_Coeff,     /** inverse src color (i.e. 1 - sc) */
+        kDC_Coeff,      /** dst color */
+        kIDC_Coeff,     /** inverse dst color (i.e. 1 - dc) */
+        kSA_Coeff,      /** src alpha */
+        kISA_Coeff,     /** inverse src alpha (i.e. 1 - sa) */
+        kDA_Coeff,      /** dst alpha */
+        kIDA_Coeff,     /** inverse dst alpha (i.e. 1 - da) */
+
+        kCoeffCount
+    };
+
+    /** List of predefined xfermodes.
+        The algebra for the modes uses the following symbols:
+        Sa, Sc  - source alpha and color
+        Da, Dc - destination alpha and color (before compositing)
+        [a, c] - Resulting (alpha, color) values
+        For these equations, the colors are in premultiplied state.
+        If no xfermode is specified, kSrcOver is assumed.
+        The modes are ordered by those that can be expressed as a pair of Coeffs, followed by those
+        that aren't Coeffs but have separable r,g,b computations, and finally
+        those that are not separable.
+     */
+    enum Mode {
+        kClear_Mode,    //!< [0, 0]
+        kSrc_Mode,      //!< [Sa, Sc]
+        kDst_Mode,      //!< [Da, Dc]
+        kSrcOver_Mode,  //!< [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)]
+        kDstOver_Mode,  //!< [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)]
+        kSrcIn_Mode,    //!< [Sa * Da, Sc * Da]
+        kDstIn_Mode,    //!< [Da * Sa, Dc * Sa]
+        kSrcOut_Mode,   //!< [Sa * (1 - Da), Sc * (1 - Da)]
+        kDstOut_Mode,   //!< [Da * (1 - Sa), Dc * (1 - Sa)]
+        kSrcATop_Mode,  //!< [Da, Sc * Da + Dc * (1 - Sa)]
+        kDstATop_Mode,  //!< [Sa, Dc * Sa + Sc * (1 - Da)]
+        kXor_Mode,      //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)]
+        kPlus_Mode,     //!< [Sa + Da, Sc + Dc]
+        kModulate_Mode, // multiplies all components (= alpha and color)
+
+        // Following blend modes are defined in the CSS Compositing standard:
+        // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending
+        kScreen_Mode,
+        kLastCoeffMode = kScreen_Mode,
+
+        kOverlay_Mode,
+        kDarken_Mode,
+        kLighten_Mode,
+        kColorDodge_Mode,
+        kColorBurn_Mode,
+        kHardLight_Mode,
+        kSoftLight_Mode,
+        kDifference_Mode,
+        kExclusion_Mode,
+        kMultiply_Mode,
+        kLastSeparableMode = kMultiply_Mode,
+
+        kHue_Mode,
+        kSaturation_Mode,
+        kColor_Mode,
+        kLuminosity_Mode,
+        kLastMode = kLuminosity_Mode
+    };
+
+    /**
+     * Gets the name of the Mode as a string.
+     */
+    static const char* ModeName(Mode);
+    static const char* ModeName(SkBlendMode mode) {
+        return ModeName(Mode(mode));
+    }
+
+    /**
+     *  If the xfermode is one of the modes in the Mode enum, then asMode()
+     *  returns true and sets (if not null) mode accordingly. Otherwise it
+     *  returns false and ignores the mode parameter.
+     */
+    virtual bool asMode(Mode* mode) const;
+
+    /**
+     *  The same as calling xfermode->asMode(mode), except that this also checks
+     *  if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
+     */
+    static bool AsMode(const SkXfermode*, Mode* mode);
+    static bool AsMode(const sk_sp<SkXfermode>& xfer, Mode* mode) {
+        return AsMode(xfer.get(), mode);
+    }
+
+    /**
+     *  Returns true if the xfermode claims to be the specified Mode. This works
+     *  correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus
+     *  you can say this without checking for a null...
+     *
+     *  If (SkXfermode::IsMode(paint.getXfermode(),
+     *                         SkXfermode::kDstOver_Mode)) {
+     *      ...
+     *  }
+     */
+    static bool IsMode(const SkXfermode* xfer, Mode mode);
+    static bool IsMode(const sk_sp<SkXfermode>& xfer, Mode mode) {
+        return IsMode(xfer.get(), mode);
+    }
+
+    /** Return an SkXfermode object for the specified mode.
+     */
+    static sk_sp<SkXfermode> Make(SkBlendMode);
+    static sk_sp<SkXfermode> Make(Mode m) { return Make((SkBlendMode)m); }
+
+    /**
+     *  Skia maintains global xfermode objects corresponding to each BlendMode. This returns a
+     *  ptr to that global xfermode (or null if the mode is srcover). Thus the caller may use
+     *  the returned ptr, but it should leave its refcnt untouched.
+     */
+    static SkXfermode* Peek(SkBlendMode mode) {
+        sk_sp<SkXfermode> xfer = Make(mode);
+        if (!xfer) {
+            SkASSERT(SkBlendMode::kSrcOver == mode);
+            return nullptr;
+        }
+        SkASSERT(!xfer->unique());
+        return xfer.get();
+    }
+
+    SkBlendMode blend() const {
+        Mode mode;
+        SkAssertResult(this->asMode(&mode));
+        return (SkBlendMode)mode;
+    }
+
+    static SkXfermodeProc GetProc(SkBlendMode);
+    static SkXfermodeProc4f GetProc4f(SkBlendMode);
+
+    /**
+     *  If the specified mode can be represented by a pair of Coeff, then return
+     *  true and set (if not NULL) the corresponding coeffs. If the mode is
+     *  not representable as a pair of Coeffs, return false and ignore the
+     *  src and dst parameters.
+     */
+    static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst);
+    static bool ModeAsCoeff(SkBlendMode mode, Coeff* src, Coeff* dst) {
+        return ModeAsCoeff((Mode)mode, src, dst);
+    }
+
+    /**
+     * Returns whether or not the xfer mode can support treating coverage as alpha
+     */
+    virtual bool supportsCoverageAsAlpha() const;
+
+    /**
+     *  The same as calling xfermode->supportsCoverageAsAlpha(), except that this also checks if
+     *  the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
+     */
+    static bool SupportsCoverageAsAlpha(const SkXfermode* xfer);
+    static bool SupportsCoverageAsAlpha(const sk_sp<SkXfermode>& xfer) {
+        return SupportsCoverageAsAlpha(xfer.get());
+    }
+
+    enum SrcColorOpacity {
+        // The src color is known to be opaque (alpha == 255)
+        kOpaque_SrcColorOpacity = 0,
+        // The src color is known to be fully transparent (color == 0)
+        kTransparentBlack_SrcColorOpacity = 1,
+        // The src alpha is known to be fully transparent (alpha == 0)
+        kTransparentAlpha_SrcColorOpacity = 2,
+        // The src color opacity is unknown
+        kUnknown_SrcColorOpacity = 3
+    };
+
+    /**
+     * Returns whether or not the result of the draw with the xfer mode will be opaque or not. The
+     * input to this call is an enum describing known information about the opacity of the src color
+     * that will be given to the xfer mode.
+     */
+    virtual bool isOpaque(SrcColorOpacity opacityType) const;
+
+    /**
+     *  The same as calling xfermode->isOpaque(...), except that this also checks if
+     *  the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
+     */
+    static bool IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType);
+    static bool IsOpaque(const sk_sp<SkXfermode>& xfer, SrcColorOpacity opacityType) {
+        return IsOpaque(xfer.get(), opacityType);
+    }
+    static bool IsOpaque(SkBlendMode, SrcColorOpacity);
+
+#if SK_SUPPORT_GPU
+    /** Used by the SkXfermodeImageFilter to blend two colors via a GrFragmentProcessor.
+        The input to the returned FP is the src color. The dst color is
+        provided by the dst param which becomes a child FP of the returned FP.
+        It is legal for the function to return a null output. This indicates that
+        the output of the blend is simply the src color.
+     */
+    virtual sk_sp<GrFragmentProcessor> makeFragmentProcessorForImageFilter(
+                                                            sk_sp<GrFragmentProcessor> dst) const;
+
+    /** A subclass must implement this factory function to work with the GPU backend.
+        The xfermode will return a factory for which the caller will get a ref. It is up
+        to the caller to install it. XferProcessors cannot use a background texture.
+      */
+    virtual sk_sp<GrXPFactory> asXPFactory() const;
+#endif
+
+    SK_TO_STRING_PUREVIRT()
+    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+    SK_DEFINE_FLATTENABLE_TYPE(SkXfermode)
+
+    enum D32Flags {
+        kSrcIsOpaque_D32Flag  = 1 << 0,
+        kSrcIsSingle_D32Flag  = 1 << 1,
+        kDstIsSRGB_D32Flag    = 1 << 2,
+    };
+    typedef void (*D32Proc)(SkBlendMode, uint32_t dst[], const SkPM4f src[],
+                            int count, const SkAlpha coverage[]);
+    static D32Proc GetD32Proc(SkBlendMode, uint32_t flags);
+
+    enum F16Flags {
+        kSrcIsOpaque_F16Flag  = 1 << 0,
+        kSrcIsSingle_F16Flag  = 1 << 1,
+    };
+    typedef void (*F16Proc)(SkBlendMode, uint64_t dst[], const SkPM4f src[], int count,
+                            const SkAlpha coverage[]);
+    static F16Proc GetF16Proc(SkBlendMode, uint32_t flags);
+
+    enum LCDFlags {
+        kSrcIsOpaque_LCDFlag    = 1 << 0,   // else src(s) may have alpha < 1
+        kSrcIsSingle_LCDFlag    = 1 << 1,   // else src[count]
+        kDstIsSRGB_LCDFlag      = 1 << 2,   // else l32 or f16
+    };
+    typedef void (*LCD32Proc)(uint32_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
+    typedef void (*LCDF16Proc)(uint64_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
+    static LCD32Proc GetLCD32Proc(uint32_t flags);
+    static LCDF16Proc GetLCDF16Proc(uint32_t) { return nullptr; }
+
+    virtual bool isArithmetic(SkArithmeticParams*) const { return false; }
+
+protected:
+    SkXfermode() {}
+    /** The default implementation of xfer32/xfer16/xferA8 in turn call this
+        method, 1 color at a time (upscaled to a SkPMColor). The default
+        implementation of this method just returns dst. If performance is
+        important, your subclass should override xfer32/xfer16/xferA8 directly.
+
+        This method will not be called directly by the client, so it need not
+        be implemented if your subclass has overridden xfer32/xfer16/xferA8
+    */
+    virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;
+
+private:
+    enum {
+        kModeCount = kLastMode + 1
+    };
+
+    typedef SkFlattenable INHERITED;
+};
+
+#endif
+
+#endif
index ca469a7233b66904dbe4a4251973ac890a432a1e..5cb109343463661647f5724b0c5c9be89a42edd3 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "SkArithmeticMode.h"
 
+class SkXfermode;
+
 struct SkArithmeticParams {
     float fK[4];
     bool fEnforcePMColor;
index ecbe558c940cbe0ef4054431e22a4b6a416bfcd5..bd1d7155e64aec8d58f52b238068f460f7306baa 100644 (file)
@@ -12,7 +12,7 @@
 #include "GrBlend.h"
 #include "SkImageInfo.h"
 #include "SkMatrix.h"
-#include "SkXfermode.h"
+#include "SkXfermodePriv.h"
 
 class GrCaps;
 class GrContext;
index 3895f57f5da95e3a0a7c788a3beea39fb6e12697..8a54d4457adf6333a92dffda04f340885bfe9dab 100644 (file)
@@ -384,8 +384,8 @@ void CustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
 
 GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory);
 sk_sp<GrXPFactory> CustomXPFactory::TestCreate(GrProcessorTestData* d) {
-    int mode = d->fRandom->nextRangeU(SkXfermode::kLastCoeffMode + 1,
-                                      SkXfermode::kLastSeparableMode);
+    int mode = d->fRandom->nextRangeU((int)SkBlendMode::kLastCoeffMode + 1,
+                                      (int)SkBlendMode::kLastSeparableMode);
 
     return sk_sp<GrXPFactory>(new CustomXPFactory(static_cast<SkBlendMode>(mode)));
 }
index d511fae45ddd3d30d3575e1d7d9a182e322e92ee..ff95dac72367b78fbc59f02cb0151b68cd0df627 100644 (file)
@@ -227,7 +227,7 @@ GR_MAKE_BITFIELD_OPS(BlendFormula::Properties);
  * with and without an opaque input color. Optimization properties are deduced at compile time so we
  * can make runtime decisions quickly. RGB coverage is not supported.
  */
-static const BlendFormula gBlendTable[2][2][SkXfermode::kLastCoeffMode + 1] = {
+static const BlendFormula gBlendTable[2][2][(int)SkBlendMode::kLastCoeffMode + 1] = {
 
                      /*>> No coverage, input color unknown <<*/ {{
 
@@ -302,7 +302,7 @@ static const BlendFormula gBlendTable[2][2][SkXfermode::kLastCoeffMode + 1] = {
     /* screen */     COEFF_FORMULA(   kOne_GrBlendCoeff,    kISC_GrBlendCoeff),
 }}};
 
-static const BlendFormula gLCDBlendTable[SkXfermode::kLastCoeffMode + 1] = {
+static const BlendFormula gLCDBlendTable[(int)SkBlendMode::kLastCoeffMode + 1] = {
     /* clear */      COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_OutputType),
     /* src */        COVERAGE_FORMULA(BlendFormula::kCoverage_OutputType, kOne_GrBlendCoeff),
     /* dst */        NO_DST_WRITE_FORMULA,
index 73a145b7c31e5d6837467351af7b198efec1cabc..da73b6644bda4b1c231e587c3b89f40660dda777 100644 (file)
@@ -4,8 +4,10 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "GrGLSLBlend.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "SkXfermodePriv.h"
 
 //////////////////////////////////////////////////////////////////////////////
 //  Advanced (non-coeff) blend helpers
index ca9e46efd305f0e572bb960232594ad25b7dc1b6..cd5e8efba7951f3d5591adf9a98c4d6b97608856 100644 (file)
@@ -67,36 +67,3 @@ DEF_TEST(Blend_byte_multiply, r) {
     };
     for (auto multiply : perfect) { REPORTER_ASSERT(r, test(multiply).diffs == 0); }
 }
-
-DEF_TEST(Blend_premul_begets_premul, r) {
-    // This test is quite slow, even if you have enough cores to run each mode in parallel.
-    if (!r->allowExtendedTest()) {
-        return;
-    }
-
-    // No matter what xfermode we use, premul inputs should create premul outputs.
-    auto test_mode = [&](int m) {
-        SkXfermode::Mode mode = (SkXfermode::Mode)m;
-        if (mode == SkXfermode::kSrcOver_Mode) {
-            return;  // TODO: can't create a SrcOver xfermode.
-        }
-        auto xfermode(SkXfermode::Make(mode));
-        SkASSERT(xfermode);
-        // We'll test all alphas and legal color values, assuming all colors work the same.
-        // This is not true for non-separable blend modes, but this test still can't hurt.
-        for (int sa = 0; sa <= 255; sa++) {
-        for (int da = 0; da <= 255; da++) {
-        for (int  s = 0;  s <= sa;   s++) {
-        for (int  d = 0;  d <= da;   d++) {
-            SkPMColor src = SkPackARGB32(sa, s, s, s),
-                      dst = SkPackARGB32(da, d, d, d);
-            xfermode->xfer32(&dst, &src, 1, nullptr);  // To keep it simple, no AA.
-            if (!SkPMColorValid(dst)) {
-                ERRORF(r, "%08x is not premul using %s", dst, SkXfermode::ModeName(mode));
-            }
-        }}}}
-    };
-
-    // Parallelism helps speed things up on my desktop from ~725s to ~50s.
-    SkTaskGroup().batch(SkXfermode::kLastMode, test_mode);
-}
index 32aec36f9f712995a421a070fad6e9252833df8f..db4262c7e9530dd765d65dcb5ced4f372177c015 100644 (file)
@@ -12,6 +12,7 @@
 #include "../include/core/SkStream.h"
 #include "../include/core/SkString.h"
 #include "../include/core/SkPictureRecorder.h"
+#include "../src/core/SkBlendModePriv.h"
 #include <cstring>
 
 // Verify that replay of a recording into a clipped canvas
@@ -160,7 +161,7 @@ DEF_TEST(SkRecordingAccuracyXfermode, reporter) {
         if (memcmp(goldenBM.getPixels(), pictureBM.getPixels(), pixelsSize)) {
             numErrors++;
             errors.appendf("For SkXfermode %d %s:    SkPictureRecorder bitmap is wrong\n",
-                           iMode, SkXfermode::ModeName(mode));
+                           iMode, SkBlendMode_Name(mode));
         }
 #endif
     }
index 028b99f4132030221a2ec62fd04f0dc8eb3eef4b..f268e5f42d357d6a536a64753ab62009c580a2a9 100644 (file)
@@ -23,15 +23,6 @@ static bool nearly_equal(float a, float b, float tol = kTolerance) {
     return fabsf(a - b) <= tol;
 }
 
-static bool nearly_equal(const SkPM4f a, const SkPM4f& b, float tol = kTolerance) {
-    for (int i = 0; i < 4; ++i) {
-        if (!nearly_equal(a.fVec[i], b.fVec[i], tol)) {
-            return false;
-        }
-    }
-    return true;
-}
-
 DEF_TEST(SkColor4f_FromColor, reporter) {
     const struct {
         SkColor     fC;
@@ -75,45 +66,3 @@ DEF_TEST(Color4f_premul, reporter) {
         REPORTER_ASSERT(reporter, nearly_equal(pm4.b(), c4.fA * c4.fB));
     }
 }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-typedef SkPM4f (*SkXfermodeProc4f)(const SkPM4f& src, const SkPM4f& dst);
-
-static bool compare_procs(SkXfermodeProc proc32, SkXfermodeProc4f proc4f) {
-    const float kTolerance = 1.0f / 255;
-
-    const SkColor colors[] = {
-        0, 0xFF000000, 0xFFFFFFFF, 0x80FF0000
-    };
-
-    for (auto s32 : colors) {
-        SkPMColor s_pm32 = SkPreMultiplyColor(s32);
-        SkPM4f    s_pm4f = SkColor4f::FromColor(s32).premul();
-        for (auto d32 : colors) {
-            SkPMColor d_pm32 = SkPreMultiplyColor(d32);
-            SkPM4f    d_pm4f = SkColor4f::FromColor(d32).premul();
-
-            SkPMColor r32 = proc32(s_pm32, d_pm32);
-            SkPM4f    r4f = proc4f(s_pm4f, d_pm4f);
-
-            SkPM4f r32_4f = SkPM4f::FromPMColor(r32);
-            if (!nearly_equal(r4f, r32_4f, kTolerance)) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-// Check that our Proc and Proc4f return (nearly) the same results
-//
-DEF_TEST(Color4f_xfermode_proc4f, reporter) {
-    // TODO: extend xfermodes so that all cases can be tested.
-    //
-    for (int mode = (int)SkBlendMode::kClear; mode <= (int)SkBlendMode::kScreen; ++mode) {
-        SkXfermodeProc   proc32 = SkXfermode::GetProc((SkBlendMode)mode);
-        SkXfermodeProc4f proc4f = SkXfermode::GetProc4f((SkBlendMode)mode);
-        REPORTER_ASSERT(reporter, compare_procs(proc32, proc4f));
-    }
-}
diff --git a/tests/XfermodeTest.cpp b/tests/XfermodeTest.cpp
deleted file mode 100644 (file)
index c3a4d96..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkColor.h"
-#include "SkXfermode.h"
-#include "Test.h"
-
-#define ILLEGAL_MODE    ((SkXfermode::Mode)-1)
-
-static void test_asMode(skiatest::Reporter* reporter) {
-    for (int mode = 0; mode <= SkXfermode::kLastMode; mode++) {
-        auto xfer = SkXfermode::Make((SkXfermode::Mode) mode);
-
-        SkXfermode::Mode reportedMode = ILLEGAL_MODE;
-        REPORTER_ASSERT(reporter, reportedMode != mode);
-
-        // test IsMode
-        REPORTER_ASSERT(reporter, SkXfermode::AsMode(xfer, &reportedMode));
-        REPORTER_ASSERT(reporter, reportedMode == mode);
-
-        // repeat that test, but with asMode instead
-        if (xfer) {
-            reportedMode = (SkXfermode::Mode) -1;
-            REPORTER_ASSERT(reporter, xfer->asMode(&reportedMode));
-            REPORTER_ASSERT(reporter, reportedMode == mode);
-        } else {
-            REPORTER_ASSERT(reporter, SkXfermode::kSrcOver_Mode == mode);
-        }
-    }
-}
-
-static void test_IsMode(skiatest::Reporter* reporter) {
-    REPORTER_ASSERT(reporter, SkXfermode::IsMode(nullptr,
-                                                 SkXfermode::kSrcOver_Mode));
-
-    for (int i = 0; i <= SkXfermode::kLastMode; ++i) {
-        SkXfermode::Mode mode = (SkXfermode::Mode)i;
-
-        auto xfer = SkXfermode::Make(mode);
-        REPORTER_ASSERT(reporter, SkXfermode::IsMode(xfer, mode));
-
-        if (SkXfermode::kSrcOver_Mode != mode) {
-            REPORTER_ASSERT(reporter, !SkXfermode::IsMode(nullptr, mode));
-        }
-    }
-}
-
-DEF_TEST(Xfermode, reporter) {
-    test_asMode(reporter);
-    test_IsMode(reporter);
-}