Index: tests/SkResourceCacheTest.cpp |
diff --git a/tests/SkResourceCacheTest.cpp b/tests/SkResourceCacheTest.cpp |
index 4432b87d3b3b7af15fe5c5334b7808013ac811c6..9faddd016da3f593882f0af86573217407a86c17 100644 |
--- a/tests/SkResourceCacheTest.cpp |
+++ b/tests/SkResourceCacheTest.cpp |
@@ -10,6 +10,8 @@ |
#include "SkCanvas.h" |
#include "SkDiscardableMemoryPool.h" |
#include "SkGraphics.h" |
+#include "SkPicture.h" |
+#include "SkPictureRecorder.h" |
#include "SkResourceCache.h" |
#include "SkSurface.h" |
@@ -219,3 +221,69 @@ DEF_TEST(BitmapCache_discarded_bitmap, reporter) { |
test_bitmap_notify(reporter, cache); |
test_mipmap_notify(reporter, cache); |
} |
+ |
+static void test_discarded_image(skiatest::Reporter* reporter, const SkMatrix& transform, |
+ SkImage* (*buildImage)()) { |
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(10, 10)); |
+ SkCanvas* canvas = surface->getCanvas(); |
+ |
+ // SkBitmapCache is global, so other threads could be evicting our bitmaps. Loop a few times |
+ // to mitigate this risk. |
+ const unsigned kRepeatCount = 42; |
+ for (unsigned i = 0; i < kRepeatCount; ++i) { |
+ SkAutoCanvasRestore acr(canvas, true); |
+ |
+ SkAutoTUnref<SkImage> image(buildImage()); |
+ |
+ // always use high quality to ensure caching when scaled |
+ SkPaint paint; |
+ paint.setFilterQuality(kHigh_SkFilterQuality); |
+ |
+ // draw the image (with a transform, to tickle different code paths) to ensure |
+ // any associated resources get cached |
+ canvas->concat(transform); |
+ canvas->drawImage(image, 0, 0, &paint); |
+ |
+ auto imageId = image->uniqueID(); |
+ |
+ // delete the image |
+ image.reset(nullptr); |
+ |
+ // all resources should have been purged |
+ SkBitmap result; |
+ REPORTER_ASSERT(reporter, !SkBitmapCache::Find(imageId, &result)); |
+ } |
+} |
+ |
+ |
+// Verify that associated bitmap cache entries are purged on SkImage destruction. |
+DEF_TEST(BitmapCache_discarded_image, reporter) { |
+ // Cache entries associated with SkImages fall into two categories: |
+ // |
+ // 1) generated image bitmaps (managed by the image cacherator) |
+ // 2) scaled/resampled bitmaps (cached when HQ filters are used) |
+ // |
+ // To exercise the first cache type, we use generated/picture-backed SkImages. |
+ // To exercise the latter, we draw scaled bitmap images using HQ filters. |
+ |
+ const SkMatrix xforms[] = { |
+ SkMatrix::MakeScale(1, 1), |
+ SkMatrix::MakeScale(1.7f, 0.5f), |
+ }; |
+ |
+ for (size_t i = 0; i < SK_ARRAY_COUNT(xforms); ++i) { |
+ test_discarded_image(reporter, xforms[i], []() { |
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(10, 10)); |
+ surface->getCanvas()->clear(SK_ColorCYAN); |
+ return surface->newImageSnapshot(); |
+ }); |
+ |
+ test_discarded_image(reporter, xforms[i], []() { |
+ SkPictureRecorder recorder; |
+ SkCanvas* canvas = recorder.beginRecording(10, 10); |
+ canvas->clear(SK_ColorCYAN); |
+ SkAutoTUnref<SkPicture> picture(recorder.endRecording()); |
+ return SkImage::NewFromPicture(picture, SkISize::Make(10, 10), nullptr, nullptr); |
+ }); |
+ } |
+} |