From b7133bed55af8dd4ca9427892bb1a5623dbaccf0 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Wed, 8 Apr 2015 09:08:31 -0700 Subject: Adding a cache + memory pool for GPU TextBlobs BUG=skia: Review URL: https://codereview.chromium.org/1055843002 --- src/gpu/GrTextBlobCache.h | 94 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/gpu/GrTextBlobCache.h (limited to 'src/gpu/GrTextBlobCache.h') diff --git a/src/gpu/GrTextBlobCache.h b/src/gpu/GrTextBlobCache.h new file mode 100644 index 0000000000..7a2b2a79a1 --- /dev/null +++ b/src/gpu/GrTextBlobCache.h @@ -0,0 +1,94 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrTextBlobCache_DEFINED +#define GrTextBlobCache_DEFINED + +#include "GrAtlasTextContext.h" +#include "SkTDynamicHash.h" +#include "SkTextBlob.h" + +class GrTextBlobCache { +public: + typedef GrAtlasTextContext::BitmapTextBlob BitmapTextBlob; + + GrTextBlobCache() : fPool(kPreAllocSize, kMinGrowthSize) {} + ~GrTextBlobCache(); + + // creates an uncached blob + BitmapTextBlob* createBlob(int glyphCount, int runCount, size_t maxVASize); + + BitmapTextBlob* createCachedBlob(const SkTextBlob* blob, size_t maxVAStride) { + int glyphCount = 0; + int runCount = 0; + BlobGlyphCount(&glyphCount, &runCount, blob); + BitmapTextBlob* cacheBlob = this->createBlob(glyphCount, runCount, maxVAStride); + cacheBlob->fUniqueID = blob->uniqueID(); + this->add(cacheBlob); + return cacheBlob; + } + + BitmapTextBlob* find(uint32_t uniqueID) { + return fCache.find(uniqueID); + } + + void remove(BitmapTextBlob* blob) { + fCache.remove(blob->fUniqueID); + fBlobList.remove(blob); + blob->unref(); + } + + void add(BitmapTextBlob* blob) { + fCache.add(blob); + fBlobList.addToHead(blob); + + // If we are overbudget, then unref until we are below budget again + if (fPool.size() > kBudget) { + BitmapBlobList::Iter iter; + iter.init(fBlobList, BitmapBlobList::Iter::kTail_IterStart); + BitmapTextBlob* lruBlob = iter.get(); + SkASSERT(lruBlob); + do { + fCache.remove(lruBlob->fUniqueID); + fBlobList.remove(lruBlob); + lruBlob->unref(); + iter.prev(); + } while (fPool.size() > kBudget && (lruBlob = iter.get())); + } + } + + void makeMRU(BitmapTextBlob* blob) { + if (fBlobList.head() == blob) { + return; + } + + fBlobList.remove(blob); + fBlobList.addToHead(blob); + } + +private: + // TODO move to SkTextBlob + void BlobGlyphCount(int* glyphCount, int* runCount, const SkTextBlob* blob) { + SkTextBlob::RunIterator itCounter(blob); + for (; !itCounter.done(); itCounter.next(), (*runCount)++) { + *glyphCount += itCounter.glyphCount(); + } + } + + typedef SkTInternalLList BitmapBlobList; + + // Budget was chosen to be ~4 megabytes. The min alloc and pre alloc sizes in the pool are + // 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; + BitmapBlobList fBlobList; + SkTDynamicHash fCache; + GrMemoryPool fPool; +}; + +#endif -- cgit v1.2.3