SkCanvas is no longer reference-counted

Change-Id: Ie821efe7c0a7d1301715e303aaf4d7ec86ac35e7
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 5e21dfc..6786a69 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -52,16 +52,20 @@
 SkiaCanvas::SkiaCanvas() {}
 
 SkiaCanvas::SkiaCanvas(SkCanvas* canvas)
-    : mCanvas(SkRef(canvas)) {}
+    : mCanvas(canvas) {}
 
 SkiaCanvas::SkiaCanvas(const SkBitmap& bitmap) {
-    mCanvas.reset(new SkCanvas(bitmap));
+    mCanvasOwned = std::unique_ptr<SkCanvas>(new SkCanvas(bitmap));
+    mCanvas = mCanvasOwned.get();
 }
 
 SkiaCanvas::~SkiaCanvas() {}
 
 void SkiaCanvas::reset(SkCanvas* skiaCanvas) {
-    mCanvas.reset(SkRef(skiaCanvas));
+    if (mCanvas != skiaCanvas) {
+        mCanvas = skiaCanvas;
+        mCanvasOwned.reset();
+    }
     mSaveStack.reset(nullptr);
     mHighContrastText = false;
 }
@@ -99,8 +103,9 @@
         mCanvas->replayClips(&copier);
     }
 
-    // unrefs the existing canvas
-    mCanvas.reset(newCanvas);
+    // deletes the previously owned canvas (if any)
+    mCanvasOwned = std::unique_ptr<SkCanvas>(newCanvas);
+    mCanvas = newCanvas;
 
     // clean up the old save stack
     mSaveStack.reset(nullptr);
@@ -307,7 +312,7 @@
     const SkMatrix saveMatrix = mCanvas->getTotalMatrix();
 
     for (auto clip = begin; clip != end; ++clip) {
-        clip->apply(mCanvas.get());
+        clip->apply(mCanvas);
     }
 
     mCanvas->setMatrix(saveMatrix);
@@ -562,7 +567,7 @@
 void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix, const SkPaint* paint) {
     SkBitmap bitmap;
     hwuiBitmap.getSkBitmap(&bitmap);
-    SkAutoCanvasRestore acr(mCanvas.get(), true);
+    SkAutoCanvasRestore acr(mCanvas, true);
     mCanvas->concat(matrix);
     mCanvas->drawBitmap(bitmap, 0, 0, paint);
 }
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index a0cdfcb..4f1d857 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -35,15 +35,15 @@
      *  Create a new SkiaCanvas.
      *
      *  @param canvas SkCanvas to handle calls made to this SkiaCanvas. Must
-     *      not be NULL. This constructor will ref() the SkCanvas, and unref()
-     *      it in its destructor.
+     *      not be NULL. This constructor does not take ownership, so the caller
+     *      must guarantee that it remains valid while the SkiaCanvas is valid.
      */
     explicit SkiaCanvas(SkCanvas* canvas);
 
     virtual ~SkiaCanvas();
 
     virtual SkCanvas* asSkCanvas() override {
-        return mCanvas.get();
+        return mCanvas;
     }
 
     virtual void resetRecording(int width, int height,
@@ -182,7 +182,9 @@
 
     class Clip;
 
-    sk_sp<SkCanvas>          mCanvas;
+    std::unique_ptr<SkCanvas> mCanvasOwned; // might own a canvas we allocated
+    SkCanvas*                 mCanvas;    // we do NOT own this canvas, it must survive us
+                                          // unless it is the same as mCanvasOwned.get()
     std::unique_ptr<SkDeque> mSaveStack; // lazily allocated, tracks partial saves.
     std::vector<Clip>        mClipStack; // tracks persistent clips.
 };
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index ae4f0f4..dd97dec 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -303,40 +303,42 @@
     static const int LAYER_HEIGHT = 200;
     class ProjectionTestCanvas : public SkCanvas {
     public:
-        ProjectionTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
+        ProjectionTestCanvas(int* drawCounter)
+            : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT)
+            , mDrawCounter(drawCounter) 
+        {}
         void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
                 const SkPaint&) override {
-            EXPECT_EQ(0, mIndex++); //part of painting the layer
+            EXPECT_EQ(0, (*mDrawCounter)++); //part of painting the layer
             EXPECT_EQ(SkRect::MakeLTRB(0, 0, LAYER_WIDTH, LAYER_HEIGHT), getBounds(this));
         }
         void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
-            EXPECT_EQ(1, mIndex++);
+            EXPECT_EQ(1, (*mDrawCounter)++);
             EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT), getBounds(this));
         }
         void onDrawOval(const SkRect&, const SkPaint&) override {
-            EXPECT_EQ(2, mIndex++);
+            EXPECT_EQ(2, (*mDrawCounter)++);
             SkMatrix expectedMatrix;
             expectedMatrix.setTranslate(100 - SCROLL_X, 100 - SCROLL_Y);
             EXPECT_EQ(expectedMatrix, getTotalMatrix());
             EXPECT_EQ(SkRect::MakeLTRB(-85, -80, 295, 300), getLocalBounds(this));
         }
-        int mIndex = 0;
+        int* mDrawCounter;
     };
 
     class ProjectionLayer : public SkSurface_Base {
     public:
-        ProjectionLayer(ProjectionTestCanvas *canvas)
+        ProjectionLayer(int* drawCounter)
             : SkSurface_Base(SkImageInfo::MakeN32Premul(LAYER_WIDTH, LAYER_HEIGHT), nullptr)
-            , mCanvas(canvas) {
+            , mDrawCounter(drawCounter) {
         }
         void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) override {
-            EXPECT_EQ(3, mCanvas->mIndex++);
+            EXPECT_EQ(3, (*mDrawCounter)++);
             EXPECT_EQ(SkRect::MakeLTRB(100 - SCROLL_X, 100 - SCROLL_Y, 300 - SCROLL_X,
-                   300 - SCROLL_Y), getBounds(mCanvas));
+                   300 - SCROLL_Y), getBounds(this->getCanvas()));
         }
         SkCanvas* onNewCanvas() override {
-            mCanvas->ref();
-            return mCanvas;
+            return new ProjectionTestCanvas(mDrawCounter);
         }
         sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override {
             return sk_sp<SkSurface>();
@@ -345,7 +347,7 @@
             return sk_sp<SkImage>();
         }
         void onCopyOnWrite(ContentChangeMode) override {}
-        ProjectionTestCanvas* mCanvas;
+        int* mDrawCounter;
     };
 
     auto receiverBackground = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
@@ -389,10 +391,10 @@
     info.observer = nullptr;
     parent->prepareTree(info);
 
-    sk_sp<ProjectionTestCanvas> canvas(new ProjectionTestCanvas());
+    int drawCounter = 0;
     //set a layer after prepareTree to avoid layer logic there
     child->animatorProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
-    sk_sp<SkSurface> surfaceLayer1(new ProjectionLayer(canvas.get()));
+    sk_sp<SkSurface> surfaceLayer1(new ProjectionLayer(&drawCounter));
     child->setLayerSurface(surfaceLayer1);
     Matrix4 windowTransform;
     windowTransform.loadTranslate(100, 100, 0);
@@ -402,11 +404,11 @@
     layerUpdateQueue.enqueueLayerWithDamage(child.get(),
             android::uirenderer::Rect(LAYER_WIDTH, LAYER_HEIGHT));
     SkiaPipeline::renderLayersImpl(layerUpdateQueue, true);
-    EXPECT_EQ(1, canvas->mIndex);  //assert index 0 is drawn on the layer
+    EXPECT_EQ(1, drawCounter);  //assert index 0 is drawn on the layer
 
-    RenderNodeDrawable drawable(parent.get(), canvas.get(), true);
-    canvas->drawDrawable(&drawable);
-    EXPECT_EQ(4, canvas->mIndex);
+    RenderNodeDrawable drawable(parent.get(), surfaceLayer1->getCanvas(), true);
+    surfaceLayer1->getCanvas()->drawDrawable(&drawable);
+    EXPECT_EQ(4, drawCounter);
 
     // clean up layer pointer, so we can safely destruct RenderNode
     child->setLayerSurface(nullptr);
@@ -479,7 +481,7 @@
     info.observer = nullptr;
     parent->prepareTree(info);
 
-    sk_sp<ProjectionChildScrollTestCanvas> canvas(new ProjectionChildScrollTestCanvas());
+    std::unique_ptr<ProjectionChildScrollTestCanvas> canvas(new ProjectionChildScrollTestCanvas());
     RenderNodeDrawable drawable(parent.get(), canvas.get(), true);
     canvas->drawDrawable(&drawable);
     EXPECT_EQ(2, canvas->mIndex);