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>
This commit is contained in:
parent
d5811b2d44
commit
303cd58870
@ -299,7 +299,8 @@ bool GrContext::init(const GrContextOptions& options) {
|
||||
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);
|
||||
|
@ -27,7 +27,12 @@ sk_sp<GrAtlasTextBlob> GrAtlasTextBlob::Make(GrMemoryPool* pool, int glyphCount,
|
||||
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);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
|
||||
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 @@ private:
|
||||
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;
|
||||
|
@ -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 @@ void GrTextBlobCache::freeAll() {
|
||||
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 @@ void GrTextBlobCache::purgeStaleBlobs() {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ void GrTextBlobCache::checkPurge(GrAtlasTextBlob* blob) {
|
||||
}
|
||||
|
||||
#ifdef SPEW_BUDGET_MESSAGE
|
||||
if (fPool.size() > fBudget) {
|
||||
if (this->overBudget()) {
|
||||
SkDebugf("Single textblob is larger than our whole budget");
|
||||
}
|
||||
#endif
|
||||
|
@ -23,8 +23,8 @@ public:
|
||||
*/
|
||||
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 @@ public:
|
||||
|
||||
// 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 @@ private:
|
||||
}
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user