Add a way to monitor cache hits and misses for deferred decoding.

Adds a new flag to bench_pictures in order to do this. Also fix
a warning.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@7965 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
scroggo@google.com 2013-03-04 19:56:21 +00:00
parent 46348e2173
commit cc690201d2
4 changed files with 90 additions and 27 deletions

View File

@ -113,6 +113,7 @@
],
'include_dirs': [
'../bench',
'../src/lazy/',
],
'dependencies': [
'skia_base_libs.gyp:skia_base_libs',

View File

@ -12,6 +12,13 @@
#include "SkImageCache.h"
#include "SkImagePriv.h"
#if LAZY_CACHE_STATS
#include "SkThread.h"
int32_t SkLazyPixelRef::gCacheHits;
int32_t SkLazyPixelRef::gCacheMisses;
#endif
SkLazyPixelRef::SkLazyPixelRef(SkData* data, SkBitmapFactory::DecodeProc proc, SkImageCache* cache)
// Pass NULL for the Mutex so that the default (ring buffer) will be used.
: INHERITED(NULL)
@ -61,33 +68,44 @@ void* SkLazyPixelRef::onLockPixels(SkColorTable**) {
}
SkBitmapFactory::Target target;
// Check to see if the pixels still exist in the cache.
target.fAddr = SkImageCache::UNINITIALIZED_ID == fCacheId ?
NULL : fImageCache->pinCache(fCacheId);
if (NULL == target.fAddr) {
SkImage::Info info;
SkASSERT(fData != NULL && fData->size() > 0);
// FIXME: As an optimization, only do this part once.
fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, NULL);
if (fErrorInDecoding) {
fCacheId = SkImageCache::UNINITIALIZED_ID;
return NULL;
if (SkImageCache::UNINITIALIZED_ID == fCacheId) {
target.fAddr = NULL;
} else {
target.fAddr = fImageCache->pinCache(fCacheId);
if (NULL != target.fAddr) {
#if LAZY_CACHE_STATS
sk_atomic_inc(&gCacheHits);
#endif
return target.fAddr;
}
// Allocate the memory.
size_t bytes = ComputeMinRowBytesAndSize(info, &target.fRowBytes);
#if LAZY_CACHE_STATS
sk_atomic_inc(&gCacheMisses);
#endif
}
SkASSERT(NULL == target.fAddr);
SkImage::Info info;
SkASSERT(fData != NULL && fData->size() > 0);
// FIXME: As an optimization, only do this part once.
fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, NULL);
if (fErrorInDecoding) {
fCacheId = SkImageCache::UNINITIALIZED_ID;
return NULL;
}
// Allocate the memory.
size_t bytes = ComputeMinRowBytesAndSize(info, &target.fRowBytes);
target.fAddr = fImageCache->allocAndPinCache(bytes, &fCacheId);
if (NULL == target.fAddr) {
// Space could not be allocated.
fCacheId = SkImageCache::UNINITIALIZED_ID;
return NULL;
}
SkASSERT(SkImageCache::UNINITIALIZED_ID != fCacheId);
fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, &target);
if (fErrorInDecoding) {
fImageCache->throwAwayCache(fCacheId);
fCacheId = SkImageCache::UNINITIALIZED_ID;
return NULL;
}
target.fAddr = fImageCache->allocAndPinCache(bytes, &fCacheId);
if (NULL == target.fAddr) {
// Space could not be allocated.
fCacheId = SkImageCache::UNINITIALIZED_ID;
return NULL;
}
SkASSERT(SkImageCache::UNINITIALIZED_ID != fCacheId);
fErrorInDecoding = !fDecodeProc(fData->data(), fData->size(), &info, &target);
if (fErrorInDecoding) {
fImageCache->throwAwayCache(fCacheId);
fCacheId = SkImageCache::UNINITIALIZED_ID;
return NULL;
}
return target.fAddr;
}

View File

@ -17,6 +17,12 @@ class SkColorTable;
class SkData;
class SkImageCache;
#ifdef SK_DEBUG
#define LAZY_CACHE_STATS 1
#elif !defined(LAZY_CACHE_STATS)
#define LAZY_CACHE_STATS 0
#endif
/**
* PixelRef which defers decoding until SkBitmap::lockPixels() is called.
*/
@ -38,6 +44,12 @@ public:
intptr_t getCacheId() const { return fCacheId; }
#endif
#if LAZY_CACHE_STATS
static int32_t GetCacheHits() { return gCacheHits; }
static int32_t GetCacheMisses() { return gCacheMisses; }
static void ResetCacheStats() { gCacheHits = gCacheMisses = 0; }
#endif
// No need to flatten this object. When flattening an SkBitmap, SkOrderedWriteBuffer will check
// the encoded data and write that instead.
// Future implementations of SkFlattenableWriteBuffer will need to special case for
@ -57,6 +69,11 @@ private:
SkImageCache* fImageCache;
intptr_t fCacheId;
#if LAZY_CACHE_STATS
static int32_t gCacheHits;
static int32_t gCacheMisses;
#endif
typedef SkPixelRef INHERITED;
};

View File

@ -44,6 +44,9 @@ DEFINE_bool(timeIndividualTiles, false, "Report times for drawing individual til
"times for drawing the whole page. Requires tiled rendering.");
DEFINE_string(timers, "", "[wcgWC]*: Display wall, cpu, gpu, truncated wall or truncated cpu time"
" for each picture.");
DEFINE_bool(trackDeferredCaching, false, "Only meaningful with --deferImageDecoding and "
"LAZY_CACHE_STATS set to true. Report percentage of cache hits when using deferred "
"image decoding.");
static char const * const gFilterTypes[] = {
"paint",
@ -140,6 +143,7 @@ static SkString filterFlagsUsage() {
#include "SkData.h"
#include "SkLruImageCache.h"
#include "SkLazyPixelRef.h"
static SkLruImageCache gLruImageCache(1024*1024);
@ -152,6 +156,11 @@ static bool lazy_decode_bitmap(const void* buffer, size_t size, SkBitmap* bitmap
return factory.installPixelRef(data, bitmap);
}
#if LAZY_CACHE_STATS
static int32_t gTotalCacheHits;
static int32_t gTotalCacheMisses;
#endif
static bool run_single_benchmark(const SkString& inputPath,
sk_tools::PictureBenchmark& benchmark) {
SkFILEStream inputStream;
@ -189,6 +198,18 @@ static bool run_single_benchmark(const SkString& inputPath,
gLogger.logProgress(result);
benchmark.run(picture);
#if LAZY_CACHE_STATS
if (FLAGS_trackDeferredCaching) {
int32_t cacheHits = SkLazyPixelRef::GetCacheHits();
int32_t cacheMisses = SkLazyPixelRef::GetCacheMisses();
SkLazyPixelRef::ResetCacheStats();
SkDebugf("Cache hit rate: %f\n", (double) cacheHits / (cacheHits + cacheMisses));
gTotalCacheHits += cacheHits;
gTotalCacheMisses += cacheMisses;
}
#endif
return true;
}
@ -200,12 +221,12 @@ static void setup_benchmark(sk_tools::PictureBenchmark* benchmark) {
const char* filters = FLAGS_filter[0];
const char* colon = strchr(filters, ':');
if (colon) {
int type = -1;
int32_t type = -1;
size_t typeLen = colon - filters;
for (size_t tIndex = 0; tIndex < kFilterTypesCount; ++tIndex) {
if (typeLen == strlen(gFilterTypes[tIndex])
&& !strncmp(filters, gFilterTypes[tIndex], typeLen)) {
type = tIndex;
type = SkToS32(tIndex);
break;
}
}
@ -396,6 +417,12 @@ int tool_main(int argc, char** argv) {
gLogger.logError(err);
return 1;
}
#if LAZY_CACHE_STATS
if (FLAGS_trackDeferredCaching) {
SkDebugf("Total cache hit rate: %f\n",
(double) gTotalCacheHits / (gTotalCacheHits + gTotalCacheMisses));
}
#endif
return 0;
}