aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/text/GrTextBlobCache.cpp
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-12-13 09:26:37 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-12-13 14:54:42 +0000
commit76d917cef19aabfdc1247336f58237800bd71875 (patch)
tree6e6be4dc09150c4d9e8f74bb80c866f5062278ed /src/gpu/text/GrTextBlobCache.cpp
parent1fbdb61f1389f01ce1cf1b7950e03a84811a9f38 (diff)
Ensure we flush TextBlobCache message queue.
If we create and delete TextBlobs without actually renderering them, their deletion messages can back up in the message queue. This adds a routine to GrContext to ensure these messages get flushed. Bug: 703297 Change-Id: Icc222373ac2a954dc3b77190cad79070ea562ba2 Reviewed-on: https://skia-review.googlesource.com/82686 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/text/GrTextBlobCache.cpp')
-rw-r--r--src/gpu/text/GrTextBlobCache.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/gpu/text/GrTextBlobCache.cpp b/src/gpu/text/GrTextBlobCache.cpp
index f1162e2634..f90ed9937c 100644
--- a/src/gpu/text/GrTextBlobCache.cpp
+++ b/src/gpu/text/GrTextBlobCache.cpp
@@ -31,3 +31,58 @@ void GrTextBlobCache::PostPurgeBlobMessage(uint32_t id) {
SkASSERT(id != SK_InvalidGenID);
SkMessageBus<PurgeBlobMessage>::Post(PurgeBlobMessage({id}));
}
+
+void GrTextBlobCache::purgeStaleBlobs() {
+ SkTArray<PurgeBlobMessage> msgs;
+ fPurgeBlobInbox.poll(&msgs);
+
+ for (const auto& msg : msgs) {
+ auto* idEntry = fBlobIDCache.find(msg.fID);
+ if (!idEntry) {
+ // no cache entries for id
+ continue;
+ }
+
+ // remove all blob entries from the LRU list
+ for (const auto& blob : idEntry->fBlobs) {
+ fBlobList.remove(blob.get());
+ }
+
+ // drop the idEntry itself (unrefs all blobs)
+ fBlobIDCache.remove(msg.fID);
+ }
+}
+
+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) {
+ BitmapBlobList::Iter iter;
+ iter.init(fBlobList, BitmapBlobList::Iter::kTail_IterStart);
+ GrAtlasTextBlob* lruBlob = nullptr;
+ while (fPool.size() > fBudget && (lruBlob = iter.get()) && lruBlob != blob) {
+ // Backup the iterator before removing and unrefing the blob
+ iter.prev();
+
+ this->remove(lruBlob);
+ }
+
+ // 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 (blob && lruBlob == blob) {
+ (*fCallback)(fData);
+ }
+
+#ifdef SPEW_BUDGET_MESSAGE
+ if (fPool.size() > fBudget) {
+ SkDebugf("Single textblob is larger than our whole budget");
+ }
+#endif
+ }
+}
+
+
+