The TextBlobCache needs the ability to trigger a flush because otherwise its entire budget can be used up, but it will not be able to free up any space due to blobs being stuck in the GrInOrderDrawBuffer. This was causing a segfault. After this CL the cache will try to purge, and then flush if it cannot purge enough. It will not purge the most recent addition to the cache.
TBR=bsalomon@google.com BUG=skia: Review URL: https://codereview.chromium.org/1071333002
This commit is contained in:
parent
c5e0891029
commit
0db6dfaeb2
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user