| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #if SK_SUPPORT_GPU | 8 #if SK_SUPPORT_GPU |
| 9 | 9 |
| 10 #include "GrContext.h" | 10 #include "GrContext.h" |
| 11 #include "GrContextFactory.h" | 11 #include "GrContextFactory.h" |
| 12 #include "GrGpu.h" | 12 #include "GrGpu.h" |
| 13 #include "GrResourceCache.h" | |
| 14 #include "GrResourceCache2.h" | 13 #include "GrResourceCache2.h" |
| 15 #include "SkCanvas.h" | 14 #include "SkCanvas.h" |
| 15 #include "SkGr.h" |
| 16 #include "SkMessageBus.h" |
| 16 #include "SkSurface.h" | 17 #include "SkSurface.h" |
| 17 #include "Test.h" | 18 #include "Test.h" |
| 18 | 19 |
| 19 static const int gWidth = 640; | 20 static const int gWidth = 640; |
| 20 static const int gHeight = 480; | 21 static const int gHeight = 480; |
| 21 | 22 |
| 22 //////////////////////////////////////////////////////////////////////////////// | 23 //////////////////////////////////////////////////////////////////////////////// |
| 23 static void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanva
s* canvas) { | 24 static void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanva
s* canvas) { |
| 24 const SkIRect size = SkIRect::MakeWH(gWidth, gHeight); | 25 const SkIRect size = SkIRect::MakeWH(gWidth, gHeight); |
| 25 | 26 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 context->setResourceCacheLimits(oldMaxNum, oldMaxBytes); | 61 context->setResourceCacheLimits(oldMaxNum, oldMaxBytes); |
| 61 } | 62 } |
| 62 | 63 |
| 63 class TestResource : public GrGpuResource { | 64 class TestResource : public GrGpuResource { |
| 64 static const size_t kDefaultSize = 100; | 65 static const size_t kDefaultSize = 100; |
| 65 | 66 |
| 66 public: | 67 public: |
| 67 SK_DECLARE_INST_COUNT(TestResource); | 68 SK_DECLARE_INST_COUNT(TestResource); |
| 68 TestResource(GrGpu* gpu) | 69 TestResource(GrGpu* gpu) |
| 69 : INHERITED(gpu, false) | 70 : INHERITED(gpu, false) |
| 70 , fCache(NULL) | |
| 71 , fToDelete(NULL) | 71 , fToDelete(NULL) |
| 72 , fSize(kDefaultSize) { | 72 , fSize(kDefaultSize) { |
| 73 ++fNumAlive; | 73 ++fNumAlive; |
| 74 this->registerWithCache(); | 74 this->registerWithCache(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 TestResource(GrGpu* gpu, const GrResourceKey& scratchKey) | 77 TestResource(GrGpu* gpu, const GrResourceKey& scratchKey) |
| 78 : INHERITED(gpu, false) | 78 : INHERITED(gpu, false) |
| 79 , fCache(NULL) | |
| 80 , fToDelete(NULL) | 79 , fToDelete(NULL) |
| 81 , fSize(kDefaultSize) { | 80 , fSize(kDefaultSize) { |
| 82 this->setScratchKey(scratchKey); | 81 this->setScratchKey(scratchKey); |
| 83 ++fNumAlive; | 82 ++fNumAlive; |
| 84 this->registerWithCache(); | 83 this->registerWithCache(); |
| 85 } | 84 } |
| 86 | 85 |
| 87 ~TestResource() { | 86 ~TestResource() { |
| 88 --fNumAlive; | 87 --fNumAlive; |
| 89 if (fToDelete) { | 88 SkSafeUnref(fToDelete); |
| 90 // Breaks our little 2-element cycle below. | |
| 91 fToDelete->setDeleteWhenDestroyed(NULL, NULL); | |
| 92 fCache->deleteResource(fToDelete->cacheAccess().getCacheEntry()); | |
| 93 } | |
| 94 this->release(); | 89 this->release(); |
| 95 } | 90 } |
| 96 | 91 |
| 97 void setSize(size_t size) { | 92 void setSize(size_t size) { |
| 98 fSize = size; | 93 fSize = size; |
| 99 this->didChangeGpuMemorySize(); | 94 this->didChangeGpuMemorySize(); |
| 100 } | 95 } |
| 101 | 96 |
| 102 static int NumAlive() { return fNumAlive; } | 97 static int NumAlive() { return fNumAlive; } |
| 103 | 98 |
| 104 void setDeleteWhenDestroyed(GrResourceCache* cache, TestResource* resource)
{ | 99 void setUnrefWhenDestroyed(TestResource* resource) { |
| 105 fCache = cache; | 100 SkRefCnt_SafeAssign(fToDelete, resource); |
| 106 fToDelete = resource; | |
| 107 } | 101 } |
| 108 | 102 |
| 109 private: | 103 private: |
| 110 size_t onGpuMemorySize() const SK_OVERRIDE { return fSize; } | 104 size_t onGpuMemorySize() const SK_OVERRIDE { return fSize; } |
| 111 | 105 |
| 112 GrResourceCache* fCache; | |
| 113 TestResource* fToDelete; | 106 TestResource* fToDelete; |
| 114 size_t fSize; | 107 size_t fSize; |
| 115 static int fNumAlive; | 108 static int fNumAlive; |
| 116 | 109 |
| 117 typedef GrGpuResource INHERITED; | 110 typedef GrGpuResource INHERITED; |
| 118 }; | 111 }; |
| 119 int TestResource::fNumAlive = 0; | 112 int TestResource::fNumAlive = 0; |
| 120 | 113 |
| 114 static void test_no_key(skiatest::Reporter* reporter) { |
| 115 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
| 116 REPORTER_ASSERT(reporter, SkToBool(context)); |
| 117 if (NULL == context) { |
| 118 return; |
| 119 } |
| 120 context->setResourceCacheLimits(10, 30000); |
| 121 GrResourceCache2* cache2 = context->getResourceCache2(); |
| 122 cache2->purgeAllUnlocked(); |
| 123 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes())
; |
| 124 |
| 125 // Create a bunch of resources with no keys |
| 126 TestResource* a = new TestResource(context->getGpu()); |
| 127 TestResource* b = new TestResource(context->getGpu()); |
| 128 TestResource* c = new TestResource(context->getGpu()); |
| 129 TestResource* d = new TestResource(context->getGpu()); |
| 130 a->setSize(11); |
| 131 b->setSize(12); |
| 132 c->setSize(13); |
| 133 d->setSize(14); |
| 134 |
| 135 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive()); |
| 136 REPORTER_ASSERT(reporter, 4 == cache2->getResourceCount()); |
| 137 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMe
morySize() + |
| 138 d->gpuMemorySize() == cache2->getResourceBytes()); |
| 139 |
| 140 // Should be safe to purge without deleting the resources since we still hav
e refs. |
| 141 cache2->purgeAllUnlocked(); |
| 142 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive()); |
| 143 |
| 144 // Since the resources have neither content nor scratch keys, delete immedia
tely upon unref. |
| 145 |
| 146 a->unref(); |
| 147 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); |
| 148 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount()); |
| 149 REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMe
morySize() == |
| 150 cache2->getResourceBytes()); |
| 151 |
| 152 c->unref(); |
| 153 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 154 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
| 155 REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() == |
| 156 cache2->getResourceBytes()); |
| 157 |
| 158 d->unref(); |
| 159 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); |
| 160 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount()); |
| 161 REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache2->getResourceBytes()); |
| 162 |
| 163 b->unref(); |
| 164 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); |
| 165 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount()); |
| 166 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes()); |
| 167 } |
| 168 |
| 121 static void test_duplicate_scratch_key(skiatest::Reporter* reporter) { | 169 static void test_duplicate_scratch_key(skiatest::Reporter* reporter) { |
| 122 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); | 170 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
| 123 REPORTER_ASSERT(reporter, SkToBool(context)); | 171 REPORTER_ASSERT(reporter, SkToBool(context)); |
| 124 if (NULL == context) { | 172 if (NULL == context) { |
| 125 return; | 173 return; |
| 126 } | 174 } |
| 127 context->setResourceCacheLimits(5, 30000); | 175 context->setResourceCacheLimits(5, 30000); |
| 128 GrResourceCache* cache = context->getResourceCache(); | 176 GrResourceCache2* cache2 = context->getResourceCache2(); |
| 129 SkDEBUGCODE(GrResourceCache2* cache2 = context->getResourceCache2();) | 177 cache2->purgeAllUnlocked(); |
| 130 cache->purgeAllUnlocked(); | 178 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes())
; |
| 131 SkASSERT(0 == cache->getCachedResourceCount() && 0 == cache->getCachedResour
ceBytes()); | |
| 132 | 179 |
| 133 GrCacheID::Key keyData; | 180 GrCacheID::Key keyData; |
| 134 memset(&keyData, 0, sizeof(keyData)); | 181 memset(&keyData, 0, sizeof(keyData)); |
| 135 GrCacheID::Domain domain = GrResourceKey::ScratchDomain(); | 182 GrCacheID::Domain domain = GrResourceKey::ScratchDomain(); |
| 136 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); | 183 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); |
| 137 GrResourceKey scratchKey(GrCacheID(domain, keyData), t, 0); | 184 GrResourceKey scratchKey(GrCacheID(domain, keyData), t, 0); |
| 138 | 185 |
| 139 // Create two resources that have the same scratch key. | 186 // Create two resources that have the same scratch key. |
| 140 TestResource* a = new TestResource(context->getGpu(), scratchKey); | 187 TestResource* a = new TestResource(context->getGpu(), scratchKey); |
| 141 TestResource* b = new TestResource(context->getGpu(), scratchKey); | 188 TestResource* b = new TestResource(context->getGpu(), scratchKey); |
| 142 a->setSize(11); | 189 a->setSize(11); |
| 143 b->setSize(12); | 190 b->setSize(12); |
| 144 // Scratch resources are registered with GrResourceCache2 just by existing.
There are 2. | 191 // Scratch resources are registered with GrResourceCache2 just by existing.
There are 2. |
| 145 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey
(scratchKey));) | |
| 146 | |
| 147 REPORTER_ASSERT(reporter, cache->addResource(scratchKey, a)); | |
| 148 | |
| 149 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey
(scratchKey));) | |
| 150 | |
| 151 // Can't add the same resource twice. | |
| 152 REPORTER_ASSERT(reporter, !cache->addResource(scratchKey, a)); | |
| 153 REPORTER_ASSERT(reporter, 1 == cache->getCachedResourceCount()); | |
| 154 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getCachedResourceByte
s()); | |
| 155 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey
(scratchKey));) | |
| 156 | |
| 157 // Add a second with the same key. | |
| 158 REPORTER_ASSERT(reporter, cache->addResource(scratchKey, b)); | |
| 159 REPORTER_ASSERT(reporter, 2 == cache->getCachedResourceCount()); | |
| 160 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == | |
| 161 cache->getCachedResourceBytes()); | |
| 162 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); | 192 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 163 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey
(scratchKey));) | 193 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey
(scratchKey));) |
| 194 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
| 195 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == |
| 196 cache2->getResourceBytes()); |
| 164 | 197 |
| 165 // Our refs mean that the resources are non purgable. | 198 // Our refs mean that the resources are non purgable. |
| 166 cache->purgeAllUnlocked(); | 199 cache2->purgeAllUnlocked(); |
| 167 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); | 200 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 168 REPORTER_ASSERT(reporter, 2 == cache->getCachedResourceCount()); | 201 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
| 169 | 202 |
| 170 // Unref but don't purge | 203 // Unref but don't purge |
| 171 a->unref(); | 204 a->unref(); |
| 172 b->unref(); | 205 b->unref(); |
| 173 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); | 206 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 174 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey
(scratchKey));) | 207 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey
(scratchKey));) |
| 175 | 208 |
| 176 // Purge again. This time resources should be purgable. | 209 // Purge again. This time resources should be purgable. |
| 177 cache->purgeAllUnlocked(); | 210 cache2->purgeAllUnlocked(); |
| 178 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); | 211 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); |
| 179 REPORTER_ASSERT(reporter, 0 == cache->getCachedResourceCount()); | 212 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount()); |
| 180 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey
(scratchKey));) | 213 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey
(scratchKey));) |
| 181 } | 214 } |
| 182 | 215 |
| 183 static void test_duplicate_content_key(skiatest::Reporter* reporter) { | 216 static void test_duplicate_content_key(skiatest::Reporter* reporter) { |
| 184 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); | 217 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
| 185 REPORTER_ASSERT(reporter, SkToBool(context)); | 218 REPORTER_ASSERT(reporter, SkToBool(context)); |
| 186 if (NULL == context) { | 219 if (NULL == context) { |
| 187 return; | 220 return; |
| 188 } | 221 } |
| 189 context->setResourceCacheLimits(5, 30000); | 222 context->setResourceCacheLimits(5, 30000); |
| 190 GrResourceCache* cache = context->getResourceCache(); | 223 GrResourceCache2* cache2 = context->getResourceCache2(); |
| 191 cache->purgeAllUnlocked(); | 224 cache2->purgeAllUnlocked(); |
| 192 SkASSERT(0 == cache->getCachedResourceCount() && 0 == cache->getCachedResour
ceBytes()); | 225 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes())
; |
| 193 | 226 |
| 194 GrCacheID::Domain domain = GrCacheID::GenerateDomain(); | 227 GrCacheID::Domain domain = GrCacheID::GenerateDomain(); |
| 195 GrCacheID::Key keyData; | 228 GrCacheID::Key keyData; |
| 196 memset(&keyData, 0, sizeof(keyData)); | 229 memset(&keyData, 0, sizeof(keyData)); |
| 197 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); | 230 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); |
| 198 GrResourceKey key(GrCacheID(domain, keyData), t, 0); | 231 GrResourceKey key(GrCacheID(domain, keyData), t, 0); |
| 199 | 232 |
| 200 | |
| 201 // Create two resources that we will attempt to register with the same conte
nt key. | 233 // Create two resources that we will attempt to register with the same conte
nt key. |
| 202 TestResource* a = new TestResource(context->getGpu()); | 234 TestResource* a = new TestResource(context->getGpu()); |
| 203 TestResource* b = new TestResource(context->getGpu()); | 235 TestResource* b = new TestResource(context->getGpu()); |
| 204 a->setSize(11); | 236 a->setSize(11); |
| 205 b->setSize(12); | 237 b->setSize(12); |
| 206 REPORTER_ASSERT(reporter, cache->addResource(key, a)); | 238 |
| 207 // Can't add the same or another resource with the same key. | 239 // Can't set the same content key on two resources. |
| 208 REPORTER_ASSERT(reporter, !cache->addResource(key, a)); | 240 REPORTER_ASSERT(reporter, a->cacheAccess().setContentKey(key)); |
| 209 REPORTER_ASSERT(reporter, !cache->addResource(key, b)); | 241 REPORTER_ASSERT(reporter, !b->cacheAccess().setContentKey(key)); |
| 210 REPORTER_ASSERT(reporter, 1 == cache->getCachedResourceCount()); | 242 |
| 211 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getCachedResourceByte
s()); | 243 // Still have two resources because b is still reffed. |
| 244 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
| 245 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == |
| 246 cache2->getResourceBytes()); |
| 212 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); | 247 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 213 | 248 |
| 214 b->unref(); | 249 b->unref(); |
| 215 cache->purgeAllUnlocked(); | 250 // Now b should be gone. |
| 216 a->setSize(10); | 251 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount()); |
| 217 REPORTER_ASSERT(reporter, 1 == cache->getCachedResourceCount()); | 252 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes()); |
| 218 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); | 253 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); |
| 219 | 254 |
| 255 cache2->purgeAllUnlocked(); |
| 256 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount()); |
| 257 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes()); |
| 258 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); |
| 259 |
| 260 // Drop the ref on a but it isn't immediately purged as it still has a valid
scratch key. |
| 220 a->unref(); | 261 a->unref(); |
| 221 cache->purgeAllUnlocked(); | 262 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount()); |
| 222 REPORTER_ASSERT(reporter, 0 == cache->getCachedResourceCount()); | 263 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes()); |
| 223 REPORTER_ASSERT(reporter, 0 == cache->getCachedResourceBytes()); | 264 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); |
| 265 |
| 266 cache2->purgeAllUnlocked(); |
| 267 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount()); |
| 268 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes()); |
| 224 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); | 269 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); |
| 225 } | 270 } |
| 226 | 271 |
| 227 static void test_purge_invalidated(skiatest::Reporter* reporter) { | 272 static void test_purge_invalidated(skiatest::Reporter* reporter) { |
| 228 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); | 273 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
| 229 REPORTER_ASSERT(reporter, SkToBool(context)); | 274 REPORTER_ASSERT(reporter, SkToBool(context)); |
| 230 if (NULL == context) { | 275 if (NULL == context) { |
| 231 return; | 276 return; |
| 232 } | 277 } |
| 233 | 278 |
| 234 GrCacheID::Domain domain = GrCacheID::GenerateDomain(); | 279 GrCacheID::Domain domain = GrCacheID::GenerateDomain(); |
| 235 GrCacheID::Key keyData; | 280 GrCacheID::Key keyData; |
| 236 memset(&keyData, 0, sizeof(keyData)); | 281 memset(&keyData, 0, sizeof(keyData)); |
| 237 | 282 |
| 238 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); | 283 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); |
| 239 | 284 |
| 240 keyData.fData64[0] = 1; | 285 keyData.fData64[0] = 1; |
| 241 GrResourceKey key1(GrCacheID(domain, keyData), t, 0); | 286 GrResourceKey key1(GrCacheID(domain, keyData), t, 0); |
| 242 keyData.fData64[0] = 2; | 287 keyData.fData64[0] = 2; |
| 243 GrResourceKey key2(GrCacheID(domain, keyData), t, 0); | 288 GrResourceKey key2(GrCacheID(domain, keyData), t, 0); |
| 244 keyData.fData64[0] = 3; | 289 keyData.fData64[0] = 3; |
| 245 GrResourceKey key3(GrCacheID(domain, keyData), t, 0); | 290 GrResourceKey key3(GrCacheID(domain, keyData), t, 0); |
| 246 | 291 |
| 247 context->setResourceCacheLimits(5, 30000); | 292 context->setResourceCacheLimits(5, 30000); |
| 248 GrResourceCache* cache = context->getResourceCache(); | |
| 249 GrResourceCache2* cache2 = context->getResourceCache2(); | 293 GrResourceCache2* cache2 = context->getResourceCache2(); |
| 250 cache->purgeAllUnlocked(); | 294 cache2->purgeAllUnlocked(); |
| 251 SkASSERT(0 == cache->getCachedResourceCount() && 0 == cache->getCachedResour
ceBytes()); | 295 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes())
; |
| 252 | 296 |
| 253 // Add three resources to the cache. | 297 // Add three resources to the cache. |
| 254 TestResource* a = new TestResource(context->getGpu()); | 298 TestResource* a = new TestResource(context->getGpu()); |
| 255 TestResource* b = new TestResource(context->getGpu()); | 299 TestResource* b = new TestResource(context->getGpu()); |
| 256 TestResource* c = new TestResource(context->getGpu()); | 300 TestResource* c = new TestResource(context->getGpu()); |
| 257 cache->addResource(key1, a); | 301 a->cacheAccess().setContentKey(key1); |
| 258 cache->addResource(key2, b); | 302 b->cacheAccess().setContentKey(key2); |
| 259 cache->addResource(key3, c); | 303 c->cacheAccess().setContentKey(key3); |
| 260 a->unref(); | 304 a->unref(); |
| 261 b->unref(); | 305 b->unref(); |
| 262 c->unref(); | 306 c->unref(); |
| 263 | 307 |
| 264 REPORTER_ASSERT(reporter, cache2->hasContentKey(key1)); | 308 REPORTER_ASSERT(reporter, cache2->hasContentKey(key1)); |
| 265 REPORTER_ASSERT(reporter, cache2->hasContentKey(key2)); | 309 REPORTER_ASSERT(reporter, cache2->hasContentKey(key2)); |
| 266 REPORTER_ASSERT(reporter, cache2->hasContentKey(key3)); | 310 REPORTER_ASSERT(reporter, cache2->hasContentKey(key3)); |
| 267 | 311 |
| 268 // Invalidate two of the three, they should be purged and destroyed. | 312 // Invalidate two of the three, they should be purged and destroyed. |
| 269 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); | 313 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); |
| 270 const GrResourceInvalidatedMessage msg1 = { key1 }; | 314 const GrResourceInvalidatedMessage msg1 = { key1 }; |
| 271 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg1); | 315 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg1); |
| 272 const GrResourceInvalidatedMessage msg2 = { key2 }; | 316 const GrResourceInvalidatedMessage msg2 = { key2 }; |
| 273 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg2); | 317 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg2); |
| 274 cache->purgeAsNeeded(); | |
| 275 #if 0 // Disabled until reimplemented in GrResourceCache2. | 318 #if 0 // Disabled until reimplemented in GrResourceCache2. |
| 319 cache2->purgeAsNeeded(); |
| 276 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); | 320 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); |
| 277 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1)); | 321 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1)); |
| 278 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key2)); | 322 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key2)); |
| 279 REPORTER_ASSERT(reporter, cache2->hasContentKey(key3)); | 323 REPORTER_ASSERT(reporter, cache2->hasContentKey(key3)); |
| 280 #endif | 324 #endif |
| 281 | 325 |
| 282 // Invalidate the third. | 326 // Invalidate the third. |
| 283 const GrResourceInvalidatedMessage msg3 = { key3 }; | 327 const GrResourceInvalidatedMessage msg3 = { key3 }; |
| 284 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg3); | 328 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg3); |
| 285 cache->purgeAsNeeded(); | |
| 286 #if 0 // Disabled until reimplemented in GrResourceCache2. | 329 #if 0 // Disabled until reimplemented in GrResourceCache2. |
| 330 cache2->purgeAsNeeded(); |
| 287 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); | 331 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); |
| 288 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key3)); | 332 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key3)); |
| 289 #endif | 333 #endif |
| 334 |
| 335 cache2->purgeAllUnlocked(); |
| 336 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); |
| 337 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount()); |
| 338 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes()); |
| 290 } | 339 } |
| 291 | 340 |
| 292 static void test_cache_delete_on_destruction(skiatest::Reporter* reporter) { | 341 static void test_cache_chained_purge(skiatest::Reporter* reporter) { |
| 293 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); | 342 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
| 294 REPORTER_ASSERT(reporter, SkToBool(context)); | 343 REPORTER_ASSERT(reporter, SkToBool(context)); |
| 295 if (NULL == context) { | 344 if (NULL == context) { |
| 296 return; | 345 return; |
| 297 } | 346 } |
| 298 | 347 |
| 299 GrCacheID::Domain domain = GrCacheID::GenerateDomain(); | 348 GrCacheID::Domain domain = GrCacheID::GenerateDomain(); |
| 300 GrCacheID::Key keyData; | 349 GrCacheID::Key keyData; |
| 301 memset(&keyData, 0, sizeof(keyData)); | 350 memset(&keyData, 0, sizeof(keyData)); |
| 302 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); | 351 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); |
| 303 | 352 |
| 304 keyData.fData64[0] = 1; | 353 keyData.fData64[0] = 1; |
| 305 GrResourceKey key1(GrCacheID(domain, keyData), t, 0); | 354 GrResourceKey key1(GrCacheID(domain, keyData), t, 0); |
| 306 | 355 |
| 307 keyData.fData64[0] = 2; | 356 keyData.fData64[0] = 2; |
| 308 GrResourceKey key2(GrCacheID(domain, keyData), t, 0); | 357 GrResourceKey key2(GrCacheID(domain, keyData), t, 0); |
| 309 | 358 |
| 310 { | 359 { |
| 311 context->setResourceCacheLimits(3, 30000); | 360 context->setResourceCacheLimits(3, 30000); |
| 312 GrResourceCache* cache = context->getResourceCache(); | 361 GrResourceCache2* cache2 = context->getResourceCache2(); |
| 313 cache->purgeAllUnlocked(); | 362 cache2->purgeAllUnlocked(); |
| 314 SkASSERT(0 == cache->getCachedResourceCount() && 0 == cache->getCachedRe
sourceBytes()); | 363 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceByte
s()); |
| 315 | 364 |
| 316 TestResource* a = new TestResource(context->getGpu()); | 365 TestResource* a = new TestResource(context->getGpu()); |
| 317 TestResource* b = new TestResource(context->getGpu()); | 366 TestResource* b = new TestResource(context->getGpu()); |
| 318 cache->addResource(key1, a); | 367 a->cacheAccess().setContentKey(key1); |
| 319 cache->addResource(key2, b); | 368 b->cacheAccess().setContentKey(key2); |
| 320 | 369 |
| 321 a->setDeleteWhenDestroyed(cache, b); | 370 // Make a cycle |
| 322 b->setDeleteWhenDestroyed(cache, a); | 371 a->setUnrefWhenDestroyed(b); |
| 372 b->setUnrefWhenDestroyed(a); |
| 373 |
| 374 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 323 | 375 |
| 324 a->unref(); | 376 a->unref(); |
| 325 b->unref(); | 377 b->unref(); |
| 326 | 378 |
| 327 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); | 379 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 328 | 380 |
| 329 cache->purgeAllUnlocked(); | 381 cache2->purgeAllUnlocked(); |
| 330 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); | 382 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 331 } | |
| 332 { | |
| 333 context->setResourceCacheLimits(3, 30000); | |
| 334 GrResourceCache* cache = context->getResourceCache(); | |
| 335 cache->purgeAllUnlocked(); | |
| 336 SkASSERT(0 == cache->getCachedResourceCount() && 0 == cache->getCachedRe
sourceBytes()); | |
| 337 | 383 |
| 338 TestResource* a = new TestResource(context->getGpu()); | 384 // Break the cycle |
| 339 TestResource* b = new TestResource(context->getGpu()); | 385 a->setUnrefWhenDestroyed(NULL); |
| 340 cache->addResource(key1, a); | 386 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
| 341 cache->addResource(key2, b); | |
| 342 | 387 |
| 343 a->setDeleteWhenDestroyed(cache, b); | 388 cache2->purgeAllUnlocked(); |
| 344 b->setDeleteWhenDestroyed(cache, a); | |
| 345 | |
| 346 a->unref(); | |
| 347 b->unref(); | |
| 348 | |
| 349 cache->deleteResource(a->cacheAccess().getCacheEntry()); | |
| 350 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); | 389 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); |
| 351 } | 390 } |
| 352 } | 391 } |
| 353 | 392 |
| 354 static void test_resource_size_changed(skiatest::Reporter* reporter) { | 393 static void test_resource_size_changed(skiatest::Reporter* reporter) { |
| 355 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); | 394 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
| 356 REPORTER_ASSERT(reporter, SkToBool(context)); | 395 REPORTER_ASSERT(reporter, SkToBool(context)); |
| 357 if (NULL == context) { | 396 if (NULL == context) { |
| 358 return; | 397 return; |
| 359 } | 398 } |
| 360 | 399 |
| 361 GrCacheID::Domain domain = GrCacheID::GenerateDomain(); | 400 GrCacheID::Domain domain = GrCacheID::GenerateDomain(); |
| 362 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); | 401 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); |
| 363 | 402 |
| 364 GrCacheID::Key key1Data; | 403 GrCacheID::Key key1Data; |
| 365 key1Data.fData64[0] = 0; | 404 key1Data.fData64[0] = 0; |
| 366 key1Data.fData64[1] = 0; | 405 key1Data.fData64[1] = 0; |
| 367 GrResourceKey key1(GrCacheID(domain, key1Data), t, 0); | 406 GrResourceKey key1(GrCacheID(domain, key1Data), t, 0); |
| 368 | 407 |
| 369 GrCacheID::Key key2Data; | 408 GrCacheID::Key key2Data; |
| 370 key2Data.fData64[0] = 1; | 409 key2Data.fData64[0] = 1; |
| 371 key2Data.fData64[1] = 0; | 410 key2Data.fData64[1] = 0; |
| 372 GrResourceKey key2(GrCacheID(domain, key2Data), t, 0); | 411 GrResourceKey key2(GrCacheID(domain, key2Data), t, 0); |
| 373 | 412 |
| 374 // Test changing resources sizes (both increase & decrease). | 413 // Test changing resources sizes (both increase & decrease). |
| 375 { | 414 { |
| 376 context->setResourceCacheLimits(3, 30000); | 415 context->setResourceCacheLimits(3, 30000); |
| 377 GrResourceCache* cache = context->getResourceCache(); | |
| 378 GrResourceCache2* cache2 = context->getResourceCache2(); | 416 GrResourceCache2* cache2 = context->getResourceCache2(); |
| 379 cache->purgeAllUnlocked(); | 417 cache2->purgeAllUnlocked(); |
| 380 SkASSERT(0 == cache->getCachedResourceCount() && 0 == cache->getCachedRe
sourceBytes()); | 418 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceByte
s()); |
| 381 | 419 |
| 382 TestResource* a = new TestResource(context->getGpu()); | 420 TestResource* a = new TestResource(context->getGpu()); |
| 383 a->setSize(100); // Test didChangeGpuMemorySize() when not in the cache. | 421 a->cacheAccess().setContentKey(key1); |
| 384 cache->addResource(key1, a); | |
| 385 a->unref(); | 422 a->unref(); |
| 386 | 423 |
| 387 TestResource* b = new TestResource(context->getGpu()); | 424 TestResource* b = new TestResource(context->getGpu()); |
| 388 b->setSize(100); | 425 b->cacheAccess().setContentKey(key2); |
| 389 cache->addResource(key2, b); | |
| 390 b->unref(); | 426 b->unref(); |
| 391 | 427 |
| 392 REPORTER_ASSERT(reporter, 200 == cache->getCachedResourceBytes()); | 428 REPORTER_ASSERT(reporter, 200 == cache2->getResourceBytes()); |
| 393 REPORTER_ASSERT(reporter, 2 == cache->getCachedResourceCount()); | 429 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
| 394 { | 430 { |
| 395 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(cache2->
findAndRefContentResource(key2))); | 431 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(cache2->
findAndRefContentResource(key2))); |
| 396 find2->setSize(200); | 432 find2->setSize(200); |
| 397 SkAutoTUnref<TestResource> find1(static_cast<TestResource*>(cache2->
findAndRefContentResource(key1))); | 433 SkAutoTUnref<TestResource> find1(static_cast<TestResource*>(cache2->
findAndRefContentResource(key1))); |
| 398 find1->setSize(50); | 434 find1->setSize(50); |
| 399 } | 435 } |
| 400 | 436 |
| 401 REPORTER_ASSERT(reporter, 250 == cache->getCachedResourceBytes()); | 437 REPORTER_ASSERT(reporter, 250 == cache2->getResourceBytes()); |
| 402 REPORTER_ASSERT(reporter, 2 == cache->getCachedResourceCount()); | 438 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
| 403 } | 439 } |
| 404 | 440 |
| 405 // Test increasing a resources size beyond the cache budget. | 441 // Test increasing a resources size beyond the cache budget. |
| 406 { | 442 { |
| 407 context->setResourceCacheLimits(2, 300); | 443 context->setResourceCacheLimits(2, 300); |
| 408 GrResourceCache* cache = context->getResourceCache(); | |
| 409 GrResourceCache2* cache2 = context->getResourceCache2(); | 444 GrResourceCache2* cache2 = context->getResourceCache2(); |
| 410 cache->purgeAllUnlocked(); | 445 cache2->purgeAllUnlocked(); |
| 411 SkASSERT(0 == cache->getCachedResourceCount() && 0 == cache->getCachedRe
sourceBytes()); | 446 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceByte
s()); |
| 412 | 447 |
| 413 TestResource* a = new TestResource(context->getGpu()); | 448 TestResource* a = new TestResource(context->getGpu()); |
| 414 a->setSize(100); | 449 a->setSize(100); |
| 415 cache->addResource(key1, a); | 450 a->cacheAccess().setContentKey(key1); |
| 416 a->unref(); | 451 a->unref(); |
| 417 | 452 |
| 418 TestResource* b = new TestResource(context->getGpu()); | 453 TestResource* b = new TestResource(context->getGpu()); |
| 419 b->setSize(100); | 454 b->setSize(100); |
| 420 cache->addResource(key2, b); | 455 b->cacheAccess().setContentKey(key2); |
| 421 b->unref(); | 456 b->unref(); |
| 422 | 457 |
| 423 REPORTER_ASSERT(reporter, 200 == cache->getCachedResourceBytes()); | 458 REPORTER_ASSERT(reporter, 200 == cache2->getResourceBytes()); |
| 424 REPORTER_ASSERT(reporter, 2 == cache->getCachedResourceCount()); | 459 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
| 425 | 460 |
| 426 { | 461 { |
| 427 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(cache2->
findAndRefContentResource(key2))); | 462 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(cache2->
findAndRefContentResource(key2))); |
| 428 find2->setSize(201); | 463 find2->setSize(201); |
| 429 } | 464 } |
| 430 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1)); | 465 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1)); |
| 431 | 466 |
| 432 REPORTER_ASSERT(reporter, 201 == cache->getCachedResourceBytes()); | 467 REPORTER_ASSERT(reporter, 201 == cache2->getResourceBytes()); |
| 433 REPORTER_ASSERT(reporter, 1 == cache->getCachedResourceCount()); | 468 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount()); |
| 434 } | 469 } |
| 435 } | 470 } |
| 436 | 471 |
| 437 //////////////////////////////////////////////////////////////////////////////// | 472 //////////////////////////////////////////////////////////////////////////////// |
| 438 DEF_GPUTEST(ResourceCache, reporter, factory) { | 473 DEF_GPUTEST(ResourceCache, reporter, factory) { |
| 439 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { | 474 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { |
| 440 GrContextFactory::GLContextType glType = static_cast<GrContextFactory::G
LContextType>(type); | 475 GrContextFactory::GLContextType glType = static_cast<GrContextFactory::G
LContextType>(type); |
| 441 if (!GrContextFactory::IsRenderingGLContext(glType)) { | 476 if (!GrContextFactory::IsRenderingGLContext(glType)) { |
| 442 continue; | 477 continue; |
| 443 } | 478 } |
| 444 GrContext* context = factory->get(glType); | 479 GrContext* context = factory->get(glType); |
| 445 if (NULL == context) { | 480 if (NULL == context) { |
| 446 continue; | 481 continue; |
| 447 } | 482 } |
| 448 GrSurfaceDesc desc; | 483 GrSurfaceDesc desc; |
| 449 desc.fConfig = kSkia8888_GrPixelConfig; | 484 desc.fConfig = kSkia8888_GrPixelConfig; |
| 450 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 485 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 451 desc.fWidth = gWidth; | 486 desc.fWidth = gWidth; |
| 452 desc.fHeight = gHeight; | 487 desc.fHeight = gHeight; |
| 453 SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight); | 488 SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight); |
| 454 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, info
)); | 489 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, info
)); |
| 455 test_cache(reporter, context, surface->getCanvas()); | 490 test_cache(reporter, context, surface->getCanvas()); |
| 456 } | 491 } |
| 457 | 492 |
| 458 // The below tests create their own mock contexts. | 493 // The below tests create their own mock contexts. |
| 494 test_no_key(reporter); |
| 459 test_duplicate_content_key(reporter); | 495 test_duplicate_content_key(reporter); |
| 460 test_duplicate_scratch_key(reporter); | 496 test_duplicate_scratch_key(reporter); |
| 461 test_purge_invalidated(reporter); | 497 test_purge_invalidated(reporter); |
| 462 test_cache_delete_on_destruction(reporter); | 498 test_cache_chained_purge(reporter); |
| 463 test_resource_size_changed(reporter); | 499 test_resource_size_changed(reporter); |
| 464 } | 500 } |
| 465 | 501 |
| 466 #endif | 502 #endif |
| OLD | NEW |