Index: tests/ResourceCacheTest.cpp |
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp |
index 737d7432b10df6e3b6af294adc5a0cbcb35b3c15..f92ba87d6284352143990403523e569868c76a44 100644 |
--- a/tests/ResourceCacheTest.cpp |
+++ b/tests/ResourceCacheTest.cpp |
@@ -5,6 +5,9 @@ |
* found in the LICENSE file. |
*/ |
+// Include here to ensure SK_SUPPORT_GPU is set correctly before it is examined. |
+#include "SkTypes.h" |
+ |
#if SK_SUPPORT_GPU |
#include "GrContext.h" |
@@ -1023,6 +1026,88 @@ static void test_timestamp_wrap(skiatest::Reporter* reporter) { |
} |
} |
+static void test_flush(skiatest::Reporter* reporter) { |
+ Mock mock(1000000, 1000000); |
+ GrContext* context = mock.context(); |
+ GrResourceCache* cache = mock.cache(); |
+ |
+ // The current cache impl will round the max flush count to the next power of 2. So we choose a |
+ // power of two here to keep things simpler. |
+ static const int kFlushCount = 16; |
+ cache->setLimits(1000000, 1000000, kFlushCount); |
+ |
+ { |
+ // Insert a resource and send a flush notification kFlushCount times. |
+ for (int i = 0; i < kFlushCount; ++i) { |
+ TestResource* r = SkNEW_ARGS(TestResource, (context->getGpu())); |
+ GrUniqueKey k; |
+ make_unique_key<1>(&k, i); |
+ r->resourcePriv().setUniqueKey(k); |
+ r->unref(); |
+ cache->notifyFlushOccurred(); |
+ } |
+ |
+ // Send flush notifications to the cache. Each flush should purge the oldest resource. |
+ for (int i = 0; i < kFlushCount - 1; ++i) { |
+ // The first resource was purged after the last flush in the initial loop, hence the -1. |
+ REPORTER_ASSERT(reporter, kFlushCount - i - 1 == cache->getResourceCount()); |
+ for (int j = 0; j < i; ++j) { |
+ GrUniqueKey k; |
+ make_unique_key<1>(&k, j); |
+ GrGpuResource* r = cache->findAndRefUniqueResource(k); |
+ REPORTER_ASSERT(reporter, !SkToBool(r)); |
+ SkSafeUnref(r); |
+ } |
+ cache->notifyFlushOccurred(); |
+ } |
+ |
+ REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); |
+ cache->purgeAllUnlocked(); |
+ } |
+ |
+ // Do a similar test but where we leave refs on some resources to prevent them from being |
+ // purged. |
+ { |
+ GrGpuResource* refedResources[kFlushCount >> 1]; |
+ for (int i = 0; i < kFlushCount; ++i) { |
+ TestResource* r = SkNEW_ARGS(TestResource, (context->getGpu())); |
+ GrUniqueKey k; |
+ make_unique_key<1>(&k, i); |
+ r->resourcePriv().setUniqueKey(k); |
+ // Leave a ref on every other resource, beginning with the first. |
+ if (SkToBool(i & 0x1)) { |
+ refedResources[i/2] = r; |
+ } else { |
+ r->unref(); |
+ } |
+ cache->notifyFlushOccurred(); |
+ } |
+ |
+ for (int i = 0; i < kFlushCount; ++i) { |
+ // Should get a resource purged every other flush. |
+ REPORTER_ASSERT(reporter, kFlushCount - i/2 - 1 == cache->getResourceCount()); |
+ cache->notifyFlushOccurred(); |
+ } |
+ |
+ // Unref all the resources that we kept refs on in the first loop. |
+ for (int i = 0; i < kFlushCount >> 1; ++i) { |
+ refedResources[i]->unref(); |
+ } |
+ |
+ // When we unref'ed them their timestamps got updated. So nothing should be purged until we |
+ // get kFlushCount additional flushes. Then everything should be purged. |
+ for (int i = 0; i < kFlushCount; ++i) { |
+ REPORTER_ASSERT(reporter, kFlushCount >> 1 == cache->getResourceCount()); |
+ cache->notifyFlushOccurred(); |
+ } |
+ REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); |
+ |
+ cache->purgeAllUnlocked(); |
+ } |
+ |
+ REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); |
+} |
+ |
static void test_large_resource_count(skiatest::Reporter* reporter) { |
// 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 |
@@ -1118,6 +1203,7 @@ DEF_GPUTEST(ResourceCache, reporter, factory) { |
test_cache_chained_purge(reporter); |
test_resource_size_changed(reporter); |
test_timestamp_wrap(reporter); |
+ test_flush(reporter); |
test_large_resource_count(reporter); |
} |