Move SkTileModes to top level

- move shader factories to their host (e.g. picture->makeShader)

More to do to formally deprecated SkShader::TileMode

Bug: skia:8937
Change-Id: I101e42fb9fba4ab91d028a34888f1fde16fdece4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/205589
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Auto-Submit: Mike Reed <reed@google.com>
diff --git a/bench/ShaderMaskFilterBench.cpp b/bench/ShaderMaskFilterBench.cpp
index 4a2ec14..4de5f47 100644
--- a/bench/ShaderMaskFilterBench.cpp
+++ b/bench/ShaderMaskFilterBench.cpp
@@ -33,10 +33,8 @@
     SkPictureRecorder recorder;
     recorder.beginRecording(100, 100)->drawCircle(50, 50, 50, p);
 
-    return SkPictureShader::Make(recorder.finishRecordingAsPicture(),
-                                 SkShader::kRepeat_TileMode,
-                                 SkShader::kRepeat_TileMode,
-                                 nullptr, nullptr);
+    return recorder.finishRecordingAsPicture()->makeShader(SkTileMode::kRepeat,
+                                                           SkTileMode::kRepeat);
 }
 
 class ShaderMFBench final : public Benchmark {
diff --git a/gm/filterbug.cpp b/gm/filterbug.cpp
index 258374f..bd413b3 100644
--- a/gm/filterbug.cpp
+++ b/gm/filterbug.cpp
@@ -7,7 +7,7 @@
 
 #include "gm.h"
 #include "SkColorPriv.h"
-#include "SkImageShader.h"
+#include "SkImage.h"
 
 static const sk_sp<SkImage> make_image(int firstBlackRow, int lastBlackRow) {
     static const int kWidth = 25;
@@ -56,9 +56,7 @@
             p1.setFilterQuality(kFilterQuality);
             SkMatrix localMat;
             localMat.setScaleTranslate(2.0f, 2.0f, 50.0f, 0.0f);
-            p1.setShader(SkImageShader::Make(fTop,
-                                             SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode,
-                                             &localMat));
+            p1.setShader(fTop->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &localMat));
 
             canvas->drawRect(r1, p1);
         }
@@ -82,9 +80,7 @@
             p3.setFilterQuality(kFilterQuality);
             SkMatrix localMat;
             localMat.setScaleTranslate(2.0f, 2.0f, 50.0f, 86.0f);
-            p3.setShader(SkImageShader::Make(fBot,
-                                             SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode,
-                                             &localMat));
+            p3.setShader(fBot->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &localMat));
 
             canvas->drawRect(r3, p3);
         }
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index 7eaac07..3cd8efe 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -14,7 +14,8 @@
 #include "SkImageEncoder.h"
 #include "SkRefCnt.h"
 #include "SkScalar.h"
-#include "SkShader.h"
+#include "SkShader.h"   // can remove once we switch to SkTileMode
+#include "SkTileMode.h"
 
 #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
 #include <android/hardware_buffer.h>
@@ -670,18 +671,22 @@
     bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); }
 
     /** Creates SkShader from SkImage. SkShader dimensions are taken from SkImage. SkShader uses
-        SkShader::TileMode rules to fill drawn area outside SkImage. localMatrix permits
+        SkTileMode rules to fill drawn area outside SkImage. localMatrix permits
         transforming SkImage before SkCanvas matrix is applied.
 
-        @param tileMode1    tiling on x-axis, one of: SkShader::kClamp_TileMode,
-                            SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode
-        @param tileMode2    tiling on y-axis, one of: SkShader::kClamp_TileMode,
-                            SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode
+        @param tmx          tiling in the x direction
+        @param tmy          tiling in the y direction
         @param localMatrix  SkImage transformation, or nullptr
         @return             SkShader containing SkImage
     */
-    sk_sp<SkShader> makeShader(SkShader::TileMode tileMode1, SkShader::TileMode tileMode2,
+    sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy,
                                const SkMatrix* localMatrix = nullptr) const;
+    // DEPRECATED. Use SkTileMode
+    sk_sp<SkShader> makeShader(SkShader::TileMode tmx, SkShader::TileMode tmy,
+                               const SkMatrix* localMatrix = nullptr) const {
+        return this->makeShader(static_cast<SkTileMode>(tmx), static_cast<SkTileMode>(tmy),
+                                localMatrix);
+    }
 
     /** Creates SkShader from SkImage. SkShader dimensions are taken from SkImage. SkShader uses
         SkShader::kClamp_TileMode to fill drawn area outside SkImage. localMatrix permits
@@ -691,7 +696,7 @@
         @return             SkShader containing SkImage
     */
     sk_sp<SkShader> makeShader(const SkMatrix* localMatrix = nullptr) const {
-        return this->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, localMatrix);
+        return this->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, localMatrix);
     }
 
     /** Copies SkImage pixel address, row bytes, and SkImageInfo to pixmap, if address
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index 3db040f..49798a8 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -10,13 +10,16 @@
 
 #include "SkRefCnt.h"
 #include "SkRect.h"
+#include "SkTileMode.h"
 #include "SkTypes.h"
 
 class SkCanvas;
 class SkData;
 struct SkDeserialProcs;
 class SkImage;
+class SkMatrix;
 struct SkSerialProcs;
+class SkShader;
 class SkStream;
 class SkWStream;
 
@@ -193,6 +196,23 @@
     */
     virtual size_t approximateBytesUsed() const = 0;
 
+    /** Return a new shader that will draw with this picture.
+     *
+     *  @param tmx  The tiling mode to use when sampling in the x-direction.
+     *  @param tmy  The tiling mode to use when sampling in the y-direction.
+     *  @param localMatrix Optional matrix used when sampling
+     *  @param tile The tile rectangle in picture coordinates: this represents the subset
+     *              (or superset) of the picture used when building a tile. It is not
+     *              affected by localMatrix and does not imply scaling (only translation
+     *              and cropping). If null, the tile rect is considered equal to the picture
+     *              bounds.
+     *  @return     Returns a new shader object. Note: this function never returns null.
+     */
+    sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy,
+                               const SkMatrix* localMatrix, const SkRect* tileRect) const;
+    sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy,
+                               const SkMatrix* localMatrix = nullptr) const;
+
 private:
     // Subclass whitelist.
     SkPicture();
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 97d7c3f..3ab87f0 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -14,6 +14,7 @@
 #include "SkFlattenable.h"
 #include "SkImageInfo.h"
 #include "SkMatrix.h"
+#include "SkTileMode.h"
 
 class SkArenaAlloc;
 class SkBitmap;
@@ -221,12 +222,19 @@
      *  @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
      *  @return     Returns a new shader object. Note: this function never returns null.
     */
-    static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
+    static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, SkTileMode tmx, SkTileMode tmy,
                                             const SkMatrix* localMatrix = nullptr);
+    // DEPRECATED. Use SkTileMode
+    static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
+                                            const SkMatrix* localMatrix = nullptr) {
+        return MakeBitmapShader(src, static_cast<SkTileMode>(tmx), static_cast<SkTileMode>(tmy),
+                                localMatrix);
+    }
 
     // NOTE: You can create an SkImage Shader with SkImage::newShader().
 
-    /** Call this to create a new shader that will draw with the specified picture.
+    /** DEPRECATED: call picture->makeShader(...)
+     *  Call this to create a new shader that will draw with the specified picture.
      *
      *  @param src  The picture to use inside the shader (if not NULL, its ref count
      *              is incremented). The SkPicture must not be changed after
diff --git a/include/core/SkTileMode.h b/include/core/SkTileMode.h
new file mode 100644
index 0000000..8761b4c
--- /dev/null
+++ b/include/core/SkTileMode.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTileModes_DEFINED
+#define SkTileModes_DEFINED
+
+#include "SkTypes.h"
+
+enum class SkTileMode {
+    /**
+     *  Replicate the edge color if the shader draws outside of its
+     *  original bounds.
+     */
+    kClamp,
+
+    /**
+     *  Repeat the shader's image horizontally and vertically.
+     */
+    kRepeat,
+
+    /**
+     *  Repeat the shader's image horizontally and vertically, alternating
+     *  mirror images so that adjacent images always seam.
+     */
+    kMirror,
+
+    /**
+     *  Only draw within the original domain, return transparent-black everywhere else.
+     */
+    kDecal,
+
+    kLastTileMode = kDecal,
+};
+
+static constexpr int kSkTileModeCount = static_cast<int>(SkTileMode::kLastTileMode) + 1;
+
+#endif
diff --git a/modules/canvaskit/canvaskit_bindings.cpp b/modules/canvaskit/canvaskit_bindings.cpp
index 0ec66fa..c80c0a6 100644
--- a/modules/canvaskit/canvaskit_bindings.cpp
+++ b/modules/canvaskit/canvaskit_bindings.cpp
@@ -636,14 +636,14 @@
     function("_MakeImageShader", optional_override([](sk_sp<SkImage> img,
                                 SkShader::TileMode tx, SkShader::TileMode ty,
                                 bool clampAsIfUnpremul)->sk_sp<SkShader> {
-        return SkImageShader::Make(img, tx, ty, nullptr, clampAsIfUnpremul);
+        return SkImageShader::Make(img, (SkTileMode)tx, (SkTileMode)ty, nullptr, clampAsIfUnpremul);
     }), allow_raw_pointers());
     function("_MakeImageShader", optional_override([](sk_sp<SkImage> img,
                                 SkShader::TileMode tx, SkShader::TileMode ty,
                                 bool clampAsIfUnpremul, const SimpleMatrix& lm)->sk_sp<SkShader> {
         SkMatrix localMatrix = toSkMatrix(lm);
 
-        return SkImageShader::Make(img, tx, ty, &localMatrix, clampAsIfUnpremul);
+        return SkImageShader::Make(img, (SkTileMode)tx, (SkTileMode)ty, &localMatrix, clampAsIfUnpremul);
     }), allow_raw_pointers());
     function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
                                 uintptr_t /* SkColor*  */ cPtr, uintptr_t /* SkScalar*  */ pPtr,
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 7bb14d2..48f58bf 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -518,8 +518,8 @@
     // if its mutable, since that precaution is not needed (give the short lifetime of the shader).
 
     // construct a shader, so we can call drawRect with the dst
-    auto s = SkMakeBitmapShaderForPaint(paint, *bitmapPtr, SkShader::kClamp_TileMode,
-            SkShader::kClamp_TileMode, &matrix, kNever_SkCopyPixelsMode);
+    auto s = SkMakeBitmapShaderForPaint(paint, *bitmapPtr, SkTileMode::kClamp,
+                                        SkTileMode::kClamp, &matrix, kNever_SkCopyPixelsMode);
     if (!s) {
         return;
     }
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 67d0622..b30f654 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -40,8 +40,9 @@
 static SkPaint make_paint_with_image(
     const SkPaint& origPaint, const SkBitmap& bitmap, SkMatrix* matrix = nullptr) {
     SkPaint paint(origPaint);
-    paint.setShader(SkMakeBitmapShaderForPaint(origPaint, bitmap, SkShader::kClamp_TileMode,
-            SkShader::kClamp_TileMode, matrix, kNever_SkCopyPixelsMode));
+    paint.setShader(SkMakeBitmapShaderForPaint(origPaint, bitmap, SkTileMode::kClamp,
+                                               SkTileMode::kClamp, matrix,
+                                               kNever_SkCopyPixelsMode));
     return paint;
 }
 
diff --git a/src/core/SkImagePriv.h b/src/core/SkImagePriv.h
index 46a9370..6e82b73 100644
--- a/src/core/SkImagePriv.h
+++ b/src/core/SkImagePriv.h
@@ -10,6 +10,7 @@
 
 #include "SkImage.h"
 #include "SkSurface.h"
+#include "SkTileMode.h"
 
 enum SkCopyPixelsMode {
     kIfMutable_SkCopyPixelsMode,  //!< only copy src pixels if they are marked mutable
@@ -22,7 +23,7 @@
 
 // If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive
 // the SkShader.
-sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode, SkShader::TileMode,
+sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkTileMode, SkTileMode,
                                    const SkMatrix* localMatrix, SkCopyPixelsMode);
 
 // Convenience function to return a shader that implements the shader+image behavior defined for
@@ -30,7 +31,7 @@
 // properly compose them together when it is an alpha image. This allows the returned paint to
 // be assigned to a paint clone without discarding the original behavior.
 sk_sp<SkShader> SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap& src,
-                                           SkShader::TileMode, SkShader::TileMode,
+                                           SkTileMode, SkTileMode,
                                            const SkMatrix* localMatrix, SkCopyPixelsMode);
 
 /**
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index 7661802..2c3faa3 100644
--- a/src/core/SkPixmap.cpp
+++ b/src/core/SkPixmap.cpp
@@ -217,8 +217,8 @@
 
     // We'll create a shader to do this draw so we have control over the bicubic clamp.
     sk_sp<SkShader> shader = SkImageShader::Make(SkImage::MakeFromBitmap(bitmap),
-                                                 SkShader::kClamp_TileMode,
-                                                 SkShader::kClamp_TileMode,
+                                                 SkTileMode::kClamp,
+                                                 SkTileMode::kClamp,
                                                  &scale,
                                                  clampAsIfUnpremul);
 
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index a7cdff0..4ec23a3 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -82,9 +82,9 @@
 
 sk_sp<SkColorSpace> SkImage::refColorSpace() const { return fInfo.refColorSpace(); }
 
-sk_sp<SkShader> SkImage::makeShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
+sk_sp<SkShader> SkImage::makeShader(SkTileMode tmx, SkTileMode tmy,
                                     const SkMatrix* localMatrix) const {
-    return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tileX, tileY, localMatrix);
+    return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy, localMatrix);
 }
 
 sk_sp<SkData> SkImage::encodeToData(SkEncodedImageFormat type, int quality) const {
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp
index fa4d9b7..c65a0d0 100644
--- a/src/shaders/SkImageShader.cpp
+++ b/src/shaders/SkImageShader.cpp
@@ -21,19 +21,19 @@
 /**
  *  We are faster in clamp, so always use that tiling when we can.
  */
-static SkShader::TileMode optimize(SkShader::TileMode tm, int dimension) {
+static SkShader::TileMode optimize(SkTileMode tm, int dimension) {
     SkASSERT(dimension > 0);
 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
     // need to update frameworks/base/libs/hwui/tests/unit/SkiaBehaviorTests.cpp:55 to allow
     // for transforming to clamp.
-    return tm;
+    return static_cast<SkShader::TileMode>(tm);
 #else
-    return dimension == 1 ? SkShader::kClamp_TileMode : tm;
+    return dimension == 1 ? SkShader::kClamp_TileMode : static_cast<SkShader::TileMode>(tm);
 #endif
 }
 
 SkImageShader::SkImageShader(sk_sp<SkImage> img,
-                             TileMode tmx, TileMode tmy,
+                             SkTileMode tmx, SkTileMode tmy,
                              const SkMatrix* localMatrix,
                              bool clampAsIfUnpremul)
     : INHERITED(localMatrix)
@@ -47,15 +47,15 @@
 // so there's no need to read or write it here.
 
 sk_sp<SkFlattenable> SkImageShader::CreateProc(SkReadBuffer& buffer) {
-    const TileMode tx = (TileMode)buffer.readUInt();
-    const TileMode ty = (TileMode)buffer.readUInt();
+    auto tmx = buffer.read32LE<SkTileMode>(SkTileMode::kLastTileMode);
+    auto tmy = buffer.read32LE<SkTileMode>(SkTileMode::kLastTileMode);
     SkMatrix localMatrix;
     buffer.readMatrix(&localMatrix);
     sk_sp<SkImage> img = buffer.readImage();
     if (!img) {
         return nullptr;
     }
-    return SkImageShader::Make(std::move(img), tx, ty, &localMatrix);
+    return SkImageShader::Make(std::move(img), tmx, tmy, &localMatrix);
 }
 
 void SkImageShader::flatten(SkWriteBuffer& buffer) const {
@@ -150,13 +150,13 @@
 }
 
 sk_sp<SkShader> SkImageShader::Make(sk_sp<SkImage> image,
-                                    TileMode tx, TileMode ty,
+                                    SkTileMode tmx, SkTileMode tmy,
                                     const SkMatrix* localMatrix,
                                     bool clampAsIfUnpremul) {
     if (!image) {
         return sk_make_sp<SkEmptyShader>();
     }
-    return sk_sp<SkShader>{ new SkImageShader(image, tx,ty, localMatrix, clampAsIfUnpremul) };
+    return sk_sp<SkShader>{ new SkImageShader(image, tmx, tmy, localMatrix, clampAsIfUnpremul) };
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -265,15 +265,14 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 #include "SkImagePriv.h"
 
-sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode tmx,
-                                   SkShader::TileMode tmy, const SkMatrix* localMatrix,
-                                   SkCopyPixelsMode cpm) {
+sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkTileMode tmx, SkTileMode tmy,
+                                   const SkMatrix* localMatrix, SkCopyPixelsMode cpm) {
     return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, cpm),
                                tmx, tmy, localMatrix);
 }
 
 sk_sp<SkShader> SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap& src,
-                                           SkShader::TileMode tmx, SkShader::TileMode tmy,
+                                           SkTileMode tmx, SkTileMode tmy,
                                            const SkMatrix* localMatrix, SkCopyPixelsMode mode) {
     auto s = SkMakeBitmapShader(src, tmx, tmy, localMatrix, mode);
     if (!s) {
diff --git a/src/shaders/SkImageShader.h b/src/shaders/SkImageShader.h
index 431a4b8..de45f29 100644
--- a/src/shaders/SkImageShader.h
+++ b/src/shaders/SkImageShader.h
@@ -15,8 +15,8 @@
 class SkImageShader : public SkShaderBase {
 public:
     static sk_sp<SkShader> Make(sk_sp<SkImage>,
-                                SkShader::TileMode tx,
-                                SkShader::TileMode ty,
+                                SkTileMode tmx,
+                                SkTileMode tmy,
                                 const SkMatrix* localMatrix,
                                 bool clampAsIfUnpremul = false);
 
@@ -30,8 +30,8 @@
     SK_FLATTENABLE_HOOKS(SkImageShader)
 
     SkImageShader(sk_sp<SkImage>,
-                  SkShader::TileMode tx,
-                  SkShader::TileMode ty,
+                  SkTileMode tmx,
+                  SkTileMode tmy,
                   const SkMatrix* localMatrix,
                   bool clampAsIfUnpremul);
 
diff --git a/src/shaders/SkPictureShader.cpp b/src/shaders/SkPictureShader.cpp
index ce54475..cf7dd41 100644
--- a/src/shaders/SkPictureShader.cpp
+++ b/src/shaders/SkPictureShader.cpp
@@ -28,6 +28,19 @@
 #include "SkGr.h"
 #endif
 
+sk_sp<SkShader> SkPicture::makeShader(SkTileMode tmx, SkTileMode tmy, const SkMatrix* localMatrix,
+                                      const SkRect* tile) const {
+    if (localMatrix && !localMatrix->invert(nullptr)) {
+        return nullptr;
+    }
+    return SkPictureShader::Make(sk_ref_sp(this), tmx, tmy, localMatrix, tile);
+}
+
+sk_sp<SkShader> SkPicture::makeShader(SkTileMode tmx, SkTileMode tmy,
+                                      const SkMatrix* localMatrix) const {
+    return this->makeShader(tmx, tmy, localMatrix, nullptr);
+}
+
 namespace {
 static unsigned gBitmapShaderKeyNamespaceLabel;
 
@@ -121,19 +134,22 @@
     }
 }
 
-sk_sp<SkShader> SkPictureShader::Make(sk_sp<SkPicture> picture, TileMode tmx, TileMode tmy,
+sk_sp<SkShader> SkPictureShader::Make(sk_sp<SkPicture> picture, SkTileMode tmx, SkTileMode tmy,
                                       const SkMatrix* localMatrix, const SkRect* tile) {
     if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) {
         return SkShader::MakeEmptyShader();
     }
-    return sk_sp<SkShader>(new SkPictureShader(std::move(picture), tmx, tmy, localMatrix, tile));
+    return sk_sp<SkShader>(new SkPictureShader(std::move(picture),
+                                               static_cast<TileMode>(tmx),
+                                               static_cast<TileMode>(tmy),
+                                               localMatrix, tile));
 }
 
 sk_sp<SkFlattenable> SkPictureShader::CreateProc(SkReadBuffer& buffer) {
     SkMatrix lm;
     buffer.readMatrix(&lm);
-    TileMode mx = (TileMode)buffer.read32();
-    TileMode my = (TileMode)buffer.read32();
+    auto tmx = buffer.read32LE(SkTileMode::kLastTileMode);
+    auto tmy = buffer.read32LE(SkTileMode::kLastTileMode);
     SkRect tile;
     buffer.readRect(&tile);
 
@@ -143,7 +159,7 @@
     if (didSerialize) {
         picture = SkPicturePriv::MakeFromBuffer(buffer);
     }
-    return SkPictureShader::Make(picture, mx, my, &lm, &tile);
+    return SkPictureShader::Make(picture, tmx, tmy, &lm, &tile);
 }
 
 void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/shaders/SkPictureShader.h b/src/shaders/SkPictureShader.h
index d233a0c..0c69de2 100644
--- a/src/shaders/SkPictureShader.h
+++ b/src/shaders/SkPictureShader.h
@@ -9,6 +9,7 @@
 #define SkPictureShader_DEFINED
 
 #include "SkShaderBase.h"
+#include "SkTileMode.h"
 #include <atomic>
 
 class SkArenaAlloc;
@@ -25,7 +26,7 @@
 public:
     ~SkPictureShader() override;
 
-    static sk_sp<SkShader> Make(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*,
+    static sk_sp<SkShader> Make(sk_sp<SkPicture>, SkTileMode, SkTileMode, const SkMatrix*,
                                 const SkRect*);
 
 #if SK_SUPPORT_GPU
diff --git a/src/shaders/SkShader.cpp b/src/shaders/SkShader.cpp
index 8edeafb..d2d72dc 100644
--- a/src/shaders/SkShader.cpp
+++ b/src/shaders/SkShader.cpp
@@ -140,7 +140,7 @@
 
 sk_sp<SkShader> SkShader::MakeColorShader(SkColor color) { return sk_make_sp<SkColorShader>(color); }
 
-sk_sp<SkShader> SkShader::MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
+sk_sp<SkShader> SkShader::MakeBitmapShader(const SkBitmap& src, SkTileMode tmx, SkTileMode tmy,
                                            const SkMatrix* localMatrix) {
     if (localMatrix && !localMatrix->invert(nullptr)) {
         return nullptr;
@@ -148,12 +148,12 @@
     return SkMakeBitmapShader(src, tmx, tmy, localMatrix, kIfMutable_SkCopyPixelsMode);
 }
 
+// deprecated
 sk_sp<SkShader> SkShader::MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
                                             const SkMatrix* localMatrix, const SkRect* tile) {
-    if (localMatrix && !localMatrix->invert(nullptr)) {
-        return nullptr;
-    }
-    return SkPictureShader::Make(std::move(src), tmx, tmy, localMatrix, tile);
+    return src ? src->makeShader(static_cast<SkTileMode>(tmx), static_cast<SkTileMode>(tmy),
+                                 localMatrix, tile)
+               : MakeEmptyShader();
 }
 
 bool SkShaderBase::appendStages(const SkStageRec& rec) const {
diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp
index 98c40ac..5247c54 100644
--- a/src/xps/SkXPSDevice.cpp
+++ b/src/xps/SkXPSDevice.cpp
@@ -2084,8 +2084,8 @@
         }
         matrix.mapRect(&actualDst, srcBounds);
     }
-    auto bitmapShader = SkMakeBitmapShaderForPaint(paint, bitmap, SkShader::kClamp_TileMode,
-                                                   SkShader::kClamp_TileMode, &matrix,
+    auto bitmapShader = SkMakeBitmapShaderForPaint(paint, bitmap, SkTileMode::kClamp,
+                                                   SkTileMode::kClamp, &matrix,
                                                    kNever_SkCopyPixelsMode);
     SkASSERT(bitmapShader);
     if (!bitmapShader) { return; }
diff --git a/tests/PictureShaderTest.cpp b/tests/PictureShaderTest.cpp
index 742b72d..ea2c210 100644
--- a/tests/PictureShaderTest.cpp
+++ b/tests/PictureShaderTest.cpp
@@ -56,9 +56,7 @@
 
     {
         SkPaint paint;
-        paint.setShader(SkPictureShader::Make(picture,
-                                              SkShader::kRepeat_TileMode,
-                                              SkShader::kRepeat_TileMode, nullptr, nullptr));
+        paint.setShader(picture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
         surface->getCanvas()->drawPaint(paint);
 
         // We should have about 3 refs by now: local + shader + shader cache.
@@ -68,9 +66,7 @@
     // Draw another picture shader to have a chance to purge.
     {
         SkPaint paint;
-        paint.setShader(SkPictureShader::Make(makePicture(),
-                                              SkShader::kRepeat_TileMode,
-                                              SkShader::kRepeat_TileMode, nullptr, nullptr));
+        paint.setShader(makePicture()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
         surface->getCanvas()->drawPaint(paint);
 
     }
diff --git a/tests/SVGDeviceTest.cpp b/tests/SVGDeviceTest.cpp
index 9698108..202a285 100644
--- a/tests/SVGDeviceTest.cpp
+++ b/tests/SVGDeviceTest.cpp
@@ -184,10 +184,10 @@
 #endif
 
 
-void SetImageShader(SkPaint* paint, int imageWidth, int imageHeight, SkShader::TileMode xTile,
-                    SkShader::TileMode yTile) {
+void SetImageShader(SkPaint* paint, int imageWidth, int imageHeight, SkTileMode xTile,
+                    SkTileMode yTile) {
     auto surface = SkSurface::MakeRasterN32Premul(imageWidth, imageHeight);
-    paint->setShader(SkImageShader::Make(surface->makeImageSnapshot(), xTile, yTile, nullptr));
+    paint->setShader(surface->makeImageSnapshot()->makeShader(xTile, yTile, nullptr));
 }
 
 // Attempt to find the three nodes on which we have expectations:
@@ -234,8 +234,7 @@
 }
 
 void ImageShaderTestSetup(SkDOM* dom, SkPaint* paint, int imageWidth, int imageHeight,
-                          int rectWidth, int rectHeight, SkShader::TileMode xTile,
-                          SkShader::TileMode yTile) {
+                          int rectWidth, int rectHeight, SkTileMode xTile, SkTileMode yTile) {
     SetImageShader(paint, imageWidth, imageHeight, xTile, yTile);
     auto svgCanvas = MakeDOMCanvas(dom);
 
@@ -250,7 +249,7 @@
     int imageWidth = 3, imageHeight = 3;
     int rectWidth = 10, rectHeight = 10;
     ImageShaderTestSetup(&dom, &paint, imageWidth, imageHeight, rectWidth, rectHeight,
-                         SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+                         SkTileMode::kClamp, SkTileMode::kClamp);
 
     const SkDOM::Node* root = dom.finishParsing();
 
@@ -275,7 +274,7 @@
     int imageWidth = 3, imageHeight = 3;
     int rectWidth = 10, rectHeight = 10;
     ImageShaderTestSetup(&dom, &paint, imageWidth, imageHeight, rectWidth, rectHeight,
-                         SkShader::kRepeat_TileMode, SkShader::kClamp_TileMode);
+                         SkTileMode::kRepeat, SkTileMode::kClamp);
 
     const SkDOM::Node* root = dom.finishParsing();
     const SkDOM::Node* innerSvg = dom.getFirstChild(root, "svg");
@@ -305,7 +304,7 @@
     int imageNodeWidth = 3, imageNodeHeight = 3;
     int rectNodeWidth = 10, rectNodeHeight = 10;
     ImageShaderTestSetup(&dom, &paint, imageNodeWidth, imageNodeHeight, rectNodeWidth,
-                         rectNodeHeight, SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode);
+                         rectNodeHeight, SkTileMode::kClamp, SkTileMode::kRepeat);
 
     const SkDOM::Node* root = dom.finishParsing();
     const SkDOM::Node* innerSvg = dom.getFirstChild(root, "svg");
@@ -335,7 +334,7 @@
     int imageWidth = 3, imageHeight = 3;
     int rectWidth = 10, rectHeight = 10;
     ImageShaderTestSetup(&dom, &paint, imageWidth, imageHeight, rectWidth, rectHeight,
-                         SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
+                         SkTileMode::kRepeat, SkTileMode::kRepeat);
 
     const SkDOM::Node* root = dom.finishParsing();