private iterator to visit all resource cache entries

BUG=skia:
TBR=

Review URL: https://codereview.chromium.org/1271033002
This commit is contained in:
reed 2015-08-19 12:25:40 -07:00 committed by Commit bot
parent fea7763140
commit 216b643fc7
14 changed files with 121 additions and 7 deletions

View File

@ -26,6 +26,8 @@ struct TestRec : public SkResourceCache::Rec {
const Key& getKey() const override { return fKey; }
size_t bytesUsed() const override { return sizeof(fKey) + sizeof(fValue); }
const char* getCategory() const override { return "imagecachebench-test"; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const override { return NULL; }
static bool Visitor(const SkResourceCache::Rec&, void*) {
return true;

View File

@ -24,6 +24,7 @@ class SkData;
struct SkIRect;
class GrTexture;
class SkDiscardableMemory;
/** \class SkPixelRef
@ -262,6 +263,8 @@ public:
fAddedToCache.store(true);
}
virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return NULL; }
protected:
/**
* On success, returns true and fills out the LockRec for the pixels. On

View File

@ -1473,9 +1473,18 @@ bool SampleWindow::previousSample() {
return true;
}
#include "SkResourceCache.h"
#include "SkGlyphCache.h"
bool SampleWindow::nextSample() {
fCurrIndex = (fCurrIndex + 1) % fSamples.count();
this->loadView((*fSamples[fCurrIndex])());
if (false) {
SkResourceCache::TestDumpMemoryStatistics();
SkGlyphCache::Dump();
SkDebugf("\n");
}
return true;
}

View File

@ -74,6 +74,11 @@ struct BitmapRec : public SkResourceCache::Rec {
const Key& getKey() const override { return fKey; }
size_t bytesUsed() const override { return sizeof(fKey) + fBitmap.getSize(); }
const char* getCategory() const override { return "bitmap"; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
return fBitmap.pixelRef()->diagnostic_only_getDiscardable();
}
static bool Finder(const SkResourceCache::Rec& baseRec, void* contextBitmap) {
const BitmapRec& rec = static_cast<const BitmapRec&>(baseRec);
SkBitmap* result = (SkBitmap*)contextBitmap;
@ -187,6 +192,10 @@ struct MipMapRec : public SkResourceCache::Rec {
const Key& getKey() const override { return fKey; }
size_t bytesUsed() const override { return sizeof(fKey) + fMipMap->size(); }
const char* getCategory() const override { return "mipmap"; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
return fMipMap->diagnostic_only_getDiscardable();
}
static bool Finder(const SkResourceCache::Rec& baseRec, void* contextMip) {
const MipMapRec& rec = static_cast<const MipMapRec&>(baseRec);

View File

@ -31,6 +31,10 @@ public:
bool testing_only_isLocked() const { return fIsLocked; }
bool testing_only_isInCache() const { return fInCache; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const {
return kDiscardableMemory_StorageType == fStorageType ? fStorage.fDM : nullptr;
}
protected:
// called when fData changes. could be NULL.
virtual void onDataChange(void* oldData, void* newData) {}

View File

@ -104,10 +104,14 @@ SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) {
return fScalerContext->glyphIDToChar(glyphID);
}
unsigned SkGlyphCache::getGlyphCount() {
unsigned SkGlyphCache::getGlyphCount() const {
return fScalerContext->getGlyphCount();
}
int SkGlyphCache::countCachedGlyphs() const {
return fGlyphMap.count();
}
///////////////////////////////////////////////////////////////////////////////
const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) {
@ -402,18 +406,39 @@ void SkGlyphCache::AttachCache(SkGlyphCache* cache) {
get_globals().attachCacheToHead(cache);
}
static void dump_visitor(const SkGlyphCache& cache, void* context) {
int* counter = (int*)context;
int index = *counter;
*counter += 1;
const SkScalerContextRec& rec = cache.getScalerContext()->getRec();
SkDebugf("[%3d] ID %3d, glyphs %3d, size %g, scale %g, skew %g, [%g %g %g %g]\n",
index, rec.fFontID, cache.countCachedGlyphs(),
rec.fTextSize, rec.fPreScaleX, rec.fPreSkewX,
rec.fPost2x2[0][0], rec.fPost2x2[0][1], rec.fPost2x2[1][0], rec.fPost2x2[1][1]);
}
void SkGlyphCache::Dump() {
SkDebugf("GlyphCache [ used budget ]\n");
SkDebugf(" bytes [ %8zu %8zu ]\n",
SkGraphics::GetFontCacheUsed(), SkGraphics::GetFontCacheLimit());
SkDebugf(" count [ %8zu %8zu ]\n",
SkGraphics::GetFontCacheCountUsed(), SkGraphics::GetFontCacheCountLimit());
int counter = 0;
SkGlyphCache::VisitAll(dump_visitor, &counter);
}
void SkGlyphCache::VisitAll(Visitor visitor, void* context) {
SkGlyphCache_Globals& globals = get_globals();
AutoAcquire ac(globals.fLock);
SkGlyphCache* cache;
globals.validate();
SkDebugf("SkGlyphCache strikes:%d memory:%d\n",
globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed());
for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext) {
cache->dump();
visitor(*cache, context);
}
}

View File

@ -66,7 +66,10 @@ public:
/** Returns the number of glyphs for this strike.
*/
unsigned getGlyphCount();
unsigned getGlyphCount() const;
/** Return the number of glyphs currently cached. */
int countCachedGlyphs() const;
/** Return the image associated with the glyph. If it has not been generated this will
trigger that.
@ -138,6 +141,9 @@ public:
static void Dump();
typedef void (*Visitor)(const SkGlyphCache&, void* context);
static void VisitAll(Visitor, void* context);
#ifdef SK_DEBUG
void validate() const;
#else

View File

@ -53,6 +53,10 @@ struct RRectBlurRec : public SkResourceCache::Rec {
const Key& getKey() const override { return fKey; }
size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
const char* getCategory() const override { return "rrect-blur"; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
return fValue.fData->diagnostic_only_getDiscardable();
}
static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
const RRectBlurRec& rec = static_cast<const RRectBlurRec&>(baseRec);
@ -144,6 +148,10 @@ struct RectsBlurRec : public SkResourceCache::Rec {
const Key& getKey() const override { return fKey; }
size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
const char* getCategory() const override { return "rects-blur"; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
return fValue.fData->diagnostic_only_getDiscardable();
}
static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
const RectsBlurRec& rec = static_cast<const RectsBlurRec&>(baseRec);

View File

@ -75,6 +75,8 @@ struct BitmapShaderRec : public SkResourceCache::Rec {
size_t bytesUsed() const override {
return sizeof(fKey) + sizeof(SkShader) + fBitmapBytes;
}
const char* getCategory() const override { return "bitmap-shader"; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const override { return nullptr; }
static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextShader) {
const BitmapShaderRec& rec = static_cast<const BitmapShaderRec&>(baseRec);

View File

@ -347,6 +347,18 @@ void SkResourceCache::purgeSharedID(uint64_t sharedID) {
#endif
}
void SkResourceCache::visitAll(Visitor visitor, void* context) {
// go backwards, just like purgeAsNeeded, just to make the code similar.
// could iterate either direction and still be correct.
Rec* rec = fTail;
while (rec) {
visitor(*rec, context);
rec = rec->fPrev;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
size_t SkResourceCache::setTotalByteLimit(size_t newLimit) {
size_t prevLimit = fTotalByteLimit;
fTotalByteLimit = newLimit;
@ -608,6 +620,11 @@ void SkResourceCache::Add(Rec* rec) {
get_cache()->add(rec);
}
void SkResourceCache::VisitAll(Visitor visitor, void* context) {
SkAutoMutexAcquire am(gMutex);
get_cache()->visitAll(visitor, context);
}
void SkResourceCache::PostPurgeSharedID(uint64_t sharedID) {
if (sharedID) {
SkMessageBus<PurgeSharedIDMessage>::Post(PurgeSharedIDMessage(sharedID));
@ -644,3 +661,13 @@ void SkGraphics::PurgeResourceCache() {
return SkResourceCache::PurgeAll();
}
/////////////
static void dump_visitor(const SkResourceCache::Rec& rec, void*) {
SkDebugf("RC: %12s bytes %9lu discardable %p\n",
rec.getCategory(), rec.bytesUsed(), rec.diagnostic_only_getDiscardable());
}
void SkResourceCache::TestDumpMemoryStatistics() {
VisitAll(dump_visitor, nullptr);
}

View File

@ -14,7 +14,6 @@
class SkCachedData;
class SkDiscardableMemory;
class SkMipMap;
/**
* Cache object for bitmaps (with possible scale in X Y as part of the key).
@ -78,6 +77,10 @@ public:
virtual const Key& getKey() const = 0;
virtual size_t bytesUsed() const = 0;
// for memory usage diagnostics
virtual const char* getCategory() const = 0;
virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return NULL; }
// for SkTDynamicHash::Traits
static uint32_t Hash(const Key& key) { return key.hash(); }
static const Key& GetKey(const Rec& rec) { return rec.getKey(); }
@ -133,6 +136,10 @@ public:
static bool Find(const Key& key, FindVisitor, void* context);
static void Add(Rec*);
typedef void (*Visitor)(const Rec&, void* context);
// Call the visitor for every Rec in the cache.
static void VisitAll(Visitor, void* context);
static size_t GetTotalBytesUsed();
static size_t GetTotalByteLimit();
static size_t SetTotalByteLimit(size_t newLimit);
@ -143,6 +150,8 @@ public:
static void PurgeAll();
static void TestDumpMemoryStatistics();
/**
* Returns the DiscardableFactory used by the global cache, or NULL.
*/
@ -194,6 +203,7 @@ public:
*/
bool find(const Key&, FindVisitor, void* context);
void add(Rec*);
void visitAll(Visitor, void* context);
size_t getTotalBytesUsed() const { return fTotalBytesUsed; }
size_t getTotalByteLimit() const { return fTotalByteLimit; }

View File

@ -48,6 +48,10 @@ struct YUVPlanesRec : public SkResourceCache::Rec {
const Key& getKey() const override { return fKey; }
size_t bytesUsed() const override { return sizeof(*this) + fValue.fData->size(); }
const char* getCategory() const override { return "yuv-planes"; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
return fValue.fData->diagnostic_only_getDiscardable();
}
static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextData) {
const YUVPlanesRec& rec = static_cast<const YUVPlanesRec&>(baseRec);

View File

@ -21,6 +21,9 @@
class SkDiscardablePixelRef : public SkPixelRef {
public:
SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
return fDiscardableMemory;
}
protected:
~SkDiscardablePixelRef();

View File

@ -26,6 +26,8 @@ struct TestingRec : public SkResourceCache::Rec {
const Key& getKey() const override { return fKey; }
size_t bytesUsed() const override { return sizeof(fKey) + sizeof(fValue); }
const char* getCategory() const override { return "test_cache"; }
SkDiscardableMemory* diagnostic_only_getDiscardable() const override { return NULL; }
static bool Visitor(const SkResourceCache::Rec& baseRec, void* context) {
const TestingRec& rec = static_cast<const TestingRec&>(baseRec);