blob: 28cda94000ebe9a9ba64a07f01f79e88c20c0eac [file] [log] [blame]
reed@google.com772443a2013-12-11 15:30:24 +00001 /*
reed@google.com602a1d72013-07-23 19:13:54 +00002 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
reed@google.come4eb1222013-12-09 22:29:30 +00008#include "SkDiscardableMemory.h"
reed@google.com602a1d72013-07-23 19:13:54 +00009#include "SkScaledImageCache.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000010#include "Test.h"
reed@google.com602a1d72013-07-23 19:13:54 +000011
reed04617132014-08-21 09:46:49 -070012namespace {
13static void* gGlobalAddress;
14struct TestingKey : public SkScaledImageCache::Key {
15 void* fPtr;
16 intptr_t fValue;
17
18 TestingKey(intptr_t value) : fPtr(&gGlobalAddress), fValue(value) {
19 this->init(sizeof(fPtr) + sizeof(fValue));
20 }
21};
reed680fb9e2014-08-26 09:08:04 -070022struct TestingRec : public SkScaledImageCache::Rec {
23 TestingRec(const TestingKey& key, uint32_t value) : fKey(key), fValue(value) {}
reed04617132014-08-21 09:46:49 -070024
reed680fb9e2014-08-26 09:08:04 -070025 TestingKey fKey;
26 intptr_t fValue;
27
28 virtual const Key& getKey() const SK_OVERRIDE { return fKey; }
29 virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + sizeof(fValue); }
30};
reed@google.com602a1d72013-07-23 19:13:54 +000031}
32
reed@google.come4eb1222013-12-09 22:29:30 +000033static const int COUNT = 10;
34static const int DIM = 256;
35
36static void test_cache(skiatest::Reporter* reporter, SkScaledImageCache& cache,
37 bool testPurge) {
reed680fb9e2014-08-26 09:08:04 -070038 SkScaledImageCache::ID id;
skia.committer@gmail.comcf0803b2013-12-10 07:02:03 +000039
reed@google.com772443a2013-12-11 15:30:24 +000040 for (int i = 0; i < COUNT; ++i) {
reed680fb9e2014-08-26 09:08:04 -070041 TestingKey key(i);
tfarina@chromium.org4f3c3052013-12-14 15:12:48 +000042
reed680fb9e2014-08-26 09:08:04 -070043 const TestingRec* rec = (const TestingRec*)cache.findAndLock(key);
44 REPORTER_ASSERT(reporter, NULL == rec);
skia.committer@gmail.comcf0803b2013-12-10 07:02:03 +000045
reed680fb9e2014-08-26 09:08:04 -070046 TestingRec* newRec = SkNEW_ARGS(TestingRec, (key, i));
47 const TestingRec* addedRec = (const TestingRec*)cache.addAndLock(newRec);
48 REPORTER_ASSERT(reporter, NULL != addedRec);
skia.committer@gmail.comcf0803b2013-12-10 07:02:03 +000049
reed680fb9e2014-08-26 09:08:04 -070050 const TestingRec* foundRec = (const TestingRec*)cache.findAndLock(key);
51 REPORTER_ASSERT(reporter, foundRec == addedRec);
52 REPORTER_ASSERT(reporter, foundRec->fValue == i);
53 cache.unlock(foundRec);
54 cache.unlock(addedRec);
reed@google.com602a1d72013-07-23 19:13:54 +000055 }
skia.committer@gmail.comcf0803b2013-12-10 07:02:03 +000056
reed@google.come4eb1222013-12-09 22:29:30 +000057 if (testPurge) {
58 // stress test, should trigger purges
59 for (size_t i = 0; i < COUNT * 100; ++i) {
reed04617132014-08-21 09:46:49 -070060 TestingKey key(i);
reed680fb9e2014-08-26 09:08:04 -070061 SkScaledImageCache::ID id = cache.addAndLock(SkNEW_ARGS(TestingRec, (key, i)));
reed@google.come4eb1222013-12-09 22:29:30 +000062 REPORTER_ASSERT(reporter, NULL != id);
63 cache.unlock(id);
64 }
reed@google.com602a1d72013-07-23 19:13:54 +000065 }
reed@google.com772443a2013-12-11 15:30:24 +000066
67 // test the originals after all that purging
68 for (int i = 0; i < COUNT; ++i) {
reed680fb9e2014-08-26 09:08:04 -070069 id = cache.findAndLock(TestingKey(i));
reed@google.com772443a2013-12-11 15:30:24 +000070 if (id) {
71 cache.unlock(id);
72 }
73 }
74
halcanary805ef152014-07-17 06:58:01 -070075 cache.setTotalByteLimit(0);
reed@google.com602a1d72013-07-23 19:13:54 +000076}
77
reed@google.com772443a2013-12-11 15:30:24 +000078#include "SkDiscardableMemoryPool.h"
79
80static SkDiscardableMemoryPool* gPool;
81static SkDiscardableMemory* pool_factory(size_t bytes) {
commit-bot@chromium.orgcf2f0082014-04-04 16:43:38 +000082 SkASSERT(gPool);
reed@google.com772443a2013-12-11 15:30:24 +000083 return gPool->create(bytes);
84}
85
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000086DEF_TEST(ImageCache, reporter) {
reed@google.com772443a2013-12-11 15:30:24 +000087 static const size_t defLimit = DIM * DIM * 4 * COUNT + 1024; // 1K slop
88
reed@google.come4eb1222013-12-09 22:29:30 +000089 {
reed@google.come4eb1222013-12-09 22:29:30 +000090 SkScaledImageCache cache(defLimit);
91 test_cache(reporter, cache, true);
92 }
93 {
commit-bot@chromium.orgcf2f0082014-04-04 16:43:38 +000094 SkAutoTUnref<SkDiscardableMemoryPool> pool(
95 SkDiscardableMemoryPool::Create(defLimit, NULL));
96 gPool = pool.get();
reed@google.com772443a2013-12-11 15:30:24 +000097 SkScaledImageCache cache(pool_factory);
98 test_cache(reporter, cache, true);
99 }
100 {
reed@google.come4eb1222013-12-09 22:29:30 +0000101 SkScaledImageCache cache(SkDiscardableMemory::Create);
102 test_cache(reporter, cache, false);
103 }
104}
105
rmistry@google.comd6bab022013-12-02 13:50:38 +0000106DEF_TEST(ImageCache_doubleAdd, r) {
107 // Adding the same key twice should be safe.
commit-bot@chromium.org5e4112b2014-03-05 13:44:18 +0000108 SkScaledImageCache cache(4096);
rmistry@google.comd6bab022013-12-02 13:50:38 +0000109
reed680fb9e2014-08-26 09:08:04 -0700110 TestingKey key(1);
rmistry@google.comd6bab022013-12-02 13:50:38 +0000111
reed680fb9e2014-08-26 09:08:04 -0700112 SkScaledImageCache::ID id1 = cache.addAndLock(SkNEW_ARGS(TestingRec, (key, 2)));
113 SkScaledImageCache::ID id2 = cache.addAndLock(SkNEW_ARGS(TestingRec, (key, 3)));
rmistry@google.comd6bab022013-12-02 13:50:38 +0000114 // We don't really care if id1 == id2 as long as unlocking both works.
115 cache.unlock(id1);
116 cache.unlock(id2);
commit-bot@chromium.org5e4112b2014-03-05 13:44:18 +0000117
reed680fb9e2014-08-26 09:08:04 -0700118 // Lookup can return either value.
119 const TestingRec* rec = (const TestingRec*)cache.findAndLock(key);
120 REPORTER_ASSERT(r, NULL != rec);
121 REPORTER_ASSERT(r, 2 == rec->fValue || 3 == rec->fValue);
122 cache.unlock(rec);
rmistry@google.comd6bab022013-12-02 13:50:38 +0000123}