diff options
author | reed <reed@google.com> | 2015-08-19 12:25:40 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-19 12:25:41 -0700 |
commit | 216b643fc77e754a3fabbb0ed397e7cf55d1954d (patch) | |
tree | 32e75226963e5cbeab12a9e4acfd380a7ff7096d | |
parent | fea7763140ba74b78f2c30028452e250140b6f21 (diff) |
private iterator to visit all resource cache entries
BUG=skia:
TBR=
Review URL: https://codereview.chromium.org/1271033002
-rw-r--r-- | bench/ImageCacheBench.cpp | 2 | ||||
-rw-r--r-- | include/core/SkPixelRef.h | 3 | ||||
-rw-r--r-- | samplecode/SampleApp.cpp | 9 | ||||
-rw-r--r-- | src/core/SkBitmapCache.cpp | 9 | ||||
-rw-r--r-- | src/core/SkCachedData.h | 4 | ||||
-rwxr-xr-x | src/core/SkGlyphCache.cpp | 35 | ||||
-rw-r--r-- | src/core/SkGlyphCache.h | 8 | ||||
-rw-r--r-- | src/core/SkMaskCache.cpp | 8 | ||||
-rw-r--r-- | src/core/SkPictureShader.cpp | 2 | ||||
-rw-r--r-- | src/core/SkResourceCache.cpp | 27 | ||||
-rw-r--r-- | src/core/SkResourceCache.h | 12 | ||||
-rw-r--r-- | src/core/SkYUVPlanesCache.cpp | 4 | ||||
-rw-r--r-- | src/lazy/SkDiscardablePixelRef.h | 3 | ||||
-rw-r--r-- | tests/ImageCacheTest.cpp | 2 |
14 files changed, 121 insertions, 7 deletions
diff --git a/bench/ImageCacheBench.cpp b/bench/ImageCacheBench.cpp index 4a068b03ab..96c64f84c1 100644 --- a/bench/ImageCacheBench.cpp +++ b/bench/ImageCacheBench.cpp @@ -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; diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h index 2e3e85a47f..5d1aef7dd0 100644 --- a/include/core/SkPixelRef.h +++ b/include/core/SkPixelRef.h @@ -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 diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index 0a89b48e3c..c985b1eb09 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -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; } diff --git a/src/core/SkBitmapCache.cpp b/src/core/SkBitmapCache.cpp index 3f1feac7bb..08e3fdc71f 100644 --- a/src/core/SkBitmapCache.cpp +++ b/src/core/SkBitmapCache.cpp @@ -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); diff --git a/src/core/SkCachedData.h b/src/core/SkCachedData.h index a861157298..d44fbc5895 100644 --- a/src/core/SkCachedData.h +++ b/src/core/SkCachedData.h @@ -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) {} diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp index 9b0199f6cf..e719c00b83 100755 --- a/src/core/SkGlyphCache.cpp +++ b/src/core/SkGlyphCache.cpp @@ -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); } } diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h index 1c985bf671..dc2aa579a7 100644 --- a/src/core/SkGlyphCache.h +++ b/src/core/SkGlyphCache.h @@ -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 diff --git a/src/core/SkMaskCache.cpp b/src/core/SkMaskCache.cpp index 31a789fd38..7dc4e4e3b8 100644 --- a/src/core/SkMaskCache.cpp +++ b/src/core/SkMaskCache.cpp @@ -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); diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp index f8c2ab09f8..b84333939e 100644 --- a/src/core/SkPictureShader.cpp +++ b/src/core/SkPictureShader.cpp @@ -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); diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp index 6c76d350c3..6febbd2971 100644 --- a/src/core/SkResourceCache.cpp +++ b/src/core/SkResourceCache.cpp @@ -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); +} diff --git a/src/core/SkResourceCache.h b/src/core/SkResourceCache.h index b43572f4be..7267c6739b 100644 --- a/src/core/SkResourceCache.h +++ b/src/core/SkResourceCache.h @@ -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; } diff --git a/src/core/SkYUVPlanesCache.cpp b/src/core/SkYUVPlanesCache.cpp index 79136db795..b113c07974 100644 --- a/src/core/SkYUVPlanesCache.cpp +++ b/src/core/SkYUVPlanesCache.cpp @@ -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); diff --git a/src/lazy/SkDiscardablePixelRef.h b/src/lazy/SkDiscardablePixelRef.h index 6f422e31db..e8451ee269 100644 --- a/src/lazy/SkDiscardablePixelRef.h +++ b/src/lazy/SkDiscardablePixelRef.h @@ -21,6 +21,9 @@ class SkDiscardablePixelRef : public SkPixelRef { public: + SkDiscardableMemory* diagnostic_only_getDiscardable() const override { + return fDiscardableMemory; + } protected: ~SkDiscardablePixelRef(); diff --git a/tests/ImageCacheTest.cpp b/tests/ImageCacheTest.cpp index 2244bb0a53..e2efe971d0 100644 --- a/tests/ImageCacheTest.cpp +++ b/tests/ImageCacheTest.cpp @@ -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); |