Pass Bitmap instead of SkBitmap in canvas.drawBitmap(Bitmap, float,float,Paint)
Test: refactoring cl.
bug:32216791

Change-Id: If9f9fbc19e683b14cce6c3c268258bd832d495d2
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index a4c1d1b..2730ed9 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -21,6 +21,7 @@
 #include "RenderNode.h"
 #include "VectorDrawable.h"
 #include "hwui/MinikinUtils.h"
+#include "hwui/Bitmap.h"
 
 namespace android {
 namespace uirenderer {
@@ -468,10 +469,12 @@
 }
 
 // Bitmap-based
-void RecordingCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) {
+void RecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
+    SkBitmap skBitmap;
+    bitmap.getSkBitmap(&skBitmap);
     save(SaveFlags::Matrix);
     translate(left, top);
-    drawBitmap(&bitmap, paint);
+    drawBitmap(&skBitmap, paint);
     restore();
 }
 
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 627a1af..c5ed61c 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -176,7 +176,7 @@
     virtual void drawVectorDrawable(VectorDrawableRoot* tree) override;
 
     // Bitmap-based
-    virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) override;
+    virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
     virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
                             const SkPaint* paint) override;
     virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 7b2fda1..c99219f 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -18,6 +18,7 @@
 
 #include "CanvasProperty.h"
 #include "VectorDrawable.h"
+#include "hwui/Bitmap.h"
 #include "hwui/MinikinUtils.h"
 
 #include <SkDrawable.h>
@@ -490,8 +491,10 @@
 // Canvas draw operations: Bitmaps
 // ----------------------------------------------------------------------------
 
-void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) {
-    mCanvas->drawBitmap(bitmap, left, top, paint);
+void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
+    SkBitmap skBitmap;
+    bitmap.getSkBitmap(&skBitmap);
+    mCanvas->drawBitmap(skBitmap, left, top, paint);
 }
 
 void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) {
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 017af2a..9c4d7c4 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -124,8 +124,7 @@
             const float* verts, const float* tex, const int* colors,
             const uint16_t* indices, int indexCount, const SkPaint& paint) override;
 
-    virtual void drawBitmap(const SkBitmap& bitmap, float left, float top,
-            const SkPaint* paint) override;
+    virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
     virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
             const SkPaint* paint) override;
     virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index fded604..6620458 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -16,6 +16,8 @@
 
 #include "SkiaCanvasProxy.h"
 
+#include "hwui/Bitmap.h"
+
 #include <cutils/log.h>
 #include <SkPatchUtils.h>
 #include <SkPaint.h>
@@ -122,7 +124,8 @@
                             top + bitmap.dimensions().height(),
                             paint);
     } else {
-        mCanvas->drawBitmap(bitmap, left, top, paint);
+        auto hwuiBitmap= Bitmap::createFrom(bitmap.info(), *pxRef);
+        mCanvas->drawBitmap(*hwuiBitmap, left, top, paint);
     }
 }
 
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index f2fce18..341ece3 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -101,6 +101,19 @@
     return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, ctable));
 }
 
+void FreePixelRef(void* addr, void* context) {
+    auto pixelRef = (SkPixelRef*) context;
+    pixelRef->unlockPixels();
+    pixelRef->unref();
+}
+
+sk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef) {
+    pixelRef.ref();
+    pixelRef.lockPixels();
+    return sk_sp<Bitmap>(new Bitmap((void*) pixelRef.pixels(), (void*) &pixelRef, FreePixelRef,
+            info, pixelRef.rowBytes(), pixelRef.colorTable()));
+}
+
 void Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
     if (kIndex_8_SkColorType != newInfo.colorType()) {
         ctable = nullptr;
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 047f9f5..2a5d00b 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -41,6 +41,7 @@
     static sk_sp<Bitmap> allocateAshmemBitmap(size_t allocSize, const SkImageInfo& info,
         size_t rowBytes, SkColorTable* ctable);
 
+    static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
     Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes,
             SkColorTable* ctable);
     Bitmap(void* address, void* context, FreeFunc freeFunc,
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 84eced8..8d08608 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -65,6 +65,7 @@
 };
 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
 
+class Bitmap;
 class Paint;
 struct Typeface;
 
@@ -217,7 +218,7 @@
                               const uint16_t* indices, int indexCount, const SkPaint& paint) = 0;
 
     // Bitmap-based
-    virtual void drawBitmap(const SkBitmap& bitmap, float left, float top,
+    virtual void drawBitmap(Bitmap& bitmap, float left, float top,
             const SkPaint* paint) = 0;
     virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
             const SkPaint* paint) = 0;
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 4708547..cdfa2f4 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -122,6 +122,19 @@
         return snapshot;
     }
 
+    static sk_sp<Bitmap> createBitmap(int width, int height,
+            SkColorType colorType = kN32_SkColorType) {
+        SkImageInfo info = SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType);
+        size_t size = height * info.minRowBytes();
+        return Bitmap::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr);
+    }
+
+    static sk_sp<Bitmap> createBitmap(int width, int height, SkBitmap* outBitmap) {
+        SkImageInfo info = SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType);
+        outBitmap->setInfo(info);
+        return Bitmap::allocateHeapBitmap(outBitmap, nullptr);
+    }
+
     static SkBitmap createSkBitmap(int width, int height,
             SkColorType colorType = kN32_SkColorType) {
         SkBitmap bitmap;
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index 24c3b23..c1144be 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -29,10 +29,11 @@
 });
 
 class ListViewAnimation : public TestListViewSceneBase {
-    SkBitmap createRandomCharIcon(int cardHeight) {
+    sk_sp<Bitmap> createRandomCharIcon(int cardHeight) {
+        SkBitmap skBitmap;
         int size = cardHeight - (dp(10) * 2);
-        SkBitmap bitmap = TestUtils::createSkBitmap(size, size);
-        SkCanvas canvas(bitmap);
+        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(size, size, &skBitmap));
+        SkCanvas canvas(skBitmap);
         canvas.clear(0);
 
         SkPaint paint;
@@ -54,11 +55,12 @@
         return bitmap;
     }
 
-    static SkBitmap createBoxBitmap(bool filled) {
+    static sk_sp<Bitmap> createBoxBitmap(bool filled) {
         int size = dp(20);
         int stroke = dp(2);
-        SkBitmap bitmap = TestUtils::createSkBitmap(size, size);
-        SkCanvas canvas(bitmap);
+        SkBitmap skBitmap;
+        auto bitmap = TestUtils::createBitmap(size, size, &skBitmap);
+        SkCanvas canvas(skBitmap);
         canvas.clear(Color::Transparent);
 
         SkPaint paint;
@@ -72,8 +74,8 @@
 
     void createListItem(RenderProperties& props, Canvas& canvas, int cardId,
             int itemWidth, int itemHeight) override {
-        static SkBitmap filledBox = createBoxBitmap(true);
-        static SkBitmap strokedBox = createBoxBitmap(false);
+        static sk_sp<Bitmap> filledBox(createBoxBitmap(true));
+        static sk_sp<Bitmap> strokedBox(createBoxBitmap(false));
         // TODO: switch to using round rect clipping, once merging correctly handles that
         SkPaint roundRectPaint;
         roundRectPaint.setAntiAlias(true);
@@ -92,9 +94,10 @@
         TestUtils::drawUtf8ToCanvas(&canvas, "This is some more text on the card", textPaint,
                 itemHeight, dp(45));
 
-        canvas.drawBitmap(createRandomCharIcon(itemHeight), dp(10), dp(10), nullptr);
+        auto randomIcon = createRandomCharIcon(itemHeight);
+        canvas.drawBitmap(*randomIcon, dp(10), dp(10), nullptr);
 
-        const SkBitmap& boxBitmap = rand() % 2 ? filledBox : strokedBox;
-        canvas.drawBitmap(boxBitmap, itemWidth - dp(10) - boxBitmap.width(), dp(10), nullptr);
+        auto box = rand() % 2 ? filledBox : strokedBox;
+        canvas.drawBitmap(*box, itemWidth - dp(10) - box->width(), dp(10), nullptr);
     }
 };
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index 10cf05a..da724a9 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -93,7 +93,7 @@
     delete canvas->finishRecording();
 
     SkPaint rectPaint;
-    SkBitmap iconBitmap = TestUtils::createSkBitmap(80, 80);
+    sk_sp<Bitmap> iconBitmap(TestUtils::createBitmap(80, 80));
 
     while (benchState.KeepRunning()) {
         canvas->resetRecording(100, 100);
@@ -105,7 +105,7 @@
         {
             canvas->save(SaveFlags::MatrixClip);
             canvas->translate(10, 10);
-            canvas->drawBitmap(iconBitmap, 0, 0, nullptr);
+            canvas->drawBitmap(*iconBitmap, 0, 0, nullptr);
             canvas->restore();
         }
         benchmark::DoNotOptimize(canvas.get());
diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
index 93aa574..d68f5bd 100644
--- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp
+++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
@@ -41,7 +41,7 @@
 static sp<RenderNode> createTestNode() {
     auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        SkBitmap bitmap = TestUtils::createSkBitmap(10, 10);
+        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(10, 10));
         SkPaint paint;
 
         // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
@@ -50,7 +50,7 @@
         for (int i = 0; i < 30; i++) {
             canvas.translate(0, 10);
             canvas.drawRect(0, 0, 10, 10, paint);
-            canvas.drawBitmap(bitmap, 5, 0, nullptr);
+            canvas.drawBitmap(*bitmap, 5, 0, nullptr);
         }
         canvas.restore();
     });
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 818c29c..fb6067d 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -129,9 +129,9 @@
 
     auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        SkBitmap bitmap = TestUtils::createSkBitmap(25, 25);
+        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(25, 25));
         canvas.drawRect(0, 0, 100, 200, SkPaint());
-        canvas.drawBitmap(bitmap, 10, 10, nullptr);
+        canvas.drawBitmap(*bitmap, 10, 10, nullptr);
     });
     FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200,
             sLightGeometry, Caches::getInstance());
@@ -200,8 +200,9 @@
 
     auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        SkBitmap bitmap = TestUtils::createSkBitmap(10, 10,
-                kAlpha_8_SkColorType); // Disable merging by using alpha 8 bitmap
+
+        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(10, 10,
+                kAlpha_8_SkColorType)); // Disable merging by using alpha 8 bitmap
 
         // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
         // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
@@ -209,7 +210,7 @@
         for (int i = 0; i < LOOPS; i++) {
             canvas.translate(0, 10);
             canvas.drawRect(0, 0, 10, 10, SkPaint());
-            canvas.drawBitmap(bitmap, 5, 0, nullptr);
+            canvas.drawBitmap(*bitmap, 5, 0, nullptr);
         }
         canvas.restore();
     });
@@ -393,19 +394,19 @@
 }
 
 RENDERTHREAD_TEST(FrameBuilder, avoidOverdraw_bitmaps) {
-    static SkBitmap opaqueBitmap = TestUtils::createSkBitmap(50, 50,
-            SkColorType::kRGB_565_SkColorType);
-    static SkBitmap transpBitmap = TestUtils::createSkBitmap(50, 50,
-            SkColorType::kAlpha_8_SkColorType);
+    static sk_sp<Bitmap> opaqueBitmap(TestUtils::createBitmap(50, 50,
+            SkColorType::kRGB_565_SkColorType));
+    static sk_sp<Bitmap> transpBitmap(TestUtils::createBitmap(50, 50,
+            SkColorType::kAlpha_8_SkColorType));
     class AvoidOverdrawBitmapsTestRenderer : public TestRendererBase {
     public:
         void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
             switch(mIndex++) {
             case 0:
-                EXPECT_EQ(opaqueBitmap.pixelRef(), op.bitmap->pixelRef());
+                EXPECT_EQ(opaqueBitmap.get(), op.bitmap->pixelRef());
                 break;
             case 1:
-                EXPECT_EQ(transpBitmap.pixelRef(), op.bitmap->pixelRef());
+                EXPECT_EQ(transpBitmap.get(), op.bitmap->pixelRef());
                 break;
             default:
                 ADD_FAILURE() << "Only two ops expected.";
@@ -417,11 +418,11 @@
             [](RenderProperties& props, RecordingCanvas& canvas) {
         canvas.drawRect(0, 0, 50, 50, SkPaint());
         canvas.drawRect(0, 0, 50, 50, SkPaint());
-        canvas.drawBitmap(transpBitmap, 0, 0, nullptr);
+        canvas.drawBitmap(*transpBitmap, 0, 0, nullptr);
 
         // only the below draws should remain, since they're
-        canvas.drawBitmap(opaqueBitmap, 0, 0, nullptr);
-        canvas.drawBitmap(transpBitmap, 0, 0, nullptr);
+        canvas.drawBitmap(*opaqueBitmap, 0, 0, nullptr);
+        canvas.drawBitmap(*transpBitmap, 0, 0, nullptr);
     });
     FrameBuilder frameBuilder(SkRect::MakeWH(50, 50), 50, 50,
             sLightGeometry, Caches::getInstance());
@@ -449,23 +450,23 @@
     };
     auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        SkBitmap bitmap = TestUtils::createSkBitmap(20, 20);
+        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(20, 20));
 
         // left side clipped (to inset left half)
         canvas.clipRect(10, 0, 50, 100, SkRegion::kReplace_Op);
-        canvas.drawBitmap(bitmap, 0, 40, nullptr);
+        canvas.drawBitmap(*bitmap, 0, 40, nullptr);
 
         // top side clipped (to inset top half)
         canvas.clipRect(0, 10, 100, 50, SkRegion::kReplace_Op);
-        canvas.drawBitmap(bitmap, 40, 0, nullptr);
+        canvas.drawBitmap(*bitmap, 40, 0, nullptr);
 
         // right side clipped (to inset right half)
         canvas.clipRect(50, 0, 90, 100, SkRegion::kReplace_Op);
-        canvas.drawBitmap(bitmap, 80, 40, nullptr);
+        canvas.drawBitmap(*bitmap, 80, 40, nullptr);
 
         // bottom not clipped, just abutting (inset bottom half)
         canvas.clipRect(0, 50, 100, 90, SkRegion::kReplace_Op);
-        canvas.drawBitmap(bitmap, 40, 70, nullptr);
+        canvas.drawBitmap(*bitmap, 40, 70, nullptr);
     });
 
     FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100,
@@ -822,8 +823,8 @@
 
     auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        SkBitmap bitmap = TestUtils::createSkBitmap(200, 200);
-        canvas.drawBitmap(bitmap, 0, 0, nullptr);
+        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(200, 200));
+        canvas.drawBitmap(*bitmap, 0, 0, nullptr);
     });
 
     // clip to small area, should see in receiver
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 46e685c..3bfbf12 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -261,8 +261,7 @@
 
 TEST(RecordingCanvas, backgroundAndImage) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
-        SkBitmap bitmap;
-        bitmap.setInfo(SkImageInfo::MakeUnknown(25, 25));
+        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(25, 25));
         SkPaint paint;
         paint.setColor(SK_ColorBLUE);
 
@@ -278,7 +277,7 @@
             canvas.save(SaveFlags::MatrixClip);
             canvas.translate(25, 25);
             canvas.scale(2, 2);
-            canvas.drawBitmap(bitmap, 0, 0, nullptr);
+            canvas.drawBitmap(*bitmap, 0, 0, nullptr);
             canvas.restore();
         }
         canvas.restore();
@@ -728,9 +727,9 @@
 }
 
 TEST(RecordingCanvas, refBitmap) {
-    SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
+    sk_sp<Bitmap> bitmap(TestUtils::createBitmap(100, 100));
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
-        canvas.drawBitmap(bitmap, 0, 0, nullptr);
+        canvas.drawBitmap(*bitmap, 0, 0, nullptr);
     });
     auto& bitmaps = dl->getBitmapResources();
     EXPECT_EQ(1u, bitmaps.size());