Chromium Code Reviews| Index: src/gpu/GrTextBlobCache.h |
| diff --git a/src/gpu/GrTextBlobCache.h b/src/gpu/GrTextBlobCache.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5870f0edc6948fad39d0186b4a2a8965ab37be3d |
| --- /dev/null |
| +++ b/src/gpu/GrTextBlobCache.h |
| @@ -0,0 +1,89 @@ |
| +/* |
| + * 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(2 << 17, 2 << 17), fBudget(2 << 22) {} |
|
jvanverth1
2015/04/06 20:44:12
These seem like magic numbers. I'm not sure why th
|
| + ~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() > fBudget) { |
| + 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() > fBudget && (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<BitmapTextBlob> BitmapBlobList; |
| + BitmapBlobList fBlobList; |
| + SkTDynamicHash<BitmapTextBlob, uint32_t> fCache; |
| + GrMemoryPool fPool; |
| + size_t fBudget; |
| +}; |
| + |
| +#endif |