aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/ResourceCacheTest.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-03-22 10:04:27 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-22 14:42:11 +0000
commitfbb56ce83fc717b7c6722324bbccd1ae73c350a4 (patch)
tree0025d8cca6e55eb2fd25b370f7c1bded5e5e910c /tests/ResourceCacheTest.cpp
parentb667fe2f67a072da74d7a7da32cae4f06a2f0ee4 (diff)
Add a new GrResourceCache purging mechanism for purging unused resources.
The client may call GrContext::purgeResourceNotUsedSince() with a stead_clock::time_point and all resources that have been purgeable since before that time point are purged. This is intended to replace the "max unused flushes" purging mechanism once Chrome adopts it. Change-Id: I28881dd2959cc01c0acca81b2d6001ee5626439d Reviewed-on: https://skia-review.googlesource.com/8920 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Reviewed-by: Eric Karl <ericrk@google.com>
Diffstat (limited to 'tests/ResourceCacheTest.cpp')
-rw-r--r--tests/ResourceCacheTest.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 8051191d4b..7766a6a04c 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -1241,6 +1241,98 @@ static void test_flush(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
}
+static void test_time_purge(skiatest::Reporter* reporter) {
+ Mock mock(1000000, 1000000);
+ GrContext* context = mock.context();
+ GrResourceCache* cache = mock.cache();
+
+ static constexpr int kCnts[] = {1, 10, 1024};
+ for (int cnt : kCnts) {
+ std::unique_ptr<std::chrono::steady_clock::time_point[]> timeStamps(
+ new std::chrono::steady_clock::time_point[cnt]);
+ {
+ // Insert resources and get time points between each addition.
+ for (int i = 0; i < cnt; ++i) {
+ TestResource* r = new TestResource(context->getGpu());
+ GrUniqueKey k;
+ make_unique_key<1>(&k, i);
+ r->resourcePriv().setUniqueKey(k);
+ r->unref();
+ timeStamps.get()[i] = std::chrono::steady_clock::now();
+ }
+
+ // Purge based on the time points between resource additions. Each purge should remove
+ // the oldest resource.
+ for (int i = 0; i < cnt; ++i) {
+ cache->purgeResourcesNotUsedSince(timeStamps[i]);
+ REPORTER_ASSERT(reporter, cnt - 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);
+ }
+ }
+
+ 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.
+ {
+ std::unique_ptr<GrGpuResource* []> refedResources(new GrGpuResource*[cnt / 2]);
+ for (int i = 0; i < cnt; ++i) {
+ TestResource* r = new 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.get()[i / 2] = r;
+ } else {
+ r->unref();
+ }
+ timeStamps.get()[i] = std::chrono::steady_clock::now();
+ }
+
+ for (int i = 0; i < cnt; ++i) {
+ // Should get a resource purged every other frame.
+ cache->purgeResourcesNotUsedSince(timeStamps[i]);
+ REPORTER_ASSERT(reporter, cnt - i / 2 - 1 == cache->getResourceCount());
+ }
+
+ // Unref all the resources that we kept refs on in the first loop.
+ for (int i = 0; i < (cnt / 2); ++i) {
+ refedResources.get()[i]->unref();
+ context->purgeResourcesNotUsedSince(std::chrono::steady_clock::now());
+ REPORTER_ASSERT(reporter, cnt / 2 - i - 1 == cache->getResourceCount());
+ }
+
+ cache->purgeAllUnlocked();
+ }
+
+ REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
+
+ // Verify that calling flush() on a GrContext with nothing to do will not trigger resource
+ // eviction
+ context->flush();
+ for (int i = 0; i < 10; ++i) {
+ TestResource* r = new TestResource(context->getGpu());
+ GrUniqueKey k;
+ make_unique_key<1>(&k, i);
+ r->resourcePriv().setUniqueKey(k);
+ r->unref();
+ }
+ REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
+ context->flush();
+ REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
+ context->purgeResourcesNotUsedSince(std::chrono::steady_clock::now());
+ 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
@@ -1393,6 +1485,7 @@ DEF_GPUTEST(ResourceCacheMisc, reporter, factory) {
test_resource_size_changed(reporter);
test_timestamp_wrap(reporter);
test_flush(reporter);
+ test_time_purge(reporter);
test_large_resource_count(reporter);
test_custom_data(reporter);
test_abandoned(reporter);