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:
parent
46348e2173
commit
cc690201d2
@ -113,6 +113,7 @@
|
||||
],
|
||||
'include_dirs': [
|
||||
'../bench',
|
||||
'../src/lazy/',
|
||||
],
|
||||
'dependencies': [
|
||||
'skia_base_libs.gyp:skia_base_libs',
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user