summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author John Reck <jreck@google.com> 2023-07-21 17:10:51 -0400
committer John Reck <jreck@google.com> 2023-07-21 21:13:19 -0400
commit11fa206f3092b146e9e0e90f64d66226fc2cc5ac (patch)
tree6d1a4d123ac04a348d798f9e878a45d1c90d30a9
parent22d86f519c414278dac1cdd918d76ddf98562ac1 (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.h2
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp11
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.h2
-rw-r--r--libs/hwui/tests/unit/SkiaDisplayListTests.cpp27
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 {