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