diff options
author | mtklein <mtklein@chromium.org> | 2015-09-29 12:17:08 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-29 12:17:08 -0700 |
commit | 242397a1c95e34e3e2e5e85c85c81090317115cb (patch) | |
tree | 833cdd358618557089590ffc3beb15209d7fa3db /src | |
parent | 75135d8ae1aa12e8e6bfce63291e5e876a77546f (diff) |
Revert of Implement SkImageFilter::Cache with SkResourceCache. (patchset #8 id:140001 of https://codereview.chromium.org/1370323002/ )
Reason for revert:
Landed PS8 temporarily to trigger the perf bots.
Original issue's description:
> Implement SkImageFilter::Cache with SkResourceCache.
>
> The single global cache now uses the global SkResourceCache,
> and any Create()ed cache uses a local SkResourceCache.
>
> No real public API changes (and only deletes).
>
> I don't see any pixel diffs on .skps or GMs.
> Don't see any significant perf difference on 8888 or gpu configs.
> DM peak memory usage did drop by about 113M, close to the 128M cache size.
>
> BUG=skia:3662
>
> Landing PS8 temporarily to trigger the perf bots.
> TBR=reed@google.com
>
> Committed: https://skia.googlesource.com/skia/+/75135d8ae1aa12e8e6bfce63291e5e876a77546f
TBR=reed@google.com,robertphillips@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:3662
Review URL: https://codereview.chromium.org/1381523002
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkImageFilter.cpp | 176 | ||||
-rw-r--r-- | src/core/SkResourceCache.cpp | 1 |
2 files changed, 81 insertions, 96 deletions
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index 6c4561b064..ffb1f836d8 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -14,10 +14,8 @@ #include "SkMatrixImageFilter.h" #include "SkMutex.h" #include "SkOncePtr.h" -#include "SkPixelRef.h" #include "SkReadBuffer.h" #include "SkRect.h" -#include "SkResourceCache.h" #include "SkTDynamicHash.h" #include "SkTInternalLList.h" #include "SkValidationUtils.h" @@ -29,6 +27,12 @@ #include "SkGr.h" #endif +#ifdef SK_BUILD_FOR_IOS + enum { kDefaultCacheSize = 2 * 1024 * 1024 }; +#else + enum { kDefaultCacheSize = 128 * 1024 * 1024 }; +#endif + #ifndef SK_IGNORE_TO_STRING void SkImageFilter::CropRect::toString(SkString* str) const { if (!fFlags) { @@ -473,122 +477,102 @@ bool SkImageFilter::getInputResultGPU(SkImageFilter::Proxy* proxy, namespace { -class ImageFilterRec : public SkResourceCache::Rec { +class CacheImpl : public SkImageFilter::Cache { public: - struct Keys { - Keys(SkImageFilter::Cache::Key ifcKey) : fIFCKey(ifcKey) { - static bool unique_namespace; - fRCKey.init(&unique_namespace, - 0 /*shared ids allow fine-grained purging, which we can't use here*/, - sizeof(fIFCKey)); - } - // The SkImageFilter::Cache::Key must immediately follow the SkResourceCache::Key. - SkResourceCache::Key fRCKey; - const SkImageFilter::Cache::Key fIFCKey; - }; - - ImageFilterRec(SkImageFilter::Cache::Key ifcKey, const SkBitmap& bm, const SkIPoint& offset) - : fKeys(ifcKey) - , fBitmap(bm) - , fOffset(offset) {} - - const Key& getKey() const override { return fKeys.fRCKey; } - size_t bytesUsed() const override { return sizeof(*this) + fBitmap.getSize(); } - const char* getCategory() const override { return "SkImageFilter::Cache"; } + CacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) { + } + virtual ~CacheImpl() { + SkTDynamicHash<Value, Key>::Iter iter(&fLookup); - SkDiscardableMemory* diagnostic_only_getDiscardable() const override { - if (auto pr = fBitmap.pixelRef()) { - return pr->diagnostic_only_getDiscardable(); + while (!iter.done()) { + Value* v = &*iter; + ++iter; + delete v; } - return nullptr; } - - const SkBitmap& bitmap() const { return fBitmap; } - const SkIPoint& offset() const { return fOffset; } - -private: - const Keys fKeys; - const SkBitmap fBitmap; - const SkIPoint fOffset; -}; - -struct GetVisitor { - SkBitmap* fResult; - SkIPoint* fOffset; - - static bool Visit(const SkResourceCache::Rec& rec, void* context) { - auto r = (const ImageFilterRec&)rec; - auto c = (GetVisitor*)context; - *c->fResult = r.bitmap(); - *c->fOffset = r.offset(); - return true; + struct Value { + Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset) + : fKey(key), fBitmap(bitmap), fOffset(offset) {} + Key fKey; + SkBitmap fBitmap; + SkIPoint fOffset; + static const Key& GetKey(const Value& v) { + return v.fKey; + } + static uint32_t Hash(const Key& key) { + return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key), sizeof(Key)); + } + SK_DECLARE_INTERNAL_LLIST_INTERFACE(Value); + }; + bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const override { + SkAutoMutexAcquire mutex(fMutex); + if (Value* v = fLookup.find(key)) { + *result = v->fBitmap; + *offset = v->fOffset; + if (v != fLRU.head()) { + fLRU.remove(v); + fLRU.addToHead(v); + } + return true; + } + return false; } -}; - -// Thread-safe SkImageFilter::Cache that uses the global SkResourceCache. -class GlobalCache : public SkImageFilter::Cache { -public: - GlobalCache() {} - void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) override { - const SkBitmap* bm = &result; - SkBitmap copy; - // Image filters allocate their own result bitmaps. - // If we're putting a bitmap into the SkResourceCache backed by discardable memory, - // we'd better make sure those bitmaps are discardable too (and vice versa). - // The expected case in Chrome is: rcIsDiscardable == true, bmIsDiscardable == false. - auto allocator = SkResourceCache::GetAllocator(); -#if 0 - bool rcIsDiscardable = allocator, - bmIsDiscardable = bm->pixelRef() && bm->pixelRef()->diagnostic_only_getDiscardable(); - if (rcIsDiscardable != bmIsDiscardable) { -#else - { -#endif - bm->copyTo(©, allocator); - bm = © + SkAutoMutexAcquire mutex(fMutex); + if (Value* v = fLookup.find(key)) { + removeInternal(v); + } + Value* v = new Value(key, result, offset); + fLookup.add(v); + fLRU.addToHead(v); + fCurrentBytes += result.getSize(); + while (fCurrentBytes > fMaxBytes) { + Value* tail = fLRU.tail(); + SkASSERT(tail); + if (tail == v) { + break; + } + removeInternal(tail); } - SkResourceCache::Add(new ImageFilterRec(key, *bm, offset)); - } - - bool get(const Key& ifcKey, SkBitmap* result, SkIPoint* offset) const override { - const ImageFilterRec::Keys keys(ifcKey); - GetVisitor visitor { result, offset }; - return SkResourceCache::Find(keys.fRCKey, GetVisitor::Visit, &visitor); - } -}; - -// Non-thread-safe siloed SkImageFilter::Cache, meant to be small and ephemeral. -class LocalCache : public SkImageFilter::Cache { -public: - LocalCache(size_t maxBytes) : fRC(maxBytes) { - SkASSERT(fRC.allocator() == nullptr); } - void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) override { - SkASSERT(result.pixelRef() == nullptr || - result.pixelRef()->diagnostic_only_getDiscardable() == nullptr); - fRC.add(new ImageFilterRec(key, result, offset)); + void purge() override { + SkAutoMutexAcquire mutex(fMutex); + while (fCurrentBytes > 0) { + Value* tail = fLRU.tail(); + SkASSERT(tail); + this->removeInternal(tail); + } } - bool get(const Key& ifcKey, SkBitmap* result, SkIPoint* offset) const override { - const ImageFilterRec::Keys keys(ifcKey); - GetVisitor visitor { result, offset }; - return fRC.find(keys.fRCKey, GetVisitor::Visit, &visitor); +private: + void removeInternal(Value* v) { + fCurrentBytes -= v->fBitmap.getSize(); + fLRU.remove(v); + fLookup.remove(v->fKey); + delete v; } private: - mutable SkResourceCache fRC; // SkResourceCache::find() is not const (updates LRU). + SkTDynamicHash<Value, Key> fLookup; + mutable SkTInternalLList<Value> fLRU; + size_t fMaxBytes; + size_t fCurrentBytes; + mutable SkMutex fMutex; }; } // namespace SkImageFilter::Cache* SkImageFilter::Cache::Create(size_t maxBytes) { - return new LocalCache(maxBytes); + return new CacheImpl(maxBytes); } SK_DECLARE_STATIC_ONCE_PTR(SkImageFilter::Cache, cache); SkImageFilter::Cache* SkImageFilter::Cache::Get() { - return cache.get([]{ return new GlobalCache; }); + return cache.get([]{ return SkImageFilter::Cache::Create(kDefaultCacheSize); }); +} + +void SkImageFilter::PurgeCache() { + Cache::Get()->purge(); } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp index a79c9539b9..54091f1fd4 100644 --- a/src/core/SkResourceCache.cpp +++ b/src/core/SkResourceCache.cpp @@ -658,6 +658,7 @@ size_t SkGraphics::SetResourceCacheSingleAllocationByteLimit(size_t newLimit) { } void SkGraphics::PurgeResourceCache() { + SkImageFilter::PurgeCache(); return SkResourceCache::PurgeAll(); } |