GrTextBlobCache.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  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. #include "src/gpu/text/GrTextBlobCache.h"
  8. DECLARE_SKMESSAGEBUS_MESSAGE(GrTextBlobCache::PurgeBlobMessage)
  9. static inline bool SkShouldPostMessageToBus(
  10. const GrTextBlobCache::PurgeBlobMessage& msg, uint32_t msgBusUniqueID) {
  11. return msg.fContextID == msgBusUniqueID;
  12. }
  13. GrTextBlobCache::~GrTextBlobCache() {
  14. this->freeAll();
  15. }
  16. void GrTextBlobCache::freeAll() {
  17. fBlobIDCache.foreach([this](uint32_t, BlobIDCacheEntry* entry) {
  18. for (const auto& blob : entry->fBlobs) {
  19. fBlobList.remove(blob.get());
  20. }
  21. });
  22. fBlobIDCache.reset();
  23. fCurrentSize = 0;
  24. // There should be no allocations in the memory pool at this point
  25. SkASSERT(fBlobList.isEmpty());
  26. }
  27. void GrTextBlobCache::PostPurgeBlobMessage(uint32_t blobID, uint32_t cacheID) {
  28. SkASSERT(blobID != SK_InvalidGenID);
  29. SkMessageBus<PurgeBlobMessage>::Post(PurgeBlobMessage(blobID, cacheID));
  30. }
  31. void GrTextBlobCache::purgeStaleBlobs() {
  32. SkTArray<PurgeBlobMessage> msgs;
  33. fPurgeBlobInbox.poll(&msgs);
  34. for (const auto& msg : msgs) {
  35. auto* idEntry = fBlobIDCache.find(msg.fBlobID);
  36. if (!idEntry) {
  37. // no cache entries for id
  38. continue;
  39. }
  40. // remove all blob entries from the LRU list
  41. for (const auto& blob : idEntry->fBlobs) {
  42. fCurrentSize -= blob->size();
  43. fBlobList.remove(blob.get());
  44. }
  45. // drop the idEntry itself (unrefs all blobs)
  46. fBlobIDCache.remove(msg.fBlobID);
  47. }
  48. }
  49. void GrTextBlobCache::checkPurge(GrTextBlob* blob) {
  50. // First, purge all stale blob IDs.
  51. this->purgeStaleBlobs();
  52. // If we are still over budget, then unref until we are below budget again
  53. if (fCurrentSize > fSizeBudget) {
  54. BitmapBlobList::Iter iter;
  55. iter.init(fBlobList, BitmapBlobList::Iter::kTail_IterStart);
  56. GrTextBlob* lruBlob = nullptr;
  57. while (fCurrentSize > fSizeBudget && (lruBlob = iter.get()) && lruBlob != blob) {
  58. // Backup the iterator before removing and unrefing the blob
  59. iter.prev();
  60. this->remove(lruBlob);
  61. }
  62. // If we break out of the loop with lruBlob == blob, then we haven't purged enough
  63. // use the call back and try to free some more. If we are still overbudget after this,
  64. // then this single textblob is over our budget
  65. if (blob && lruBlob == blob) {
  66. (*fCallback)(fData);
  67. }
  68. #ifdef SPEW_BUDGET_MESSAGE
  69. if (fCurrentSize > fSizeBudget) {
  70. SkDebugf("Single textblob is larger than our whole budget");
  71. }
  72. #endif
  73. }
  74. }