From 3b0d532df72db806c255cad98538fcbb4d9678a8 Mon Sep 17 00:00:00 2001 From: fmalita Date: Fri, 18 Sep 2015 08:07:31 -0700 Subject: Purge cached resources on SkImage destruction. BUG=532981 R=reed@google.com,mtklein@google.com Review URL: https://codereview.chromium.org/1352883004 --- tests/SkResourceCacheTest.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'tests/SkResourceCacheTest.cpp') diff --git a/tests/SkResourceCacheTest.cpp b/tests/SkResourceCacheTest.cpp index 4432b87d3b..9faddd016d 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 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 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 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 picture(recorder.endRecording()); + return SkImage::NewFromPicture(picture, SkISize::Make(10, 10), nullptr, nullptr); + }); + } +} -- cgit v1.2.3