ImageCacheTest.cpp revision 49f085dddff10473b6ebf832a974288300224e60
1 /* 2 * 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 8#include "SkDiscardableMemory.h" 9#include "SkResourceCache.h" 10#include "Test.h" 11 12namespace { 13static void* gGlobalAddress; 14struct TestingKey : public SkResourceCache::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}; 22struct TestingRec : public SkResourceCache::Rec { 23 TestingRec(const TestingKey& key, uint32_t value) : fKey(key), fValue(value) {} 24 25 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}; 31} 32 33static const int COUNT = 10; 34static const int DIM = 256; 35 36static void test_cache(skiatest::Reporter* reporter, SkResourceCache& cache, 37 bool testPurge) { 38 SkResourceCache::ID id; 39 40 for (int i = 0; i < COUNT; ++i) { 41 TestingKey key(i); 42 43 const TestingRec* rec = (const TestingRec*)cache.findAndLock(key); 44 REPORTER_ASSERT(reporter, NULL == rec); 45 46 TestingRec* newRec = SkNEW_ARGS(TestingRec, (key, i)); 47 const TestingRec* addedRec = (const TestingRec*)cache.addAndLock(newRec); 48 REPORTER_ASSERT(reporter, addedRec); 49 50 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); 55 } 56 57 if (testPurge) { 58 // stress test, should trigger purges 59 for (size_t i = 0; i < COUNT * 100; ++i) { 60 TestingKey key(i); 61 SkResourceCache::ID id = cache.addAndLock(SkNEW_ARGS(TestingRec, (key, i))); 62 REPORTER_ASSERT(reporter, id); 63 cache.unlock(id); 64 } 65 } 66 67 // test the originals after all that purging 68 for (int i = 0; i < COUNT; ++i) { 69 id = cache.findAndLock(TestingKey(i)); 70 if (id) { 71 cache.unlock(id); 72 } 73 } 74 75 cache.setTotalByteLimit(0); 76} 77 78#include "SkDiscardableMemoryPool.h" 79 80static SkDiscardableMemoryPool* gPool; 81static SkDiscardableMemory* pool_factory(size_t bytes) { 82 SkASSERT(gPool); 83 return gPool->create(bytes); 84} 85 86DEF_TEST(ImageCache, reporter) { 87 static const size_t defLimit = DIM * DIM * 4 * COUNT + 1024; // 1K slop 88 89 { 90 SkResourceCache cache(defLimit); 91 test_cache(reporter, cache, true); 92 } 93 { 94 SkAutoTUnref<SkDiscardableMemoryPool> pool( 95 SkDiscardableMemoryPool::Create(defLimit, NULL)); 96 gPool = pool.get(); 97 SkResourceCache cache(pool_factory); 98 test_cache(reporter, cache, true); 99 } 100 { 101 SkResourceCache cache(SkDiscardableMemory::Create); 102 test_cache(reporter, cache, false); 103 } 104} 105 106DEF_TEST(ImageCache_doubleAdd, r) { 107 // Adding the same key twice should be safe. 108 SkResourceCache cache(4096); 109 110 TestingKey key(1); 111 112 SkResourceCache::ID id1 = cache.addAndLock(SkNEW_ARGS(TestingRec, (key, 2))); 113 SkResourceCache::ID id2 = cache.addAndLock(SkNEW_ARGS(TestingRec, (key, 3))); 114 // We don't really care if id1 == id2 as long as unlocking both works. 115 cache.unlock(id1); 116 cache.unlock(id2); 117 118 // Lookup can return either value. 119 const TestingRec* rec = (const TestingRec*)cache.findAndLock(key); 120 REPORTER_ASSERT(r, rec); 121 REPORTER_ASSERT(r, 2 == rec->fValue || 3 == rec->fValue); 122 cache.unlock(rec); 123} 124