diff options
author | xidachen <xidachen@chromium.org> | 2015-12-17 14:12:23 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-17 14:12:23 -0800 |
commit | f5d1f8dcc841516d7ea63c151b13059af40ca76d (patch) | |
tree | 362de1df4d47a53c5e3ae03d0351cbcdb3c23a18 /src | |
parent | e80eb928ba0248a5a5dea6e1f0005aa08ecf8740 (diff) |
Create a hash table from id<-->key in SkImageFilter::CacheImpl
There is memory leak in the SkImageFilter::Cache. There are two sources
of memory leak:
1. The cache filling up quickly.
2. A slow small leak that never stops.
This CL solves the first issue, which prevents the cache filling up quickly.
This CL creates a new hash table that index the
SkImageFilter::uniqueID to an array of keys, and with the existing
key<-->Value hash table, we can have SkImageFilters proactively
purge content derived cached content when destroyed.
BUG=489543
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1514893003
Review URL: https://codereview.chromium.org/1514893003
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkImageFilter.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index a3f89d08fa..9bf9b28ab6 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -18,6 +18,7 @@ #include "SkReadBuffer.h" #include "SkRect.h" #include "SkTDynamicHash.h" +#include "SkTHash.h" #include "SkTInternalLList.h" #include "SkValidationUtils.h" #include "SkWriteBuffer.h" @@ -201,6 +202,7 @@ SkImageFilter::~SkImageFilter() { SkSafeUnref(fInputs[i]); } delete[] fInputs; + Cache::Get()->purgeByImageFilterId(fUniqueID); } SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer) @@ -600,6 +602,13 @@ public: removeInternal(v); } Value* v = new Value(key, result, offset); + if (SkTArray<Key>** array = fIdToKeys.find(key.fUniqueID)) { + (*array)->push_back(key); + } else { + SkTArray<Key>* keyArray = new SkTArray<Key>(); + keyArray->push_back(key); + fIdToKeys.set(key.fUniqueID, keyArray); + } fLookup.add(v); fLRU.addToHead(v); fCurrentBytes += result.getSize(); @@ -622,6 +631,19 @@ public: } } + void purgeByImageFilterId(uint32_t uniqueID) override { + SkAutoMutexAcquire mutex(fMutex); + if (SkTArray<Key>** array = fIdToKeys.find(uniqueID)) { + for (auto& key : **array) { + if (Value* v = fLookup.find(key)) { + this->removeInternal(v); + } + } + fIdToKeys.remove(uniqueID); + delete *array; // This can be deleted outside the lock + } + } + private: void removeInternal(Value* v) { fCurrentBytes -= v->fBitmap.getSize(); @@ -630,11 +652,12 @@ private: delete v; } private: - SkTDynamicHash<Value, Key> fLookup; - mutable SkTInternalLList<Value> fLRU; - size_t fMaxBytes; - size_t fCurrentBytes; - mutable SkMutex fMutex; + SkTDynamicHash<Value, Key> fLookup; + SkTHashMap<uint32_t, SkTArray<Key>*> fIdToKeys; + mutable SkTInternalLList<Value> fLRU; + size_t fMaxBytes; + size_t fCurrentBytes; + mutable SkMutex fMutex; }; } // namespace |