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 |