Light cleanup of GrTextBlob cache
* Remove unused methods
* GrTextBlobCache::makeBlob -> GrTextBlob::Make
* Fix up comments
* Move impl to .cpp
Change-Id: Ife4de04e709d3a6d212486f631bc67561957cdd6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/291198
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp
index 9db7bfc..4156a9a 100644
--- a/src/core/SkGlyphRunPainter.cpp
+++ b/src/core/SkGlyphRunPainter.cpp
@@ -351,8 +351,7 @@
cachedBlob = textBlobCache->makeCachedBlob(glyphRunList, key, blurRec, drawMatrix,
initialVertexColor, forceW);
} else {
- cachedBlob = textBlobCache->makeBlob(glyphRunList, drawMatrix,
- initialVertexColor, forceW);
+ cachedBlob = GrTextBlob::Make(glyphRunList, drawMatrix, initialVertexColor, forceW);
}
painter->processGlyphRunList(
glyphRunList, drawMatrix, props, supportsSDFT, fOptions, cachedBlob.get());
@@ -395,7 +394,7 @@
auto glyphRunList = builder.useGlyphRunList();
sk_sp<GrTextBlob> blob;
if (!glyphRunList.empty()) {
- blob = direct->priv().getTextBlobCache()->makeBlob(glyphRunList, drawMatrix, color, false);
+ blob = GrTextBlob::Make(glyphRunList, drawMatrix, color, false);
SkGlyphRunListPainter* painter = rtc->textTarget()->glyphPainter();
painter->processGlyphRunList(
glyphRunList, drawMatrix, surfaceProps,
diff --git a/src/gpu/text/GrTextBlobCache.cpp b/src/gpu/text/GrTextBlobCache.cpp
index c3a6860..37489c6 100644
--- a/src/gpu/text/GrTextBlobCache.cpp
+++ b/src/gpu/text/GrTextBlobCache.cpp
@@ -9,15 +9,63 @@
DECLARE_SKMESSAGEBUS_MESSAGE(GrTextBlobCache::PurgeBlobMessage)
+// This function is captured by the above macro using implementations from SkMessageBus.h
static inline bool SkShouldPostMessageToBus(
const GrTextBlobCache::PurgeBlobMessage& msg, uint32_t msgBusUniqueID) {
return msg.fContextID == msgBusUniqueID;
}
+GrTextBlobCache::GrTextBlobCache(GrTextBlobCache::PFOverBudgetCB cb, void* data, uint32_t uniqueID)
+ : fCallback(cb)
+ , fData(data)
+ , fSizeBudget(kDefaultBudget)
+ , fUniqueID(uniqueID)
+ , fPurgeBlobInbox(uniqueID) {
+ SkASSERT(cb != nullptr && data != nullptr);
+}
+
GrTextBlobCache::~GrTextBlobCache() {
this->freeAll();
}
+sk_sp<GrTextBlob>
+GrTextBlobCache::makeCachedBlob(const SkGlyphRunList& glyphRunList, const GrTextBlob::Key& key,
+ const SkMaskFilterBase::BlurRec& blurRec,
+ const SkMatrix& viewMatrix, GrColor color, bool forceW) {
+ sk_sp<GrTextBlob> cacheBlob(GrTextBlob::Make(glyphRunList, viewMatrix, color, forceW));
+ cacheBlob->setupKey(key, blurRec, glyphRunList.paint());
+ this->add(cacheBlob);
+ glyphRunList.temporaryShuntBlobNotifyAddedToCache(fUniqueID);
+ return cacheBlob;
+}
+
+sk_sp<GrTextBlob> GrTextBlobCache::find(const GrTextBlob::Key& key) const {
+ const auto* idEntry = fBlobIDCache.find(key.fUniqueID);
+ return idEntry ? idEntry->find(key) : nullptr;
+}
+
+void GrTextBlobCache::remove(GrTextBlob* blob) {
+ auto id = GrTextBlob::GetKey(*blob).fUniqueID;
+ auto* idEntry = fBlobIDCache.find(id);
+ SkASSERT(idEntry);
+
+ fCurrentSize -= blob->size();
+ fBlobList.remove(blob);
+ idEntry->removeBlob(blob);
+ if (idEntry->fBlobs.empty()) {
+ fBlobIDCache.remove(id);
+ }
+}
+
+void GrTextBlobCache::makeMRU(GrTextBlob* blob) {
+ if (fBlobList.head() == blob) {
+ return;
+ }
+
+ fBlobList.remove(blob);
+ fBlobList.addToHead(blob);
+}
+
void GrTextBlobCache::freeAll() {
fBlobIDCache.foreach([this](uint32_t, BlobIDCacheEntry* entry) {
for (const auto& blob : entry->fBlobs) {
@@ -33,6 +81,11 @@
SkASSERT(fBlobList.isEmpty());
}
+void GrTextBlobCache::setBudget(size_t budget) {
+ fSizeBudget = budget;
+ this->checkPurge();
+}
+
void GrTextBlobCache::PostPurgeBlobMessage(uint32_t blobID, uint32_t cacheID) {
SkASSERT(blobID != SK_InvalidGenID);
SkMessageBus<PurgeBlobMessage>::Post(PurgeBlobMessage(blobID, cacheID));
@@ -66,8 +119,8 @@
// If we are still over budget, then unref until we are below budget again
if (fCurrentSize > fSizeBudget) {
- BitmapBlobList::Iter iter;
- iter.init(fBlobList, BitmapBlobList::Iter::kTail_IterStart);
+ TextBlobList::Iter iter;
+ iter.init(fBlobList, TextBlobList::Iter::kTail_IterStart);
GrTextBlob* lruBlob = nullptr;
while (fCurrentSize > fSizeBudget && (lruBlob = iter.get()) && lruBlob != blob) {
// Backup the iterator before removing and unrefing the blob
@@ -83,13 +136,66 @@
(*fCallback)(fData);
}
-#ifdef SPEW_BUDGET_MESSAGE
+ #ifdef SPEW_BUDGET_MESSAGE
if (fCurrentSize > fSizeBudget) {
SkDebugf("Single textblob is larger than our whole budget");
}
-#endif
+ #endif
}
}
+void GrTextBlobCache::add(sk_sp<GrTextBlob> blob) {
+ auto id = GrTextBlob::GetKey(*blob).fUniqueID;
+ auto* idEntry = fBlobIDCache.find(id);
+ if (!idEntry) {
+ idEntry = fBlobIDCache.set(id, BlobIDCacheEntry(id));
+ }
+ // Safe to retain a raw ptr temporarily here, because the cache will hold a ref.
+ GrTextBlob* rawBlobPtr = blob.get();
+ fBlobList.addToHead(rawBlobPtr);
+ fCurrentSize += blob->size();
+ idEntry->addBlob(std::move(blob));
+ this->checkPurge(rawBlobPtr);
+}
+
+GrTextBlobCache::BlobIDCacheEntry::BlobIDCacheEntry() : fID(SK_InvalidGenID) {}
+
+GrTextBlobCache::BlobIDCacheEntry::BlobIDCacheEntry(uint32_t id) : fID(id) {}
+
+uint32_t GrTextBlobCache::BlobIDCacheEntry::GetKey(const GrTextBlobCache::BlobIDCacheEntry& entry) {
+ return entry.fID;
+}
+
+void GrTextBlobCache::BlobIDCacheEntry::addBlob(sk_sp<GrTextBlob> blob) {
+ SkASSERT(blob);
+ SkASSERT(GrTextBlob::GetKey(*blob).fUniqueID == fID);
+ SkASSERT(!this->find(GrTextBlob::GetKey(*blob)));
+
+ fBlobs.emplace_back(std::move(blob));
+}
+
+void GrTextBlobCache::BlobIDCacheEntry::removeBlob(GrTextBlob* blob) {
+ SkASSERT(blob);
+ SkASSERT(GrTextBlob::GetKey(*blob).fUniqueID == fID);
+
+ auto index = this->findBlobIndex(GrTextBlob::GetKey(*blob));
+ SkASSERT(index >= 0);
+
+ fBlobs.removeShuffle(index);
+}
+
+sk_sp<GrTextBlob> GrTextBlobCache::BlobIDCacheEntry::find(const GrTextBlob::Key& key) const {
+ auto index = this->findBlobIndex(key);
+ return index < 0 ? nullptr : fBlobs[index];
+}
+
+int GrTextBlobCache::BlobIDCacheEntry::findBlobIndex(const GrTextBlob::Key& key) const {
+ for (int i = 0; i < fBlobs.count(); ++i) {
+ if (GrTextBlob::GetKey(*fBlobs[i]) == key) {
+ return i;
+ }
+ }
+ return -1;
+}
diff --git a/src/gpu/text/GrTextBlobCache.h b/src/gpu/text/GrTextBlobCache.h
index 9af2f2c..01433d1 100644
--- a/src/gpu/text/GrTextBlobCache.h
+++ b/src/gpu/text/GrTextBlobCache.h
@@ -17,83 +17,28 @@
class GrTextBlobCache {
public:
- /**
- * 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);
+ // The callback function used by the cache when it is still over budget after a purge.
+ using PFOverBudgetCB = void (*)(void* data);
- GrTextBlobCache(PFOverBudgetCB cb, void* data, uint32_t uniqueID)
- : fCallback(cb)
- , fData(data)
- , fSizeBudget(kDefaultBudget)
- , fUniqueID(uniqueID)
- , fPurgeBlobInbox(uniqueID) {
- SkASSERT(cb && data);
- }
+ GrTextBlobCache(PFOverBudgetCB cb, void* data, uint32_t uniqueID);
~GrTextBlobCache();
- sk_sp<GrTextBlob> makeBlob(const SkGlyphRunList& glyphRunList,
- const SkMatrix& viewMatrix,
- GrColor color,
- bool forceW) {
- return GrTextBlob::Make(glyphRunList, viewMatrix, color, forceW);
- }
-
sk_sp<GrTextBlob> makeCachedBlob(const SkGlyphRunList& glyphRunList,
const GrTextBlob::Key& key,
const SkMaskFilterBase::BlurRec& blurRec,
const SkMatrix& viewMatrix,
GrColor color,
- bool forceW) {
- sk_sp<GrTextBlob> cacheBlob(this->makeBlob(glyphRunList, viewMatrix, color, forceW));
- cacheBlob->setupKey(key, blurRec, glyphRunList.paint());
- this->add(cacheBlob);
- glyphRunList.temporaryShuntBlobNotifyAddedToCache(fUniqueID);
- return cacheBlob;
- }
+ bool forceW);
- sk_sp<GrTextBlob> find(const GrTextBlob::Key& key) const {
- const auto* idEntry = fBlobIDCache.find(key.fUniqueID);
- return idEntry ? idEntry->find(key) : nullptr;
- }
+ sk_sp<GrTextBlob> find(const GrTextBlob::Key& key) const;
- void remove(GrTextBlob* blob) {
- auto id = GrTextBlob::GetKey(*blob).fUniqueID;
- auto* idEntry = fBlobIDCache.find(id);
- SkASSERT(idEntry);
+ void remove(GrTextBlob* blob);
- fCurrentSize -= blob->size();
- fBlobList.remove(blob);
- idEntry->removeBlob(blob);
- if (idEntry->fBlobs.empty()) {
- fBlobIDCache.remove(id);
- }
- }
-
- void makeMRU(GrTextBlob* blob) {
- if (fBlobList.head() == blob) {
- return;
- }
-
- fBlobList.remove(blob);
- fBlobList.addToHead(blob);
- }
+ void makeMRU(GrTextBlob* blob);
void freeAll();
- // TODO move to SkTextBlob
- static void BlobGlyphCount(int* glyphCount, int* runCount, const SkTextBlob* blob) {
- SkTextBlobRunIterator itCounter(blob);
- for (; !itCounter.done(); itCounter.next(), (*runCount)++) {
- *glyphCount += itCounter.glyphCount();
- }
- }
-
- void setBudget(size_t budget) {
- fSizeBudget = budget;
- this->checkPurge();
- }
+ void setBudget(size_t budget);
struct PurgeBlobMessage {
PurgeBlobMessage(uint32_t blobID, uint32_t contextUniqueID)
@@ -110,75 +55,35 @@
size_t usedBytes() const { return fCurrentSize; }
private:
- using BitmapBlobList = SkTInternalLList<GrTextBlob>;
+ using TextBlobList = SkTInternalLList<GrTextBlob>;
struct BlobIDCacheEntry {
- BlobIDCacheEntry() : fID(SK_InvalidGenID) {}
- explicit BlobIDCacheEntry(uint32_t id) : fID(id) {}
+ BlobIDCacheEntry();
+ explicit BlobIDCacheEntry(uint32_t id);
- static uint32_t GetKey(const BlobIDCacheEntry& entry) {
- return entry.fID;
- }
+ static uint32_t GetKey(const BlobIDCacheEntry& entry);
- void addBlob(sk_sp<GrTextBlob> blob) {
- SkASSERT(blob);
- SkASSERT(GrTextBlob::GetKey(*blob).fUniqueID == fID);
- SkASSERT(!this->find(GrTextBlob::GetKey(*blob)));
+ void addBlob(sk_sp<GrTextBlob> blob);
- fBlobs.emplace_back(std::move(blob));
- }
+ void removeBlob(GrTextBlob* blob);
- void removeBlob(GrTextBlob* blob) {
- SkASSERT(blob);
- SkASSERT(GrTextBlob::GetKey(*blob).fUniqueID == fID);
+ sk_sp<GrTextBlob> find(const GrTextBlob::Key& key) const;
- auto index = this->findBlobIndex(GrTextBlob::GetKey(*blob));
- SkASSERT(index >= 0);
+ int findBlobIndex(const GrTextBlob::Key& key) const;
- fBlobs.removeShuffle(index);
- }
-
- sk_sp<GrTextBlob> find(const GrTextBlob::Key& key) const {
- auto index = this->findBlobIndex(key);
- return index < 0 ? nullptr : fBlobs[index];
- }
-
- int findBlobIndex(const GrTextBlob::Key& key) const{
- for (int i = 0; i < fBlobs.count(); ++i) {
- if (GrTextBlob::GetKey(*fBlobs[i]) == key) {
- return i;
- }
- }
- return -1;
- }
-
- uint32_t fID;
+ uint32_t fID;
// Current clients don't generate multiple GrAtlasTextBlobs per SkTextBlob, so an array w/
// linear search is acceptable. If usage changes, we should re-evaluate this structure.
SkSTArray<1, sk_sp<GrTextBlob>> fBlobs;
};
- void add(sk_sp<GrTextBlob> blob) {
- auto id = GrTextBlob::GetKey(*blob).fUniqueID;
- auto* idEntry = fBlobIDCache.find(id);
- if (!idEntry) {
- idEntry = fBlobIDCache.set(id, BlobIDCacheEntry(id));
- }
-
- // Safe to retain a raw ptr temporarily here, because the cache will hold a ref.
- GrTextBlob* rawBlobPtr = blob.get();
- fBlobList.addToHead(rawBlobPtr);
- fCurrentSize += blob->size();
- idEntry->addBlob(std::move(blob));
-
- this->checkPurge(rawBlobPtr);
- }
+ void add(sk_sp<GrTextBlob> blob);
void checkPurge(GrTextBlob* blob = nullptr);
- static const int kMinGrowthSize = 1 << 16;
static const int kDefaultBudget = 1 << 22;
- BitmapBlobList fBlobList;
+
+ TextBlobList fBlobList;
SkTHashMap<uint32_t, BlobIDCacheEntry> fBlobIDCache;
PFOverBudgetCB fCallback;
void* fData;