diff options
author | 2017-01-06 13:54:58 -0500 | |
---|---|---|
committer | 2017-01-06 19:42:08 +0000 | |
commit | 19f0ed5b83a6ddf163a78bcb1c701f6020e6a17c (patch) | |
tree | 1f95cbab5eae57a734aeee489099b9b9f97f2331 /include/private | |
parent | 9953737bcf885a52c08ade6c503f2202e4dd9aa5 (diff) |
Purge clip masks when they are no longer findable.
This improves memory usage when the content contains frequently changing clips implemented as masks.
BUG=chromium:676459
Change-Id: I06ea5f9fe1cff9564ea136bad9fe97f6ecd77ad9
Reviewed-on: https://skia-review.googlesource.com/6629
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'include/private')
-rw-r--r-- | include/private/SkMessageBus.h | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/include/private/SkMessageBus.h b/include/private/SkMessageBus.h new file mode 100644 index 0000000000..79f5c026dc --- /dev/null +++ b/include/private/SkMessageBus.h @@ -0,0 +1,110 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkMessageBus_DEFINED +#define SkMessageBus_DEFINED + +#include "SkMutex.h" +#include "SkOnce.h" +#include "SkTArray.h" +#include "SkTDArray.h" +#include "SkTypes.h" + +template <typename Message> +class SkMessageBus : SkNoncopyable { +public: + // Post a message to be received by all Inboxes for this Message type. Threadsafe. + static void Post(const Message& m); + + class Inbox { + public: + Inbox(); + ~Inbox(); + + // Overwrite out with all the messages we've received since the last call. Threadsafe. + void poll(SkTArray<Message>* out); + + private: + SkTArray<Message> fMessages; + SkMutex fMessagesMutex; + + friend class SkMessageBus; + void receive(const Message& m); // SkMessageBus is a friend only to call this. + }; + +private: + SkMessageBus(); + static SkMessageBus* Get(); + + SkTDArray<Inbox*> fInboxes; + 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. NOTE: at most one per file will compile. +#define DECLARE_SKMESSAGEBUS_MESSAGE(Message) \ + template <> \ + SkMessageBus<Message>* SkMessageBus<Message>::Get() { \ + static SkOnce once; \ + static SkMessageBus<Message>* bus; \ + once([] { bus = new SkMessageBus<Message>(); }); \ + return bus; \ + } + +// ----------------------- Implementation of SkMessageBus::Inbox ----------------------- + +template<typename Message> +SkMessageBus<Message>::Inbox::Inbox() { + // Register ourselves with the corresponding message bus. + SkMessageBus<Message>* bus = SkMessageBus<Message>::Get(); + SkAutoMutexAcquire lock(bus->fInboxesMutex); + bus->fInboxes.push(this); +} + +template<typename Message> +SkMessageBus<Message>::Inbox::~Inbox() { + // Remove ourselves from the corresponding message bus. + SkMessageBus<Message>* bus = SkMessageBus<Message>::Get(); + SkAutoMutexAcquire lock(bus->fInboxesMutex); + // This is a cheaper fInboxes.remove(fInboxes.find(this)) when order doesn't matter. + for (int i = 0; i < bus->fInboxes.count(); i++) { + if (this == bus->fInboxes[i]) { + bus->fInboxes.removeShuffle(i); + break; + } + } +} + +template<typename Message> +void SkMessageBus<Message>::Inbox::receive(const Message& m) { + SkAutoMutexAcquire lock(fMessagesMutex); + fMessages.push_back(m); +} + +template<typename Message> +void SkMessageBus<Message>::Inbox::poll(SkTArray<Message>* messages) { + SkASSERT(messages); + messages->reset(); + SkAutoMutexAcquire lock(fMessagesMutex); + fMessages.swap(messages); +} + +// ----------------------- Implementation of SkMessageBus ----------------------- + +template <typename Message> +SkMessageBus<Message>::SkMessageBus() {} + +template <typename Message> +/*static*/ void SkMessageBus<Message>::Post(const Message& m) { + SkMessageBus<Message>* bus = SkMessageBus<Message>::Get(); + SkAutoMutexAcquire lock(bus->fInboxesMutex); + for (int i = 0; i < bus->fInboxes.count(); i++) { + bus->fInboxes[i]->receive(m); + } +} + +#endif // SkMessageBus_DEFINED |