1805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary/* 2805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary * Copyright 2014 Google Inc. 3805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary * 4805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary * Use of this source code is governed by a BSD-style license that can be 5805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary * found in the LICENSE file. 6805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary */ 730ad5306be25565484a3dd76237984e071b7c4b3reed 8805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary#include "Test.h" 904617139f7f715bdc05a32a58e65e3c208bccff4reed#include "SkBitmapCache.h" 1030ad5306be25565484a3dd76237984e071b7c4b3reed#include "SkCanvas.h" 11790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj#include "SkDiscardableMemoryPool.h" 1230ad5306be25565484a3dd76237984e071b7c4b3reed#include "SkGraphics.h" 1330ad5306be25565484a3dd76237984e071b7c4b3reed#include "SkResourceCache.h" 143054be16dfdb0d06233770cbfc338958edef44eareed#include "SkSurface.h" 15805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 16805ef159d197007b9529e60e5b918ee0f9d3802dhalcanarystatic const int kCanvasSize = 1; 17805ef159d197007b9529e60e5b918ee0f9d3802dhalcanarystatic const int kBitmapSize = 16; 18805ef159d197007b9529e60e5b918ee0f9d3802dhalcanarystatic const int kScale = 8; 19805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 201d1795b199f216e17ff6b63f8c8c1f653666cb79halcanarystatic bool is_in_scaled_image_cache(const SkBitmap& orig, 211d1795b199f216e17ff6b63f8c8c1f653666cb79halcanary SkScalar xScale, 221d1795b199f216e17ff6b63f8c8c1f653666cb79halcanary SkScalar yScale) { 231d1795b199f216e17ff6b63f8c8c1f653666cb79halcanary SkBitmap scaled; 24d73c169637f1ab0b96bae43269da7216bb93a7e1humper float roundedImageWidth = SkScalarRoundToScalar(orig.width() * xScale); 2590acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he float roundedImageHeight = SkScalarRoundToScalar(orig.height() * yScale); 26d73c169637f1ab0b96bae43269da7216bb93a7e1humper return SkBitmapCache::Find(orig, roundedImageWidth, roundedImageHeight, &scaled); 271d1795b199f216e17ff6b63f8c8c1f653666cb79halcanary} 281d1795b199f216e17ff6b63f8c8c1f653666cb79halcanary 2990acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he// Draw a scaled bitmap, then return true if it has been cached. 3090acb8e97cb123adc25d030b6dbe868d32856f47yunchao.hestatic bool test_scaled_image_cache_usage() { 313054be16dfdb0d06233770cbfc338958edef44eareed SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(kCanvasSize, kCanvasSize)); 323054be16dfdb0d06233770cbfc338958edef44eareed SkCanvas* canvas = surface->getCanvas(); 33805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary SkBitmap bitmap; 34848250415eddc54075f7eb8795e8db79e749c6abreed bitmap.allocN32Pixels(kBitmapSize, kBitmapSize); 350db38ccfefcfb45d1542678cc45415f2d2b01c85halcanary bitmap.eraseColor(0xFFFFFFFF); 3690acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he SkScalar xScale = SkIntToScalar(kScale); 3790acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he SkScalar yScale = xScale / 2; 3890acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he SkScalar xScaledSize = SkIntToScalar(kBitmapSize) * xScale; 3990acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he SkScalar yScaledSize = SkIntToScalar(kBitmapSize) * yScale; 4090acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he canvas->clipRect(SkRect::MakeLTRB(0, 0, xScaledSize, yScaledSize)); 41805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary SkPaint paint; 4293a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed paint.setFilterQuality(kHigh_SkFilterQuality); 431d1795b199f216e17ff6b63f8c8c1f653666cb79halcanary 44805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary canvas->drawBitmapRect(bitmap, 4590acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he SkRect::MakeLTRB(0, 0, xScaledSize, yScaledSize), 46805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary &paint); 471d1795b199f216e17ff6b63f8c8c1f653666cb79halcanary 4890acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he return is_in_scaled_image_cache(bitmap, xScale, yScale); 49805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary} 50805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 51805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary// http://crbug.com/389439 52011f39aeb2b9715546eb74d9ebb71be7baf95fdereedDEF_TEST(ResourceCache_SingleAllocationByteLimit, reporter) { 53011f39aeb2b9715546eb74d9ebb71be7baf95fdereed size_t originalByteLimit = SkGraphics::GetResourceCacheTotalByteLimit(); 54805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary size_t originalAllocationLimit = 55011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::GetResourceCacheSingleAllocationByteLimit(); 56805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 57805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary size_t size = kBitmapSize * kScale * kBitmapSize * kScale 58805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary * SkColorTypeBytesPerPixel(kN32_SkColorType); 59805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 60011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheTotalByteLimit(0); // clear cache 61011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheTotalByteLimit(2 * size); 62011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheSingleAllocationByteLimit(0); // No limit 63805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 6490acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he REPORTER_ASSERT(reporter, test_scaled_image_cache_usage()); 65805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 66011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheTotalByteLimit(0); // clear cache 67011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheTotalByteLimit(2 * size); 68011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheSingleAllocationByteLimit(size * 2); // big enough 69805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 7090acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he REPORTER_ASSERT(reporter, test_scaled_image_cache_usage()); 71805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 72011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheTotalByteLimit(0); // clear cache 73011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheTotalByteLimit(2 * size); 74011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheSingleAllocationByteLimit(size / 2); // too small 75805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 7690acb8e97cb123adc25d030b6dbe868d32856f47yunchao.he REPORTER_ASSERT(reporter, !test_scaled_image_cache_usage()); 77805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary 78011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheSingleAllocationByteLimit(originalAllocationLimit); 79011f39aeb2b9715546eb74d9ebb71be7baf95fdereed SkGraphics::SetResourceCacheTotalByteLimit(originalByteLimit); 80805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary} 8142b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr 8230ad5306be25565484a3dd76237984e071b7c4b3reed//////////////////////////////////////////////////////////////////////////////////////// 8326abcf10a4994a0bb13a074d79baa85cd8d67b2cmtklein 8430ad5306be25565484a3dd76237984e071b7c4b3reedstatic void make_bitmap(SkBitmap* bitmap, const SkImageInfo& info, SkBitmap::Allocator* allocator) { 8549f085dddff10473b6ebf832a974288300224e60bsalomon if (allocator) { 8630ad5306be25565484a3dd76237984e071b7c4b3reed bitmap->setInfo(info); 8730ad5306be25565484a3dd76237984e071b7c4b3reed allocator->allocPixelRef(bitmap, 0); 8842b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr } else { 8930ad5306be25565484a3dd76237984e071b7c4b3reed bitmap->allocPixels(info); 9042b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr } 9142b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr} 9242b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr 9342b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr// http://skbug.com/2894 9442b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixrDEF_TEST(BitmapCache_add_rect, reporter) { 9530ad5306be25565484a3dd76237984e071b7c4b3reed SkResourceCache::DiscardableFactory factory = SkResourceCache::GetDiscardableFactory(); 9630ad5306be25565484a3dd76237984e071b7c4b3reed SkBitmap::Allocator* allocator = SkBitmapCache::GetAllocator(); 9730ad5306be25565484a3dd76237984e071b7c4b3reed 9830ad5306be25565484a3dd76237984e071b7c4b3reed SkAutoTDelete<SkResourceCache> cache; 9930ad5306be25565484a3dd76237984e071b7c4b3reed if (factory) { 10030ad5306be25565484a3dd76237984e071b7c4b3reed cache.reset(SkNEW_ARGS(SkResourceCache, (factory))); 10130ad5306be25565484a3dd76237984e071b7c4b3reed } else { 10230ad5306be25565484a3dd76237984e071b7c4b3reed const size_t byteLimit = 100 * 1024; 10330ad5306be25565484a3dd76237984e071b7c4b3reed cache.reset(SkNEW_ARGS(SkResourceCache, (byteLimit))); 10430ad5306be25565484a3dd76237984e071b7c4b3reed } 10530ad5306be25565484a3dd76237984e071b7c4b3reed SkBitmap cachedBitmap; 10630ad5306be25565484a3dd76237984e071b7c4b3reed make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator); 10730ad5306be25565484a3dd76237984e071b7c4b3reed cachedBitmap.setImmutable(); 10830ad5306be25565484a3dd76237984e071b7c4b3reed 10942b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr SkBitmap bm; 11042b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr SkIRect rect = SkIRect::MakeWH(5, 5); 11183787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed uint32_t cachedID = cachedBitmap.getGenerationID(); 11283787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed SkPixelRef* cachedPR = cachedBitmap.pixelRef(); 11342b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr 11442b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr // Wrong subset size 11583787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, !SkBitmapCache::Add(cachedPR, SkIRect::MakeWH(4, 6), cachedBitmap, cache)); 11683787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedID, rect, &bm, cache)); 11742b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr // Wrong offset value 11883787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, !SkBitmapCache::Add(cachedPR, SkIRect::MakeXYWH(-1, 0, 5, 5), cachedBitmap, cache)); 11983787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedID, rect, &bm, cache)); 12042b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr 12142b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr // Should not be in the cache 12283787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedID, rect, &bm, cache)); 12342b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr 12483787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedPR, rect, cachedBitmap, cache)); 12542b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr // Should be in the cache, we just added it 12683787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedID, rect, &bm, cache)); 12742b0dfeb29e993b7fd247dcecff705d3dd4cf191piotaixr} 128790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj 1299d93c2ebb31bf996905532446644f242339a774ereed#include "SkMipMap.h" 1309d93c2ebb31bf996905532446644f242339a774ereed 1319d93c2ebb31bf996905532446644f242339a774ereedenum LockedState { 1329d93c2ebb31bf996905532446644f242339a774ereed kNotLocked, 1339d93c2ebb31bf996905532446644f242339a774ereed kLocked, 1349d93c2ebb31bf996905532446644f242339a774ereed}; 1359d93c2ebb31bf996905532446644f242339a774ereed 1369d93c2ebb31bf996905532446644f242339a774ereedenum CachedState { 1379d93c2ebb31bf996905532446644f242339a774ereed kNotInCache, 1389d93c2ebb31bf996905532446644f242339a774ereed kInCache, 1399d93c2ebb31bf996905532446644f242339a774ereed}; 1409d93c2ebb31bf996905532446644f242339a774ereed 1419d93c2ebb31bf996905532446644f242339a774ereedstatic void check_data(skiatest::Reporter* reporter, const SkCachedData* data, 1429d93c2ebb31bf996905532446644f242339a774ereed int refcnt, CachedState cacheState, LockedState lockedState) { 1439d93c2ebb31bf996905532446644f242339a774ereed REPORTER_ASSERT(reporter, data->testing_only_getRefCnt() == refcnt); 1449d93c2ebb31bf996905532446644f242339a774ereed REPORTER_ASSERT(reporter, data->testing_only_isInCache() == (kInCache == cacheState)); 1459d93c2ebb31bf996905532446644f242339a774ereed bool isLocked = (data->data() != NULL); 1469d93c2ebb31bf996905532446644f242339a774ereed REPORTER_ASSERT(reporter, isLocked == (lockedState == kLocked)); 1479d93c2ebb31bf996905532446644f242339a774ereed} 1489d93c2ebb31bf996905532446644f242339a774ereed 1499d93c2ebb31bf996905532446644f242339a774ereedstatic void test_mipmapcache(skiatest::Reporter* reporter, SkResourceCache* cache) { 1509d93c2ebb31bf996905532446644f242339a774ereed cache->purgeAll(); 1519d93c2ebb31bf996905532446644f242339a774ereed 1529d93c2ebb31bf996905532446644f242339a774ereed SkBitmap src; 1539d93c2ebb31bf996905532446644f242339a774ereed src.allocN32Pixels(5, 5); 1549d93c2ebb31bf996905532446644f242339a774ereed src.setImmutable(); 1559d93c2ebb31bf996905532446644f242339a774ereed 1569d93c2ebb31bf996905532446644f242339a774ereed const SkMipMap* mipmap = SkMipMapCache::FindAndRef(src, cache); 1579d93c2ebb31bf996905532446644f242339a774ereed REPORTER_ASSERT(reporter, NULL == mipmap); 1589d93c2ebb31bf996905532446644f242339a774ereed 1599d93c2ebb31bf996905532446644f242339a774ereed mipmap = SkMipMapCache::AddAndRef(src, cache); 1609d93c2ebb31bf996905532446644f242339a774ereed REPORTER_ASSERT(reporter, mipmap); 1617eeba2587760a0802fd2b90765b4fd0e5e895375reed 1627eeba2587760a0802fd2b90765b4fd0e5e895375reed { 1637eeba2587760a0802fd2b90765b4fd0e5e895375reed const SkMipMap* mm = SkMipMapCache::FindAndRef(src, cache); 1647eeba2587760a0802fd2b90765b4fd0e5e895375reed REPORTER_ASSERT(reporter, mm); 1657eeba2587760a0802fd2b90765b4fd0e5e895375reed REPORTER_ASSERT(reporter, mm == mipmap); 1667eeba2587760a0802fd2b90765b4fd0e5e895375reed mm->unref(); 1677eeba2587760a0802fd2b90765b4fd0e5e895375reed } 1687eeba2587760a0802fd2b90765b4fd0e5e895375reed 1699d93c2ebb31bf996905532446644f242339a774ereed check_data(reporter, mipmap, 2, kInCache, kLocked); 1709d93c2ebb31bf996905532446644f242339a774ereed 1719d93c2ebb31bf996905532446644f242339a774ereed mipmap->unref(); 1729d93c2ebb31bf996905532446644f242339a774ereed // tricky, since technically after this I'm no longer an owner, but since the cache is 1739d93c2ebb31bf996905532446644f242339a774ereed // local, I know it won't get purged behind my back 1749d93c2ebb31bf996905532446644f242339a774ereed check_data(reporter, mipmap, 1, kInCache, kNotLocked); 1759d93c2ebb31bf996905532446644f242339a774ereed 1769d93c2ebb31bf996905532446644f242339a774ereed // find us again 1779d93c2ebb31bf996905532446644f242339a774ereed mipmap = SkMipMapCache::FindAndRef(src, cache); 1789d93c2ebb31bf996905532446644f242339a774ereed check_data(reporter, mipmap, 2, kInCache, kLocked); 1799d93c2ebb31bf996905532446644f242339a774ereed 1809d93c2ebb31bf996905532446644f242339a774ereed cache->purgeAll(); 1819d93c2ebb31bf996905532446644f242339a774ereed check_data(reporter, mipmap, 1, kNotInCache, kLocked); 1829d93c2ebb31bf996905532446644f242339a774ereed 1839d93c2ebb31bf996905532446644f242339a774ereed mipmap->unref(); 1849d93c2ebb31bf996905532446644f242339a774ereed} 1859d93c2ebb31bf996905532446644f242339a774ereed 1867eeba2587760a0802fd2b90765b4fd0e5e895375reedstatic void test_mipmap_notify(skiatest::Reporter* reporter, SkResourceCache* cache) { 1877eeba2587760a0802fd2b90765b4fd0e5e895375reed const int N = 3; 1887eeba2587760a0802fd2b90765b4fd0e5e895375reed SkBitmap src[N]; 1897eeba2587760a0802fd2b90765b4fd0e5e895375reed for (int i = 0; i < N; ++i) { 1907eeba2587760a0802fd2b90765b4fd0e5e895375reed src[i].allocN32Pixels(5, 5); 1917eeba2587760a0802fd2b90765b4fd0e5e895375reed src[i].setImmutable(); 1927eeba2587760a0802fd2b90765b4fd0e5e895375reed SkMipMapCache::AddAndRef(src[i], cache)->unref(); 1937eeba2587760a0802fd2b90765b4fd0e5e895375reed } 1947eeba2587760a0802fd2b90765b4fd0e5e895375reed 1957eeba2587760a0802fd2b90765b4fd0e5e895375reed for (int i = 0; i < N; ++i) { 1967eeba2587760a0802fd2b90765b4fd0e5e895375reed const SkMipMap* mipmap = SkMipMapCache::FindAndRef(src[i], cache); 1977eeba2587760a0802fd2b90765b4fd0e5e895375reed if (cache) { 1987eeba2587760a0802fd2b90765b4fd0e5e895375reed // if cache is null, we're working on the global cache, and other threads might purge 1997eeba2587760a0802fd2b90765b4fd0e5e895375reed // it, making this check fragile. 2007eeba2587760a0802fd2b90765b4fd0e5e895375reed REPORTER_ASSERT(reporter, mipmap); 2017eeba2587760a0802fd2b90765b4fd0e5e895375reed } 2027eeba2587760a0802fd2b90765b4fd0e5e895375reed SkSafeUnref(mipmap); 2037eeba2587760a0802fd2b90765b4fd0e5e895375reed 2047eeba2587760a0802fd2b90765b4fd0e5e895375reed src[i].reset(); // delete the underlying pixelref, which *should* remove us from the cache 2057eeba2587760a0802fd2b90765b4fd0e5e895375reed 2067eeba2587760a0802fd2b90765b4fd0e5e895375reed mipmap = SkMipMapCache::FindAndRef(src[i], cache); 2077eeba2587760a0802fd2b90765b4fd0e5e895375reed REPORTER_ASSERT(reporter, !mipmap); 2087eeba2587760a0802fd2b90765b4fd0e5e895375reed } 2097eeba2587760a0802fd2b90765b4fd0e5e895375reed} 2107eeba2587760a0802fd2b90765b4fd0e5e895375reed 2117eeba2587760a0802fd2b90765b4fd0e5e895375reedstatic void test_bitmap_notify(skiatest::Reporter* reporter, SkResourceCache* cache) { 2127eeba2587760a0802fd2b90765b4fd0e5e895375reed const SkIRect subset = SkIRect::MakeWH(5, 5); 2137eeba2587760a0802fd2b90765b4fd0e5e895375reed const int N = 3; 2147eeba2587760a0802fd2b90765b4fd0e5e895375reed SkBitmap src[N], dst[N]; 2157eeba2587760a0802fd2b90765b4fd0e5e895375reed for (int i = 0; i < N; ++i) { 2167eeba2587760a0802fd2b90765b4fd0e5e895375reed src[i].allocN32Pixels(5, 5); 2177eeba2587760a0802fd2b90765b4fd0e5e895375reed src[i].setImmutable(); 2187eeba2587760a0802fd2b90765b4fd0e5e895375reed dst[i].allocN32Pixels(5, 5); 2197eeba2587760a0802fd2b90765b4fd0e5e895375reed dst[i].setImmutable(); 22083787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed SkBitmapCache::Add(src[i].pixelRef(), subset, dst[i], cache); 2217eeba2587760a0802fd2b90765b4fd0e5e895375reed } 2227eeba2587760a0802fd2b90765b4fd0e5e895375reed 2237eeba2587760a0802fd2b90765b4fd0e5e895375reed for (int i = 0; i < N; ++i) { 2247eeba2587760a0802fd2b90765b4fd0e5e895375reed const uint32_t genID = src[i].getGenerationID(); 2257eeba2587760a0802fd2b90765b4fd0e5e895375reed SkBitmap result; 2267eeba2587760a0802fd2b90765b4fd0e5e895375reed bool found = SkBitmapCache::Find(genID, subset, &result, cache); 2277eeba2587760a0802fd2b90765b4fd0e5e895375reed if (cache) { 2287eeba2587760a0802fd2b90765b4fd0e5e895375reed // if cache is null, we're working on the global cache, and other threads might purge 2297eeba2587760a0802fd2b90765b4fd0e5e895375reed // it, making this check fragile. 2307eeba2587760a0802fd2b90765b4fd0e5e895375reed REPORTER_ASSERT(reporter, found); 2317eeba2587760a0802fd2b90765b4fd0e5e895375reed } 2327eeba2587760a0802fd2b90765b4fd0e5e895375reed 2337eeba2587760a0802fd2b90765b4fd0e5e895375reed src[i].reset(); // delete the underlying pixelref, which *should* remove us from the cache 2347eeba2587760a0802fd2b90765b4fd0e5e895375reed 2357eeba2587760a0802fd2b90765b4fd0e5e895375reed found = SkBitmapCache::Find(genID, subset, &result, cache); 2367eeba2587760a0802fd2b90765b4fd0e5e895375reed REPORTER_ASSERT(reporter, !found); 2377eeba2587760a0802fd2b90765b4fd0e5e895375reed } 2387eeba2587760a0802fd2b90765b4fd0e5e895375reed} 2397eeba2587760a0802fd2b90765b4fd0e5e895375reed 240790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakjDEF_TEST(BitmapCache_discarded_bitmap, reporter) { 24130ad5306be25565484a3dd76237984e071b7c4b3reed SkResourceCache::DiscardableFactory factory = SkResourceCache::GetDiscardableFactory(); 24230ad5306be25565484a3dd76237984e071b7c4b3reed SkBitmap::Allocator* allocator = SkBitmapCache::GetAllocator(); 24330ad5306be25565484a3dd76237984e071b7c4b3reed 24430ad5306be25565484a3dd76237984e071b7c4b3reed SkAutoTDelete<SkResourceCache> cache; 24530ad5306be25565484a3dd76237984e071b7c4b3reed if (factory) { 24630ad5306be25565484a3dd76237984e071b7c4b3reed cache.reset(SkNEW_ARGS(SkResourceCache, (factory))); 24730ad5306be25565484a3dd76237984e071b7c4b3reed } else { 24830ad5306be25565484a3dd76237984e071b7c4b3reed const size_t byteLimit = 100 * 1024; 24930ad5306be25565484a3dd76237984e071b7c4b3reed cache.reset(SkNEW_ARGS(SkResourceCache, (byteLimit))); 25030ad5306be25565484a3dd76237984e071b7c4b3reed } 25130ad5306be25565484a3dd76237984e071b7c4b3reed SkBitmap cachedBitmap; 25230ad5306be25565484a3dd76237984e071b7c4b3reed make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator); 253790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj cachedBitmap.setImmutable(); 254790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj cachedBitmap.unlockPixels(); 255790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj 25630ad5306be25565484a3dd76237984e071b7c4b3reed SkBitmap bm; 25730ad5306be25565484a3dd76237984e071b7c4b3reed SkIRect rect = SkIRect::MakeWH(5, 5); 25830ad5306be25565484a3dd76237984e071b7c4b3reed 259790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj // Add a bitmap to the cache. 26083787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.pixelRef(), rect, cachedBitmap, cache)); 26130ad5306be25565484a3dd76237984e071b7c4b3reed REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache)); 262790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj 263790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj // Finding more than once works fine. 26430ad5306be25565484a3dd76237984e071b7c4b3reed REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache)); 265790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj bm.unlockPixels(); 266790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj 267790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj // Drop the pixels in the bitmap. 26830ad5306be25565484a3dd76237984e071b7c4b3reed if (factory) { 26930ad5306be25565484a3dd76237984e071b7c4b3reed REPORTER_ASSERT(reporter, SkGetGlobalDiscardableMemoryPool()->getRAMUsed() > 0); 27030ad5306be25565484a3dd76237984e071b7c4b3reed SkGetGlobalDiscardableMemoryPool()->dumpPool(); 27130ad5306be25565484a3dd76237984e071b7c4b3reed REPORTER_ASSERT(reporter, SkGetGlobalDiscardableMemoryPool()->getRAMUsed() == 0); 272790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj 27330ad5306be25565484a3dd76237984e071b7c4b3reed // The bitmap is not in the cache since it has been dropped. 27430ad5306be25565484a3dd76237984e071b7c4b3reed REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache)); 27530ad5306be25565484a3dd76237984e071b7c4b3reed } 276790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj 27730ad5306be25565484a3dd76237984e071b7c4b3reed make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator); 278790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj cachedBitmap.setImmutable(); 279790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj cachedBitmap.unlockPixels(); 280790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj 281790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj // We can add the bitmap back to the cache and find it again. 28283787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.pixelRef(), rect, cachedBitmap, cache)); 28330ad5306be25565484a3dd76237984e071b7c4b3reed REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache)); 2849d93c2ebb31bf996905532446644f242339a774ereed 2859d93c2ebb31bf996905532446644f242339a774ereed test_mipmapcache(reporter, cache); 2867eeba2587760a0802fd2b90765b4fd0e5e895375reed test_bitmap_notify(reporter, cache); 2877eeba2587760a0802fd2b90765b4fd0e5e895375reed test_mipmap_notify(reporter, cache); 288790ffe3feb90370318f42b28eb9c6af6e38cd4f9danakj} 289