aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@google.com>2015-02-19 08:53:52 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-19 08:53:52 -0800
commit90c6bc4e85df2da37f436ea1da203e194c4740e2 (patch)
treebc71dc3d3a7160bb8118a1e349e11a6e58a4b8cb
parentcabc08c4296e1ce6c6d9d84cf702361cf439c1bc (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.cpp84
-rw-r--r--src/core/SkBitmapCache.h10
-rw-r--r--src/core/SkPixelRef.cpp11
-rw-r--r--src/core/SkResourceCache.cpp39
-rw-r--r--src/core/SkResourceCache.h38
-rw-r--r--tests/SkResourceCacheTest.cpp71
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);
}