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