2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "SkDiscardableMemory.h"
9 #include "SkResourceCache.h"
13 static void* gGlobalAddress;
14 struct TestingKey : public SkResourceCache::Key {
17 TestingKey(intptr_t value, uint64_t sharedID = 0) : fValue(value) {
18 this->init(&gGlobalAddress, sharedID, sizeof(fValue));
21 struct TestingRec : public SkResourceCache::Rec {
22 TestingRec(const TestingKey& key, uint32_t value) : fKey(key), fValue(value) {}
27 const Key& getKey() const override { return fKey; }
28 size_t bytesUsed() const override { return sizeof(fKey) + sizeof(fValue); }
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;
40 static const int COUNT = 10;
41 static const int DIM = 256;
43 static void test_cache(skiatest::Reporter* reporter, SkResourceCache& cache, bool testPurge) {
44 for (int i = 0; i < COUNT; ++i) {
48 REPORTER_ASSERT(reporter, !cache.find(key, TestingRec::Visitor, &value));
49 REPORTER_ASSERT(reporter, -1 == value);
51 cache.add(SkNEW_ARGS(TestingRec, (key, i)));
53 REPORTER_ASSERT(reporter, cache.find(key, TestingRec::Visitor, &value));
54 REPORTER_ASSERT(reporter, i == value);
58 // stress test, should trigger purges
59 for (int i = 0; i < COUNT * 100; ++i) {
61 cache.add(SkNEW_ARGS(TestingRec, (key, i)));
65 // test the originals after all that purging
66 for (int i = 0; i < COUNT; ++i) {
68 (void)cache.find(TestingKey(i), TestingRec::Visitor, &value);
71 cache.setTotalByteLimit(0);
74 static 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)));
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
85 REPORTER_ASSERT(reporter, cache.find(key, TestingRec::Visitor, &value));
86 REPORTER_ASSERT(reporter, value == i);
89 // Now purge the ones that had a non-zero sharedID (the odd-indexed ones)
90 cache.purgeSharedID(1);
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
98 REPORTER_ASSERT(reporter, !cache.find(key, TestingRec::Visitor, &value));
100 REPORTER_ASSERT(reporter, cache.find(key, TestingRec::Visitor, &value));
101 REPORTER_ASSERT(reporter, value == i);
106 #include "SkDiscardableMemoryPool.h"
108 static SkDiscardableMemoryPool* gPool;
109 static SkDiscardableMemory* pool_factory(size_t bytes) {
111 return gPool->create(bytes);
114 DEF_TEST(ImageCache, reporter) {
115 static const size_t defLimit = DIM * DIM * 4 * COUNT + 1024; // 1K slop
118 SkResourceCache cache(defLimit);
119 test_cache(reporter, cache, true);
122 SkAutoTUnref<SkDiscardableMemoryPool> pool(
123 SkDiscardableMemoryPool::Create(defLimit, NULL));
125 SkResourceCache cache(pool_factory);
126 test_cache(reporter, cache, true);
129 SkResourceCache cache(SkDiscardableMemory::Create);
130 test_cache(reporter, cache, false);
133 SkResourceCache cache(defLimit);
134 test_cache_purge_shared_id(reporter, cache);
138 DEF_TEST(ImageCache_doubleAdd, r) {
139 // Adding the same key twice should be safe.
140 SkResourceCache cache(4096);
144 cache.add(SkNEW_ARGS(TestingRec, (key, 2)));
145 cache.add(SkNEW_ARGS(TestingRec, (key, 3)));
147 // Lookup can return either value.
149 REPORTER_ASSERT(r, cache.find(key, TestingRec::Visitor, &value));
150 REPORTER_ASSERT(r, 2 == value || 3 == value);