The TextBlobCache needs the ability to trigger a flush because otherwise its entire...
authorjoshualitt <joshualitt@chromium.org>
Fri, 10 Apr 2015 14:01:30 +0000 (07:01 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 10 Apr 2015 14:01:30 +0000 (07:01 -0700)
TBR=bsalomon@google.com
BUG=skia:

Review URL: https://codereview.chromium.org/1071333002

include/gpu/GrContext.h
src/gpu/GrContext.cpp
src/gpu/GrTextBlobCache.h

index f6c3590..38ad7bf 100644 (file)
@@ -787,6 +787,12 @@ private:
      */
     static void OverBudgetCB(void* data);
 
+    /**
+     * 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);
+
     // TODO see note on createTextContext
     friend class SkGpuDevice;
 
index 2d61f35..04e3f8f 100755 (executable)
@@ -137,7 +137,7 @@ void GrContext::initCommon() {
     // GrBatchFontCache will eventually replace GrFontCache
     fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this));
 
-    fTextBlobCache.reset(SkNEW(GrTextBlobCache));
+    fTextBlobCache.reset(SkNEW_ARGS(GrTextBlobCache, (TextBlobCacheOverBudgetCB, this)));
 }
 
 GrContext::~GrContext() {
@@ -354,6 +354,17 @@ void GrContext::OverBudgetCB(void* data) {
     context->fFlushToReduceCacheSize = true;
 }
 
+void GrContext::TextBlobCacheOverBudgetCB(void* data) {
+    SkASSERT(data);
+
+    // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they
+    // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush.  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();
+}
+
 int GrContext::getMaxTextureSize() const {
     return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride);
 }
index 7a2b2a7..9ce4ec7 100644 (file)
@@ -16,7 +16,18 @@ class GrTextBlobCache {
 public:
     typedef GrAtlasTextContext::BitmapTextBlob BitmapTextBlob;
 
-    GrTextBlobCache() : fPool(kPreAllocSize, kMinGrowthSize) {}
+    /**
+     * The callback function used by the cache when it is still over budget after a purge. The
+     * passed in 'data' is the same 'data' handed to setOverbudgetCallback.
+     */
+    typedef void (*PFOverBudgetCB)(void* data);
+
+    GrTextBlobCache(PFOverBudgetCB cb, void* data)
+        : fPool(kPreAllocSize, kMinGrowthSize)
+        , fCallback(cb)
+        , fData(data) {
+        SkASSERT(cb && data);
+    }
     ~GrTextBlobCache();
 
     // creates an uncached blob
@@ -52,12 +63,25 @@ public:
             iter.init(fBlobList, BitmapBlobList::Iter::kTail_IterStart);
             BitmapTextBlob* lruBlob = iter.get();
             SkASSERT(lruBlob);
-            do {
+            while (fPool.size() > kBudget && (lruBlob = iter.get()) && lruBlob != blob) {
                 fCache.remove(lruBlob->fUniqueID);
                 fBlobList.remove(lruBlob);
-                lruBlob->unref();
                 iter.prev();
-            } while (fPool.size() > kBudget && (lruBlob = iter.get()));
+                lruBlob->unref();
+            }
+
+            // If we break out of the loop with lruBlob == blob, then we haven't purged enough
+            // use the call back and try to free some more.  If we are still overbudget after this,
+            // then this single textblob is over our budget
+            if (lruBlob == blob) {
+                (*fCallback)(fData);
+            }
+
+#ifdef SK_DEBUG
+            if (fPool.size() > kBudget) {
+                SkDebugf("Single textblob is larger than our whole budget");
+            }
+#endif
         }
     }
 
@@ -85,10 +109,12 @@ private:
     // based off of the largest cached textblob I have seen in the skps(a couple of kilobytes).
     static const int kPreAllocSize = 1 << 17;
     static const int kMinGrowthSize = 1 << 17;
-    static const int kBudget = 1 << 20;
+    static const int kBudget = 1 << 22;
     BitmapBlobList fBlobList;
     SkTDynamicHash<BitmapTextBlob, uint32_t> fCache;
     GrMemoryPool fPool;
+    PFOverBudgetCB fCallback;
+    void* fData;
 };
 
 #endif