Index: tests/ResourceCacheTest.cpp |
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp |
index 930bd1217c601b1c89a538d2fcfaf2b4e63f94e7..f925b0775443813e9c12a780665dc40573abb74f 100644 |
--- a/tests/ResourceCacheTest.cpp |
+++ b/tests/ResourceCacheTest.cpp |
@@ -313,6 +313,68 @@ static void test_duplicate_scratch_key(skiatest::Reporter* reporter) { |
SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));) |
} |
+static void test_remove_scratch_key(skiatest::Reporter* reporter) { |
+ SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
+ REPORTER_ASSERT(reporter, SkToBool(context)); |
+ if (NULL == context) { |
+ return; |
+ } |
+ context->setResourceCacheLimits(5, 30000); |
+ GrResourceCache2* cache2 = context->getResourceCache2(); |
+ cache2->purgeAllUnlocked(); |
+ SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes()); |
+ |
+ GrCacheID::Key keyData; |
+ memset(&keyData, 0, sizeof(keyData)); |
+ GrCacheID::Domain domain = GrResourceKey::ScratchDomain(); |
+ GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); |
+ GrResourceKey scratchKey(GrCacheID(domain, keyData), t, 0); |
+ |
+ // Create two resources that have the same scratch key. |
+ TestResource* a = new TestResource(context->getGpu(), scratchKey); |
+ TestResource* b = new TestResource(context->getGpu(), scratchKey); |
+ a->unref(); |
+ b->unref(); |
+ |
+ // Scratch resources are registered with GrResourceCache2 just by existing. There are 2. |
+ REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
+ SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey(scratchKey));) |
+ REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
+ |
+ // Find the first resource and remove its scratch key |
+ GrGpuResource* find; |
+ find = cache2->findAndRefScratchResource(scratchKey); |
+ find->cacheAccess().removeScratchKey(); |
+ // It's still alive, but not cached by scratch key anymore |
+ REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); |
+ SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache2->countScratchEntriesForKey(scratchKey));) |
+ REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount()); |
+ |
+ // The cache should immediately delete it when it's unrefed since it isn't accessible. |
+ find->unref(); |
+ REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); |
+ SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache2->countScratchEntriesForKey(scratchKey));) |
+ REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount()); |
+ |
+ // Repeat for the second resource. |
+ find = cache2->findAndRefScratchResource(scratchKey); |
+ find->cacheAccess().removeScratchKey(); |
+ REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); |
+ SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));) |
+ REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount()); |
+ |
+ // Should be able to call this multiple times with no problem. |
+ find->cacheAccess().removeScratchKey(); |
+ REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); |
+ SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));) |
+ REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount()); |
+ |
+ find->unref(); |
+ REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); |
+ SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));) |
+ REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount()); |
+} |
+ |
static void test_duplicate_content_key(skiatest::Reporter* reporter) { |
SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
REPORTER_ASSERT(reporter, SkToBool(context)); |
@@ -569,6 +631,76 @@ static void test_resource_size_changed(skiatest::Reporter* reporter) { |
} |
} |
+static void test_large_resource_count(skiatest::Reporter* reporter) { |
+ SkAutoTUnref<GrContext> context(GrContext::CreateMockContext()); |
+ REPORTER_ASSERT(reporter, SkToBool(context)); |
+ if (NULL == context) { |
+ return; |
+ } |
+ |
+ static const int kResourceCnt = 2000; |
+ // Set the cache size to double the resource count because we're going to create 2x that number |
+ // resources, using two different key domains. Add a little slop to the bytes because we resize |
+ // down to 1 byte after creating the resource. |
+ context->setResourceCacheLimits(2 * kResourceCnt, 2 * kResourceCnt + 1000); |
+ GrResourceCache2* cache2 = context->getResourceCache2(); |
+ cache2->purgeAllUnlocked(); |
+ SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes()); |
+ |
+ GrCacheID::Domain domain0 = GrCacheID::GenerateDomain(); |
+ GrCacheID::Domain domain1 = GrCacheID::GenerateDomain(); |
+ GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); |
+ |
+ GrCacheID::Key keyData; |
+ memset(&keyData, 0, sizeof(keyData)); |
+ |
+ for (int i = 0; i < kResourceCnt; ++i) { |
+ TestResource* resource; |
+ keyData.fData32[0] = i; |
+ |
+ GrResourceKey key0(GrCacheID(domain0, keyData), t, 0); |
+ resource = SkNEW_ARGS(TestResource, (context->getGpu())); |
+ resource->cacheAccess().setContentKey(key0); |
+ resource->setSize(1); |
+ resource->unref(); |
+ |
+ GrResourceKey key1(GrCacheID(domain1, keyData), t, 0); |
+ resource = SkNEW_ARGS(TestResource, (context->getGpu())); |
+ resource->cacheAccess().setContentKey(key1); |
+ resource->setSize(1); |
+ resource->unref(); |
+ } |
+ |
+ REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt); |
+ REPORTER_ASSERT(reporter, cache2->getBudgetedResourceBytes() == 2 * kResourceCnt); |
+ REPORTER_ASSERT(reporter, cache2->getBudgetedResourceCount() == 2 * kResourceCnt); |
+ REPORTER_ASSERT(reporter, cache2->getResourceBytes() == 2 * kResourceCnt); |
+ REPORTER_ASSERT(reporter, cache2->getResourceCount() == 2 * kResourceCnt); |
+ for (int i = 0; i < kResourceCnt; ++i) { |
+ keyData.fData32[0] = i; |
+ GrResourceKey key0(GrCacheID(domain0, keyData), t, 0); |
+ REPORTER_ASSERT(reporter, cache2->hasContentKey(key0)); |
+ GrResourceKey key1(GrCacheID(domain0, keyData), t, 0); |
+ REPORTER_ASSERT(reporter, cache2->hasContentKey(key1)); |
+ } |
+ |
+ cache2->purgeAllUnlocked(); |
+ REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0); |
+ REPORTER_ASSERT(reporter, cache2->getBudgetedResourceBytes() == 0); |
+ REPORTER_ASSERT(reporter, cache2->getBudgetedResourceCount() == 0); |
+ REPORTER_ASSERT(reporter, cache2->getResourceBytes() == 0); |
+ REPORTER_ASSERT(reporter, cache2->getResourceCount() == 0); |
+ |
+ for (int i = 0; i < kResourceCnt; ++i) { |
+ keyData.fData32[0] = i; |
+ GrResourceKey key0(GrCacheID(domain0, keyData), t, 0); |
+ REPORTER_ASSERT(reporter, !cache2->hasContentKey(key0)); |
+ GrResourceKey key1(GrCacheID(domain0, keyData), t, 0); |
+ REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1)); |
+ } |
+} |
+ |
+ |
//////////////////////////////////////////////////////////////////////////////// |
DEF_GPUTEST(ResourceCache, reporter, factory) { |
for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { |
@@ -595,9 +727,11 @@ DEF_GPUTEST(ResourceCache, reporter, factory) { |
test_budgeting(reporter); |
test_duplicate_content_key(reporter); |
test_duplicate_scratch_key(reporter); |
+ test_remove_scratch_key(reporter); |
test_purge_invalidated(reporter); |
test_cache_chained_purge(reporter); |
test_resource_size_changed(reporter); |
+ test_large_resource_count(reporter); |
} |
#endif |