blob: a60903fca3b64d6d1f55149c0fa3be552ae7e0ee [file] [log] [blame]
joshualittb7133be2015-04-08 09:08:31 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrTextBlobCache.h"
9
Florin Malita4a01ac92017-03-13 16:45:28 -040010DECLARE_SKMESSAGEBUS_MESSAGE(GrTextBlobCache::PurgeBlobMessage)
11
joshualittb7133be2015-04-08 09:08:31 -070012GrTextBlobCache::~GrTextBlobCache() {
Robert Phillips303cd582018-02-14 18:54:01 -050013 this->freeAll();
joshualittb7133be2015-04-08 09:08:31 -070014}
15
joshualitt26ffc002015-04-16 11:24:04 -070016void GrTextBlobCache::freeAll() {
Florin Malita33fdb8d2017-03-07 16:51:57 -050017 fBlobIDCache.foreach([this](uint32_t, BlobIDCacheEntry* entry) {
Florin Malitac337c9e2017-03-10 18:02:29 +000018 for (const auto& blob : entry->fBlobs) {
19 fBlobList.remove(blob.get());
Florin Malita33fdb8d2017-03-07 16:51:57 -050020 }
21 });
22
23 fBlobIDCache.reset();
joshualitt20ccd402016-01-05 08:56:56 -080024
Herb Derbyb12175f2018-05-23 16:38:09 -040025 fCurrentSize = 0;
26
joshualitt20ccd402016-01-05 08:56:56 -080027 // There should be no allocations in the memory pool at this point
Florin Malita33fdb8d2017-03-07 16:51:57 -050028 SkASSERT(fBlobList.isEmpty());
joshualitt26ffc002015-04-16 11:24:04 -070029}
Florin Malita4a01ac92017-03-13 16:45:28 -040030
Jim Van Verth474d6872017-12-14 13:00:05 -050031void GrTextBlobCache::PostPurgeBlobMessage(uint32_t blobID, uint32_t cacheID) {
32 SkASSERT(blobID != SK_InvalidGenID);
Brian Salomon238069b2018-07-11 15:58:57 -040033 SkMessageBus<PurgeBlobMessage>::Post(PurgeBlobMessage(blobID, cacheID));
Florin Malita4a01ac92017-03-13 16:45:28 -040034}
Jim Van Verth76d917c2017-12-13 09:26:37 -050035
36void GrTextBlobCache::purgeStaleBlobs() {
37 SkTArray<PurgeBlobMessage> msgs;
38 fPurgeBlobInbox.poll(&msgs);
39
40 for (const auto& msg : msgs) {
Brian Salomon238069b2018-07-11 15:58:57 -040041 auto* idEntry = fBlobIDCache.find(msg.fBlobID);
Jim Van Verth76d917c2017-12-13 09:26:37 -050042 if (!idEntry) {
43 // no cache entries for id
44 continue;
45 }
46
47 // remove all blob entries from the LRU list
48 for (const auto& blob : idEntry->fBlobs) {
Herb Derbyb12175f2018-05-23 16:38:09 -040049 fCurrentSize -= blob->size();
Jim Van Verth76d917c2017-12-13 09:26:37 -050050 fBlobList.remove(blob.get());
51 }
52
53 // drop the idEntry itself (unrefs all blobs)
Brian Salomon238069b2018-07-11 15:58:57 -040054 fBlobIDCache.remove(msg.fBlobID);
Jim Van Verth76d917c2017-12-13 09:26:37 -050055 }
56}
57
Herb Derby86240592018-05-24 16:12:31 -040058void GrTextBlobCache::checkPurge(GrTextBlob* blob) {
Jim Van Verth76d917c2017-12-13 09:26:37 -050059 // First, purge all stale blob IDs.
60 this->purgeStaleBlobs();
61
62 // If we are still over budget, then unref until we are below budget again
Herb Derbyb12175f2018-05-23 16:38:09 -040063 if (fCurrentSize > fSizeBudget) {
Jim Van Verth76d917c2017-12-13 09:26:37 -050064 BitmapBlobList::Iter iter;
65 iter.init(fBlobList, BitmapBlobList::Iter::kTail_IterStart);
Herb Derby86240592018-05-24 16:12:31 -040066 GrTextBlob* lruBlob = nullptr;
Herb Derbyb12175f2018-05-23 16:38:09 -040067 while (fCurrentSize > fSizeBudget && (lruBlob = iter.get()) && lruBlob != blob) {
Jim Van Verth76d917c2017-12-13 09:26:37 -050068 // Backup the iterator before removing and unrefing the blob
69 iter.prev();
70
71 this->remove(lruBlob);
72 }
73
74 // If we break out of the loop with lruBlob == blob, then we haven't purged enough
75 // use the call back and try to free some more. If we are still overbudget after this,
76 // then this single textblob is over our budget
77 if (blob && lruBlob == blob) {
78 (*fCallback)(fData);
79 }
80
81#ifdef SPEW_BUDGET_MESSAGE
Herb Derbyb12175f2018-05-23 16:38:09 -040082 if (fCurrentSize > fSizeBudget) {
Jim Van Verth76d917c2017-12-13 09:26:37 -050083 SkDebugf("Single textblob is larger than our whole budget");
84 }
85#endif
86 }
87}
88
89
90