Send TextBlobCache purge messages only to owning cache.

Bug: 703297
Change-Id: I95cdaa5bdebadd5ce88ae3ee468c59baa08353c6
Reviewed-on: https://skia-review.googlesource.com/85046
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h
index 228747a..b27ec87 100644
--- a/include/core/SkTextBlob.h
+++ b/include/core/SkTextBlob.h
@@ -98,17 +98,17 @@
 
     // Call when this blob is part of the key to a cache entry. This allows the cache
     // to know automatically those entries can be purged when this SkTextBlob is deleted.
-    void notifyAddedToCache() const {
-        fAddedToCache.store(true);
+    void notifyAddedToCache(uint32_t cacheID) const {
+        fCacheID.store(cacheID);
     }
 
     friend class GrTextBlobCache;
     friend class SkTextBlobBuilder;
     friend class SkTextBlobRunIterator;
 
-    const SkRect           fBounds;
-    const uint32_t         fUniqueID;
-    mutable SkAtomic<bool> fAddedToCache;
+    const SkRect               fBounds;
+    const uint32_t             fUniqueID;
+    mutable SkAtomic<uint32_t> fCacheID;
 
     SkDEBUGCODE(size_t fStorageSize;)
 
diff --git a/include/private/SkMessageBus.h b/include/private/SkMessageBus.h
index 79f5c02..6ddf82c 100644
--- a/include/private/SkMessageBus.h
+++ b/include/private/SkMessageBus.h
@@ -17,12 +17,14 @@
 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);
+    // Post a message to be received by Inboxes for this Message type.  Threadsafe.
+    // If id is SK_InvalidUniqueID then it will be sent to all inboxes.
+    // Otherwise it will be sent to the inbox with that id.
+    static void Post(const Message& m, uint32_t destID = SK_InvalidUniqueID);
 
     class Inbox {
     public:
-        Inbox();
+        Inbox(uint32_t uniqueID = SK_InvalidUniqueID);
         ~Inbox();
 
         // Overwrite out with all the messages we've received since the last call.  Threadsafe.
@@ -31,6 +33,7 @@
     private:
         SkTArray<Message>  fMessages;
         SkMutex            fMessagesMutex;
+        uint32_t           fUniqueID;
 
         friend class SkMessageBus;
         void receive(const Message& m);  // SkMessageBus is a friend only to call this.
@@ -58,7 +61,7 @@
 //   ----------------------- Implementation of SkMessageBus::Inbox -----------------------
 
 template<typename Message>
-SkMessageBus<Message>::Inbox::Inbox() {
+SkMessageBus<Message>::Inbox::Inbox(uint32_t uniqueID) : fUniqueID(uniqueID) {
     // Register ourselves with the corresponding message bus.
     SkMessageBus<Message>* bus = SkMessageBus<Message>::Get();
     SkAutoMutexAcquire lock(bus->fInboxesMutex);
@@ -99,11 +102,13 @@
 SkMessageBus<Message>::SkMessageBus() {}
 
 template <typename Message>
-/*static*/ void SkMessageBus<Message>::Post(const Message& m) {
+/*static*/ void SkMessageBus<Message>::Post(const Message& m, uint32_t destID) {
     SkMessageBus<Message>* bus = SkMessageBus<Message>::Get();
     SkAutoMutexAcquire lock(bus->fInboxesMutex);
     for (int i = 0; i < bus->fInboxes.count(); i++) {
-        bus->fInboxes[i]->receive(m);
+        if (SK_InvalidUniqueID == destID || bus->fInboxes[i]->fUniqueID == destID) {
+            bus->fInboxes[i]->receive(m);
+        }
     }
 }
 
diff --git a/include/private/SkTArray.h b/include/private/SkTArray.h
index 9e0b954..3f4cc42 100644
--- a/include/private/SkTArray.h
+++ b/include/private/SkTArray.h
@@ -441,7 +441,7 @@
         if (!count && !reserveCount) {
             fAllocCount = 0;
             fMemArray = nullptr;
-            fOwnMemory = false;
+            fOwnMemory = true;
             fReserved = false;
         } else {
             fAllocCount = SkTMax(count, SkTMax(kMinHeapAllocCount, reserveCount));
diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
index f778c68..1f02476 100644
--- a/src/core/SkTextBlob.cpp
+++ b/src/core/SkTextBlob.cpp
@@ -308,12 +308,12 @@
 SkTextBlob::SkTextBlob(const SkRect& bounds)
     : fBounds(bounds)
     , fUniqueID(next_id())
-    , fAddedToCache(false) {}
+    , fCacheID(SK_InvalidUniqueID) {}
 
 SkTextBlob::~SkTextBlob() {
 #if SK_SUPPORT_GPU
-    if (fAddedToCache.load()) {
-        GrTextBlobCache::PostPurgeBlobMessage(fUniqueID);
+    if (SK_InvalidUniqueID != fCacheID.load()) {
+        GrTextBlobCache::PostPurgeBlobMessage(fUniqueID, fCacheID);
     }
 #endif
 
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 50ed2cf..c410874 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -258,7 +258,7 @@
                                              allowMultitexturing);
     this->contextPriv().addOnFlushCallbackObject(fAtlasGlyphCache);
 
-    fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this));
+    fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this, this->uniqueID()));
 
     if (options.fExecutor) {
         fTaskGroup = skstd::make_unique<SkTaskGroup>(*options.fExecutor);
diff --git a/src/gpu/text/GrTextBlobCache.cpp b/src/gpu/text/GrTextBlobCache.cpp
index f90ed99..64941ef 100644
--- a/src/gpu/text/GrTextBlobCache.cpp
+++ b/src/gpu/text/GrTextBlobCache.cpp
@@ -27,9 +27,9 @@
     SkASSERT(fBlobList.isEmpty());
 }
 
-void GrTextBlobCache::PostPurgeBlobMessage(uint32_t id) {
-    SkASSERT(id != SK_InvalidGenID);
-    SkMessageBus<PurgeBlobMessage>::Post(PurgeBlobMessage({id}));
+void GrTextBlobCache::PostPurgeBlobMessage(uint32_t blobID, uint32_t cacheID) {
+    SkASSERT(blobID != SK_InvalidGenID);
+    SkMessageBus<PurgeBlobMessage>::Post(PurgeBlobMessage({blobID}), cacheID);
 }
 
 void GrTextBlobCache::purgeStaleBlobs() {
diff --git a/src/gpu/text/GrTextBlobCache.h b/src/gpu/text/GrTextBlobCache.h
index dc7e4c5..ac15124 100644
--- a/src/gpu/text/GrTextBlobCache.h
+++ b/src/gpu/text/GrTextBlobCache.h
@@ -23,11 +23,13 @@
      */
     typedef void (*PFOverBudgetCB)(void* data);
 
-    GrTextBlobCache(PFOverBudgetCB cb, void* data)
+    GrTextBlobCache(PFOverBudgetCB cb, void* data, uint32_t uniqueID)
         : fPool(0u, kMinGrowthSize)
         , fCallback(cb)
         , fData(data)
-        , fBudget(kDefaultBudget) {
+        , fBudget(kDefaultBudget)
+        , fUniqueID(uniqueID)
+        , fPurgeBlobInbox(uniqueID) {
         SkASSERT(cb && data);
     }
     ~GrTextBlobCache();
@@ -51,7 +53,7 @@
         sk_sp<GrAtlasTextBlob> cacheBlob(this->makeBlob(blob));
         cacheBlob->setupKey(key, blurRec, paint);
         this->add(cacheBlob);
-        blob->notifyAddedToCache();
+        blob->notifyAddedToCache(fUniqueID);
         return cacheBlob;
     }
 
@@ -100,7 +102,7 @@
         uint32_t fID;
     };
 
-    static void PostPurgeBlobMessage(uint32_t);
+    static void PostPurgeBlobMessage(uint32_t blobID, uint32_t cacheID);
 
     void purgeStaleBlobs();
 
@@ -178,6 +180,7 @@
     PFOverBudgetCB fCallback;
     void* fData;
     size_t fBudget;
+    uint32_t fUniqueID;      // unique id to use for messaging
     SkMessageBus<PurgeBlobMessage>::Inbox fPurgeBlobInbox;
 };