From c665804300096c2e7617379835bb83d715538788 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 15 Jan 2014 23:09:01 +0000 Subject: [PATCH] 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 --- src/core/SkMessageBus.h | 23 +++++++------- src/gpu/GrResourceCache.cpp | 4 +-- tests/MessageBusTest.cpp | 5 +-- tests/ResourceCacheTest.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 17 deletions(-) diff --git a/src/core/SkMessageBus.h b/src/core/SkMessageBus.h index 0a40831..ddeac57 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* SkMessageBus::Get() { \ + static SkMessageBus* bus = NULL; \ + SK_DECLARE_STATIC_ONCE(once); \ + SkOnce(&once, &New, &bus); \ + SkASSERT(bus != NULL); \ + return bus; \ + } + // ----------------------- Implementation of SkMessageBus::Inbox ----------------------- template @@ -93,17 +105,6 @@ template } template -/*static*/ SkMessageBus* SkMessageBus::Get() { - // The first time this method is called, create the singleton bus for this message type. - static SkMessageBus* bus = NULL; - SK_DECLARE_STATIC_ONCE(once); - SkOnce(&once, &New, &bus); - - SkASSERT(bus != NULL); - return bus; -} - -template /*static*/ void SkMessageBus::Post(const Message& m) { SkMessageBus* bus = SkMessageBus::Get(); SkAutoMutexAcquire lock(bus->fInboxesMutex); diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp index 5cf3f82..1ba60e8 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 0e40d12..f7a02b2 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 845094b..c912ae0 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::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(type); @@ -79,6 +153,7 @@ DEF_GPUTEST(ResourceCache, reporter, factory) { SkCanvas canvas(device.get()); test_cache(reporter, context, &canvas); + test_purge_invalidated(reporter, context); } } -- 2.7.4