blob: 5fef3d0e75b6276db2210de644c37b83aefcf399 [file] [log] [blame]
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +00008#if SK_SUPPORT_GPU
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +00009
bsalomonbcf0a522014-10-08 08:40:09 -070010#include "GrContext.h"
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000011#include "GrContextFactory.h"
bsalomonbcf0a522014-10-08 08:40:09 -070012#include "GrGpu.h"
bsalomon33435572014-11-05 14:47:41 -080013#include "GrResourceCache2.h"
bsalomonbcf0a522014-10-08 08:40:09 -070014#include "SkCanvas.h"
bsalomon71cb0c22014-11-14 12:10:14 -080015#include "SkGr.h"
16#include "SkMessageBus.h"
reed69f6f002014-09-18 06:09:44 -070017#include "SkSurface.h"
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +000018#include "Test.h"
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000019
20static const int gWidth = 640;
21static const int gHeight = 480;
22
23////////////////////////////////////////////////////////////////////////////////
bsalomon33435572014-11-05 14:47:41 -080024static void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanvas* canvas) {
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000025 const SkIRect size = SkIRect::MakeWH(gWidth, gHeight);
26
27 SkBitmap src;
mike@reedtribe.orgdeee4962014-02-13 14:41:43 +000028 src.allocN32Pixels(size.width(), size.height());
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000029 src.eraseColor(SK_ColorBLACK);
30 size_t srcSize = src.getSize();
31
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000032 size_t initialCacheSize;
33 context->getResourceCacheUsage(NULL, &initialCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000034
35 int oldMaxNum;
36 size_t oldMaxBytes;
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000037 context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes);
skia.committer@gmail.com17f1ae62013-08-09 07:01:22 +000038
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000039 // Set the cache limits so we can fit 10 "src" images and the
40 // max number of textures doesn't matter
41 size_t maxCacheSize = initialCacheSize + 10*srcSize;
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000042 context->setResourceCacheLimits(1000, maxCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000043
44 SkBitmap readback;
mike@reedtribe.orgdeee4962014-02-13 14:41:43 +000045 readback.allocN32Pixels(size.width(), size.height());
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000046
47 for (int i = 0; i < 100; ++i) {
48 canvas->drawBitmap(src, 0, 0);
49 canvas->readPixels(size, &readback);
50
51 // "modify" the src texture
52 src.notifyPixelsChanged();
53
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000054 size_t curCacheSize;
55 context->getResourceCacheUsage(NULL, &curCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000056
57 // we should never go over the size limit
58 REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize);
59 }
60
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000061 context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000062}
63
bsalomon6d3fe022014-07-25 08:35:45 -070064class TestResource : public GrGpuResource {
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000065 static const size_t kDefaultSize = 100;
66
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +000067public:
68 SK_DECLARE_INST_COUNT(TestResource);
bsalomondace19e2014-11-17 07:34:06 -080069 TestResource(GrGpu* gpu, bool isWrapped)
70 : INHERITED(gpu, isWrapped)
71 , fToDelete(NULL)
72 , fSize(kDefaultSize) {
73 ++fNumAlive;
74 this->registerWithCache();
75 }
76
bsalomon8b79d232014-11-10 10:19:06 -080077 TestResource(GrGpu* gpu)
bsalomonc44be0e2014-07-25 07:32:33 -070078 : INHERITED(gpu, false)
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000079 , fToDelete(NULL)
bsalomon8b79d232014-11-10 10:19:06 -080080 , fSize(kDefaultSize) {
81 ++fNumAlive;
82 this->registerWithCache();
83 }
84
85 TestResource(GrGpu* gpu, const GrResourceKey& scratchKey)
86 : INHERITED(gpu, false)
bsalomon8b79d232014-11-10 10:19:06 -080087 , fToDelete(NULL)
88 , fSize(kDefaultSize) {
89 this->setScratchKey(scratchKey);
bsalomon33435572014-11-05 14:47:41 -080090 ++fNumAlive;
bsalomon16961262014-08-26 14:01:07 -070091 this->registerWithCache();
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +000092 }
93
94 ~TestResource() {
bsalomon33435572014-11-05 14:47:41 -080095 --fNumAlive;
bsalomon71cb0c22014-11-14 12:10:14 -080096 SkSafeUnref(fToDelete);
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +000097 }
98
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000099 void setSize(size_t size) {
100 fSize = size;
101 this->didChangeGpuMemorySize();
102 }
103
bsalomon33435572014-11-05 14:47:41 -0800104 static int NumAlive() { return fNumAlive; }
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000105
bsalomon71cb0c22014-11-14 12:10:14 -0800106 void setUnrefWhenDestroyed(TestResource* resource) {
107 SkRefCnt_SafeAssign(fToDelete, resource);
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000108 }
109
110private:
bsalomon69ed47f2014-11-12 11:13:39 -0800111 size_t onGpuMemorySize() const SK_OVERRIDE { return fSize; }
112
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000113 TestResource* fToDelete;
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000114 size_t fSize;
bsalomon33435572014-11-05 14:47:41 -0800115 static int fNumAlive;
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000116
bsalomon6d3fe022014-07-25 08:35:45 -0700117 typedef GrGpuResource INHERITED;
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000118};
bsalomon33435572014-11-05 14:47:41 -0800119int TestResource::fNumAlive = 0;
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000120
bsalomon71cb0c22014-11-14 12:10:14 -0800121static void test_no_key(skiatest::Reporter* reporter) {
122 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
123 REPORTER_ASSERT(reporter, SkToBool(context));
124 if (NULL == context) {
125 return;
126 }
127 context->setResourceCacheLimits(10, 30000);
128 GrResourceCache2* cache2 = context->getResourceCache2();
129 cache2->purgeAllUnlocked();
130 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
131
132 // Create a bunch of resources with no keys
133 TestResource* a = new TestResource(context->getGpu());
134 TestResource* b = new TestResource(context->getGpu());
135 TestResource* c = new TestResource(context->getGpu());
136 TestResource* d = new TestResource(context->getGpu());
137 a->setSize(11);
138 b->setSize(12);
139 c->setSize(13);
140 d->setSize(14);
141
142 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
143 REPORTER_ASSERT(reporter, 4 == cache2->getResourceCount());
144 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
145 d->gpuMemorySize() == cache2->getResourceBytes());
146
147 // Should be safe to purge without deleting the resources since we still have refs.
148 cache2->purgeAllUnlocked();
149 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
150
151 // Since the resources have neither content nor scratch keys, delete immediately upon unref.
152
153 a->unref();
154 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
155 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount());
156 REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() ==
157 cache2->getResourceBytes());
158
159 c->unref();
160 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
161 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
162 REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() ==
163 cache2->getResourceBytes());
164
165 d->unref();
166 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
167 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
168 REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache2->getResourceBytes());
169
170 b->unref();
171 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
172 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
173 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
174}
175
bsalomondace19e2014-11-17 07:34:06 -0800176static void test_wrapped(skiatest::Reporter* reporter) {
177 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
178 REPORTER_ASSERT(reporter, SkToBool(context));
179 if (NULL == context) {
180 return;
181 }
182 context->setResourceCacheLimits(10, 300);
183 GrResourceCache2* cache2 = context->getResourceCache2();
184 cache2->purgeAllUnlocked();
185 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
186 SkASSERT(0 == cache2->getBudgetedResourceCount() && 0 == cache2->getBudgetedResourceBytes());
187
188 GrCacheID::Key keyData;
189 memset(&keyData, 0, sizeof(keyData));
190 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType();
191 GrResourceKey scratchKey(GrCacheID(GrResourceKey::ScratchDomain(), keyData), t, 0);
192 GrResourceKey contentKey(GrCacheID(GrCacheID::GenerateDomain(), keyData), t, 0);
193
194 // Create a scratch, a content, and a wrapped resource
195 TestResource* scratch = new TestResource(context->getGpu(), scratchKey);
196 scratch->setSize(10);
197 TestResource* content = new TestResource(context->getGpu());
198 scratch->setSize(11);
199 REPORTER_ASSERT(reporter, content->cacheAccess().setContentKey(contentKey));
200 TestResource* wrapped = new TestResource(context->getGpu(), true);
201 scratch->setSize(12);
202
203 // Make sure we can't add a content key to the wrapped resource
204 keyData.fData8[0] = 1;
205 GrResourceKey contentKey2(GrCacheID(GrCacheID::GenerateDomain(), keyData), t, 0);
206 REPORTER_ASSERT(reporter, !wrapped->cacheAccess().setContentKey(contentKey2));
207 REPORTER_ASSERT(reporter, NULL == cache2->findAndRefContentResource(contentKey2));
208
209 // Make sure sizes are as we expect
210 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount());
211 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() +
212 wrapped->gpuMemorySize() == cache2->getResourceBytes());
213 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
214 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() ==
215 cache2->getBudgetedResourceBytes());
216
217 // Our refs mean that the resources are non purgable.
218 cache2->purgeAllUnlocked();
219 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount());
220 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() +
221 wrapped->gpuMemorySize() == cache2->getResourceBytes());
222 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
223 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() ==
224 cache2->getBudgetedResourceBytes());
225
226 // Unreffing the wrapped resource should free it right away.
227 wrapped->unref();
228 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
229 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() ==
230 cache2->getResourceBytes());
231
232 // Now try freeing the other two resources first
233 wrapped = new TestResource(context->getGpu(), true);
234 scratch->setSize(12);
235 content->unref();
236 cache2->purgeAllUnlocked();
237 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
238 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() ==
239 cache2->getResourceBytes());
240 REPORTER_ASSERT(reporter, 1 == cache2->getBudgetedResourceCount());
241 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache2->getBudgetedResourceBytes());
242
243 scratch->unref();
244 cache2->purgeAllUnlocked();
245 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
246 REPORTER_ASSERT(reporter, wrapped->gpuMemorySize() == cache2->getResourceBytes());
247 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
248 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
249
250 wrapped->unref();
251 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
252 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
253}
254
bsalomon8b79d232014-11-10 10:19:06 -0800255static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
256 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
257 REPORTER_ASSERT(reporter, SkToBool(context));
258 if (NULL == context) {
259 return;
260 }
261 context->setResourceCacheLimits(5, 30000);
bsalomon71cb0c22014-11-14 12:10:14 -0800262 GrResourceCache2* cache2 = context->getResourceCache2();
263 cache2->purgeAllUnlocked();
264 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800265
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000266 GrCacheID::Key keyData;
bsalomon48ea2022014-11-12 10:28:17 -0800267 memset(&keyData, 0, sizeof(keyData));
bsalomon8b79d232014-11-10 10:19:06 -0800268 GrCacheID::Domain domain = GrResourceKey::ScratchDomain();
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000269 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType();
bsalomon8b79d232014-11-10 10:19:06 -0800270 GrResourceKey scratchKey(GrCacheID(domain, keyData), t, 0);
271
272 // Create two resources that have the same scratch key.
273 TestResource* a = new TestResource(context->getGpu(), scratchKey);
274 TestResource* b = new TestResource(context->getGpu(), scratchKey);
275 a->setSize(11);
276 b->setSize(12);
277 // Scratch resources are registered with GrResourceCache2 just by existing. There are 2.
bsalomon8b79d232014-11-10 10:19:06 -0800278 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
279 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey(scratchKey));)
bsalomon71cb0c22014-11-14 12:10:14 -0800280 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
281 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
282 cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800283
284 // Our refs mean that the resources are non purgable.
bsalomon71cb0c22014-11-14 12:10:14 -0800285 cache2->purgeAllUnlocked();
bsalomon8b79d232014-11-10 10:19:06 -0800286 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon71cb0c22014-11-14 12:10:14 -0800287 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
bsalomon8b79d232014-11-10 10:19:06 -0800288
289 // Unref but don't purge
290 a->unref();
291 b->unref();
292 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
293 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey(scratchKey));)
294
295 // Purge again. This time resources should be purgable.
bsalomon71cb0c22014-11-14 12:10:14 -0800296 cache2->purgeAllUnlocked();
bsalomon8b79d232014-11-10 10:19:06 -0800297 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
bsalomon71cb0c22014-11-14 12:10:14 -0800298 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
bsalomon8b79d232014-11-10 10:19:06 -0800299 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));)
300}
301
302static void test_duplicate_content_key(skiatest::Reporter* reporter) {
303 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
304 REPORTER_ASSERT(reporter, SkToBool(context));
305 if (NULL == context) {
306 return;
307 }
bsalomon33435572014-11-05 14:47:41 -0800308 context->setResourceCacheLimits(5, 30000);
bsalomon71cb0c22014-11-14 12:10:14 -0800309 GrResourceCache2* cache2 = context->getResourceCache2();
310 cache2->purgeAllUnlocked();
311 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000312
bsalomon8b79d232014-11-10 10:19:06 -0800313 GrCacheID::Domain domain = GrCacheID::GenerateDomain();
314 GrCacheID::Key keyData;
315 memset(&keyData, 0, sizeof(keyData));
316 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType();
317 GrResourceKey key(GrCacheID(domain, keyData), t, 0);
318
bsalomon8b79d232014-11-10 10:19:06 -0800319 // Create two resources that we will attempt to register with the same content key.
bsalomonc44be0e2014-07-25 07:32:33 -0700320 TestResource* a = new TestResource(context->getGpu());
321 TestResource* b = new TestResource(context->getGpu());
bsalomon8b79d232014-11-10 10:19:06 -0800322 a->setSize(11);
323 b->setSize(12);
bsalomon71cb0c22014-11-14 12:10:14 -0800324
325 // Can't set the same content key on two resources.
326 REPORTER_ASSERT(reporter, a->cacheAccess().setContentKey(key));
327 REPORTER_ASSERT(reporter, !b->cacheAccess().setContentKey(key));
328
329 // Still have two resources because b is still reffed.
330 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
331 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
332 cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800333 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
334
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000335 b->unref();
bsalomon71cb0c22014-11-14 12:10:14 -0800336 // Now b should be gone.
337 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
338 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800339 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000340
bsalomon71cb0c22014-11-14 12:10:14 -0800341 cache2->purgeAllUnlocked();
342 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
343 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes());
344 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
345
346 // Drop the ref on a but it isn't immediately purged as it still has a valid scratch key.
bsalomon8b79d232014-11-10 10:19:06 -0800347 a->unref();
bsalomon71cb0c22014-11-14 12:10:14 -0800348 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
349 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes());
350 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
351
352 cache2->purgeAllUnlocked();
353 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
354 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
bsalomon33435572014-11-05 14:47:41 -0800355 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000356}
357
bsalomon8b79d232014-11-10 10:19:06 -0800358static void test_purge_invalidated(skiatest::Reporter* reporter) {
359 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
360 REPORTER_ASSERT(reporter, SkToBool(context));
361 if (NULL == context) {
362 return;
363 }
364
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000365 GrCacheID::Domain domain = GrCacheID::GenerateDomain();
366 GrCacheID::Key keyData;
bsalomon8b79d232014-11-10 10:19:06 -0800367 memset(&keyData, 0, sizeof(keyData));
368
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000369 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType();
370
bsalomon8b79d232014-11-10 10:19:06 -0800371 keyData.fData64[0] = 1;
372 GrResourceKey key1(GrCacheID(domain, keyData), t, 0);
373 keyData.fData64[0] = 2;
374 GrResourceKey key2(GrCacheID(domain, keyData), t, 0);
375 keyData.fData64[0] = 3;
376 GrResourceKey key3(GrCacheID(domain, keyData), t, 0);
377
378 context->setResourceCacheLimits(5, 30000);
bsalomon8b79d232014-11-10 10:19:06 -0800379 GrResourceCache2* cache2 = context->getResourceCache2();
bsalomon71cb0c22014-11-14 12:10:14 -0800380 cache2->purgeAllUnlocked();
381 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800382
383 // Add three resources to the cache.
384 TestResource* a = new TestResource(context->getGpu());
385 TestResource* b = new TestResource(context->getGpu());
386 TestResource* c = new TestResource(context->getGpu());
bsalomon71cb0c22014-11-14 12:10:14 -0800387 a->cacheAccess().setContentKey(key1);
388 b->cacheAccess().setContentKey(key2);
389 c->cacheAccess().setContentKey(key3);
bsalomon8b79d232014-11-10 10:19:06 -0800390 a->unref();
391 b->unref();
392 c->unref();
393
394 REPORTER_ASSERT(reporter, cache2->hasContentKey(key1));
395 REPORTER_ASSERT(reporter, cache2->hasContentKey(key2));
396 REPORTER_ASSERT(reporter, cache2->hasContentKey(key3));
397
398 // Invalidate two of the three, they should be purged and destroyed.
399 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
400 const GrResourceInvalidatedMessage msg1 = { key1 };
401 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg1);
402 const GrResourceInvalidatedMessage msg2 = { key2 };
403 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg2);
bsalomon6d4488c2014-11-11 07:27:16 -0800404#if 0 // Disabled until reimplemented in GrResourceCache2.
bsalomon71cb0c22014-11-14 12:10:14 -0800405 cache2->purgeAsNeeded();
bsalomon8b79d232014-11-10 10:19:06 -0800406 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
407 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1));
408 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key2));
409 REPORTER_ASSERT(reporter, cache2->hasContentKey(key3));
bsalomon6d4488c2014-11-11 07:27:16 -0800410#endif
bsalomon8b79d232014-11-10 10:19:06 -0800411
412 // Invalidate the third.
413 const GrResourceInvalidatedMessage msg3 = { key3 };
414 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg3);
bsalomon6d4488c2014-11-11 07:27:16 -0800415#if 0 // Disabled until reimplemented in GrResourceCache2.
bsalomon71cb0c22014-11-14 12:10:14 -0800416 cache2->purgeAsNeeded();
bsalomon8b79d232014-11-10 10:19:06 -0800417 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
418 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key3));
bsalomon6d4488c2014-11-11 07:27:16 -0800419#endif
bsalomon71cb0c22014-11-14 12:10:14 -0800420
421 cache2->purgeAllUnlocked();
422 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
423 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
424 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800425}
426
bsalomon71cb0c22014-11-14 12:10:14 -0800427static void test_cache_chained_purge(skiatest::Reporter* reporter) {
bsalomon8b79d232014-11-10 10:19:06 -0800428 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
429 REPORTER_ASSERT(reporter, SkToBool(context));
430 if (NULL == context) {
431 return;
432 }
433
434 GrCacheID::Domain domain = GrCacheID::GenerateDomain();
435 GrCacheID::Key keyData;
436 memset(&keyData, 0, sizeof(keyData));
437 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType();
438
439 keyData.fData64[0] = 1;
440 GrResourceKey key1(GrCacheID(domain, keyData), t, 0);
441
442 keyData.fData64[0] = 2;
443 GrResourceKey key2(GrCacheID(domain, keyData), t, 0);
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000444
445 {
bsalomon33435572014-11-05 14:47:41 -0800446 context->setResourceCacheLimits(3, 30000);
bsalomon71cb0c22014-11-14 12:10:14 -0800447 GrResourceCache2* cache2 = context->getResourceCache2();
448 cache2->purgeAllUnlocked();
449 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000450
bsalomon820dd6c2014-11-05 12:09:45 -0800451 TestResource* a = new TestResource(context->getGpu());
452 TestResource* b = new TestResource(context->getGpu());
bsalomon71cb0c22014-11-14 12:10:14 -0800453 a->cacheAccess().setContentKey(key1);
454 b->cacheAccess().setContentKey(key2);
bsalomon820dd6c2014-11-05 12:09:45 -0800455
bsalomon71cb0c22014-11-14 12:10:14 -0800456 // Make a cycle
457 a->setUnrefWhenDestroyed(b);
458 b->setUnrefWhenDestroyed(a);
459
460 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon33435572014-11-05 14:47:41 -0800461
462 a->unref();
463 b->unref();
bsalomon8b79d232014-11-10 10:19:06 -0800464
bsalomon33435572014-11-05 14:47:41 -0800465 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon8b79d232014-11-10 10:19:06 -0800466
bsalomon71cb0c22014-11-14 12:10:14 -0800467 cache2->purgeAllUnlocked();
468 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon8b79d232014-11-10 10:19:06 -0800469
bsalomon71cb0c22014-11-14 12:10:14 -0800470 // Break the cycle
471 a->setUnrefWhenDestroyed(NULL);
472 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon33435572014-11-05 14:47:41 -0800473
bsalomon71cb0c22014-11-14 12:10:14 -0800474 cache2->purgeAllUnlocked();
bsalomon33435572014-11-05 14:47:41 -0800475 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000476 }
477}
478
bsalomon8b79d232014-11-10 10:19:06 -0800479static void test_resource_size_changed(skiatest::Reporter* reporter) {
480 SkAutoTUnref<GrContext> context(GrContext::CreateMockContext());
481 REPORTER_ASSERT(reporter, SkToBool(context));
482 if (NULL == context) {
483 return;
484 }
485
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000486 GrCacheID::Domain domain = GrCacheID::GenerateDomain();
487 GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType();
488
489 GrCacheID::Key key1Data;
490 key1Data.fData64[0] = 0;
491 key1Data.fData64[1] = 0;
492 GrResourceKey key1(GrCacheID(domain, key1Data), t, 0);
493
494 GrCacheID::Key key2Data;
495 key2Data.fData64[0] = 1;
496 key2Data.fData64[1] = 0;
497 GrResourceKey key2(GrCacheID(domain, key2Data), t, 0);
498
499 // Test changing resources sizes (both increase & decrease).
500 {
bsalomon33435572014-11-05 14:47:41 -0800501 context->setResourceCacheLimits(3, 30000);
bsalomon8b79d232014-11-10 10:19:06 -0800502 GrResourceCache2* cache2 = context->getResourceCache2();
bsalomon71cb0c22014-11-14 12:10:14 -0800503 cache2->purgeAllUnlocked();
504 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000505
bsalomonc44be0e2014-07-25 07:32:33 -0700506 TestResource* a = new TestResource(context->getGpu());
bsalomon71cb0c22014-11-14 12:10:14 -0800507 a->cacheAccess().setContentKey(key1);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000508 a->unref();
509
bsalomonc44be0e2014-07-25 07:32:33 -0700510 TestResource* b = new TestResource(context->getGpu());
bsalomon71cb0c22014-11-14 12:10:14 -0800511 b->cacheAccess().setContentKey(key2);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000512 b->unref();
513
bsalomon71cb0c22014-11-14 12:10:14 -0800514 REPORTER_ASSERT(reporter, 200 == cache2->getResourceBytes());
515 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
bsalomon8b79d232014-11-10 10:19:06 -0800516 {
517 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(cache2->findAndRefContentResource(key2)));
518 find2->setSize(200);
519 SkAutoTUnref<TestResource> find1(static_cast<TestResource*>(cache2->findAndRefContentResource(key1)));
520 find1->setSize(50);
521 }
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000522
bsalomon71cb0c22014-11-14 12:10:14 -0800523 REPORTER_ASSERT(reporter, 250 == cache2->getResourceBytes());
524 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000525 }
526
527 // Test increasing a resources size beyond the cache budget.
528 {
bsalomon33435572014-11-05 14:47:41 -0800529 context->setResourceCacheLimits(2, 300);
bsalomon8b79d232014-11-10 10:19:06 -0800530 GrResourceCache2* cache2 = context->getResourceCache2();
bsalomon71cb0c22014-11-14 12:10:14 -0800531 cache2->purgeAllUnlocked();
532 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000533
bsalomon8b79d232014-11-10 10:19:06 -0800534 TestResource* a = new TestResource(context->getGpu());
535 a->setSize(100);
bsalomon71cb0c22014-11-14 12:10:14 -0800536 a->cacheAccess().setContentKey(key1);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000537 a->unref();
538
bsalomon8b79d232014-11-10 10:19:06 -0800539 TestResource* b = new TestResource(context->getGpu());
540 b->setSize(100);
bsalomon71cb0c22014-11-14 12:10:14 -0800541 b->cacheAccess().setContentKey(key2);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000542 b->unref();
543
bsalomon71cb0c22014-11-14 12:10:14 -0800544 REPORTER_ASSERT(reporter, 200 == cache2->getResourceBytes());
545 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000546
bsalomon8b79d232014-11-10 10:19:06 -0800547 {
548 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(cache2->findAndRefContentResource(key2)));
549 find2->setSize(201);
550 }
551 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1));
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000552
bsalomon71cb0c22014-11-14 12:10:14 -0800553 REPORTER_ASSERT(reporter, 201 == cache2->getResourceBytes());
554 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000555 }
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000556}
557
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000558////////////////////////////////////////////////////////////////////////////////
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +0000559DEF_GPUTEST(ResourceCache, reporter, factory) {
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000560 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
561 GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
562 if (!GrContextFactory::IsRenderingGLContext(glType)) {
563 continue;
564 }
565 GrContext* context = factory->get(glType);
bsalomonfdcf2c02014-11-05 12:30:32 -0800566 if (NULL == context) {
567 continue;
568 }
bsalomonf2703d82014-10-28 14:33:06 -0700569 GrSurfaceDesc desc;
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000570 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomonf2703d82014-10-28 14:33:06 -0700571 desc.fFlags = kRenderTarget_GrSurfaceFlag;
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000572 desc.fWidth = gWidth;
573 desc.fHeight = gHeight;
reed69f6f002014-09-18 06:09:44 -0700574 SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
reed4a8126e2014-09-22 07:29:03 -0700575 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, info));
reed69f6f002014-09-18 06:09:44 -0700576 test_cache(reporter, context, surface->getCanvas());
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000577 }
bsalomon33435572014-11-05 14:47:41 -0800578
bsalomon8b79d232014-11-10 10:19:06 -0800579 // The below tests create their own mock contexts.
bsalomon71cb0c22014-11-14 12:10:14 -0800580 test_no_key(reporter);
bsalomondace19e2014-11-17 07:34:06 -0800581 test_wrapped(reporter);
bsalomon8b79d232014-11-10 10:19:06 -0800582 test_duplicate_content_key(reporter);
583 test_duplicate_scratch_key(reporter);
584 test_purge_invalidated(reporter);
bsalomon71cb0c22014-11-14 12:10:14 -0800585 test_cache_chained_purge(reporter);
bsalomon8b79d232014-11-10 10:19:06 -0800586 test_resource_size_changed(reporter);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000587}
588
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000589#endif