diff options
author | mtklein <mtklein@google.com> | 2015-02-19 08:53:52 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-19 08:53:52 -0800 |
commit | 90c6bc4e85df2da37f436ea1da203e194c4740e2 (patch) | |
tree | bc71dc3d3a7160bb8118a1e349e11a6e58a4b8cb | |
parent | cabc08c4296e1ce6c6d9d84cf702361cf439c1bc (diff) |
Revert of notify resource caches when pixelref genID goes stale (patchset #4 id:60001 of https://codereview.chromium.org/825263005/)
Reason for revert:
Crazy failures.
http://build.chromium.org/p/client.skia/builders/Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug/builds/1428/steps/dm/logs/stdio
Original issue's description:
> notify resource caches when pixelref genID goes stale
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/4675819b9dbb3ad71ec851776e5de26d342f29fe
TBR=bsalomon@google.com,reed@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Review URL: https://codereview.chromium.org/936423002
-rw-r--r-- | src/core/SkBitmapCache.cpp | 84 | ||||
-rw-r--r-- | src/core/SkBitmapCache.h | 10 | ||||
-rw-r--r-- | src/core/SkPixelRef.cpp | 11 | ||||
-rw-r--r-- | src/core/SkResourceCache.cpp | 39 | ||||
-rw-r--r-- | src/core/SkResourceCache.h | 38 | ||||
-rw-r--r-- | tests/SkResourceCacheTest.cpp | 71 |
6 files changed, 23 insertions, 230 deletions
diff --git a/src/core/SkBitmapCache.cpp b/src/core/SkBitmapCache.cpp index 9929080164..3af582232b 100644 --- a/src/core/SkBitmapCache.cpp +++ b/src/core/SkBitmapCache.cpp @@ -33,11 +33,11 @@ static unsigned gBitmapKeyNamespaceLabel; struct BitmapKey : public SkResourceCache::Key { public: - BitmapKey(uint32_t genID, SkScalar sx, SkScalar sy, const SkIRect& bounds) - : fGenID(genID) - , fScaleX(sx) - , fScaleY(sy) - , fBounds(bounds) + BitmapKey(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& bounds) + : fGenID(genID) + , fScaleX(scaleX) + , fScaleY(scaleY) + , fBounds(bounds) { this->init(&gBitmapKeyNamespaceLabel, sizeof(fGenID) + sizeof(fScaleX) + sizeof(fScaleY) + sizeof(fBounds)); @@ -49,6 +49,8 @@ public: SkIRect fBounds; }; +////////////////////////////////////////////////////////////////////////////////////////// + struct BitmapRec : public SkResourceCache::Rec { BitmapRec(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& bounds, const SkBitmap& result) @@ -56,10 +58,13 @@ struct BitmapRec : public SkResourceCache::Rec { , fBitmap(result) {} + BitmapKey fKey; + SkBitmap fBitmap; + const Key& getKey() const SK_OVERRIDE { return fKey; } size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fBitmap.getSize(); } - static bool Finder(const SkResourceCache::Rec& baseRec, void* contextBitmap) { + static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextBitmap) { const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec); SkBitmap* result = (SkBitmap*)contextBitmap; @@ -67,22 +72,6 @@ struct BitmapRec : public SkResourceCache::Rec { result->lockPixels(); return SkToBool(result->getPixels()); } - - static SkResourceCache::PurgeVisitorResult PurgeGenID(const SkResourceCache::Rec& baseRec, - void* contextGenID) { - const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec); - uintptr_t genID = (uintptr_t)contextGenID; - if (rec.fKey.fGenID == genID) { -// SkDebugf("BitmapRec purging genID %d\n", genID); - return SkResourceCache::kPurgeAndContinue_PurgeVisitorResult; - } else { - return SkResourceCache::kRetainAndContinue_PurgeVisitorResult; - } - } - -private: - BitmapKey fKey; - SkBitmap fBitmap; }; } // namespace @@ -97,7 +86,7 @@ bool SkBitmapCache::Find(const SkBitmap& src, SkScalar invScaleX, SkScalar invSc } BitmapKey key(src.getGenerationID(), invScaleX, invScaleY, get_bounds_from_bitmap(src)); - return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Finder, result); + return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Visitor, result); } void SkBitmapCache::Add(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY, @@ -116,7 +105,7 @@ bool SkBitmapCache::Find(uint32_t genID, const SkIRect& subset, SkBitmap* result SkResourceCache* localCache) { BitmapKey key(genID, SK_Scalar1, SK_Scalar1, subset); - return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Finder, result); + return CHECK_LOCAL(localCache, find, Find, key, BitmapRec::Visitor, result); } bool SkBitmapCache::Add(uint32_t genID, const SkIRect& subset, const SkBitmap& result, @@ -136,31 +125,11 @@ bool SkBitmapCache::Add(uint32_t genID, const SkIRect& subset, const SkBitmap& r return true; } } - -void SkBitmapCache::NotifyGenIDStale(uint32_t genID) { - SkResourceCache::Purge(&gBitmapKeyNamespaceLabel, BitmapRec::PurgeGenID, - (void*)((uintptr_t)genID)); -} - ////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// - -namespace { -static unsigned gMipMapKeyNamespaceLabel; - -struct MipMapKey : public SkResourceCache::Key { -public: - MipMapKey(uint32_t genID, const SkIRect& bounds) : fGenID(genID), fBounds(bounds) { - this->init(&gMipMapKeyNamespaceLabel, sizeof(fGenID) + sizeof(fBounds)); - } - - uint32_t fGenID; - SkIRect fBounds; -}; struct MipMapRec : public SkResourceCache::Rec { MipMapRec(const SkBitmap& src, const SkMipMap* result) - : fKey(src.getGenerationID(), get_bounds_from_bitmap(src)) + : fKey(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src)) , fMipMap(result) { fMipMap->attachToCacheAndRef(); @@ -173,7 +142,7 @@ struct MipMapRec : public SkResourceCache::Rec { const Key& getKey() const SK_OVERRIDE { return fKey; } size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + fMipMap->size(); } - static bool Finder(const SkResourceCache::Rec& baseRec, void* contextMip) { + static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextMip) { const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec); const SkMipMap* mm = SkRef(rec.fMipMap); // the call to ref() above triggers a "lock" in the case of discardable memory, @@ -187,29 +156,16 @@ struct MipMapRec : public SkResourceCache::Rec { return true; } - static SkResourceCache::PurgeVisitorResult PurgeGenID(const SkResourceCache::Rec& baseRec, - void* contextGenID) { - const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec); - uintptr_t genID = (uintptr_t)contextGenID; - if (rec.fKey.fGenID == genID) { -// SkDebugf("MipMapRec purging genID %d\n", genID); - return SkResourceCache::kPurgeAndContinue_PurgeVisitorResult; - } else { - return SkResourceCache::kRetainAndContinue_PurgeVisitorResult; - } - } - private: - MipMapKey fKey; + BitmapKey fKey; const SkMipMap* fMipMap; }; -} const SkMipMap* SkMipMapCache::FindAndRef(const SkBitmap& src, SkResourceCache* localCache) { - MipMapKey key(src.getGenerationID(), get_bounds_from_bitmap(src)); + BitmapKey key(src.getGenerationID(), 0, 0, get_bounds_from_bitmap(src)); const SkMipMap* result; - if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Finder, &result)) { + if (!CHECK_LOCAL(localCache, find, Find, key, MipMapRec::Visitor, &result)) { result = NULL; } return result; @@ -229,7 +185,3 @@ const SkMipMap* SkMipMapCache::AddAndRef(const SkBitmap& src, SkResourceCache* l return mipmap; } -void SkMipMapCache::NotifyGenIDStale(uint32_t genID) { - SkResourceCache::Purge(&gMipMapKeyNamespaceLabel, MipMapRec::PurgeGenID, - (void*)((uintptr_t)genID)); -} diff --git a/src/core/SkBitmapCache.h b/src/core/SkBitmapCache.h index abda1b4d66..ec8a6b803e 100644 --- a/src/core/SkBitmapCache.h +++ b/src/core/SkBitmapCache.h @@ -48,22 +48,12 @@ public: */ static bool Add(uint32_t genID, const SkIRect& subset, const SkBitmap& result, SkResourceCache* localCache = NULL); - - /** - * Call this to (as a hint) preemptively purge caches related to this genID - */ - static void NotifyGenIDStale(uint32_t); }; class SkMipMapCache { public: static const SkMipMap* FindAndRef(const SkBitmap& src, SkResourceCache* localCache = NULL); static const SkMipMap* AddAndRef(const SkBitmap& src, SkResourceCache* localCache = NULL); - - /** - * Call this to (as a hint) preemptively purge caches related to this genID - */ - static void NotifyGenIDStale(uint32_t); }; #endif diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp index a2638c9431..f56298165c 100644 --- a/src/core/SkPixelRef.cpp +++ b/src/core/SkPixelRef.cpp @@ -5,7 +5,6 @@ * found in the LICENSE file. */ -#include "SkBitmapCache.h" #include "SkPixelRef.h" #include "SkThread.h" @@ -223,7 +222,6 @@ void SkPixelRef::addGenIDChangeListener(GenIDChangeListener* listener) { *fGenIDChangeListeners.append() = listener; } -// we need to be called *before* the genID gets changed or zerod void SkPixelRef::callGenIDChangeListeners() { // We don't invalidate ourselves if we think another SkPixelRef is sharing our genID. if (fUniqueGenerationID) { @@ -233,15 +231,6 @@ void SkPixelRef::callGenIDChangeListeners() { } // Listeners get at most one shot, so whether these triggered or not, blow them away. fGenIDChangeListeners.deleteAll(); - - // if fGenerationID is 0, then perhaps we never had one, and we are in the destructor - if (fGenerationID) { - // If the ResourceCache ever generalizes/standardizes on accessing the gen-id field, - // then it would be more efficient to roll these together, and only grab the mutex - // and fixing the resources once... - SkBitmapCache::NotifyGenIDStale(fGenerationID); - SkMipMapCache::NotifyGenIDStale(fGenerationID); - } } void SkPixelRef::notifyPixelsChanged() { diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp index 62263605de..4ed889a0ab 100644 --- a/src/core/SkResourceCache.cpp +++ b/src/core/SkResourceCache.cpp @@ -61,8 +61,6 @@ void SkResourceCache::init() { // One of these should be explicit set by the caller after we return. fTotalByteLimit = 0; fDiscardableFactory = NULL; - - fInsidePurgeAllCounter = 0; } #include "SkDiscardableMemory.h" @@ -201,7 +199,7 @@ SkResourceCache::~SkResourceCache() { //////////////////////////////////////////////////////////////////////////////// -bool SkResourceCache::find(const Key& key, FindVisitor visitor, void* context) { +bool SkResourceCache::find(const Key& key, VisitorProc visitor, void* context) { Rec* rec = fHash->find(key); if (rec) { if (visitor(*rec, context)) { @@ -296,34 +294,6 @@ void SkResourceCache::purgeAsNeeded(bool forcePurge) { } } -void SkResourceCache::purge(const void* nameSpace, PurgeVisitor proc, void* context) { - if (this->insidePurgeAll()) { - return; - } - - // go backwards, just like purgeAsNeeded, just to make the code similar. - // could iterate either direction and still be correct. - Rec* rec = fTail; - while (rec) { - Rec* prev = rec->fPrev; - if (rec->getKey().getNamespace() == nameSpace) { - switch (proc(*rec, context)) { - case kRetainAndContinue_PurgeVisitorResult: - break; - case kPurgeAndContinue_PurgeVisitorResult: - this->remove(rec); - break; - case kRetainAndStop_PurgeVisitorResult: - return; - case kPurgeAndStop_PurgeVisitorResult: - this->remove(rec); - return; - } - } - rec = prev; - } -} - size_t SkResourceCache::setTotalByteLimit(size_t newLimit) { size_t prevLimit = fTotalByteLimit; fTotalByteLimit = newLimit; @@ -562,17 +532,12 @@ size_t SkResourceCache::GetEffectiveSingleAllocationByteLimit() { return get_cache()->getEffectiveSingleAllocationByteLimit(); } -void SkResourceCache::Purge(const void* nameSpace, PurgeVisitor proc, void* context) { - SkAutoMutexAcquire am(gMutex); - return get_cache()->purge(nameSpace, proc, context); -} - void SkResourceCache::PurgeAll() { SkAutoMutexAcquire am(gMutex); return get_cache()->purgeAll(); } -bool SkResourceCache::Find(const Key& key, FindVisitor visitor, void* context) { +bool SkResourceCache::Find(const Key& key, VisitorProc visitor, void* context) { SkAutoMutexAcquire am(gMutex); return get_cache()->find(key, visitor, context); } diff --git a/src/core/SkResourceCache.h b/src/core/SkResourceCache.h index 36ca27cd73..88ccb87ed8 100644 --- a/src/core/SkResourceCache.h +++ b/src/core/SkResourceCache.h @@ -35,8 +35,6 @@ public: // length must be a multiple of 4 void init(void* nameSpace, size_t length); - void* getNamespace() const { return fNamespace; } - // This is only valid after having called init(). uint32_t hash() const { return fHash; } @@ -94,21 +92,7 @@ public: * true, then the Rec is considered "valid". If false is returned, the Rec will be considered * "stale" and will be purged from the cache. */ - typedef bool (*FindVisitor)(const Rec&, void* context); - - enum PurgeVisitorResult { - kRetainAndContinue_PurgeVisitorResult, - kPurgeAndContinue_PurgeVisitorResult, - kRetainAndStop_PurgeVisitorResult, - kPurgeAndStop_PurgeVisitorResult, - }; - - /** - * Callback function for purge(). If called, the cache will have found a match for the - * specified Key, and will pass in the corresponding Rec, along with a caller-specified - * context. The function can read the data in Rec. - */ - typedef PurgeVisitorResult (*PurgeVisitor)(const Rec&, void* context); + typedef bool (*VisitorProc)(const Rec&, void* context); /** * Returns a locked/pinned SkDiscardableMemory instance for the specified @@ -130,7 +114,7 @@ public: * true : Rec is valid * false : Rec is "stale" -- the cache will purge it. */ - static bool Find(const Key& key, FindVisitor, void* context); + static bool Find(const Key& key, VisitorProc, void* context); static void Add(Rec*); static size_t GetTotalBytesUsed(); @@ -141,12 +125,6 @@ public: static size_t GetSingleAllocationByteLimit(); static size_t GetEffectiveSingleAllocationByteLimit(); - /** - * Visit all Rec that match the specified namespace, and purge entries as indicated by the - * visitor. - */ - static void Purge(const void* nameSpace, PurgeVisitor, void* context); - static void PurgeAll(); /** @@ -196,7 +174,7 @@ public: * true : Rec is valid * false : Rec is "stale" -- the cache will purge it. */ - bool find(const Key&, FindVisitor, void* context); + bool find(const Key&, VisitorProc, void* context); void add(Rec*); size_t getTotalBytesUsed() const { return fTotalBytesUsed; } @@ -220,12 +198,8 @@ public: */ size_t setTotalByteLimit(size_t newLimit); - void purge(const void* nameSpace, PurgeVisitor, void* context); - void purgeAll() { - fInsidePurgeAllCounter += 1; this->purgeAsNeeded(true); - fInsidePurgeAllCounter -= 1; } DiscardableFactory discardableFactory() const { return fDiscardableFactory; } @@ -254,12 +228,6 @@ private: size_t fSingleAllocationByteLimit; int fCount; - bool insidePurgeAll() const { - SkASSERT(fInsidePurgeAllCounter >= 0); - return fInsidePurgeAllCounter > 0; - } - int fInsidePurgeAllCounter; - void purgeAsNeeded(bool forcePurge = false); // linklist management diff --git a/tests/SkResourceCacheTest.cpp b/tests/SkResourceCacheTest.cpp index e93bcf9c71..179e771ed8 100644 --- a/tests/SkResourceCacheTest.cpp +++ b/tests/SkResourceCacheTest.cpp @@ -156,14 +156,6 @@ static void test_mipmapcache(skiatest::Reporter* reporter, SkResourceCache* cach mipmap = SkMipMapCache::AddAndRef(src, cache); REPORTER_ASSERT(reporter, mipmap); - - { - const SkMipMap* mm = SkMipMapCache::FindAndRef(src, cache); - REPORTER_ASSERT(reporter, mm); - REPORTER_ASSERT(reporter, mm == mipmap); - mm->unref(); - } - check_data(reporter, mipmap, 2, kInCache, kLocked); mipmap->unref(); @@ -181,67 +173,6 @@ static void test_mipmapcache(skiatest::Reporter* reporter, SkResourceCache* cach mipmap->unref(); } -// In a multi-threaded run, we can't reliably assert that something is in the global cache -// even if we just added it, since another thread might have caused a purge, hence we guard -// those checks with this flag (to be defined only when run locally in 1 thread). -#define ONLY_WORKS_RELIABLY_SINGLE_THREADED_SINCE_CACHE_MAY_HAVE_BEEN_PURGED - -static void test_mipmap_notify(skiatest::Reporter* reporter, SkResourceCache* cache) { - // TODO make our pixelref notification work for all caches (right now it is only global caches) - cache = NULL; - - const int N = 3; - SkBitmap src[N]; - for (int i = 0; i < N; ++i) { - src[i].allocN32Pixels(5, 5); - src[i].setImmutable(); - SkMipMapCache::AddAndRef(src[i], cache)->unref(); - } - - for (int i = 0; i < N; ++i) { - const SkMipMap* mipmap = SkMipMapCache::FindAndRef(src[i], cache); -#ifdef ONLY_WORKS_RELIABLY_SINGLE_THREADED_SINCE_CACHE_MAY_HAVE_BEEN_PURGED - REPORTER_ASSERT(reporter, mipmap); -#endif - SkSafeUnref(mipmap); - - src[i].reset(); // delete the underlying pixelref, which *should* remove us from the cache - - mipmap = SkMipMapCache::FindAndRef(src[i], cache); - REPORTER_ASSERT(reporter, !mipmap); - } -} - -static void test_bitmap_notify(skiatest::Reporter* reporter, SkResourceCache* cache) { - // TODO make our pixelref notification work for all caches (right now it is only global caches) - cache = NULL; - - const SkIRect subset = SkIRect::MakeWH(5, 5); - const int N = 3; - SkBitmap src[N], dst[N]; - for (int i = 0; i < N; ++i) { - src[i].allocN32Pixels(5, 5); - src[i].setImmutable(); - dst[i].allocN32Pixels(5, 5); - dst[i].setImmutable(); - SkBitmapCache::Add(src[i].getGenerationID(), subset, dst[i], cache); - } - - for (int i = 0; i < N; ++i) { - const uint32_t genID = src[i].getGenerationID(); - SkBitmap result; - bool found = SkBitmapCache::Find(genID, subset, &result, cache); -#ifdef ONLY_WORKS_RELIABLY_SINGLE_THREADED_SINCE_CACHE_MAY_HAVE_BEEN_PURGED - REPORTER_ASSERT(reporter, found); -#endif - - src[i].reset(); // delete the underlying pixelref, which *should* remove us from the cache - - found = SkBitmapCache::Find(genID, subset, &result, cache); - REPORTER_ASSERT(reporter, !found); - } -} - DEF_TEST(BitmapCache_discarded_bitmap, reporter) { SkResourceCache::DiscardableFactory factory = SkResourceCache::GetDiscardableFactory(); SkBitmap::Allocator* allocator = SkBitmapCache::GetAllocator(); @@ -288,6 +219,4 @@ DEF_TEST(BitmapCache_discarded_bitmap, reporter) { REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache)); test_mipmapcache(reporter, cache); - test_bitmap_notify(reporter, cache); - test_mipmap_notify(reporter, cache); } |