Index: tests/ResourceCacheTest.cpp |
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp |
index 845094b3ea842f1a567cf475503c582f09f81c57..c912ae07f4cda5315532ed0c28cc60b08d7c1a79 100644 |
--- a/tests/ResourceCacheTest.cpp |
+++ b/tests/ResourceCacheTest.cpp |
@@ -8,6 +8,7 @@ |
#if SK_SUPPORT_GPU |
#include "GrContextFactory.h" |
+#include "GrResourceCache.h" |
#include "SkGpuDevice.h" |
#include "Test.h" |
@@ -57,6 +58,79 @@ static void test_cache(skiatest::Reporter* reporter, |
context->setTextureCacheLimits(oldMaxNum, oldMaxBytes); |
} |
+class TestResource : public GrResource { |
+public: |
+ SK_DECLARE_INST_COUNT(TestResource); |
+ explicit TestResource(GrGpu* gpu) |
+ : INHERITED(gpu, false) |
+ , fCache(NULL) |
+ , fToDelete(NULL) { |
+ ++fAlive; |
+ } |
+ |
+ ~TestResource() { |
+ --fAlive; |
+ if (NULL != fToDelete) { |
+ // Breaks our little 2-element cycle below. |
+ fToDelete->setDeleteWhenDestroyed(NULL, NULL); |
+ fCache->deleteResource(fToDelete->getCacheEntry()); |
+ } |
+ this->release(); |
+ } |
+ |
+ size_t sizeInBytes() const SK_OVERRIDE { return 100; } |
+ |
+ static int alive() { return fAlive; } |
+ |
+ void setDeleteWhenDestroyed(GrResourceCache* cache, TestResource* resource) { |
+ fCache = cache; |
+ fToDelete = resource; |
+ } |
+ |
+private: |
+ GrResourceCache* fCache; |
+ TestResource* fToDelete; |
+ static int fAlive; |
+ |
+ typedef GrResource INHERITED; |
+}; |
+int TestResource::fAlive = 0; |
+ |
+static void test_purge_invalidated(skiatest::Reporter* reporter, GrContext* context) { |
+ GrCacheID::Domain domain = GrCacheID::GenerateDomain(); |
+ GrCacheID::Key keyData; |
+ keyData.fData64[0] = 5; |
+ keyData.fData64[1] = 18; |
+ GrResourceKey::ResourceType t = GrResourceKey::GenerateResourceType(); |
+ GrResourceKey key(GrCacheID(domain, keyData), t, 0); |
+ |
+ GrResourceCache cache(5, 30000); |
+ |
+ // Add two resources with the same key that delete each other from the cache when destroyed. |
+ TestResource* a = new TestResource(context->getGpu()); |
+ TestResource* b = new TestResource(context->getGpu()); |
+ cache.addResource(key, a); |
+ cache.addResource(key, b); |
+ // Circle back. |
+ a->setDeleteWhenDestroyed(&cache, b); |
+ b->setDeleteWhenDestroyed(&cache, a); |
+ a->unref(); |
+ b->unref(); |
+ |
+ // Add a third independent resource also with the same key. |
+ GrResource* r = new TestResource(context->getGpu()); |
+ cache.addResource(key, r); |
+ r->unref(); |
+ |
+ // Invalidate all three, all three should be purged and destroyed. |
+ REPORTER_ASSERT(reporter, 3 == TestResource::alive()); |
+ const GrResourceInvalidatedMessage msg = { key }; |
+ SkMessageBus<GrResourceInvalidatedMessage>::Post(msg); |
+ cache.purgeAsNeeded(); |
+ REPORTER_ASSERT(reporter, 0 == TestResource::alive()); |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
DEF_GPUTEST(ResourceCache, reporter, factory) { |
for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { |
GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type); |
@@ -79,6 +153,7 @@ DEF_GPUTEST(ResourceCache, reporter, factory) { |
SkCanvas canvas(device.get()); |
test_cache(reporter, context, &canvas); |
+ test_purge_invalidated(reporter, context); |
} |
} |