aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar xidachen <xidachen@chromium.org>2015-12-17 14:12:23 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-12-17 14:12:23 -0800
commitf5d1f8dcc841516d7ea63c151b13059af40ca76d (patch)
tree362de1df4d47a53c5e3ae03d0351cbcdb3c23a18 /src
parente80eb928ba0248a5a5dea6e1f0005aa08ecf8740 (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.cpp33
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