Revert[2] "Change SkCanvas to *not* inherit from SkRefCnt"

Changes over original:
- conditionalize ownership in SkPictureRecorder
- conditionalize ownership in SkCanvasStateUtils

This reverts commit b613c266df48cf45296ecc23d1bd7098c84bb7ba.

BUG=skia:

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

Change-Id: Ib25514d6f546c69b6650b5c957403b04f7380dc2
Reviewed-on: https://skia-review.googlesource.com/4742
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 3bef299..b495520 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -1192,8 +1192,7 @@
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
 Error NullSink::draw(const Src& src, SkBitmap*, SkWStream*, SkString*) const {
-    std::unique_ptr<SkCanvas> canvas(SkCreateNullCanvas());
-    return src.draw(canvas.get());
+    return src.draw(SkMakeNullCanvas().get());
 }
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
@@ -1356,7 +1355,7 @@
     if (!err.isEmpty()) {
         return err;
     }
-    sk_sp<SkCanvas> nullCanvas(SkCreateNullCanvas());
+    std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
     UrlDataManager dataManager(SkString("data"));
     Json::Value json = debugCanvas.toJSON(
             dataManager, debugCanvas.getSize(), nullCanvas.get());
@@ -1371,10 +1370,9 @@
 Error SVGSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const {
 #if defined(SK_XML)
     std::unique_ptr<SkXMLWriter> xmlWriter(new SkXMLStreamWriter(dst));
-    sk_sp<SkCanvas> canvas(SkSVGCanvas::Create(
-        SkRect::MakeWH(SkIntToScalar(src.size().width()), SkIntToScalar(src.size().height())),
-        xmlWriter.get()));
-    return src.draw(canvas.get());
+    return src.draw(SkSVGCanvas::Make(SkRect::MakeWH(SkIntToScalar(src.size().width()),
+                                                     SkIntToScalar(src.size().height())),
+                                      xmlWriter.get()).get());
 #else
     return Error("SVG sink is disabled.");
 #endif // SK_XML
diff --git a/gm/aaclip.cpp b/gm/aaclip.cpp
index dd83b7c..683f5ff 100644
--- a/gm/aaclip.cpp
+++ b/gm/aaclip.cpp
@@ -8,6 +8,7 @@
 #include "gm.h"
 #include "SkCanvas.h"
 #include "SkPath.h"
+#include "SkMakeUnique.h"
 
 static void do_draw(SkCanvas* canvas, const SkRect& r) {
     SkPaint paint;
@@ -166,14 +167,14 @@
 
 #ifdef SK_BUILD_FOR_MAC
 
-static SkCanvas* make_canvas(const SkBitmap& bm) {
+static std::unique_ptr<SkCanvas> make_canvas(const SkBitmap& bm) {
     const SkImageInfo& info = bm.info();
     if (info.bytesPerPixel() == 4) {
-        return SkCanvas::NewRasterDirectN32(info.width(), info.height(),
-                                            (SkPMColor*)bm.getPixels(),
-                                            bm.rowBytes());
+        return SkCanvas::MakeRasterDirectN32(info.width(), info.height(),
+                                             (SkPMColor*)bm.getPixels(),
+                                             bm.rowBytes());
     } else {
-        return new SkCanvas(bm);
+        return skstd::make_unique<SkCanvas>(bm);
     }
 }
 
@@ -182,7 +183,6 @@
     SkBitmap bm;
     bm.allocPixels(info);
 
-    sk_sp<SkCanvas> newc(make_canvas(bm));
     if (info.isOpaque()) {
         bm.eraseColor(SK_ColorGREEN);
     } else {
@@ -192,7 +192,7 @@
     SkPaint paint;
     paint.setAntiAlias(true);
     paint.setColor(SK_ColorBLUE);
-    newc->drawCircle(50, 50, 49, paint);
+    make_canvas(bm)->drawCircle(50, 50, 49, paint);
     canvas->drawBitmap(bm, 10, 10);
 
     CGImageRef image = SkCreateCGImageRefWithColorspace(bm, nullptr);
diff --git a/gn/android_framework_defines.gni b/gn/android_framework_defines.gni
index 12e3b11..90fea2f 100644
--- a/gn/android_framework_defines.gni
+++ b/gn/android_framework_defines.gni
@@ -12,6 +12,7 @@
   "SK_SUPPORT_LEGACY_GRADIENT_DITHERING",
   "SK_SUPPORT_LEGACY_DRAWFILTER",
   "SK_IGNORE_GPU_DITHER",
+  "SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT",
   "SK_SUPPORT_LEGACY_CLIP_REGIONOPS",
   "SK_SUPPORT_LEGACY_SHADER_ISABITMAP",
 ]
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index ab47edd..ba8a383 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -60,7 +60,13 @@
     color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
     etc.
 */
-class SK_API SkCanvas : public SkRefCnt {
+class SK_API SkCanvas
+#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT
+: public SkRefCnt
+#else
+: SkNoncopyable
+#endif
+{
     enum PrivateSaveLayerFlags {
         kDontClipToLayer_PrivateSaveLayerFlag   = 1U << 31,
     };
@@ -100,11 +106,22 @@
      *  Note: it is valid to request a supported ImageInfo, but with zero
      *  dimensions.
      */
-    static SkCanvas* NewRasterDirect(const SkImageInfo&, void*, size_t);
+    static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo&, void*, size_t);
+
+    static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
+                                                         size_t rowBytes) {
+        return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
+    }
+
+#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT
+    static SkCanvas* NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) {
+        return MakeRasterDirect(info, pixels, rowBytes).release();
+    }
 
     static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) {
-        return NewRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
+        return MakeRasterDirectN32(width, height, pixels, rowBytes).release();
     }
+#endif
 
     /**
      *  Creates an empty canvas with no backing device/pixels, and zero
diff --git a/include/core/SkMultiPictureDraw.h b/include/core/SkMultiPictureDraw.h
index cd46a30..9995721 100644
--- a/include/core/SkMultiPictureDraw.h
+++ b/include/core/SkMultiPictureDraw.h
@@ -57,7 +57,7 @@
 
 private:
     struct DrawData {
-        SkCanvas*        fCanvas;  // reffed
+        SkCanvas*        fCanvas;
         const SkPicture* fPicture; // reffed
         SkMatrix         fMatrix;
         SkPaint*         fPaint;   // owned
diff --git a/include/core/SkPictureRecorder.h b/include/core/SkPictureRecorder.h
index 59e8f14..7bf081d 100644
--- a/include/core/SkPictureRecorder.h
+++ b/include/core/SkPictureRecorder.h
@@ -111,13 +111,17 @@
     friend class SkPictureRecorderReplayTester; // for unit testing
     void partialReplay(SkCanvas* canvas) const;
 
-    bool                   fActivelyRecording;
-    uint32_t               fFlags;
-    SkRect                 fCullRect;
-    sk_sp<SkBBoxHierarchy> fBBH;
-    sk_sp<SkRecorder>      fRecorder;
-    sk_sp<SkRecord>        fRecord;
-    SkMiniRecorder         fMiniRecorder;
+    bool                        fActivelyRecording;
+    uint32_t                    fFlags;
+    SkRect                      fCullRect;
+    sk_sp<SkBBoxHierarchy>      fBBH;
+#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT
+    sk_sp<SkRecorder> fRecorder;
+#else
+    std::unique_ptr<SkRecorder> fRecorder;
+#endif
+    sk_sp<SkRecord>             fRecord;
+    SkMiniRecorder              fMiniRecorder;
 
     typedef SkNoncopyable INHERITED;
 };
diff --git a/include/svg/SkSVGCanvas.h b/include/svg/SkSVGCanvas.h
index e285faa..b72f273 100644
--- a/include/svg/SkSVGCanvas.h
+++ b/include/svg/SkSVGCanvas.h
@@ -25,7 +25,13 @@
      *  The 'bounds' parameter defines an initial SVG viewport (viewBox attribute on the root
      *  SVG element).
      */
-    static SkCanvas* Create(const SkRect& bounds, SkXMLWriter*);
+    static std::unique_ptr<SkCanvas> Make(const SkRect& bounds, SkXMLWriter*);
+
+#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT
+    static SkCanvas* Create(const SkRect& bounds, SkXMLWriter* writer) {
+        return Make(bounds, writer).release();
+    }
+#endif
 };
 
 #endif
diff --git a/include/utils/SkCanvasStateUtils.h b/include/utils/SkCanvasStateUtils.h
index 3071c75..fbc3a6f 100644
--- a/include/utils/SkCanvasStateUtils.h
+++ b/include/utils/SkCanvasStateUtils.h
@@ -62,7 +62,12 @@
      *         identical to the captured canvas. The caller is responsible for
      *         calling unref on the SkCanvas.
      */
-    static SkCanvas* CreateFromCanvasState(const SkCanvasState* state);
+    static std::unique_ptr<SkCanvas> MakeFromCanvasState(const SkCanvasState* state);
+#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT
+    static SkCanvas* CreateFromCanvasState(const SkCanvasState* state) {
+        return MakeFromCanvasState(state).release();
+    }
+#endif
 
     /**
      * Free the memory associated with the captured canvas state.  The state
diff --git a/include/utils/SkNullCanvas.h b/include/utils/SkNullCanvas.h
index 99a26da..884b68b 100644
--- a/include/utils/SkNullCanvas.h
+++ b/include/utils/SkNullCanvas.h
@@ -15,6 +15,12 @@
 /**
  * Creates a canvas that draws nothing. This is useful for performance testing.
  */
-SK_API SkCanvas* SkCreateNullCanvas();
+SK_API std::unique_ptr<SkCanvas> SkMakeNullCanvas();
+
+#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT
+static inline SkCanvas* SkCreateNullCanvas() {
+    return SkMakeNullCanvas().release();
+}
+#endif
 
 #endif
diff --git a/public.bzl b/public.bzl
index de3d6f2..734aaaf 100644
--- a/public.bzl
+++ b/public.bzl
@@ -600,6 +600,7 @@
     "GOOGLE3",
     # Staging flags for API changes
     "SK_SUPPORT_LEGACY_ACCESSBITMAP",
+    "SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT",
     "SK_SUPPORT_LEGACY_CLIP_REGIONOPS",
 ]
 
diff --git a/samplecode/SamplePathFuzz.cpp b/samplecode/SamplePathFuzz.cpp
index 05eb76f..b66b881 100644
--- a/samplecode/SamplePathFuzz.cpp
+++ b/samplecode/SamplePathFuzz.cpp
@@ -629,8 +629,8 @@
         const SkPath& path = fuzzPath.getPath();
         const SkPaint& paint = fuzzPath.getPaint();
         const SkImageInfo& info = bitmap->info();
-        SkCanvas* canvas(
-            SkCanvas::NewRasterDirect(info, bitmap->getPixels(), bitmap->rowBytes()));
+        std::unique_ptr<SkCanvas> canvas(
+            SkCanvas::MakeRasterDirect(info, bitmap->getPixels(), bitmap->rowBytes()));
         int w = info.width() / 4;
         int h = info.height() / 4;
         int x = localSeed / 4 % 4;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index cd4dcbc..a8d73a9 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -19,6 +19,7 @@
 #include "SkImageFilter.h"
 #include "SkImageFilterCache.h"
 #include "SkLatticeIter.h"
+#include "SkMakeUnique.h"
 #include "SkMatrixUtils.h"
 #include "SkMetaData.h"
 #include "SkNx.h"
@@ -3323,7 +3324,8 @@
     return true;
 }
 
-SkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) {
+std::unique_ptr<SkCanvas> SkCanvas::MakeRasterDirect(const SkImageInfo& info, void* pixels,
+                                                     size_t rowBytes) {
     if (!supported_for_raster_canvas(info)) {
         return nullptr;
     }
@@ -3332,7 +3334,7 @@
     if (!bitmap.installPixels(info, pixels, rowBytes)) {
         return nullptr;
     }
-    return new SkCanvas(bitmap);
+    return skstd::make_unique<SkCanvas>(bitmap);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkConfig8888.cpp b/src/core/SkConfig8888.cpp
index 639a444..fd945cf 100644
--- a/src/core/SkConfig8888.cpp
+++ b/src/core/SkConfig8888.cpp
@@ -354,8 +354,8 @@
         if (!bm.installPixels(srcInfo, const_cast<void*>(srcPixels), srcRB, ctable, nullptr, nullptr)) {
             return false;
         }
-        sk_sp<SkCanvas> canvas(SkCanvas::NewRasterDirect(dstInfo, dstPixels, dstRB));
-        if (nullptr == canvas.get()) {
+        std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(dstInfo, dstPixels, dstRB);
+        if (!canvas) {
             return false;
         }
 
diff --git a/src/core/SkMultiPictureDraw.cpp b/src/core/SkMultiPictureDraw.cpp
index b3c6368..1df27ff 100644
--- a/src/core/SkMultiPictureDraw.cpp
+++ b/src/core/SkMultiPictureDraw.cpp
@@ -18,7 +18,7 @@
 void SkMultiPictureDraw::DrawData::init(SkCanvas* canvas, const SkPicture* picture,
                                         const SkMatrix* matrix, const SkPaint* paint) {
     fPicture = SkRef(picture);
-    fCanvas = SkRef(canvas);
+    fCanvas = canvas;
     if (matrix) {
         fMatrix = *matrix;
     } else {
@@ -34,7 +34,6 @@
 void SkMultiPictureDraw::DrawData::Reset(SkTDArray<DrawData>& data) {
     for (int i = 0; i < data.count(); ++i) {
         data[i].fPicture->unref();
-        data[i].fCanvas->unref();
         delete data[i].fPaint;
     }
     data.rewind();
diff --git a/src/core/SkSpecialSurface.cpp b/src/core/SkSpecialSurface.cpp
index beba915..b490421 100644
--- a/src/core/SkSpecialSurface.cpp
+++ b/src/core/SkSpecialSurface.cpp
@@ -29,7 +29,7 @@
     virtual sk_sp<SkSpecialImage> onMakeImageSnapshot() = 0;
 
 protected:
-    sk_sp<SkCanvas> fCanvas;   // initialized by derived classes in ctors
+    std::unique_ptr<SkCanvas> fCanvas;   // initialized by derived classes in ctors
 
 private:
     typedef SkSpecialSurface INHERITED;
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 38bab9e..3d6670f 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -58,14 +58,12 @@
 SkSurface_Base::SkSurface_Base(int width, int height, const SkSurfaceProps* props)
     : INHERITED(width, height, props)
 {
-    fCachedCanvas = nullptr;
     fCachedImage = nullptr;
 }
 
 SkSurface_Base::SkSurface_Base(const SkImageInfo& info, const SkSurfaceProps* props)
     : INHERITED(info, props)
 {
-    fCachedCanvas = nullptr;
     fCachedImage = nullptr;
 }
 
@@ -76,7 +74,6 @@
     }
 
     SkSafeUnref(fCachedImage);
-    SkSafeUnref(fCachedCanvas);
 }
 
 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h
index 8351bb8..a8c1d8f 100644
--- a/src/image/SkSurface_Base.h
+++ b/src/image/SkSurface_Base.h
@@ -89,8 +89,8 @@
     uint32_t newGenerationID();
 
 private:
-    SkCanvas*   fCachedCanvas;
-    SkImage*    fCachedImage;
+    std::unique_ptr<SkCanvas>   fCachedCanvas;
+    SkImage*                    fCachedImage;
 
     void aboutToDraw(ContentChangeMode mode);
 
@@ -106,12 +106,12 @@
 
 SkCanvas* SkSurface_Base::getCachedCanvas() {
     if (nullptr == fCachedCanvas) {
-        fCachedCanvas = this->onNewCanvas();
+        fCachedCanvas = std::unique_ptr<SkCanvas>(this->onNewCanvas());
         if (fCachedCanvas) {
             fCachedCanvas->setSurfaceBase(this);
         }
     }
-    return fCachedCanvas;
+    return fCachedCanvas.get();
 }
 
 sk_sp<SkImage> SkSurface_Base::refCachedImage(SkBudgeted budgeted, ForceUnique unique) {
diff --git a/src/pdf/SkPDFDocument.cpp b/src/pdf/SkPDFDocument.cpp
index ab5f465..92e82fc 100644
--- a/src/pdf/SkPDFDocument.cpp
+++ b/src/pdf/SkPDFDocument.cpp
@@ -217,7 +217,7 @@
             SkScalarRoundToInt(width), SkScalarRoundToInt(height));
     fPageDevice.reset(
             SkPDFDevice::Create(pageSize, fRasterDpi, this));
-    fCanvas = sk_make_sp<SkPDFCanvas>(fPageDevice);
+    fCanvas.reset(new SkPDFCanvas(fPageDevice));
     fCanvas->clipRect(trimBox);
     fCanvas->translate(trimBox.x(), trimBox.y());
     return fCanvas.get();
diff --git a/src/pdf/SkPDFDocument.h b/src/pdf/SkPDFDocument.h
index b62a7a5..15e1479 100644
--- a/src/pdf/SkPDFDocument.h
+++ b/src/pdf/SkPDFDocument.h
@@ -76,7 +76,7 @@
     SkTHashSet<SkPDFFont*> fFonts;
     sk_sp<SkPDFDict> fDests;
     sk_sp<SkPDFDevice> fPageDevice;
-    sk_sp<SkCanvas> fCanvas;
+    std::unique_ptr<SkCanvas> fCanvas;
     sk_sp<SkPDFObject> fID;
     sk_sp<SkPDFObject> fXMP;
     SkScalar fRasterDpi;
diff --git a/src/svg/SkSVGCanvas.cpp b/src/svg/SkSVGCanvas.cpp
index d3511c0..95a4625 100644
--- a/src/svg/SkSVGCanvas.cpp
+++ b/src/svg/SkSVGCanvas.cpp
@@ -7,11 +7,12 @@
 
 #include "SkSVGCanvas.h"
 #include "SkSVGDevice.h"
+#include "SkMakeUnique.h"
 
-SkCanvas* SkSVGCanvas::Create(const SkRect& bounds, SkXMLWriter* writer) {
+std::unique_ptr<SkCanvas> SkSVGCanvas::Make(const SkRect& bounds, SkXMLWriter* writer) {
     // TODO: pass full bounds to the device
     SkISize size = bounds.roundOut().size();
     sk_sp<SkBaseDevice> device(SkSVGDevice::Create(size, writer));
 
-    return new SkCanvas(device.get());
+    return skstd::make_unique<SkCanvas>(device.get());
 }
diff --git a/src/utils/SkCanvasStateUtils.cpp b/src/utils/SkCanvasStateUtils.cpp
index 062dc13..6ee1c33 100644
--- a/src/utils/SkCanvasStateUtils.cpp
+++ b/src/utils/SkCanvasStateUtils.cpp
@@ -100,14 +100,16 @@
 public:
     static const int32_t kVersion = 1;
 
-    SkCanvasState_v1(SkCanvas* canvas)
-    : INHERITED(kVersion, canvas)
-    {
+    SkCanvasState_v1(SkCanvas* canvas) : INHERITED(kVersion, canvas) {
         layerCount = 0;
         layers = nullptr;
         mcState.clipRectCount = 0;
         mcState.clipRects = nullptr;
+#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT
         originalCanvas = SkRef(canvas);
+#else
+        originalCanvas = canvas;
+#endif
     }
 
     ~SkCanvasState_v1() {
@@ -119,9 +121,9 @@
         sk_free(mcState.clipRects);
         sk_free(layers);
 
-        // it is now safe to free the canvas since there should be no remaining
-        // references to the content that is referenced by this canvas (e.g. pixels)
+#ifdef SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT
         originalCanvas->unref();
+#endif
     }
 
     SkMCState mcState;
@@ -284,7 +286,8 @@
     canvas->clipRegion(clip, SkCanvas::kReplace_Op);
 }
 
-static SkCanvas* create_canvas_from_canvas_layer(const SkCanvasLayerState& layerState) {
+static std::unique_ptr<SkCanvas>
+make_canvas_from_canvas_layer(const SkCanvasLayerState& layerState) {
     SkASSERT(kRaster_CanvasBackend == layerState.type);
 
     SkBitmap bitmap;
@@ -304,15 +307,15 @@
     SkASSERT(!bitmap.empty());
     SkASSERT(!bitmap.isNull());
 
-    sk_sp<SkCanvas> canvas(new SkCanvas(bitmap));
+    std::unique_ptr<SkCanvas> canvas(new SkCanvas(bitmap));
 
     // setup the matrix and clip
     setup_canvas_from_MC_state(layerState.mcState, canvas.get());
 
-    return canvas.release();
+    return canvas;
 }
 
-SkCanvas* SkCanvasStateUtils::CreateFromCanvasState(const SkCanvasState* state) {
+std::unique_ptr<SkCanvas> SkCanvasStateUtils::MakeFromCanvasState(const SkCanvasState* state) {
     SkASSERT(state);
     // Currently there is only one possible version.
     SkASSERT(SkCanvasState_v1::kVersion == state->version);
@@ -323,14 +326,14 @@
         return nullptr;
     }
 
-    sk_sp<SkCanvasStack> canvas(new SkCanvasStack(state->width, state->height));
+    std::unique_ptr<SkCanvasStack> canvas(new SkCanvasStack(state->width, state->height));
 
     // setup the matrix and clip on the n-way canvas
     setup_canvas_from_MC_state(state_v1->mcState, canvas.get());
 
     // Iterate over the layers and add them to the n-way canvas
     for (int i = state_v1->layerCount - 1; i >= 0; --i) {
-        sk_sp<SkCanvas> canvasLayer(create_canvas_from_canvas_layer(state_v1->layers[i]));
+        std::unique_ptr<SkCanvas> canvasLayer = make_canvas_from_canvas_layer(state_v1->layers[i]);
         if (!canvasLayer.get()) {
             return nullptr;
         }
@@ -338,7 +341,7 @@
                                                              state_v1->layers[i].y));
     }
 
-    return canvas.release();
+    return std::move(canvas);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp
index a223456..27127df 100644
--- a/src/utils/SkLua.cpp
+++ b/src/utils/SkLua.cpp
@@ -73,6 +73,13 @@
     lua_setmetatable(L, -2);
 }
 
+template <typename T> T* push_ptr(lua_State* L, T* ptr) {
+    *(T**)lua_newuserdata(L, sizeof(T*)) = ptr;
+    luaL_getmetatable(L, get_mtname<T>());
+    lua_setmetatable(L, -2);
+    return ptr;
+}
+
 template <typename T> T* push_ref(lua_State* L, T* ref) {
     *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
     luaL_getmetatable(L, get_mtname<T>());
@@ -333,7 +340,7 @@
 }
 
 void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
-    push_ref(fL, canvas);
+    push_ptr(fL, canvas);
     CHECK_SETFIELD(key);
 }
 
@@ -715,7 +722,7 @@
 }
 
 static int lcanvas_gc(lua_State* L) {
-    get_ref<SkCanvas>(L, 1)->unref();
+    // don't know how to track a ptr...
     return 0;
 }
 
@@ -757,7 +764,7 @@
 
 static int ldocument_beginPage(lua_State* L) {
     const SkRect* contentPtr = nullptr;
-    push_ref(L, get_ref<SkDocument>(L, 1)->beginPage(lua2scalar(L, 2),
+    push_ptr(L, get_ref<SkDocument>(L, 1)->beginPage(lua2scalar(L, 2),
                                                      lua2scalar(L, 3),
                                                      contentPtr));
     return 1;
@@ -1750,7 +1757,7 @@
     if (nullptr == canvas) {
         lua_pushnil(L);
     } else {
-        push_ref(L, canvas);
+        push_ptr(L, canvas);
         // note: we don't unref canvas, since getCanvas did not ref it.
         // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
         // the real owner (the surface) go away, but still hold onto the canvas?
@@ -1814,7 +1821,7 @@
         return 1;
     }
 
-    push_ref(L, canvas);
+    push_ptr(L, canvas);
     return 1;
 }
 
@@ -1824,7 +1831,7 @@
         lua_pushnil(L);
         return 1;
     }
-    push_ref(L, canvas);
+    push_ptr(L, canvas);
     return 1;
 }
 
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index b2d71d2..a910284 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -15,7 +15,6 @@
 
 void SkNWayCanvas::addCanvas(SkCanvas* canvas) {
     if (canvas) {
-        canvas->ref();
         *fList.append() = canvas;
     }
 }
@@ -23,13 +22,11 @@
 void SkNWayCanvas::removeCanvas(SkCanvas* canvas) {
     int index = fList.find(canvas);
     if (index >= 0) {
-        canvas->unref();
         fList.removeShuffle(index);
     }
 }
 
 void SkNWayCanvas::removeAll() {
-    fList.unrefAll();
     fList.reset();
 }
 
diff --git a/src/utils/SkNullCanvas.cpp b/src/utils/SkNullCanvas.cpp
index b5ee8d3..1f28706 100644
--- a/src/utils/SkNullCanvas.cpp
+++ b/src/utils/SkNullCanvas.cpp
@@ -9,10 +9,10 @@
 
 #include "SkCanvas.h"
 #include "SkNWayCanvas.h"
+#include "SkMakeUnique.h"
 
-
-SkCanvas* SkCreateNullCanvas() {
+std::unique_ptr<SkCanvas> SkMakeNullCanvas() {
     // An N-Way canvas forwards calls to N canvas's. When N == 0 it's
     // effectively a null canvas.
-    return new SkNWayCanvas(0, 0);
+    return std::unique_ptr<SkCanvas>(new SkNWayCanvas(0, 0));
 }
diff --git a/src/xps/SkDocument_XPS.cpp b/src/xps/SkDocument_XPS.cpp
index e333b5a..d05764a 100644
--- a/src/xps/SkDocument_XPS.cpp
+++ b/src/xps/SkDocument_XPS.cpp
@@ -58,7 +58,7 @@
 
 private:
     SkXPSDevice fDevice;
-    sk_sp<SkCanvas> fCanvas;
+    std::unique_ptr<SkCanvas> fCanvas;
     SkVector fUnitsPerMeter;
     SkVector fPixelsPerMeter;
 };
diff --git a/tests/CanvasStateHelpers.cpp b/tests/CanvasStateHelpers.cpp
index 801eaea..98b5d23 100644
--- a/tests/CanvasStateHelpers.cpp
+++ b/tests/CanvasStateHelpers.cpp
@@ -27,12 +27,11 @@
 
 extern "C" bool complex_layers_draw_from_canvas_state(SkCanvasState* state,
         float left, float top, float right, float bottom, int32_t spacer) {
-    SkCanvas* canvas = SkCanvasStateUtils::CreateFromCanvasState(state);
+    std::unique_ptr<SkCanvas> canvas = SkCanvasStateUtils::MakeFromCanvasState(state);
     if (!canvas) {
         return false;
     }
-    complex_layers_draw(canvas, left, top, right, bottom, spacer);
-    canvas->unref();
+    complex_layers_draw(canvas.get(), left, top, right, bottom, spacer);
     return true;
 }
 
@@ -52,7 +51,7 @@
 extern "C" bool complex_clips_draw_from_canvas_state(SkCanvasState* state,
         int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t clipOp,
         int32_t regionRects, int32_t* rectCoords) {
-    SkCanvas* canvas = SkCanvasStateUtils::CreateFromCanvasState(state);
+    std::unique_ptr<SkCanvas> canvas = SkCanvasStateUtils::MakeFromCanvasState(state);
     if (!canvas) {
         return false;
     }
@@ -64,8 +63,7 @@
         rectCoords += 4;
     }
 
-    complex_clips_draw(canvas, left, top, right, bottom, clipOp, localRegion);
-    canvas->unref();
+    complex_clips_draw(canvas.get(), left, top, right, bottom, clipOp, localRegion);
     return true;
 }
 #endif // SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
diff --git a/tests/CanvasStateTest.cpp b/tests/CanvasStateTest.cpp
index 890e85d..2c7c590 100644
--- a/tests/CanvasStateTest.cpp
+++ b/tests/CanvasStateTest.cpp
@@ -278,13 +278,12 @@
 
     SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(&canvas);
     REPORTER_ASSERT(reporter, state);
-    SkCanvas* tmpCanvas = SkCanvasStateUtils::CreateFromCanvasState(state);
+    std::unique_ptr<SkCanvas> tmpCanvas = SkCanvasStateUtils::MakeFromCanvasState(state);
     REPORTER_ASSERT(reporter, tmpCanvas);
 
     REPORTER_ASSERT(reporter, canvas.getDrawFilter());
     REPORTER_ASSERT(reporter, nullptr == tmpCanvas->getDrawFilter());
 
-    tmpCanvas->unref();
     SkCanvasStateUtils::ReleaseCanvasState(state);
 }
 
diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp
index c062e6c..3f418db 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -542,7 +542,7 @@
     SkPMColor* baseAddr = storage.get();
     sk_bzero(baseAddr, size);
 
-    SkCanvas* canvas = SkCanvas::NewRasterDirect(info, baseAddr, minRowBytes);
+    std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, baseAddr, minRowBytes);
     REPORTER_ASSERT(reporter, canvas);
 
     SkPixmap pmap;
@@ -556,25 +556,23 @@
         }
         addr = (const SkPMColor*)((const char*)addr + pmap.rowBytes());
     }
-    delete canvas;
 
     // now try a deliberately bad info
     info = info.makeWH(-1, info.height());
-    REPORTER_ASSERT(reporter, nullptr == SkCanvas::NewRasterDirect(info, baseAddr, minRowBytes));
+    REPORTER_ASSERT(reporter, nullptr == SkCanvas::MakeRasterDirect(info, baseAddr, minRowBytes));
 
     // too big
     info = info.makeWH(1 << 30, 1 << 30);
-    REPORTER_ASSERT(reporter, nullptr == SkCanvas::NewRasterDirect(info, baseAddr, minRowBytes));
+    REPORTER_ASSERT(reporter, nullptr == SkCanvas::MakeRasterDirect(info, baseAddr, minRowBytes));
 
     // not a valid pixel type
     info = SkImageInfo::Make(10, 10, kUnknown_SkColorType, info.alphaType());
-    REPORTER_ASSERT(reporter, nullptr == SkCanvas::NewRasterDirect(info, baseAddr, minRowBytes));
+    REPORTER_ASSERT(reporter, nullptr == SkCanvas::MakeRasterDirect(info, baseAddr, minRowBytes));
 
     // We should succeed with a zero-sized valid info
     info = SkImageInfo::MakeN32Premul(0, 0);
-    canvas = SkCanvas::NewRasterDirect(info, baseAddr, minRowBytes);
+    canvas = SkCanvas::MakeRasterDirect(info, baseAddr, minRowBytes);
     REPORTER_ASSERT(reporter, canvas);
-    delete canvas;
 }
 
 DEF_TEST(Canvas, reporter) {
diff --git a/tests/PipeTest.cpp b/tests/PipeTest.cpp
index 3b89441..e5d2f09 100644
--- a/tests/PipeTest.cpp
+++ b/tests/PipeTest.cpp
@@ -18,7 +18,7 @@
 #include "SkPictureRecorder.h"
 
 static void drain(SkPipeDeserializer* deserial, SkDynamicMemoryWStream* stream) {
-    std::unique_ptr<SkCanvas> canvas(SkCreateNullCanvas());
+    std::unique_ptr<SkCanvas> canvas = SkMakeNullCanvas();
     sk_sp<SkData> data = stream->detachAsData();
     deserial->playback(data->data(), data->size(), canvas.get());
 }
diff --git a/tests/SVGDeviceTest.cpp b/tests/SVGDeviceTest.cpp
index b010e57..715dbc7 100644
--- a/tests/SVGDeviceTest.cpp
+++ b/tests/SVGDeviceTest.cpp
@@ -91,7 +91,7 @@
 
     {
         SkXMLParserWriter writer(dom.beginParsing());
-        sk_sp<SkCanvas> svgCanvas(SkSVGCanvas::Create(SkRect::MakeWH(100, 100), &writer));
+        std::unique_ptr<SkCanvas> svgCanvas = SkSVGCanvas::Make(SkRect::MakeWH(100, 100), &writer);
         svgCanvas->drawText(txt, len, offset.x(), offset.y(), paint);
     }
     check_text_node(reporter, dom, dom.finishParsing(), offset, 0, expected);
@@ -103,7 +103,7 @@
         }
 
         SkXMLParserWriter writer(dom.beginParsing());
-        sk_sp<SkCanvas> svgCanvas(SkSVGCanvas::Create(SkRect::MakeWH(100, 100), &writer));
+        std::unique_ptr<SkCanvas> svgCanvas = SkSVGCanvas::Make(SkRect::MakeWH(100, 100), &writer);
         svgCanvas->drawPosTextH(txt, len, xpos, offset.y(), paint);
     }
     check_text_node(reporter, dom, dom.finishParsing(), offset, 1, expected);
@@ -115,7 +115,7 @@
         }
 
         SkXMLParserWriter writer(dom.beginParsing());
-        sk_sp<SkCanvas> svgCanvas(SkSVGCanvas::Create(SkRect::MakeWH(100, 100), &writer));
+        std::unique_ptr<SkCanvas> svgCanvas = SkSVGCanvas::Make(SkRect::MakeWH(100, 100), &writer);
         svgCanvas->drawPosText(txt, len, pos, paint);
     }
     check_text_node(reporter, dom, dom.finishParsing(), offset, 2, expected);
diff --git a/tools/lua/lua_pictures.cpp b/tools/lua/lua_pictures.cpp
index 68a610e..fd44901 100644
--- a/tools/lua/lua_pictures.cpp
+++ b/tools/lua/lua_pictures.cpp
@@ -145,7 +145,7 @@
 
             auto pic(load_picture(path));
             if (pic.get()) {
-                sk_sp<SkLuaCanvas> canvas(
+                std::unique_ptr<SkLuaCanvas> canvas(
                                     new SkLuaCanvas(SkScalarCeilToInt(pic->cullRect().width()),
                                                     SkScalarCeilToInt(pic->cullRect().height()),
                                                     L.get(), gAccumulateFunc));
diff --git a/tools/skiaserve/Request.h b/tools/skiaserve/Request.h
index 6b065a2..4058d7c 100644
--- a/tools/skiaserve/Request.h
+++ b/tools/skiaserve/Request.h
@@ -63,7 +63,7 @@
     SkColor getPixel(int x, int y);
 
     UploadContext* fUploadContext;
-    sk_sp<SkDebugCanvas> fDebugCanvas;
+    std::unique_ptr<SkDebugCanvas> fDebugCanvas;
     UrlDataManager fUrlDataManager;
 
 private:
diff --git a/tools/skp_parser.cpp b/tools/skp_parser.cpp
index d242524..887c50d 100644
--- a/tools/skp_parser.cpp
+++ b/tools/skp_parser.cpp
@@ -34,7 +34,7 @@
     SkISize size = pic->cullRect().roundOut().size();
     SkDebugCanvas debugCanvas(size.width(), size.height());
     pic->playback(&debugCanvas);
-    sk_sp<SkCanvas> nullCanvas(SkCreateNullCanvas());
+    std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
     UrlDataManager dataManager(SkString("data"));
     Json::Value json = debugCanvas.toJSON(
             dataManager, debugCanvas.getSize(), nullCanvas.get());