diff options
author | Chris Dalton <csmartdalton@google.com> | 2018-06-29 13:18:53 -0600 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-29 20:14:47 +0000 |
commit | 907102e6f7689a2e8e0ffca43e0adb1e5d46db97 (patch) | |
tree | 3a939e65635b2acfad2b6b52aa68ab35134f6ca9 | |
parent | 184d408b646b9c6a2685170228649c4ed652e2a6 (diff) |
ccpr: Recycle cache entries when possible to avoid malloc
Bug: skia:
Change-Id: Id06098f66ad6399c11707f8380597e7eeb392eec
Reviewed-on: https://skia-review.googlesource.com/138441
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | src/gpu/ccpr/GrCCPathCache.cpp | 48 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPathCache.h | 8 |
2 files changed, 40 insertions, 16 deletions
diff --git a/src/gpu/ccpr/GrCCPathCache.cpp b/src/gpu/ccpr/GrCCPathCache.cpp index b6eb82a05a..b22b1dd726 100644 --- a/src/gpu/ccpr/GrCCPathCache.cpp +++ b/src/gpu/ccpr/GrCCPathCache.cpp @@ -78,19 +78,6 @@ GrCCPathCache::HashNode::~HashNode() { SkASSERT(fEntry->fCacheWeakPtr); fEntry->fCacheWeakPtr->fLRU.remove(fEntry); fEntry->fCacheWeakPtr = nullptr; - - if (GrCCAtlas::CachedAtlasInfo* info = fEntry->fCachedAtlasInfo.get()) { - // Mark our own pixels invalid in the cached atlas texture now that we have been evicted. - info->fNumInvalidatedPathPixels += fEntry->height() * fEntry->width(); - if (!info->fIsPurgedFromResourceCache && - info->fNumInvalidatedPathPixels >= info->fNumPathPixels / 2) { - // Too many invalidated pixels: purge the atlas texture from the resource cache. - SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post( - GrUniqueKeyInvalidatedMessage(fEntry->fAtlasKey)); - info->fIsPurgedFromResourceCache = true; - } - } - fEntry->unref(); } @@ -115,9 +102,15 @@ sk_sp<GrCCPathCacheEntry> GrCCPathCache::find(const GrShape& shape, const MaskTr entry = node->entry(); SkASSERT(this == entry->fCacheWeakPtr); if (fuzzy_equals(m, entry->fMaskTransform)) { - ++entry->fHitCount; + ++entry->fHitCount; // The path was reused with a compatible matrix. + } else if (CreateIfAbsent::kYes == createIfAbsent && entry->unique()) { + // This entry is unique: we can recycle it instead of deleting and malloc-ing a new one. + entry->fMaskTransform = m; + entry->fHitCount = 1; + entry->invalidateAtlas(); + SkASSERT(!entry->fCurrFlushAtlas); // Should be null because 'entry' is unique. } else { - this->evict(entry); // The path was reused with an incompatible matrix. + this->evict(entry); entry = nullptr; } } @@ -148,6 +141,14 @@ void GrCCPathCache::evict(const GrCCPathCacheEntry* entry) { fHashTable.remove(HashNode::GetKey(entry)); // ~HashNode() handles the rest. } + +GrCCPathCacheEntry::~GrCCPathCacheEntry() { + SkASSERT(!fCacheWeakPtr); // HashNode should have cleared our cache pointer. + SkASSERT(!fCurrFlushAtlas); // Client is required to reset fCurrFlushAtlas back to null. + + this->invalidateAtlas(); +} + void GrCCPathCacheEntry::initAsStashedAtlas(const GrUniqueKey& atlasKey, const SkIVector& atlasOffset, const SkRect& devBounds, const SkRect& devBounds45, const SkIRect& devIBounds, @@ -179,6 +180,23 @@ void GrCCPathCacheEntry::updateToCachedAtlas(const GrUniqueKey& atlasKey, fCachedAtlasInfo->fNumPathPixels += this->height() * this->width(); } +void GrCCPathCacheEntry::invalidateAtlas() { + if (fCachedAtlasInfo) { + // Mark our own pixels invalid in the cached atlas texture. + fCachedAtlasInfo->fNumInvalidatedPathPixels += this->height() * this->width(); + if (!fCachedAtlasInfo->fIsPurgedFromResourceCache && + fCachedAtlasInfo->fNumInvalidatedPathPixels >= fCachedAtlasInfo->fNumPathPixels / 2) { + // Too many invalidated pixels: purge the atlas texture from the resource cache. + SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post( + GrUniqueKeyInvalidatedMessage(fAtlasKey)); + fCachedAtlasInfo->fIsPurgedFromResourceCache = true; + } + } + + fAtlasKey.reset(); + fCachedAtlasInfo = nullptr; +} + void GrCCPathCacheEntry::onChange() { // Our corresponding path was modified or deleted. Evict ourselves. if (fCacheWeakPtr) { diff --git a/src/gpu/ccpr/GrCCPathCache.h b/src/gpu/ccpr/GrCCPathCache.h index 6315f7cbd3..67e7d9f571 100644 --- a/src/gpu/ccpr/GrCCPathCache.h +++ b/src/gpu/ccpr/GrCCPathCache.h @@ -100,6 +100,8 @@ class GrCCPathCacheEntry : public SkPathRef::GenIDChangeListener { public: SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrCCPathCacheEntry); + ~GrCCPathCacheEntry() override; + // The number of times this specific entry (path + matrix combination) has been pulled from // the path cache. As long as the caller does exactly one lookup per draw, this translates to // the number of times the path has been drawn with a compatible matrix. @@ -153,11 +155,15 @@ private: GrCCPathCacheEntry(GrCCPathCache* cache, const MaskTransform& m) : fCacheWeakPtr(cache), fMaskTransform(m) {} + // Resets this entry back to not having an atlas, and purges its previous atlas texture from the + // resource cache if needed. + void invalidateAtlas(); + // Called when our corresponding path is modified or deleted. void onChange() override; GrCCPathCache* fCacheWeakPtr; // Gets manually reset to null by the path cache upon eviction. - const MaskTransform fMaskTransform; + MaskTransform fMaskTransform; int fHitCount = 1; GrUniqueKey fAtlasKey; |