Remove fCacheKeys from SkImageFilter.
No public API changes. Bug: skia:7666, skia:7887 Change-Id: I8ac4ec37dd3d0fcc050bc977db41439a8e18895f Reviewed-on: https://skia-review.googlesource.com/125500 Commit-Queue: Ben Wagner <benjaminwagner@google.com> Reviewed-by: Mike Klein <mtklein@google.com> Auto-Submit: Ben Wagner <benjaminwagner@google.com>
This commit is contained in:
parent
d401da64f0
commit
da926dbd69
@ -437,8 +437,7 @@ private:
|
|||||||
bool fUsesSrcInput;
|
bool fUsesSrcInput;
|
||||||
CropRect fCropRect;
|
CropRect fCropRect;
|
||||||
uint32_t fUniqueID; // Globally unique
|
uint32_t fUniqueID; // Globally unique
|
||||||
mutable SkTArray<SkImageFilterCacheKey> fCacheKeys;
|
|
||||||
mutable SkMutex fMutex;
|
|
||||||
typedef SkFlattenable INHERITED;
|
typedef SkFlattenable INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,8 +167,7 @@ SkImageFilter::SkImageFilter(sk_sp<SkImageFilter> const* inputs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkImageFilter::~SkImageFilter() {
|
SkImageFilter::~SkImageFilter() {
|
||||||
SkAutoMutexAcquire lock(fMutex);
|
SkImageFilterCache::Get()->purgeByImageFilter(this);
|
||||||
SkImageFilterCache::Get()->purgeByKeys(fCacheKeys.begin(), fCacheKeys.count());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer)
|
SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer)
|
||||||
@ -224,30 +223,11 @@ sk_sp<SkSpecialImage> SkImageFilter::filterImage(SkSpecialImage* src, const Cont
|
|||||||
|
|
||||||
if (result && context.cache()) {
|
if (result && context.cache()) {
|
||||||
context.cache()->set(key, result.get(), *offset, this);
|
context.cache()->set(key, result.get(), *offset, this);
|
||||||
SkAutoMutexAcquire mutex(fMutex);
|
|
||||||
fCacheKeys.push_back(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkImageFilter::removeKey(const SkImageFilterCacheKey& key) const {
|
|
||||||
SkAutoMutexAcquire mutex(fMutex);
|
|
||||||
for (int i = 0; i < fCacheKeys.count(); i++) {
|
|
||||||
if (fCacheKeys[i] == key) {
|
|
||||||
fCacheKeys.removeShuffle(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef SK_DEBUG
|
|
||||||
for (int i = 0; i < fCacheKeys.count(); i++) {
|
|
||||||
if (fCacheKeys[i] == key) {
|
|
||||||
SkASSERT(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm,
|
SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm,
|
||||||
MapDirection direction) const {
|
MapDirection direction) const {
|
||||||
if (kReverse_MapDirection == direction) {
|
if (kReverse_MapDirection == direction) {
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "SkImageFilterCache.h"
|
#include "SkImageFilterCache.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "SkImageFilter.h"
|
#include "SkImageFilter.h"
|
||||||
#include "SkMutex.h"
|
#include "SkMutex.h"
|
||||||
#include "SkOnce.h"
|
#include "SkOnce.h"
|
||||||
@ -14,6 +16,7 @@
|
|||||||
#include "SkRefCnt.h"
|
#include "SkRefCnt.h"
|
||||||
#include "SkSpecialImage.h"
|
#include "SkSpecialImage.h"
|
||||||
#include "SkTDynamicHash.h"
|
#include "SkTDynamicHash.h"
|
||||||
|
#include "SkTHash.h"
|
||||||
#include "SkTInternalLList.h"
|
#include "SkTInternalLList.h"
|
||||||
|
|
||||||
#ifdef SK_BUILD_FOR_IOS
|
#ifdef SK_BUILD_FOR_IOS
|
||||||
@ -76,6 +79,12 @@ public:
|
|||||||
fLookup.add(v);
|
fLookup.add(v);
|
||||||
fLRU.addToHead(v);
|
fLRU.addToHead(v);
|
||||||
fCurrentBytes += image->getSize();
|
fCurrentBytes += image->getSize();
|
||||||
|
if (auto* values = fImageFilterValues.find(filter)) {
|
||||||
|
values->push_back(v);
|
||||||
|
} else {
|
||||||
|
fImageFilterValues.set(filter, {v});
|
||||||
|
}
|
||||||
|
|
||||||
while (fCurrentBytes > fMaxBytes) {
|
while (fCurrentBytes > fMaxBytes) {
|
||||||
Value* tail = fLRU.tail();
|
Value* tail = fLRU.tail();
|
||||||
SkASSERT(tail);
|
SkASSERT(tail);
|
||||||
@ -95,18 +104,19 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void purgeByKeys(const Key keys[], int count) override {
|
void purgeByImageFilter(const SkImageFilter* filter) override {
|
||||||
SkAutoMutexAcquire mutex(fMutex);
|
SkAutoMutexAcquire mutex(fMutex);
|
||||||
// This function is only called in the destructor of SkImageFilter.
|
auto* values = fImageFilterValues.find(filter);
|
||||||
// Because the destructor will destroy the fCacheKeys anyway, we set the
|
if (!values) {
|
||||||
// filter to be null so that removeInternal() won't call the
|
return;
|
||||||
// SkImageFilter::removeKey() function.
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
if (Value* v = fLookup.find(keys[i])) {
|
|
||||||
v->fFilter = nullptr;
|
|
||||||
this->removeInternal(v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (Value* v : *values) {
|
||||||
|
// We set the filter to be null so that removeInternal() won't delete from values while
|
||||||
|
// we're iterating over it.
|
||||||
|
v->fFilter = nullptr;
|
||||||
|
this->removeInternal(v);
|
||||||
|
}
|
||||||
|
fImageFilterValues.remove(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkDEBUGCODE(int count() const override { return fLookup.count(); })
|
SkDEBUGCODE(int count() const override { return fLookup.count(); })
|
||||||
@ -114,7 +124,18 @@ private:
|
|||||||
void removeInternal(Value* v) {
|
void removeInternal(Value* v) {
|
||||||
SkASSERT(v->fImage);
|
SkASSERT(v->fImage);
|
||||||
if (v->fFilter) {
|
if (v->fFilter) {
|
||||||
v->fFilter->removeKey(v->fKey);
|
if (auto* values = fImageFilterValues.find(v->fFilter)) {
|
||||||
|
if (values->size() == 1 && (*values)[0] == v) {
|
||||||
|
fImageFilterValues.remove(v->fFilter);
|
||||||
|
} else {
|
||||||
|
for (auto it = values->begin(); it != values->end(); ++it) {
|
||||||
|
if (*it == v) {
|
||||||
|
values->erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fCurrentBytes -= v->fImage->getSize();
|
fCurrentBytes -= v->fImage->getSize();
|
||||||
fLRU.remove(v);
|
fLRU.remove(v);
|
||||||
@ -122,11 +143,13 @@ private:
|
|||||||
delete v;
|
delete v;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SkTDynamicHash<Value, Key> fLookup;
|
SkTDynamicHash<Value, Key> fLookup;
|
||||||
mutable SkTInternalLList<Value> fLRU;
|
mutable SkTInternalLList<Value> fLRU;
|
||||||
size_t fMaxBytes;
|
// Value* always points to an item in fLookup.
|
||||||
size_t fCurrentBytes;
|
SkTHashMap<const SkImageFilter*, std::vector<Value*>> fImageFilterValues;
|
||||||
mutable SkMutex fMutex;
|
size_t fMaxBytes;
|
||||||
|
size_t fCurrentBytes;
|
||||||
|
mutable SkMutex fMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
virtual void set(const SkImageFilterCacheKey& key, SkSpecialImage* image,
|
virtual void set(const SkImageFilterCacheKey& key, SkSpecialImage* image,
|
||||||
const SkIPoint& offset, const SkImageFilter* filter) = 0;
|
const SkIPoint& offset, const SkImageFilter* filter) = 0;
|
||||||
virtual void purge() = 0;
|
virtual void purge() = 0;
|
||||||
virtual void purgeByKeys(const SkImageFilterCacheKey[], int) = 0;
|
virtual void purgeByImageFilter(const SkImageFilter*) = 0;
|
||||||
SkDEBUGCODE(virtual int count() const = 0;)
|
SkDEBUGCODE(virtual int count() const = 0;)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "Test.h"
|
#include "Test.h"
|
||||||
|
|
||||||
#include "SkBitmap.h"
|
#include "SkBitmap.h"
|
||||||
|
#include "SkColorFilter.h"
|
||||||
|
#include "SkColorFilterImageFilter.h"
|
||||||
#include "SkImage.h"
|
#include "SkImage.h"
|
||||||
#include "SkImageFilter.h"
|
#include "SkImageFilter.h"
|
||||||
#include "SkImageFilterCache.h"
|
#include "SkImageFilterCache.h"
|
||||||
@ -25,6 +27,12 @@ static SkBitmap create_bm() {
|
|||||||
return bm;
|
return bm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static sk_sp<SkImageFilter> make_filter() {
|
||||||
|
sk_sp<SkColorFilter> filter(SkColorFilter::MakeModeFilter(SK_ColorBLUE,
|
||||||
|
SkBlendMode::kSrcIn));
|
||||||
|
return SkColorFilterImageFilter::Make(std::move(filter), nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the cache can return a cached image
|
// Ensure the cache can return a cached image
|
||||||
static void test_find_existing(skiatest::Reporter* reporter,
|
static void test_find_existing(skiatest::Reporter* reporter,
|
||||||
const sk_sp<SkSpecialImage>& image,
|
const sk_sp<SkSpecialImage>& image,
|
||||||
@ -37,7 +45,8 @@ static void test_find_existing(skiatest::Reporter* reporter,
|
|||||||
SkImageFilterCacheKey key2(0, SkMatrix::I(), clip, subset->uniqueID(), subset->subset());
|
SkImageFilterCacheKey key2(0, SkMatrix::I(), clip, subset->uniqueID(), subset->subset());
|
||||||
|
|
||||||
SkIPoint offset = SkIPoint::Make(3, 4);
|
SkIPoint offset = SkIPoint::Make(3, 4);
|
||||||
cache->set(key1, image.get(), offset, nullptr);
|
auto filter = make_filter();
|
||||||
|
cache->set(key1, image.get(), offset, filter.get());
|
||||||
|
|
||||||
SkIPoint foundOffset;
|
SkIPoint foundOffset;
|
||||||
|
|
||||||
@ -66,7 +75,8 @@ static void test_dont_find_if_diff_key(skiatest::Reporter* reporter,
|
|||||||
SkImageFilterCacheKey key4(0, SkMatrix::I(), clip1, subset->uniqueID(), subset->subset());
|
SkImageFilterCacheKey key4(0, SkMatrix::I(), clip1, subset->uniqueID(), subset->subset());
|
||||||
|
|
||||||
SkIPoint offset = SkIPoint::Make(3, 4);
|
SkIPoint offset = SkIPoint::Make(3, 4);
|
||||||
cache->set(key0, image.get(), offset, nullptr);
|
auto filter = make_filter();
|
||||||
|
cache->set(key0, image.get(), offset, filter.get());
|
||||||
|
|
||||||
SkIPoint foundOffset;
|
SkIPoint foundOffset;
|
||||||
REPORTER_ASSERT(reporter, !cache->get(key1, &foundOffset));
|
REPORTER_ASSERT(reporter, !cache->get(key1, &foundOffset));
|
||||||
@ -86,14 +96,16 @@ static void test_internal_purge(skiatest::Reporter* reporter, const sk_sp<SkSpec
|
|||||||
SkImageFilterCacheKey key2(1, SkMatrix::I(), clip, image->uniqueID(), image->subset());
|
SkImageFilterCacheKey key2(1, SkMatrix::I(), clip, image->uniqueID(), image->subset());
|
||||||
|
|
||||||
SkIPoint offset = SkIPoint::Make(3, 4);
|
SkIPoint offset = SkIPoint::Make(3, 4);
|
||||||
cache->set(key1, image.get(), offset, nullptr);
|
auto filter1 = make_filter();
|
||||||
|
cache->set(key1, image.get(), offset, filter1.get());
|
||||||
|
|
||||||
SkIPoint foundOffset;
|
SkIPoint foundOffset;
|
||||||
|
|
||||||
REPORTER_ASSERT(reporter, cache->get(key1, &foundOffset));
|
REPORTER_ASSERT(reporter, cache->get(key1, &foundOffset));
|
||||||
|
|
||||||
// This should knock the first one out of the cache
|
// This should knock the first one out of the cache
|
||||||
cache->set(key2, image.get(), offset, nullptr);
|
auto filter2 = make_filter();
|
||||||
|
cache->set(key2, image.get(), offset, filter2.get());
|
||||||
|
|
||||||
REPORTER_ASSERT(reporter, cache->get(key2, &foundOffset));
|
REPORTER_ASSERT(reporter, cache->get(key2, &foundOffset));
|
||||||
REPORTER_ASSERT(reporter, !cache->get(key1, &foundOffset));
|
REPORTER_ASSERT(reporter, !cache->get(key1, &foundOffset));
|
||||||
@ -111,8 +123,10 @@ static void test_explicit_purging(skiatest::Reporter* reporter,
|
|||||||
SkImageFilterCacheKey key2(1, SkMatrix::I(), clip, subset->uniqueID(), image->subset());
|
SkImageFilterCacheKey key2(1, SkMatrix::I(), clip, subset->uniqueID(), image->subset());
|
||||||
|
|
||||||
SkIPoint offset = SkIPoint::Make(3, 4);
|
SkIPoint offset = SkIPoint::Make(3, 4);
|
||||||
cache->set(key1, image.get(), offset, nullptr);
|
auto filter1 = make_filter();
|
||||||
cache->set(key2, image.get(), offset, nullptr);
|
auto filter2 = make_filter();
|
||||||
|
cache->set(key1, image.get(), offset, filter1.get());
|
||||||
|
cache->set(key2, image.get(), offset, filter2.get());
|
||||||
SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->count());)
|
SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->count());)
|
||||||
|
|
||||||
SkIPoint foundOffset;
|
SkIPoint foundOffset;
|
||||||
@ -120,7 +134,7 @@ static void test_explicit_purging(skiatest::Reporter* reporter,
|
|||||||
REPORTER_ASSERT(reporter, cache->get(key1, &foundOffset));
|
REPORTER_ASSERT(reporter, cache->get(key1, &foundOffset));
|
||||||
REPORTER_ASSERT(reporter, cache->get(key2, &foundOffset));
|
REPORTER_ASSERT(reporter, cache->get(key2, &foundOffset));
|
||||||
|
|
||||||
cache->purgeByKeys(&key1, 1);
|
cache->purgeByImageFilter(filter1.get());
|
||||||
SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->count());)
|
SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->count());)
|
||||||
|
|
||||||
REPORTER_ASSERT(reporter, !cache->get(key1, &foundOffset));
|
REPORTER_ASSERT(reporter, !cache->get(key1, &foundOffset));
|
||||||
|
Loading…
Reference in New Issue
Block a user