aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-06-29 13:18:53 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-29 20:14:47 +0000
commit907102e6f7689a2e8e0ffca43e0adb1e5d46db97 (patch)
tree3a939e65635b2acfad2b6b52aa68ab35134f6ca9
parent184d408b646b9c6a2685170228649c4ed652e2a6 (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.cpp48
-rw-r--r--src/gpu/ccpr/GrCCPathCache.h8
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;