Partial fix for mutable Bitmaps in BitmapShader

This handles the basic case only but unfortunately
a complete solution is too complex to handle just yet

Fixes: 289012318
Test: hwuiunit
Change-Id: I950da9885a40fe623f9cefc202727616fb6ce8b2
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index b785989..ced0224 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -175,7 +175,7 @@
                                   const Paint& paint, const SkPath& path, size_t start,
                                   size_t end) override;
 
-    void onFilterPaint(Paint& paint);
+    virtual void onFilterPaint(Paint& paint);
 
     Paint filterPaint(const Paint& src) {
         Paint dst(src);
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 58c14c1..e917f9a 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -236,6 +236,17 @@
     }
 }
 
+void SkiaRecordingCanvas::onFilterPaint(android::Paint& paint) {
+    INHERITED::onFilterPaint(paint);
+    SkShader* shader = paint.getShader();
+    // TODO(b/264559422): This only works for very specifically a BitmapShader.
+    //  It's better than nothing, though
+    SkImage* image = shader ? shader->isAImage(nullptr, nullptr) : nullptr;
+    if (image) {
+        mDisplayList->mMutableImages.push_back(image);
+    }
+}
+
 void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) {
     auto payload = DrawImagePayload(bitmap);
 
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index a8e4580..3bd091d 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -105,6 +105,8 @@
 
     void handleMutableImages(Bitmap& bitmap, DrawImagePayload& payload);
 
+    void onFilterPaint(Paint& paint) override;
+
     using INHERITED = SkiaCanvas;
 };
 
diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
index f6be7b2..064d42e 100644
--- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
+++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
@@ -129,6 +129,33 @@
     EXPECT_EQ(counts.destroyed, 1);
 }
 
+TEST(SkiaDisplayList, recordMutableBitmap) {
+    SkiaRecordingCanvas canvas{nullptr, 100, 100};
+    auto bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::Make(
+            10, 20, SkColorType::kN32_SkColorType, SkAlphaType::kPremul_SkAlphaType));
+    EXPECT_FALSE(bitmap->isImmutable());
+    canvas.drawBitmap(*bitmap, 0, 0, nullptr);
+    auto displayList = canvas.finishRecording();
+    ASSERT_EQ(1, displayList->mMutableImages.size());
+    EXPECT_EQ(10, displayList->mMutableImages[0]->width());
+    EXPECT_EQ(20, displayList->mMutableImages[0]->height());
+}
+
+TEST(SkiaDisplayList, recordMutableBitmapInShader) {
+    SkiaRecordingCanvas canvas{nullptr, 100, 100};
+    auto bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::Make(
+            10, 20, SkColorType::kN32_SkColorType, SkAlphaType::kPremul_SkAlphaType));
+    EXPECT_FALSE(bitmap->isImmutable());
+    SkSamplingOptions sampling(SkFilterMode::kLinear, SkMipmapMode::kNone);
+    Paint paint;
+    paint.setShader(bitmap->makeImage()->makeShader(sampling));
+    canvas.drawPaint(paint);
+    auto displayList = canvas.finishRecording();
+    ASSERT_EQ(1, displayList->mMutableImages.size());
+    EXPECT_EQ(10, displayList->mMutableImages[0]->width());
+    EXPECT_EQ(20, displayList->mMutableImages[0]->height());
+}
+
 class ContextFactory : public IContextFactory {
 public:
     virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {