diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-01-15 23:09:01 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-01-15 23:09:01 +0000 |
commit | c665804300096c2e7617379835bb83d715538788 (patch) | |
tree | 245a61d322a78dda969aadb7812f438a6598b09d | |
parent | b06faacaf13b9b5c47b8526492ad155bdce3863b (diff) |
Move SkMessageBus::Get out of header, and retry crrev.com/106563002.
BUG=
R=bsalomon@google.com, kkinnunen@nvidia.com
Author: mtklein@google.com
Review URL: https://codereview.chromium.org/140053002
git-svn-id: http://skia.googlecode.com/svn/trunk@13104 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkMessageBus.h | 23 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.cpp | 4 | ||||
-rw-r--r-- | tests/MessageBusTest.cpp | 5 | ||||
-rw-r--r-- | tests/ResourceCacheTest.cpp | 75 |
4 files changed, 90 insertions, 17 deletions
diff --git a/src/core/SkMessageBus.h b/src/core/SkMessageBus.h index 0a408319c1..ddeac57ac1 100644 --- a/src/core/SkMessageBus.h +++ b/src/core/SkMessageBus.h @@ -44,6 +44,18 @@ private: SkMutex fInboxesMutex; }; +// This must go in a single .cpp file, not some .h, or we risk creating more than one global +// SkMessageBus per type when using shared libraries. +#define DECLARE_SKMESSAGEBUS_MESSAGE(Message) \ + template <> \ + SkMessageBus<Message>* SkMessageBus<Message>::Get() { \ + static SkMessageBus<Message>* bus = NULL; \ + SK_DECLARE_STATIC_ONCE(once); \ + SkOnce(&once, &New, &bus); \ + SkASSERT(bus != NULL); \ + return bus; \ + } + // ----------------------- Implementation of SkMessageBus::Inbox ----------------------- template<typename Message> @@ -93,17 +105,6 @@ template <typename Message> } template <typename Message> -/*static*/ SkMessageBus<Message>* SkMessageBus<Message>::Get() { - // The first time this method is called, create the singleton bus for this message type. - static SkMessageBus<Message>* bus = NULL; - SK_DECLARE_STATIC_ONCE(once); - SkOnce(&once, &New, &bus); - - SkASSERT(bus != NULL); - return bus; -} - -template <typename Message> /*static*/ void SkMessageBus<Message>::Post(const Message& m) { SkMessageBus<Message>* bus = SkMessageBus<Message>::Get(); SkAutoMutexAcquire lock(bus->fInboxesMutex); diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp index 5cf3f82c7d..1ba60e8a30 100644 --- a/src/gpu/GrResourceCache.cpp +++ b/src/gpu/GrResourceCache.cpp @@ -11,6 +11,7 @@ #include "GrResourceCache.h" #include "GrResource.h" +DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() { static int32_t gNextType = 0; @@ -312,8 +313,7 @@ void GrResourceCache::purgeInvalidated() { // // This is complicated and confusing. May try this in the future. For // now, these resources are just LRU'd as if we never got the message. - GrResourceEntry* entry = fCache.find(invalidated[i].key, GrTFindUnreffedFunctor()); - if (entry) { + while (GrResourceEntry* entry = fCache.find(invalidated[i].key, GrTFindUnreffedFunctor())) { this->deleteResource(entry); } } diff --git a/tests/MessageBusTest.cpp b/tests/MessageBusTest.cpp index 0e40d12311..f7a02b2254 100644 --- a/tests/MessageBusTest.cpp +++ b/tests/MessageBusTest.cpp @@ -8,14 +8,11 @@ #include "SkMessageBus.h" #include "Test.h" -namespace { - struct TestMessage { int x; float y; }; - -} // namespace +DECLARE_SKMESSAGEBUS_MESSAGE(TestMessage) DEF_TEST(MessageBus, r) { // Register two inboxes to receive all TestMessages. diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp index 845094b3ea..c912ae07f4 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); } } |