Update GrTextBlobCache for DDL

Although, theoretically, we could update the DDLs to maintain pointers to the GrMemoryPools being used by their GrAtlasTextBlobs this method seems simpler.

Change-Id: I4835284630b9cd29eb78cf25bcdfe5c56974a8cb
Reviewed-on: https://skia-review.googlesource.com/107345
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index f8522f0..5cb5d8a 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -299,7 +299,8 @@
                                              allowMultitexturing);
     this->contextPriv().addOnFlushCallbackObject(fAtlasGlyphCache);
 
-    fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this, this->uniqueID()));
+    fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB,
+                                             this, this->uniqueID(), SkToBool(fGpu)));
 
     if (options.fExecutor) {
         fTaskGroup = skstd::make_unique<SkTaskGroup>(*options.fExecutor);
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index e805761..90bcf5a 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -27,7 +27,12 @@
                   glyphCount * sizeof(GrGlyph**) +
                   sizeof(GrAtlasTextBlob::Run) * runCount;
 
-    void* allocation = pool->allocate(size);
+    void* allocation;
+    if (pool) {
+        allocation = pool->allocate(size);
+    } else {
+        allocation = ::operator new (size);
+    }
     if (CACHE_SANITY_CHECK) {
         sk_bzero(allocation, size);
     }
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index 9132684..6e1d0b1 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -52,7 +52,7 @@
 
     class VertexRegenerator;
 
-    static sk_sp<GrAtlasTextBlob> Make(GrMemoryPool* pool, int glyphCount, int runCount);
+    static sk_sp<GrAtlasTextBlob> Make(GrMemoryPool*, int glyphCount, int runCount);
 
     /**
      * We currently force regeneration of a blob if old or new matrix differ in having perspective.
@@ -104,7 +104,11 @@
 
     void operator delete(void* p) {
         GrAtlasTextBlob* blob = reinterpret_cast<GrAtlasTextBlob*>(p);
-        blob->fPool->release(p);
+        if (blob->fPool) {
+            blob->fPool->release(p);
+        } else {
+            ::operator delete(p);
+        }
     }
     void* operator new(size_t) {
         SK_ABORT("All blobs are created by placement new.");
@@ -521,7 +525,7 @@
     char* fVertices;
     GrGlyph** fGlyphs;
     Run* fRuns;
-    GrMemoryPool* fPool;
+    GrMemoryPool* fPool;   // this will be null when DDLs are being recorded
     SkMaskFilterBase::BlurRec fBlurRec;
     StrokeInfo fStrokeInfo;
     Key fKey;
diff --git a/src/gpu/text/GrTextBlobCache.cpp b/src/gpu/text/GrTextBlobCache.cpp
index 64941ef..88cbaeb 100644
--- a/src/gpu/text/GrTextBlobCache.cpp
+++ b/src/gpu/text/GrTextBlobCache.cpp
@@ -10,7 +10,8 @@
 DECLARE_SKMESSAGEBUS_MESSAGE(GrTextBlobCache::PurgeBlobMessage)
 
 GrTextBlobCache::~GrTextBlobCache() {
-    SkDEBUGCODE(this->freeAll();)
+    this->freeAll();
+    delete fPool;
 }
 
 void GrTextBlobCache::freeAll() {
@@ -23,7 +24,7 @@
     fBlobIDCache.reset();
 
     // There should be no allocations in the memory pool at this point
-    SkASSERT(fPool.isEmpty());
+    SkASSERT(!fPool || fPool->isEmpty());
     SkASSERT(fBlobList.isEmpty());
 }
 
@@ -53,16 +54,26 @@
     }
 }
 
+bool GrTextBlobCache::overBudget() const {
+    if (fPool) {
+        return fPool->size() > fBudget;
+    }
+
+    // When DDLs are being recorded no GrAtlasTextBlob will be deleted so the cache budget is
+    // somewhat meaningless.
+    return false;
+}
+
 void GrTextBlobCache::checkPurge(GrAtlasTextBlob* blob) {
     // First, purge all stale blob IDs.
     this->purgeStaleBlobs();
 
     // If we are still over budget, then unref until we are below budget again
-    if (fPool.size() > fBudget) {
+    if (this->overBudget()) {
         BitmapBlobList::Iter iter;
         iter.init(fBlobList, BitmapBlobList::Iter::kTail_IterStart);
         GrAtlasTextBlob* lruBlob = nullptr;
-        while (fPool.size() > fBudget && (lruBlob = iter.get()) && lruBlob != blob) {
+        while (this->overBudget() && (lruBlob = iter.get()) && lruBlob != blob) {
             // Backup the iterator before removing and unrefing the blob
             iter.prev();
 
@@ -77,7 +88,7 @@
         }
 
 #ifdef SPEW_BUDGET_MESSAGE
-        if (fPool.size() > fBudget) {
+        if (this->overBudget()) {
             SkDebugf("Single textblob is larger than our whole budget");
         }
 #endif
diff --git a/src/gpu/text/GrTextBlobCache.h b/src/gpu/text/GrTextBlobCache.h
index 7a5c3a8..eb2789a 100644
--- a/src/gpu/text/GrTextBlobCache.h
+++ b/src/gpu/text/GrTextBlobCache.h
@@ -23,8 +23,8 @@
      */
     typedef void (*PFOverBudgetCB)(void* data);
 
-    GrTextBlobCache(PFOverBudgetCB cb, void* data, uint32_t uniqueID)
-        : fPool(0u, kMinGrowthSize)
+    GrTextBlobCache(PFOverBudgetCB cb, void* data, uint32_t uniqueID, bool usePool)
+        : fPool(usePool ? new GrMemoryPool(0u, kMinGrowthSize) : nullptr)
         , fCallback(cb)
         , fData(data)
         , fBudget(kDefaultBudget)
@@ -36,14 +36,14 @@
 
     // creates an uncached blob
     sk_sp<GrAtlasTextBlob> makeBlob(int glyphCount, int runCount) {
-        return GrAtlasTextBlob::Make(&fPool, glyphCount, runCount);
+        return GrAtlasTextBlob::Make(fPool, glyphCount, runCount);
     }
 
     sk_sp<GrAtlasTextBlob> makeBlob(const SkTextBlob* blob) {
         int glyphCount = 0;
         int runCount = 0;
         BlobGlyphCount(&glyphCount, &runCount, blob);
-        return GrAtlasTextBlob::Make(&fPool, glyphCount, runCount);
+        return GrAtlasTextBlob::Make(fPool, glyphCount, runCount);
     }
 
     sk_sp<GrAtlasTextBlob> makeCachedBlob(const SkTextBlob* blob,
@@ -171,10 +171,11 @@
     }
 
     void checkPurge(GrAtlasTextBlob* blob = nullptr);
+    bool overBudget() const;
 
     static const int kMinGrowthSize = 1 << 16;
     static const int kDefaultBudget = 1 << 22;
-    GrMemoryPool fPool;
+    GrMemoryPool* fPool;
     BitmapBlobList fBlobList;
     SkTHashMap<uint32_t, BlobIDCacheEntry> fBlobIDCache;
     PFOverBudgetCB fCallback;