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': [ 'include_dirs': [
'../bench', '../bench',
'../src/lazy/',
], ],
'dependencies': [ 'dependencies': [
'skia_base_libs.gyp:skia_base_libs', 'skia_base_libs.gyp:skia_base_libs',

View File

@ -12,6 +12,13 @@
#include "SkImageCache.h" #include "SkImageCache.h"
#include "SkImagePriv.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) SkLazyPixelRef::SkLazyPixelRef(SkData* data, SkBitmapFactory::DecodeProc proc, SkImageCache* cache)
// Pass NULL for the Mutex so that the default (ring buffer) will be used. // Pass NULL for the Mutex so that the default (ring buffer) will be used.
: INHERITED(NULL) : INHERITED(NULL)
@ -61,9 +68,21 @@ void* SkLazyPixelRef::onLockPixels(SkColorTable**) {
} }
SkBitmapFactory::Target target; SkBitmapFactory::Target target;
// Check to see if the pixels still exist in the cache. // Check to see if the pixels still exist in the cache.
target.fAddr = SkImageCache::UNINITIALIZED_ID == fCacheId ? if (SkImageCache::UNINITIALIZED_ID == fCacheId) {
NULL : fImageCache->pinCache(fCacheId); target.fAddr = NULL;
if (NULL == target.fAddr) { } else {
target.fAddr = fImageCache->pinCache(fCacheId);
if (NULL != target.fAddr) {
#if LAZY_CACHE_STATS
sk_atomic_inc(&gCacheHits);
#endif
return target.fAddr;
}
#if LAZY_CACHE_STATS
sk_atomic_inc(&gCacheMisses);
#endif
}
SkASSERT(NULL == target.fAddr);
SkImage::Info info; SkImage::Info info;
SkASSERT(fData != NULL && fData->size() > 0); SkASSERT(fData != NULL && fData->size() > 0);
// FIXME: As an optimization, only do this part once. // FIXME: As an optimization, only do this part once.
@ -88,7 +107,6 @@ void* SkLazyPixelRef::onLockPixels(SkColorTable**) {
fCacheId = SkImageCache::UNINITIALIZED_ID; fCacheId = SkImageCache::UNINITIALIZED_ID;
return NULL; return NULL;
} }
}
return target.fAddr; return target.fAddr;
} }

View File

@ -17,6 +17,12 @@ class SkColorTable;
class SkData; class SkData;
class SkImageCache; 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. * PixelRef which defers decoding until SkBitmap::lockPixels() is called.
*/ */
@ -38,6 +44,12 @@ public:
intptr_t getCacheId() const { return fCacheId; } intptr_t getCacheId() const { return fCacheId; }
#endif #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 // No need to flatten this object. When flattening an SkBitmap, SkOrderedWriteBuffer will check
// the encoded data and write that instead. // the encoded data and write that instead.
// Future implementations of SkFlattenableWriteBuffer will need to special case for // Future implementations of SkFlattenableWriteBuffer will need to special case for
@ -57,6 +69,11 @@ private:
SkImageCache* fImageCache; SkImageCache* fImageCache;
intptr_t fCacheId; intptr_t fCacheId;
#if LAZY_CACHE_STATS
static int32_t gCacheHits;
static int32_t gCacheMisses;
#endif
typedef SkPixelRef INHERITED; 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."); "times for drawing the whole page. Requires tiled rendering.");
DEFINE_string(timers, "", "[wcgWC]*: Display wall, cpu, gpu, truncated wall or truncated cpu time" DEFINE_string(timers, "", "[wcgWC]*: Display wall, cpu, gpu, truncated wall or truncated cpu time"
" for each picture."); " 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[] = { static char const * const gFilterTypes[] = {
"paint", "paint",
@ -140,6 +143,7 @@ static SkString filterFlagsUsage() {
#include "SkData.h" #include "SkData.h"
#include "SkLruImageCache.h" #include "SkLruImageCache.h"
#include "SkLazyPixelRef.h"
static SkLruImageCache gLruImageCache(1024*1024); 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); 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, static bool run_single_benchmark(const SkString& inputPath,
sk_tools::PictureBenchmark& benchmark) { sk_tools::PictureBenchmark& benchmark) {
SkFILEStream inputStream; SkFILEStream inputStream;
@ -189,6 +198,18 @@ static bool run_single_benchmark(const SkString& inputPath,
gLogger.logProgress(result); gLogger.logProgress(result);
benchmark.run(picture); 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; return true;
} }
@ -200,12 +221,12 @@ static void setup_benchmark(sk_tools::PictureBenchmark* benchmark) {
const char* filters = FLAGS_filter[0]; const char* filters = FLAGS_filter[0];
const char* colon = strchr(filters, ':'); const char* colon = strchr(filters, ':');
if (colon) { if (colon) {
int type = -1; int32_t type = -1;
size_t typeLen = colon - filters; size_t typeLen = colon - filters;
for (size_t tIndex = 0; tIndex < kFilterTypesCount; ++tIndex) { for (size_t tIndex = 0; tIndex < kFilterTypesCount; ++tIndex) {
if (typeLen == strlen(gFilterTypes[tIndex]) if (typeLen == strlen(gFilterTypes[tIndex])
&& !strncmp(filters, gFilterTypes[tIndex], typeLen)) { && !strncmp(filters, gFilterTypes[tIndex], typeLen)) {
type = tIndex; type = SkToS32(tIndex);
break; break;
} }
} }
@ -396,6 +417,12 @@ int tool_main(int argc, char** argv) {
gLogger.logError(err); gLogger.logError(err);
return 1; return 1;
} }
#if LAZY_CACHE_STATS
if (FLAGS_trackDeferredCaching) {
SkDebugf("Total cache hit rate: %f\n",
(double) gTotalCacheHits / (gTotalCacheHits + gTotalCacheMisses));
}
#endif
return 0; return 0;
} }