blob: 2244bb0a53f66334173c9c9fda04f7f11d034f2f [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"
reed011f39a2014-08-28 13:35:23 -07009#include "SkResourceCache.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;
reed011f39a2014-08-28 13:35:23 -070014struct TestingKey : public SkResourceCache::Key {
reed04617132014-08-21 09:46:49 -070015 intptr_t fValue;
16
reed7eeba252015-02-24 13:54:23 -080017 TestingKey(intptr_t value, uint64_t sharedID = 0) : fValue(value) {
18 this->init(&gGlobalAddress, sharedID, sizeof(fValue));
reed04617132014-08-21 09:46:49 -070019 }
20};
reed011f39a2014-08-28 13:35:23 -070021struct TestingRec : public SkResourceCache::Rec {
reed680fb9e2014-08-26 09:08:04 -070022 TestingRec(const TestingKey& key, uint32_t value) : fKey(key), fValue(value) {}
reed04617132014-08-21 09:46:49 -070023
reed680fb9e2014-08-26 09:08:04 -070024 TestingKey fKey;
25 intptr_t fValue;
26
mtklein36352bf2015-03-25 18:17:31 -070027 const Key& getKey() const override { return fKey; }
28 size_t bytesUsed() const override { return sizeof(fKey) + sizeof(fValue); }
reedc90e0142014-09-15 11:39:44 -070029
30 static bool Visitor(const SkResourceCache::Rec& baseRec, void* context) {
31 const TestingRec& rec = static_cast<const TestingRec&>(baseRec);
32 intptr_t* result = (intptr_t*)context;
33
34 *result = rec.fValue;
35 return true;
36 }
reed680fb9e2014-08-26 09:08:04 -070037};
reed@google.com602a1d72013-07-23 19:13:54 +000038}
39
reed@google.come4eb1222013-12-09 22:29:30 +000040static const int COUNT = 10;
41static const int DIM = 256;
42
reedc90e0142014-09-15 11:39:44 -070043static void test_cache(skiatest::Reporter* reporter, SkResourceCache& cache, bool testPurge) {
reed@google.com772443a2013-12-11 15:30:24 +000044 for (int i = 0; i < COUNT; ++i) {
reed680fb9e2014-08-26 09:08:04 -070045 TestingKey key(i);
reedc90e0142014-09-15 11:39:44 -070046 intptr_t value = -1;
tfarina@chromium.org4f3c3052013-12-14 15:12:48 +000047
reedc90e0142014-09-15 11:39:44 -070048 REPORTER_ASSERT(reporter, !cache.find(key, TestingRec::Visitor, &value));
49 REPORTER_ASSERT(reporter, -1 == value);
skia.committer@gmail.comcf0803b2013-12-10 07:02:03 +000050
reedc90e0142014-09-15 11:39:44 -070051 cache.add(SkNEW_ARGS(TestingRec, (key, i)));
skia.committer@gmail.comcf0803b2013-12-10 07:02:03 +000052
reedc90e0142014-09-15 11:39:44 -070053 REPORTER_ASSERT(reporter, cache.find(key, TestingRec::Visitor, &value));
54 REPORTER_ASSERT(reporter, i == value);
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
bsalomon98806072014-12-12 15:11:17 -080059 for (int i = 0; i < COUNT * 100; ++i) {
reed04617132014-08-21 09:46:49 -070060 TestingKey key(i);
reedc90e0142014-09-15 11:39:44 -070061 cache.add(SkNEW_ARGS(TestingRec, (key, i)));
reed@google.come4eb1222013-12-09 22:29:30 +000062 }
reed@google.com602a1d72013-07-23 19:13:54 +000063 }
reed@google.com772443a2013-12-11 15:30:24 +000064
65 // test the originals after all that purging
66 for (int i = 0; i < COUNT; ++i) {
reedc90e0142014-09-15 11:39:44 -070067 intptr_t value;
68 (void)cache.find(TestingKey(i), TestingRec::Visitor, &value);
reed@google.com772443a2013-12-11 15:30:24 +000069 }
70
halcanary805ef152014-07-17 06:58:01 -070071 cache.setTotalByteLimit(0);
reed@google.com602a1d72013-07-23 19:13:54 +000072}
73
reed7eeba252015-02-24 13:54:23 -080074static void test_cache_purge_shared_id(skiatest::Reporter* reporter, SkResourceCache& cache) {
75 for (int i = 0; i < COUNT; ++i) {
76 TestingKey key(i, i & 1); // every other key will have a 1 for its sharedID
77 cache.add(SkNEW_ARGS(TestingRec, (key, i)));
78 }
79
80 // Ensure that everyone is present
81 for (int i = 0; i < COUNT; ++i) {
82 TestingKey key(i, i & 1); // every other key will have a 1 for its sharedID
83 intptr_t value = -1;
84
85 REPORTER_ASSERT(reporter, cache.find(key, TestingRec::Visitor, &value));
86 REPORTER_ASSERT(reporter, value == i);
87 }
88
89 // Now purge the ones that had a non-zero sharedID (the odd-indexed ones)
90 cache.purgeSharedID(1);
91
92 // Ensure that only the even ones are still present
93 for (int i = 0; i < COUNT; ++i) {
94 TestingKey key(i, i & 1); // every other key will have a 1 for its sharedID
95 intptr_t value = -1;
96
97 if (i & 1) {
98 REPORTER_ASSERT(reporter, !cache.find(key, TestingRec::Visitor, &value));
99 } else {
100 REPORTER_ASSERT(reporter, cache.find(key, TestingRec::Visitor, &value));
101 REPORTER_ASSERT(reporter, value == i);
102 }
103 }
104}
105
reed@google.com772443a2013-12-11 15:30:24 +0000106#include "SkDiscardableMemoryPool.h"
107
108static SkDiscardableMemoryPool* gPool;
109static SkDiscardableMemory* pool_factory(size_t bytes) {
commit-bot@chromium.orgcf2f0082014-04-04 16:43:38 +0000110 SkASSERT(gPool);
reed@google.com772443a2013-12-11 15:30:24 +0000111 return gPool->create(bytes);
112}
113
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000114DEF_TEST(ImageCache, reporter) {
reed@google.com772443a2013-12-11 15:30:24 +0000115 static const size_t defLimit = DIM * DIM * 4 * COUNT + 1024; // 1K slop
116
reed@google.come4eb1222013-12-09 22:29:30 +0000117 {
reed011f39a2014-08-28 13:35:23 -0700118 SkResourceCache cache(defLimit);
reed@google.come4eb1222013-12-09 22:29:30 +0000119 test_cache(reporter, cache, true);
120 }
121 {
commit-bot@chromium.orgcf2f0082014-04-04 16:43:38 +0000122 SkAutoTUnref<SkDiscardableMemoryPool> pool(
123 SkDiscardableMemoryPool::Create(defLimit, NULL));
124 gPool = pool.get();
reed011f39a2014-08-28 13:35:23 -0700125 SkResourceCache cache(pool_factory);
reed@google.com772443a2013-12-11 15:30:24 +0000126 test_cache(reporter, cache, true);
127 }
128 {
reed011f39a2014-08-28 13:35:23 -0700129 SkResourceCache cache(SkDiscardableMemory::Create);
reed@google.come4eb1222013-12-09 22:29:30 +0000130 test_cache(reporter, cache, false);
131 }
reed7eeba252015-02-24 13:54:23 -0800132 {
133 SkResourceCache cache(defLimit);
134 test_cache_purge_shared_id(reporter, cache);
135 }
reed@google.come4eb1222013-12-09 22:29:30 +0000136}
137
rmistry@google.comd6bab022013-12-02 13:50:38 +0000138DEF_TEST(ImageCache_doubleAdd, r) {
139 // Adding the same key twice should be safe.
reed011f39a2014-08-28 13:35:23 -0700140 SkResourceCache cache(4096);
rmistry@google.comd6bab022013-12-02 13:50:38 +0000141
reed680fb9e2014-08-26 09:08:04 -0700142 TestingKey key(1);
rmistry@google.comd6bab022013-12-02 13:50:38 +0000143
reedc90e0142014-09-15 11:39:44 -0700144 cache.add(SkNEW_ARGS(TestingRec, (key, 2)));
145 cache.add(SkNEW_ARGS(TestingRec, (key, 3)));
commit-bot@chromium.org5e4112b2014-03-05 13:44:18 +0000146
reed680fb9e2014-08-26 09:08:04 -0700147 // Lookup can return either value.
reedc90e0142014-09-15 11:39:44 -0700148 intptr_t value = -1;
149 REPORTER_ASSERT(r, cache.find(key, TestingRec::Visitor, &value));
150 REPORTER_ASSERT(r, 2 == value || 3 == value);
rmistry@google.comd6bab022013-12-02 13:50:38 +0000151}