aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-08-19 12:25:40 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-08-19 12:25:41 -0700
commit216b643fc77e754a3fabbb0ed397e7cf55d1954d (patch)
tree32e75226963e5cbeab12a9e4acfd380a7ff7096d
parentfea7763140ba74b78f2c30028452e250140b6f21 (diff)
private iterator to visit all resource cache entries
BUG=skia: TBR= Review URL: https://codereview.chromium.org/1271033002
-rw-r--r--bench/ImageCacheBench.cpp2
-rw-r--r--include/core/SkPixelRef.h3
-rw-r--r--samplecode/SampleApp.cpp9
-rw-r--r--src/core/SkBitmapCache.cpp9
-rw-r--r--src/core/SkCachedData.h4
-rwxr-xr-xsrc/core/SkGlyphCache.cpp35
-rw-r--r--src/core/SkGlyphCache.h8
-rw-r--r--src/core/SkMaskCache.cpp8
-rw-r--r--src/core/SkPictureShader.cpp2
-rw-r--r--src/core/SkResourceCache.cpp27
-rw-r--r--src/core/SkResourceCache.h12
-rw-r--r--src/core/SkYUVPlanesCache.cpp4
-rw-r--r--src/lazy/SkDiscardablePixelRef.h3
-rw-r--r--tests/ImageCacheTest.cpp2
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);