Move StrikeCache and TextBlobCache to RecordingContext

TBR=bsalomon@google.com
Change-Id: I09a918eee4fab2091b0cbbbe83bc66418e43045e
Reviewed-on: https://skia-review.googlesource.com/c/193471
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 2060630..71b82f9 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -26,7 +26,6 @@
 class GrDrawingManager;
 class GrFragmentProcessor;
 struct GrGLInterface;
-class GrStrikeCache;
 class GrGpu;
 struct GrMockOptions;
 class GrPath;
@@ -37,7 +36,6 @@
 class GrSkSLFPFactoryCache;
 class GrSurfaceProxy;
 class GrSwizzle;
-class GrTextBlobCache;
 class GrTextContext;
 class GrTextureProxy;
 struct GrVkBackendContext;
@@ -310,9 +308,6 @@
     GrResourceCache*                        fResourceCache;
     GrResourceProvider*                     fResourceProvider;
 
-    GrStrikeCache*                          fGlyphCache;
-    std::unique_ptr<GrTextBlobCache>        fTextBlobCache;
-
     bool                                    fDidTestPMConversions;
     // true if the PM/UPM conversion succeeded; false otherwise
     bool                                    fPMUPMConversionsRoundTrip;
@@ -337,12 +332,6 @@
      */
     bool validPMUPMConversionExists();
 
-    /**
-     * A callback similar to the above for use by the TextBlobCache
-     * TODO move textblob draw calls below context so we can use the call above.
-     */
-    static void TextBlobCacheOverBudgetCB(void* data);
-
     typedef GrRecordingContext INHERITED;
 };
 
diff --git a/include/private/GrRecordingContext.h b/include/private/GrRecordingContext.h
index 1f90b01..014d655 100644
--- a/include/private/GrRecordingContext.h
+++ b/include/private/GrRecordingContext.h
@@ -15,6 +15,8 @@
 class GrOnFlushCallbackObject;
 class GrOpMemoryPool;
 class GrRecordingContextPriv;
+class GrStrikeCache;
+class GrTextBlobCache;
 
 class SK_API GrRecordingContext : public GrImageContext {
 public:
@@ -38,6 +40,10 @@
     sk_sp<GrOpMemoryPool> refOpMemoryPool();
     GrOpMemoryPool* opMemoryPool();
 
+    GrStrikeCache* getGlyphCache() { return fGlyphCache.get(); }
+    GrTextBlobCache* getTextBlobCache();
+    const GrTextBlobCache* getTextBlobCache() const;
+
     /**
      * Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.)
      *
@@ -100,8 +106,12 @@
 
 private:
     // All the GrOp-derived classes use this pool.
-    sk_sp<GrOpMemoryPool> fOpMemoryPool;
-    GrAuditTrail          fAuditTrail;
+    sk_sp<GrOpMemoryPool>             fOpMemoryPool;
+
+    std::unique_ptr<GrStrikeCache>    fGlyphCache;
+    std::unique_ptr<GrTextBlobCache>  fTextBlobCache;
+
+    GrAuditTrail                      fAuditTrail;
 
     typedef GrImageContext INHERITED;
 };
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 1ccbc6b..95c0c62 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -49,7 +49,6 @@
         : INHERITED(backend, options, contextID) {
     fResourceCache = nullptr;
     fResourceProvider = nullptr;
-    fGlyphCache = nullptr;
 }
 
 GrContext::~GrContext() {
@@ -60,7 +59,6 @@
     }
     delete fResourceProvider;
     delete fResourceCache;
-    delete fGlyphCache;
 }
 
 bool GrContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) {
@@ -73,6 +71,8 @@
     }
 
     SkASSERT(this->caps());
+    SkASSERT(this->getGlyphCache());
+    SkASSERT(this->getTextBlobCache());
 
     if (fGpu) {
         fResourceCache = new GrResourceCache(this->caps(), this->singleOwner(), this->contextID());
@@ -121,10 +121,6 @@
                                                this->options().fSortRenderTargets,
                                                this->options().fReduceOpListSplitting));
 
-    fGlyphCache = new GrStrikeCache(this->caps(), this->options().fGlyphCacheTextureMaximumBytes);
-
-    fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this, this->contextID()));
-
     // DDL TODO: we need to think through how the task group & persistent cache
     // get passed on to/shared between all the DDLRecorders created with this context.
     if (this->options().fExecutor) {
@@ -164,9 +160,6 @@
     fResourceCache->abandonAll();
 
     fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
-
-    fGlyphCache->freeAll();
-    fTextBlobCache->freeAll();
 }
 
 void GrContext::releaseResourcesAndAbandonContext() {
@@ -186,9 +179,6 @@
     fResourceCache->releaseAll();
 
     fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
-
-    fGlyphCache->freeAll();
-    fTextBlobCache->freeAll();
 }
 
 void GrContext::resetGLTextureBindings() {
@@ -206,7 +196,9 @@
 void GrContext::freeGpuResources() {
     ASSERT_SINGLE_OWNER
 
-    fGlyphCache->freeAll();
+    // TODO: the glyph cache doesn't hold any GpuResources so this call should not be needed here.
+    // Some slack in the GrTextBlob's implementation requires it though. That could be fixed.
+    this->getGlyphCache()->freeAll();
 
     this->drawingManager()->freeGpuResources();
 
@@ -217,7 +209,10 @@
     ASSERT_SINGLE_OWNER
     fResourceCache->purgeUnlockedResources(scratchResourcesOnly);
     fResourceCache->purgeAsNeeded();
-    fTextBlobCache->purgeStaleBlobs();
+
+    // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
+    // place to purge stale blobs
+    this->getTextBlobCache()->purgeStaleBlobs();
 }
 
 void GrContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed) {
@@ -232,7 +227,9 @@
         ccpr->purgeCacheEntriesOlderThan(this->proxyProvider(), purgeTime);
     }
 
-    fTextBlobCache->purgeStaleBlobs();
+    // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
+    // place to purge stale blobs
+    this->getTextBlobCache()->purgeStaleBlobs();
 }
 
 void GrContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
@@ -274,18 +271,6 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrContext::TextBlobCacheOverBudgetCB(void* data) {
-    SkASSERT(data);
-    // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
-    // GrRenderTargetContext to perform a necessary flush.  The solution is to move drawText calls
-    // to below the GrContext level, but this is not trivial because they call drawPath on
-    // SkGpuDevice.
-    GrContext* context = reinterpret_cast<GrContext*>(data);
-    context->flush();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 void GrContext::flush() {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
@@ -373,6 +358,6 @@
     ASSERT_SINGLE_OWNER
     fResourceCache->dumpMemoryStatistics(traceMemoryDump);
     traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
-                                      fTextBlobCache->usedBytes());
+                                      this->getTextBlobCache()->usedBytes());
 }
 
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index ea6c7a0..da8dac2 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -765,7 +765,7 @@
 }
 
 void GrContextPriv::testingOnly_setTextBlobCacheLimit(size_t bytes) {
-    fContext->fTextBlobCache->setBudget(bytes);
+    fContext->priv().getTextBlobCache()->setBudget(bytes);
 }
 
 sk_sp<SkImage> GrContextPriv::testingOnly_getFontAtlasImage(GrMaskFormat format, unsigned int index) {
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index de1d3a8..3172207 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -68,6 +68,9 @@
     sk_sp<GrOpMemoryPool> refOpMemoryPool();
     GrOpMemoryPool* opMemoryPool() { return fContext->opMemoryPool(); }
 
+    GrStrikeCache* getGlyphCache() { return fContext->getGlyphCache(); }
+    GrTextBlobCache* getTextBlobCache() { return fContext->getTextBlobCache(); }
+
     /**
      * Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.)
      *
@@ -265,9 +268,6 @@
     GrGpu* getGpu() { return fContext->fGpu.get(); }
     const GrGpu* getGpu() const { return fContext->fGpu.get(); }
 
-    GrStrikeCache* getGlyphCache() { return fContext->fGlyphCache; }
-    GrTextBlobCache* getTextBlobCache() { return fContext->fTextBlobCache.get(); }
-
     // This accessor should only ever be called by the GrOpFlushState.
     GrAtlasManager* getAtlasManager() {
         return fContext->onGetAtlasManager();
diff --git a/src/gpu/GrRecordingContext.cpp b/src/gpu/GrRecordingContext.cpp
index 47adb97..ebd9373 100644
--- a/src/gpu/GrRecordingContext.cpp
+++ b/src/gpu/GrRecordingContext.cpp
@@ -16,6 +16,7 @@
 #include "GrSkSLFPFactoryCache.h"
 #include "GrTextureContext.h"
 #include "SkGr.h"
+#include "text/GrTextBlobCache.h"
 
 #define ASSERT_SINGLE_OWNER_PRIV \
     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
@@ -28,17 +29,45 @@
 
 GrRecordingContext::~GrRecordingContext() { }
 
+/**
+ * TODO: move textblob draw calls below context (see comment below)
+ */
+static void textblobcache_overbudget_CB(void* data) {
+    SkASSERT(data);
+    GrRecordingContext* context = reinterpret_cast<GrRecordingContext*>(data);
+
+    GrContext* direct = context->priv().asDirectContext();
+    if (!direct) {
+        return;
+    }
+
+    // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
+    // GrRenderTargetContext to perform a necessary flush.  The solution is to move drawText calls
+    // to below the GrContext level, but this is not trivial because they call drawPath on
+    // SkGpuDevice.
+    direct->flush();
+}
+
 bool GrRecordingContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> cache) {
 
     if (!INHERITED::init(std::move(caps), std::move(cache))) {
         return false;
     }
 
+    fGlyphCache.reset(new GrStrikeCache(this->caps(),
+                                        this->options().fGlyphCacheTextureMaximumBytes));
+
+    fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
+                                             this->contextID()));
+
     return true;
 }
 
 void GrRecordingContext::abandonContext() {
     INHERITED::abandonContext();
+
+    fGlyphCache->freeAll();
+    fTextBlobCache->freeAll();
 }
 
 sk_sp<GrOpMemoryPool> GrRecordingContext::refOpMemoryPool() {
@@ -57,6 +86,14 @@
     return this->refOpMemoryPool().get();
 }
 
+GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
+    return fTextBlobCache.get();
+}
+
+const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
+    return fTextBlobCache.get();
+}
+
 void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
     this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
 }
diff --git a/src/gpu/GrRecordingContextPriv.h b/src/gpu/GrRecordingContextPriv.h
index b130bee..8d64f1c 100644
--- a/src/gpu/GrRecordingContextPriv.h
+++ b/src/gpu/GrRecordingContextPriv.h
@@ -52,6 +52,9 @@
     sk_sp<GrOpMemoryPool> refOpMemoryPool();
     GrOpMemoryPool* opMemoryPool() { return fContext->opMemoryPool(); }
 
+    GrStrikeCache* getGlyphCache() { return fContext->getGlyphCache(); }
+    GrTextBlobCache* getTextBlobCache() { return fContext->getTextBlobCache(); }
+
     /**
      * Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.)
      *