Provide an option in bench_pictures to count pixel ram.

In SkLruImageCache, provide an option to keep all pixels, and document
the new behavior.

In gm/factory.cpp, set the budget for the Lru image cache to 1, to
retain (basically) the old behavior.

BUG=https://code.google.com/p/skia/issues/detail?id=1010

Review URL: https://codereview.chromium.org/12378075

git-svn-id: http://skia.googlecode.com/svn/trunk@7972 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
scroggo@google.com 2013-03-04 21:32:32 +00:00
parent 8563d3089c
commit a560d00ba5
4 changed files with 50 additions and 6 deletions

View File

@ -42,7 +42,7 @@ protected:
SkBitmapFactory factory(&SkImageDecoder::DecodeMemoryToTarget);
// Create a cache which will boot the pixels out anytime the
// bitmap is unlocked.
SkAutoTUnref<SkLruImageCache> cache(SkNEW_ARGS(SkLruImageCache, (0)));
SkAutoTUnref<SkLruImageCache> cache(SkNEW_ARGS(SkLruImageCache, (1)));
factory.setImageCache(cache);
factory.installPixelRef(data, &fBitmap);
}

View File

@ -28,7 +28,21 @@ public:
CacheStatus getCacheStatus(intptr_t ID) const SK_OVERRIDE;
#endif
void setBudget(size_t newBudget);
/**
* Set the byte limit on cached pixels. If more bytes are used than this, the cache will free
* unpinned memory until under the new limit or until all unpinned memory is freed. This will
* never free pinned memory, so the cache can potentially remain over the limit. The limit is
* enforced each time memory is allocated or released.
* 0 is a special flag for an infinite budget.
* @return size_t The previous limit.
*/
size_t setImageCacheLimit(size_t newLimit);
/**
* Return the number of bytes of memory currently in use by the cache. Can include memory that
* is no longer pinned, but has not been freed.
*/
size_t getImageCacheUsed() const { return fRamUsed; }
virtual void* allocAndPinCache(size_t bytes, intptr_t* ID) SK_OVERRIDE;
virtual void* pinCache(intptr_t ID) SK_OVERRIDE;

View File

@ -87,10 +87,12 @@ SkImageCache::CacheStatus SkLruImageCache::getCacheStatus(intptr_t ID) const {
}
#endif
void SkLruImageCache::setBudget(size_t newBudget) {
size_t SkLruImageCache::setImageCacheLimit(size_t newLimit) {
size_t oldLimit = fRamBudget;
SkAutoMutexAcquire ac(&fMutex);
fRamBudget = newBudget;
fRamBudget = newLimit;
this->purgeIfNeeded();
return oldLimit;
}
void* SkLruImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) {
@ -168,7 +170,9 @@ CachedPixels* SkLruImageCache::findByID(intptr_t ID) const {
void SkLruImageCache::purgeIfNeeded() {
// Mutex is already locked.
this->purgeTilAtOrBelow(fRamBudget);
if (fRamBudget > 0) {
this->purgeTilAtOrBelow(fRamBudget);
}
}
void SkLruImageCache::purgeTilAtOrBelow(size_t limit) {

View File

@ -26,6 +26,7 @@
SkBenchLogger gLogger;
// Flags used by this file, in alphabetical order.
DEFINE_bool(countRAM, false, "Count the RAM used for bitmap pixels in each skp file");
DECLARE_bool(deferImageDecoding);
DEFINE_string(filter, "",
"type:flag : Enable canvas filtering to disable a paint flag, "
@ -173,6 +174,13 @@ static bool run_single_benchmark(const SkString& inputPath,
return false;
}
// Since the old picture has been deleted, all pixels should be cleared.
SkASSERT(gLruImageCache.getImageCacheUsed() == 0);
if (FLAGS_countRAM) {
// Set the limit to zero, so all pixels will be kept
gLruImageCache.setImageCacheLimit(0);
}
bool success = false;
SkPicture* picture;
if (FLAGS_deferImageDecoding) {
@ -204,11 +212,29 @@ static bool run_single_benchmark(const SkString& inputPath,
int32_t cacheHits = SkLazyPixelRef::GetCacheHits();
int32_t cacheMisses = SkLazyPixelRef::GetCacheMisses();
SkLazyPixelRef::ResetCacheStats();
SkDebugf("Cache hit rate: %f\n", (double) cacheHits / (cacheHits + cacheMisses));
SkString hitString;
hitString.printf("Cache hit rate: %f\n", (double) cacheHits / (cacheHits + cacheMisses));
gLogger.logProgress(hitString);
gTotalCacheHits += cacheHits;
gTotalCacheMisses += cacheMisses;
}
#endif
if (FLAGS_countRAM) {
SkString ramCount("RAM used for bitmaps: ");
size_t bytes = gLruImageCache.getImageCacheUsed();
if (bytes > 1024) {
size_t kb = bytes / 1024;
if (kb > 1024) {
size_t mb = kb / 1024;
ramCount.appendf("%zi MB\n", mb);
} else {
ramCount.appendf("%zi KB\n", kb);
}
} else {
ramCount.appendf("%zi bytes\n", bytes);
}
gLogger.logProgress(ramCount);
}
return true;
}