diff options
author | 2023-07-21 17:10:51 -0400 | |
---|---|---|
committer | 2023-07-21 21:13:19 -0400 | |
commit | 11fa206f3092b146e9e0e90f64d66226fc2cc5ac (patch) | |
tree | 6d1a4d123ac04a348d798f9e878a45d1c90d30a9 | |
parent | 22d86f519c414278dac1cdd918d76ddf98562ac1 (diff) |
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
-rw-r--r-- | libs/hwui/SkiaCanvas.h | 2 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp | 11 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaRecordingCanvas.h | 2 | ||||
-rw-r--r-- | libs/hwui/tests/unit/SkiaDisplayListTests.cpp | 27 |
4 files changed, 41 insertions, 1 deletions
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index b785989f35cb..ced02241ffe2 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -175,7 +175,7 @@ protected: 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 58c14c1fabbd..e917f9a66917 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -236,6 +236,17 @@ void SkiaRecordingCanvas::handleMutableImages(Bitmap& bitmap, DrawImagePayload& } } +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 a8e4580dc200..3bd091df1ece 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h @@ -105,6 +105,8 @@ private: 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 f6be7b20a9e2..064d42ec8941 100644 --- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp +++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp @@ -129,6 +129,33 @@ TEST(SkiaDisplayList, syncContexts) { 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 { |