2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
10 #include "GrContext.h"
11 #include "GrContextFactory.h"
13 #include "GrGpuResourceCacheAccess.h"
14 #include "GrGpuResourcePriv.h"
15 #include "GrRenderTarget.h"
16 #include "GrRenderTargetPriv.h"
17 #include "GrResourceCache.h"
20 #include "SkMessageBus.h"
21 #include "SkSurface.h"
24 static const int gWidth = 640;
25 static const int gHeight = 480;
27 ////////////////////////////////////////////////////////////////////////////////
28 static void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanvas* canvas) {
29 const SkIRect size = SkIRect::MakeWH(gWidth, gHeight);
32 src.allocN32Pixels(size.width(), size.height());
33 src.eraseColor(SK_ColorBLACK);
34 size_t srcSize = src.getSize();
36 size_t initialCacheSize;
37 context->getResourceCacheUsage(NULL, &initialCacheSize);
41 context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes);
43 // Set the cache limits so we can fit 10 "src" images and the
44 // max number of textures doesn't matter
45 size_t maxCacheSize = initialCacheSize + 10*srcSize;
46 context->setResourceCacheLimits(1000, maxCacheSize);
49 readback.allocN32Pixels(size.width(), size.height());
51 for (int i = 0; i < 100; ++i) {
52 canvas->drawBitmap(src, 0, 0);
53 canvas->readPixels(size, &readback);
55 // "modify" the src texture
56 src.notifyPixelsChanged();
59 context->getResourceCacheUsage(NULL, &curCacheSize);
61 // we should never go over the size limit
62 REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize);
65 context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
68 static void test_stencil_buffers(skiatest::Reporter* reporter, GrContext* context) {
69 GrSurfaceDesc smallDesc;
70 smallDesc.fFlags = kRenderTarget_GrSurfaceFlag;
71 smallDesc.fConfig = kSkia8888_GrPixelConfig;
73 smallDesc.fHeight = 4;
74 smallDesc.fSampleCnt = 0;
76 // Test that two budgeted RTs with the same desc share a stencil buffer.
77 SkAutoTUnref<GrTexture> smallRT0(context->createTexture(smallDesc, true));
78 if (smallRT0 && smallRT0->asRenderTarget()) {
79 smallRT0->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
82 SkAutoTUnref<GrTexture> smallRT1(context->createTexture(smallDesc, true));
83 if (smallRT1 && smallRT1->asRenderTarget()) {
84 smallRT1->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
87 REPORTER_ASSERT(reporter, smallRT0 && smallRT1 &&
88 smallRT0->asRenderTarget() && smallRT1->asRenderTarget() &&
89 smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() ==
90 smallRT1->asRenderTarget()->renderTargetPriv().getStencilBuffer());
92 // An unbudgeted RT with the same desc should also share.
93 SkAutoTUnref<GrTexture> smallRT2(context->createTexture(smallDesc, false));
94 if (smallRT2 && smallRT2->asRenderTarget()) {
95 smallRT2->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
97 REPORTER_ASSERT(reporter, smallRT0 && smallRT2 &&
98 smallRT0->asRenderTarget() && smallRT2->asRenderTarget() &&
99 smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() ==
100 smallRT2->asRenderTarget()->renderTargetPriv().getStencilBuffer());
102 // An RT with a much larger size should not share.
103 GrSurfaceDesc bigDesc;
104 bigDesc.fFlags = kRenderTarget_GrSurfaceFlag;
105 bigDesc.fConfig = kSkia8888_GrPixelConfig;
106 bigDesc.fWidth = 400;
107 bigDesc.fHeight = 200;
108 bigDesc.fSampleCnt = 0;
109 SkAutoTUnref<GrTexture> bigRT(context->createTexture(bigDesc, false));
110 if (bigRT && bigRT->asRenderTarget()) {
111 bigRT->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
113 REPORTER_ASSERT(reporter, smallRT0 && bigRT &&
114 smallRT0->asRenderTarget() && bigRT->asRenderTarget() &&
115 smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() !=
116 bigRT->asRenderTarget()->renderTargetPriv().getStencilBuffer());
118 if (context->getMaxSampleCount() >= 4) {
119 // An RT with a different sample count should not share.
120 GrSurfaceDesc smallMSAADesc = smallDesc;
121 smallMSAADesc.fSampleCnt = 4;
122 SkAutoTUnref<GrTexture> smallMSAART0(context->createTexture(smallMSAADesc, false));
123 if (smallMSAART0 && smallMSAART0->asRenderTarget()) {
124 smallMSAART0->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
126 #ifdef SK_BUILD_FOR_ANDROID
128 // The nexus player seems to fail to create MSAA textures.
132 REPORTER_ASSERT(reporter,
133 smallRT0 && smallMSAART0 &&
134 smallRT0->asRenderTarget() && smallMSAART0->asRenderTarget() &&
135 smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() !=
136 smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer());
137 // A second MSAA RT should share with the first MSAA RT.
138 SkAutoTUnref<GrTexture> smallMSAART1(context->createTexture(smallMSAADesc, false));
139 if (smallMSAART1 && smallMSAART1->asRenderTarget()) {
140 smallMSAART1->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
142 REPORTER_ASSERT(reporter,
143 smallMSAART0 && smallMSAART1 &&
144 smallMSAART0->asRenderTarget() &&
145 smallMSAART1->asRenderTarget() &&
146 smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer() ==
147 smallMSAART1->asRenderTarget()->renderTargetPriv().getStencilBuffer());
148 // But not one with a larger sample count should not. (Also check that the request for 4
149 // samples didn't get rounded up to >= 8 or else they could share.).
150 if (context->getMaxSampleCount() >= 8 && smallMSAART0 && smallMSAART0->asRenderTarget() &&
151 smallMSAART0->asRenderTarget()->numSamples() < 8) {
152 smallMSAADesc.fSampleCnt = 8;
153 smallMSAART1.reset(context->createTexture(smallMSAADesc, false));
154 SkAutoTUnref<GrTexture> smallMSAART1(context->createTexture(smallMSAADesc, false));
155 if (smallMSAART1 && smallMSAART1->asRenderTarget()) {
156 smallMSAART1->asRenderTarget()->renderTargetPriv().attachStencilBuffer();
158 REPORTER_ASSERT(reporter,
159 smallMSAART0 && smallMSAART1 &&
160 smallMSAART0->asRenderTarget() &&
161 smallMSAART1->asRenderTarget() &&
162 smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer() !=
163 smallMSAART1->asRenderTarget()->renderTargetPriv().getStencilBuffer());
168 class TestResource : public GrGpuResource {
169 static const size_t kDefaultSize = 100;
170 enum ScratchConstructor { kScratchConstructor };
172 SK_DECLARE_INST_COUNT(TestResource);
173 /** Property that distinctly categorizes the resource.
174 * For example, textures have width, height, ... */
175 enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty };
177 TestResource(GrGpu* gpu, size_t size, GrGpuResource::LifeCycle lifeCycle)
178 : INHERITED(gpu, lifeCycle)
181 , fProperty(kA_SimulatedProperty) {
183 this->registerWithCache();
186 TestResource(GrGpu* gpu, GrGpuResource::LifeCycle lifeCycle)
187 : INHERITED(gpu, lifeCycle)
189 , fSize(kDefaultSize)
190 , fProperty(kA_SimulatedProperty) {
192 this->registerWithCache();
195 TestResource(GrGpu* gpu)
196 : INHERITED(gpu, kCached_LifeCycle)
198 , fSize(kDefaultSize)
199 , fProperty(kA_SimulatedProperty) {
201 this->registerWithCache();
204 static TestResource* CreateScratch(GrGpu* gpu, SimulatedProperty property, bool cached = true) {
205 return SkNEW_ARGS(TestResource, (gpu, property, cached, kScratchConstructor));
210 SkSafeUnref(fToDelete);
213 void setSize(size_t size) {
215 this->didChangeGpuMemorySize();
218 static int NumAlive() { return fNumAlive; }
220 void setUnrefWhenDestroyed(TestResource* resource) {
221 SkRefCnt_SafeAssign(fToDelete, resource);
224 static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) {
225 static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType();
226 GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt);
227 for (int i = 0; i < kScratchKeyFieldCnt; ++i) {
228 builder[i] = static_cast<uint32_t>(i + property);
232 static size_t ExpectedScratchKeySize() {
233 return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt);
237 static const int kScratchKeyFieldCnt = 6;
239 TestResource(GrGpu* gpu, SimulatedProperty property, bool cached, ScratchConstructor)
240 : INHERITED(gpu, cached ? kCached_LifeCycle : kUncached_LifeCycle)
242 , fSize(kDefaultSize)
243 , fProperty(property) {
244 GrScratchKey scratchKey;
245 ComputeScratchKey(fProperty, &scratchKey);
246 this->setScratchKey(scratchKey);
248 this->registerWithCache();
251 size_t onGpuMemorySize() const SK_OVERRIDE { return fSize; }
253 TestResource* fToDelete;
255 static int fNumAlive;
256 SimulatedProperty fProperty;
257 typedef GrGpuResource INHERITED;
259 int TestResource::fNumAlive = 0;
263 Mock(int maxCnt, size_t maxBytes) {
264 fContext.reset(GrContext::CreateMockContext());
266 fContext->setResourceCacheLimits(maxCnt, maxBytes);
267 GrResourceCache* cache = fContext->getResourceCache();
268 cache->purgeAllUnlocked();
269 SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
272 GrResourceCache* cache() { return fContext->getResourceCache(); }
274 GrContext* context() { return fContext; }
277 SkAutoTUnref<GrContext> fContext;
280 static void test_no_key(skiatest::Reporter* reporter) {
281 Mock mock(10, 30000);
282 GrContext* context = mock.context();
283 GrResourceCache* cache = mock.cache();
285 // Create a bunch of resources with no keys
286 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
287 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
288 TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu()));
289 TestResource* d = SkNEW_ARGS(TestResource, (context->getGpu()));
295 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
296 REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
297 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
298 d->gpuMemorySize() == cache->getResourceBytes());
300 // Should be safe to purge without deleting the resources since we still have refs.
301 cache->purgeAllUnlocked();
302 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
304 // Since the resources have neither unique nor scratch keys, delete immediately upon unref.
307 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
308 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
309 REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() ==
310 cache->getResourceBytes());
313 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
314 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
315 REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() ==
316 cache->getResourceBytes());
319 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
320 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
321 REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
324 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
325 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
326 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
329 // Each integer passed as a template param creates a new domain.
330 template <int> static void make_unique_key(GrUniqueKey* key, int data) {
331 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
332 GrUniqueKey::Builder builder(key, d, 1);
336 static void test_budgeting(skiatest::Reporter* reporter) {
338 GrContext* context = mock.context();
339 GrResourceCache* cache = mock.cache();
341 GrUniqueKey uniqueKey;
342 make_unique_key<0>(&uniqueKey, 0);
344 // Create a scratch, a unique, and a wrapped resource
345 TestResource* scratch =
346 TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty);
347 scratch->setSize(10);
348 TestResource* unique = SkNEW_ARGS(TestResource, (context->getGpu()));
350 unique->resourcePriv().setUniqueKey(uniqueKey);
351 TestResource* wrapped = SkNEW_ARGS(TestResource,
352 (context->getGpu(), GrGpuResource::kWrapped_LifeCycle));
353 wrapped->setSize(12);
354 TestResource* unbudgeted = SkNEW_ARGS(TestResource,
355 (context->getGpu(), GrGpuResource::kUncached_LifeCycle));
356 unbudgeted->setSize(13);
358 // Make sure we can't add a unique key to the wrapped resource
359 GrUniqueKey uniqueKey2;
360 make_unique_key<0>(&uniqueKey2, 1);
361 wrapped->resourcePriv().setUniqueKey(uniqueKey2);
362 REPORTER_ASSERT(reporter, NULL == cache->findAndRefUniqueResource(uniqueKey2));
364 // Make sure sizes are as we expect
365 REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
366 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
367 wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
368 cache->getResourceBytes());
369 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
370 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
371 cache->getBudgetedResourceBytes());
373 // Our refs mean that the resources are non purgeable.
374 cache->purgeAllUnlocked();
375 REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
376 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
377 wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
378 cache->getResourceBytes());
379 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
380 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
381 cache->getBudgetedResourceBytes());
383 // Unreffing the wrapped resource should free it right away.
385 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
386 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
387 unbudgeted->gpuMemorySize() == cache->getResourceBytes());
389 // Now try freeing the budgeted resources first
390 wrapped = SkNEW_ARGS(TestResource, (context->getGpu(), GrGpuResource::kWrapped_LifeCycle));
391 scratch->setSize(12);
393 cache->purgeAllUnlocked();
394 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
395 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() +
396 unbudgeted->gpuMemorySize() == cache->getResourceBytes());
397 REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
398 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache->getBudgetedResourceBytes());
401 cache->purgeAllUnlocked();
402 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
403 REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() ==
404 cache->getResourceBytes());
405 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
406 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
409 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
410 REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache->getResourceBytes());
411 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
412 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
415 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
416 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
417 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
418 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
421 static void test_unbudgeted(skiatest::Reporter* reporter) {
422 Mock mock(10, 30000);
423 GrContext* context = mock.context();
424 GrResourceCache* cache = mock.cache();
426 GrUniqueKey uniqueKey;
427 make_unique_key<0>(&uniqueKey, 0);
429 TestResource* scratch;
430 TestResource* unique;
431 TestResource* wrapped;
432 TestResource* unbudgeted;
434 // A large uncached or wrapped resource shouldn't evict anything.
435 scratch = TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty);
436 scratch->setSize(10);
438 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
439 REPORTER_ASSERT(reporter, 10 == cache->getResourceBytes());
440 REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
441 REPORTER_ASSERT(reporter, 10 == cache->getBudgetedResourceBytes());
443 unique = SkNEW_ARGS(TestResource, (context->getGpu()));
445 unique->resourcePriv().setUniqueKey(uniqueKey);
447 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
448 REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
449 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
450 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
452 size_t large = 2 * cache->getResourceBytes();
453 unbudgeted = SkNEW_ARGS(TestResource,
454 (context->getGpu(), large, GrGpuResource::kUncached_LifeCycle));
455 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
456 REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
457 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
458 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
461 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
462 REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
463 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
464 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
466 wrapped = SkNEW_ARGS(TestResource,
467 (context->getGpu(), large, GrGpuResource::kWrapped_LifeCycle));
468 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
469 REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
470 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
471 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
474 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
475 REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
476 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
477 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
479 cache->purgeAllUnlocked();
480 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
481 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
482 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
483 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
486 // This method can't be static because it needs to friended in GrGpuResource::CacheAccess.
487 void test_unbudgeted_to_scratch(skiatest::Reporter* reporter);
488 /*static*/ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) {
490 GrContext* context = mock.context();
491 GrResourceCache* cache = mock.cache();
493 TestResource* resource =
494 TestResource::CreateScratch(context->getGpu(), TestResource::kA_SimulatedProperty, false);
496 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key);
498 size_t size = resource->gpuMemorySize();
499 for (int i = 0; i < 2; ++i) {
500 // Since this resource is unbudgeted, it should not be reachable as scratch.
501 REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
502 REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
503 REPORTER_ASSERT(reporter, !resource->resourcePriv().isBudgeted());
504 REPORTER_ASSERT(reporter, NULL == cache->findAndRefScratchResource(key));
505 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
506 REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
507 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
508 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
510 // Once it is unrefed, it should become available as scratch.
512 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
513 REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
514 REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
515 REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
516 resource = static_cast<TestResource*>(cache->findAndRefScratchResource(key));
517 REPORTER_ASSERT(reporter, resource);
518 REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
519 REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch());
520 REPORTER_ASSERT(reporter, resource->resourcePriv().isBudgeted());
523 // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try
524 // the above tests again.
525 resource->resourcePriv().makeUnbudgeted();
527 // After the second time around, try removing the scratch key
528 resource->resourcePriv().removeScratchKey();
529 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
530 REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
531 REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
532 REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
533 REPORTER_ASSERT(reporter, !resource->resourcePriv().getScratchKey().isValid());
534 REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
535 REPORTER_ASSERT(reporter, resource->resourcePriv().isBudgeted());
537 // now when it is unrefed it should die since it has no key.
539 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
540 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
541 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
542 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
547 static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
549 GrContext* context = mock.context();
550 GrResourceCache* cache = mock.cache();
552 // Create two resources that have the same scratch key.
553 TestResource* a = TestResource::CreateScratch(context->getGpu(),
554 TestResource::kB_SimulatedProperty);
555 TestResource* b = TestResource::CreateScratch(context->getGpu(),
556 TestResource::kB_SimulatedProperty);
559 GrScratchKey scratchKey1;
560 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
561 // Check for negative case consistency. (leaks upon test failure.)
562 REPORTER_ASSERT(reporter, NULL == cache->findAndRefScratchResource(scratchKey1));
564 GrScratchKey scratchKey;
565 TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
567 // Scratch resources are registered with GrResourceCache just by existing. There are 2.
568 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
569 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
570 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
571 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
572 cache->getResourceBytes());
574 // Our refs mean that the resources are non purgeable.
575 cache->purgeAllUnlocked();
576 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
577 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
579 // Unref but don't purge
582 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
583 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
585 // Purge again. This time resources should be purgeable.
586 cache->purgeAllUnlocked();
587 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
588 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
589 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
592 static void test_remove_scratch_key(skiatest::Reporter* reporter) {
594 GrContext* context = mock.context();
595 GrResourceCache* cache = mock.cache();
597 // Create two resources that have the same scratch key.
598 TestResource* a = TestResource::CreateScratch(context->getGpu(),
599 TestResource::kB_SimulatedProperty);
600 TestResource* b = TestResource::CreateScratch(context->getGpu(),
601 TestResource::kB_SimulatedProperty);
605 GrScratchKey scratchKey;
606 // Ensure that scratch key lookup is correct for negative case.
607 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
608 // (following leaks upon test failure).
609 REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey) == NULL);
611 // Scratch resources are registered with GrResourceCache just by existing. There are 2.
612 TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
613 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
614 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
615 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
617 // Find the first resource and remove its scratch key
619 find = cache->findAndRefScratchResource(scratchKey);
620 find->resourcePriv().removeScratchKey();
621 // It's still alive, but not cached by scratch key anymore
622 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
623 SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
624 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
626 // The cache should immediately delete it when it's unrefed since it isn't accessible.
628 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
629 SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
630 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
632 // Repeat for the second resource.
633 find = cache->findAndRefScratchResource(scratchKey);
634 find->resourcePriv().removeScratchKey();
635 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
636 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
637 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
639 // Should be able to call this multiple times with no problem.
640 find->resourcePriv().removeScratchKey();
641 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
642 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
643 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
646 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
647 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
648 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
651 static void test_scratch_key_consistency(skiatest::Reporter* reporter) {
653 GrContext* context = mock.context();
654 GrResourceCache* cache = mock.cache();
656 // Create two resources that have the same scratch key.
657 TestResource* a = TestResource::CreateScratch(context->getGpu(),
658 TestResource::kB_SimulatedProperty);
659 TestResource* b = TestResource::CreateScratch(context->getGpu(),
660 TestResource::kB_SimulatedProperty);
664 GrScratchKey scratchKey;
665 // Ensure that scratch key comparison and assignment is consistent.
666 GrScratchKey scratchKey1;
667 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
668 GrScratchKey scratchKey2;
669 TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey2);
670 REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize());
671 REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2);
672 REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1);
673 scratchKey = scratchKey1;
674 REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
675 REPORTER_ASSERT(reporter, scratchKey1 == scratchKey);
676 REPORTER_ASSERT(reporter, scratchKey == scratchKey1);
677 REPORTER_ASSERT(reporter, scratchKey2 != scratchKey);
678 REPORTER_ASSERT(reporter, scratchKey != scratchKey2);
679 scratchKey = scratchKey2;
680 REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
681 REPORTER_ASSERT(reporter, scratchKey1 != scratchKey);
682 REPORTER_ASSERT(reporter, scratchKey != scratchKey1);
683 REPORTER_ASSERT(reporter, scratchKey2 == scratchKey);
684 REPORTER_ASSERT(reporter, scratchKey == scratchKey2);
686 // Ensure that scratch key lookup is correct for negative case.
687 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
688 // (following leaks upon test failure).
689 REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey) == NULL);
691 // Find the first resource with a scratch key and a copy of a scratch key.
692 TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
693 GrGpuResource* find = cache->findAndRefScratchResource(scratchKey);
694 REPORTER_ASSERT(reporter, find != NULL);
697 scratchKey2 = scratchKey;
698 find = cache->findAndRefScratchResource(scratchKey2);
699 REPORTER_ASSERT(reporter, find != NULL);
700 REPORTER_ASSERT(reporter, find == a || find == b);
702 GrGpuResource* find2 = cache->findAndRefScratchResource(scratchKey2);
703 REPORTER_ASSERT(reporter, find2 != NULL);
704 REPORTER_ASSERT(reporter, find2 == a || find2 == b);
705 REPORTER_ASSERT(reporter, find2 != find);
710 static void test_duplicate_unique_key(skiatest::Reporter* reporter) {
712 GrContext* context = mock.context();
713 GrResourceCache* cache = mock.cache();
716 make_unique_key<0>(&key, 0);
718 // Create two resources that we will attempt to register with the same unique key.
719 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
722 // Set key on resource a.
723 a->resourcePriv().setUniqueKey(key);
724 REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
727 // Make sure that redundantly setting a's key works.
728 a->resourcePriv().setUniqueKey(key);
729 REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
731 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
732 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getResourceBytes());
733 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
735 // Create resource b and set the same key. It should replace a's unique key cache entry.
736 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
738 b->resourcePriv().setUniqueKey(key);
739 REPORTER_ASSERT(reporter, b == cache->findAndRefUniqueResource(key));
742 // Still have two resources because a is still reffed.
743 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
744 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == cache->getResourceBytes());
745 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
748 // Now a should be gone.
749 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
750 REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
751 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
753 // Now replace b with c, but make sure c can start with one unique key and change it to b's key.
754 // Also make b be unreffed when replacement occurs.
756 TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu()));
757 GrUniqueKey differentKey;
758 make_unique_key<0>(&differentKey, 1);
760 c->resourcePriv().setUniqueKey(differentKey);
761 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
762 REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() == cache->getResourceBytes());
763 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
764 // c replaces b and b should be immediately purged.
765 c->resourcePriv().setUniqueKey(key);
766 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
767 REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
768 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
770 // c shouldn't be purged because it is ref'ed.
771 cache->purgeAllUnlocked();
772 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
773 REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
774 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
776 // Drop the ref on c, it should be kept alive because it has a unique key.
778 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
779 REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
780 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
782 // Verify that we can find c, then remove its unique key. It should get purged immediately.
783 REPORTER_ASSERT(reporter, c == cache->findAndRefUniqueResource(key));
784 c->resourcePriv().removeUniqueKey();
786 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
787 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
788 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
791 static void test_purge_invalidated(skiatest::Reporter* reporter) {
793 GrContext* context = mock.context();
794 GrResourceCache* cache = mock.cache();
796 GrUniqueKey key1, key2, key3;
797 make_unique_key<0>(&key1, 1);
798 make_unique_key<0>(&key2, 2);
799 make_unique_key<0>(&key3, 3);
801 // Add three resources to the cache. Only c is usable as scratch.
802 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
803 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
804 TestResource* c = TestResource::CreateScratch(context->getGpu(),
805 TestResource::kA_SimulatedProperty);
806 a->resourcePriv().setUniqueKey(key1);
807 b->resourcePriv().setUniqueKey(key2);
808 c->resourcePriv().setUniqueKey(key3);
810 // hold b until *after* the message is sent.
813 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
814 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
815 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
816 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
818 typedef GrUniqueKeyInvalidatedMessage Msg;
819 typedef SkMessageBus<GrUniqueKeyInvalidatedMessage> Bus;
821 // Invalidate two of the three, they should be purged and no longer accessible via their keys.
822 Bus::Post(Msg(key1));
823 Bus::Post(Msg(key2));
824 cache->purgeAsNeeded();
825 // a should be deleted now, but we still have a ref on b.
826 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
827 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
828 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
829 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
831 // Invalidate the third.
832 Bus::Post(Msg(key3));
833 cache->purgeAsNeeded();
834 // we still have a ref on b, c should be recycled as scratch.
835 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
836 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key3));
838 // make b purgeable. It should be immediately deleted since it has no key.
840 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
842 // Make sure we actually get to c via it's scratch key, before we say goodbye.
843 GrScratchKey scratchKey;
844 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
845 GrGpuResource* scratch = cache->findAndRefScratchResource(scratchKey);
846 REPORTER_ASSERT(reporter, scratch == c);
847 SkSafeUnref(scratch);
850 cache->purgeAllUnlocked();
851 scratch = cache->findAndRefScratchResource(scratchKey);
852 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
853 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
854 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
855 REPORTER_ASSERT(reporter, !scratch);
856 SkSafeUnref(scratch);
859 static void test_cache_chained_purge(skiatest::Reporter* reporter) {
861 GrContext* context = mock.context();
862 GrResourceCache* cache = mock.cache();
864 GrUniqueKey key1, key2;
865 make_unique_key<0>(&key1, 1);
866 make_unique_key<0>(&key2, 2);
869 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
870 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
871 a->resourcePriv().setUniqueKey(key1);
872 b->resourcePriv().setUniqueKey(key2);
875 a->setUnrefWhenDestroyed(b);
876 b->setUnrefWhenDestroyed(a);
878 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
883 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
885 cache->purgeAllUnlocked();
886 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
889 a->setUnrefWhenDestroyed(NULL);
890 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
892 cache->purgeAllUnlocked();
893 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
896 static void test_resource_size_changed(skiatest::Reporter* reporter) {
897 GrUniqueKey key1, key2;
898 make_unique_key<0>(&key1, 1);
899 make_unique_key<0>(&key2, 2);
901 // Test changing resources sizes (both increase & decrease).
904 GrContext* context = mock.context();
905 GrResourceCache* cache = mock.cache();
907 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
908 a->resourcePriv().setUniqueKey(key1);
911 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
912 b->resourcePriv().setUniqueKey(key2);
915 REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes());
916 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
918 SkAutoTUnref<TestResource> find2(
919 static_cast<TestResource*>(cache->findAndRefUniqueResource(key2)));
921 SkAutoTUnref<TestResource> find1(
922 static_cast<TestResource*>(cache->findAndRefUniqueResource(key1)));
926 REPORTER_ASSERT(reporter, 250 == cache->getResourceBytes());
927 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
930 // Test increasing a resources size beyond the cache budget.
933 GrContext* context = mock.context();
934 GrResourceCache* cache = mock.cache();
936 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
938 a->resourcePriv().setUniqueKey(key1);
941 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
943 b->resourcePriv().setUniqueKey(key2);
946 REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes());
947 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
950 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(
951 cache->findAndRefUniqueResource(key2)));
954 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
956 REPORTER_ASSERT(reporter, 201 == cache->getResourceBytes());
957 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
961 static void test_timestamp_wrap(skiatest::Reporter* reporter) {
962 static const int kCount = 50;
963 static const int kBudgetCnt = kCount / 2;
964 static const int kLockedFreq = 8;
965 static const int kBudgetSize = 0x80000000;
969 // Run the test 2*kCount times;
970 for (int i = 0; i < 2 * kCount; ++i ) {
971 Mock mock(kBudgetCnt, kBudgetSize);
972 GrContext* context = mock.context();
973 GrResourceCache* cache = mock.cache();
975 // Pick a random number of resources to add before the timestamp will wrap.
976 cache->changeTimestamp(SK_MaxU32 - random.nextULessThan(kCount + 1));
978 static const int kNumToPurge = kCount - kBudgetCnt;
980 SkTDArray<int> shouldPurgeIdxs;
981 int purgeableCnt = 0;
982 SkTDArray<GrGpuResource*> resourcesToUnref;
984 // Add kCount resources, holding onto resources at random so we have a mix of purgeable and
985 // unpurgeable resources.
986 for (int j = 0; j < kCount; ++j) {
988 make_unique_key<0>(&key, j);
990 TestResource* r = SkNEW_ARGS(TestResource, (context->getGpu()));
991 r->resourcePriv().setUniqueKey(key);
992 if (random.nextU() % kLockedFreq) {
993 // Make this is purgeable.
996 if (purgeableCnt <= kNumToPurge) {
997 *shouldPurgeIdxs.append() = j;
1000 *resourcesToUnref.append() = r;
1004 // Verify that the correct resources were purged.
1005 int currShouldPurgeIdx = 0;
1006 for (int j = 0; j < kCount; ++j) {
1008 make_unique_key<0>(&key, j);
1009 GrGpuResource* res = cache->findAndRefUniqueResource(key);
1010 if (currShouldPurgeIdx < shouldPurgeIdxs.count() &&
1011 shouldPurgeIdxs[currShouldPurgeIdx] == j) {
1012 ++currShouldPurgeIdx;
1013 REPORTER_ASSERT(reporter, NULL == res);
1015 REPORTER_ASSERT(reporter, NULL != res);
1020 for (int j = 0; j < resourcesToUnref.count(); ++j) {
1021 resourcesToUnref[j]->unref();
1026 static void test_large_resource_count(skiatest::Reporter* reporter) {
1027 // Set the cache size to double the resource count because we're going to create 2x that number
1028 // resources, using two different key domains. Add a little slop to the bytes because we resize
1029 // down to 1 byte after creating the resource.
1030 static const int kResourceCnt = 2000;
1032 Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000);
1033 GrContext* context = mock.context();
1034 GrResourceCache* cache = mock.cache();
1036 for (int i = 0; i < kResourceCnt; ++i) {
1037 GrUniqueKey key1, key2;
1038 make_unique_key<1>(&key1, i);
1039 make_unique_key<2>(&key2, i);
1041 TestResource* resource;
1043 resource = SkNEW_ARGS(TestResource, (context->getGpu()));
1044 resource->resourcePriv().setUniqueKey(key1);
1045 resource->setSize(1);
1048 resource = SkNEW_ARGS(TestResource, (context->getGpu()));
1049 resource->resourcePriv().setUniqueKey(key2);
1050 resource->setSize(1);
1054 REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt);
1055 REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 2 * kResourceCnt);
1056 REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 2 * kResourceCnt);
1057 REPORTER_ASSERT(reporter, cache->getResourceBytes() == 2 * kResourceCnt);
1058 REPORTER_ASSERT(reporter, cache->getResourceCount() == 2 * kResourceCnt);
1059 for (int i = 0; i < kResourceCnt; ++i) {
1060 GrUniqueKey key1, key2;
1061 make_unique_key<1>(&key1, i);
1062 make_unique_key<2>(&key2, i);
1064 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
1065 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
1068 cache->purgeAllUnlocked();
1069 REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0);
1070 REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 0);
1071 REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 0);
1072 REPORTER_ASSERT(reporter, cache->getResourceBytes() == 0);
1073 REPORTER_ASSERT(reporter, cache->getResourceCount() == 0);
1075 for (int i = 0; i < kResourceCnt; ++i) {
1076 GrUniqueKey key1, key2;
1077 make_unique_key<1>(&key1, i);
1078 make_unique_key<2>(&key2, i);
1080 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
1081 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
1085 ////////////////////////////////////////////////////////////////////////////////
1086 DEF_GPUTEST(ResourceCache, reporter, factory) {
1087 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
1088 GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
1089 if (!GrContextFactory::IsRenderingGLContext(glType)) {
1092 GrContext* context = factory->get(glType);
1093 if (NULL == context) {
1097 desc.fConfig = kSkia8888_GrPixelConfig;
1098 desc.fFlags = kRenderTarget_GrSurfaceFlag;
1099 desc.fWidth = gWidth;
1100 desc.fHeight = gHeight;
1101 SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
1102 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context,
1103 SkSurface::kNo_Budgeted, info));
1104 test_cache(reporter, context, surface->getCanvas());
1105 test_stencil_buffers(reporter, context);
1108 // The below tests create their own mock contexts.
1109 test_no_key(reporter);
1110 test_budgeting(reporter);
1111 test_unbudgeted(reporter);
1112 test_unbudgeted_to_scratch(reporter);
1113 test_duplicate_unique_key(reporter);
1114 test_duplicate_scratch_key(reporter);
1115 test_remove_scratch_key(reporter);
1116 test_scratch_key_consistency(reporter);
1117 test_purge_invalidated(reporter);
1118 test_cache_chained_purge(reporter);
1119 test_resource_size_changed(reporter);
1120 test_timestamp_wrap(reporter);
1121 test_large_resource_count(reporter);