| Index: bench/GrResourceCacheBench.cpp
|
| diff --git a/bench/GrResourceCacheBench.cpp b/bench/GrResourceCacheBench.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..58681085572c76af66a3cd3174510aacb941d057
|
| --- /dev/null
|
| +++ b/bench/GrResourceCacheBench.cpp
|
| @@ -0,0 +1,246 @@
|
| +
|
| +/*
|
| + * Copyright 2013 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#if SK_SUPPORT_GPU
|
| +
|
| +#include "GrContext.h"
|
| +#include "GrResource.h"
|
| +#include "GrResourceCache.h"
|
| +#include "GrStencilBuffer.h"
|
| +#include "GrTexture.h"
|
| +#include "GrUtils.h"
|
| +#include "SkBenchmark.h"
|
| +
|
| +enum {
|
| + CACHE_SIZE_COUNT = 2048,
|
| + CACHE_SIZE_BYTES = 2 * 1024 * 1024,
|
| +};
|
| +
|
| +class StencilResource : public GrResource {
|
| +public:
|
| + SK_DECLARE_INST_COUNT(StencilResource);
|
| + StencilResource(GrGpu* gpu, int id)
|
| + : INHERITED(gpu, false),
|
| + fID(id) {
|
| + }
|
| + ~StencilResource() {
|
| + this->release();
|
| + }
|
| +
|
| + virtual size_t sizeInBytes() const SK_OVERRIDE {
|
| + return 100 + ((fID % 1 == 0) ? -5 : 6);
|
| + }
|
| +
|
| + static GrResourceKey ComputeKey(int width, int height, int sampleCnt) {
|
| + return GrStencilBuffer::ComputeKey(width, height, sampleCnt);
|
| + }
|
| +
|
| + int fID;
|
| +
|
| +private:
|
| + typedef GrResource INHERITED;
|
| +};
|
| +
|
| +class TextureResource : public GrResource {
|
| +public:
|
| + SK_DECLARE_INST_COUNT(TextureResource);
|
| + TextureResource(GrGpu* gpu, int id)
|
| + : INHERITED(gpu, false),
|
| + fID(id) {
|
| + }
|
| + ~TextureResource() {
|
| + this->release();
|
| + }
|
| +
|
| + virtual size_t sizeInBytes() const SK_OVERRIDE {
|
| + return 100 + ((fID % 1 == 0) ? -40 : 33);
|
| + }
|
| +
|
| + static GrResourceKey ComputeKey(const GrTextureDesc& desc) {
|
| + return GrTexture::ComputeScratchKey(desc);
|
| + }
|
| +
|
| + int fID;
|
| +
|
| +private:
|
| + typedef GrResource INHERITED;
|
| +};
|
| +
|
| +SK_DEFINE_INST_COUNT(StencilResource)
|
| +SK_DEFINE_INST_COUNT(TextureResource)
|
| +
|
| +static void get_stencil(int i, int* w, int* h, int* s) {
|
| + *w = i % 1024;
|
| + *h = i * 2 % 1024;
|
| + *s = i % 1 == 0 ? 0 : 4;
|
| +}
|
| +
|
| +static void get_texture_desc(int i, GrTextureDesc* desc) {
|
| + desc->fFlags = kRenderTarget_GrTextureFlagBit |
|
| + kNoStencil_GrTextureFlagBit;
|
| + desc->fWidth = i % 1024;
|
| + desc->fHeight = i * 2 % 1024;
|
| + desc->fConfig = static_cast<GrPixelConfig>(i % (kLast_GrPixelConfig + 1));
|
| + desc->fSampleCnt = i % 1 == 0 ? 0 : 4;
|
| +}
|
| +
|
| +static void populate_cache(GrResourceCache* cache, GrGpu* gpu, int resourceCount) {
|
| + for (int i = 0; i < resourceCount; ++i) {
|
| + int w, h, s;
|
| + get_stencil(i, &w, &h, &s);
|
| + GrResourceKey key = GrStencilBuffer::ComputeKey(w, h, s);
|
| + GrResource* resource = SkNEW_ARGS(StencilResource, (gpu, i));
|
| + cache->purgeAsNeeded(1, resource->sizeInBytes());
|
| + cache->addResource(key, resource);
|
| + resource->unref();
|
| + }
|
| +
|
| + for (int i = 0; i < resourceCount; ++i) {
|
| + GrTextureDesc desc;
|
| + get_texture_desc(i, &desc);
|
| + GrResourceKey key = TextureResource::ComputeKey(desc);
|
| + GrResource* resource = SkNEW_ARGS(TextureResource, (gpu, i));
|
| + cache->purgeAsNeeded(1, resource->sizeInBytes());
|
| + cache->addResource(key, resource);
|
| + resource->unref();
|
| + }
|
| +}
|
| +
|
| +static void check_cache_contents_or_die(GrResourceCache* cache, int k) {
|
| + // Benchmark find calls that succeed.
|
| + {
|
| + GrTextureDesc desc;
|
| + get_texture_desc(k, &desc);
|
| + GrResourceKey key = TextureResource::ComputeKey(desc);
|
| + GrResource* item = cache->find(key);
|
| + if (NULL == item) {
|
| + GrCrash("cache add does not work as expected");
|
| + return;
|
| + }
|
| + if (static_cast<TextureResource*>(item)->fID != k) {
|
| + GrCrash("cache add does not work as expected");
|
| + return;
|
| + }
|
| + }
|
| + {
|
| + int w, h, s;
|
| + get_stencil(k, &w, &h, &s);
|
| + GrResourceKey key = StencilResource::ComputeKey(w, h, s);
|
| + GrResource* item = cache->find(key);
|
| + if (NULL == item) {
|
| + GrCrash("cache add does not work as expected");
|
| + return;
|
| + }
|
| + if (static_cast<TextureResource*>(item)->fID != k) {
|
| + GrCrash("cache add does not work as expected");
|
| + return;
|
| + }
|
| + }
|
| +
|
| + // Benchmark also find calls that always fail.
|
| + {
|
| + GrTextureDesc desc;
|
| + get_texture_desc(k, &desc);
|
| + desc.fHeight |= 1;
|
| + GrResourceKey key = TextureResource::ComputeKey(desc);
|
| + GrResource* item = cache->find(key);
|
| + if (NULL != item) {
|
| + GrCrash("cache add does not work as expected");
|
| + return;
|
| + }
|
| + }
|
| + {
|
| + int w, h, s;
|
| + get_stencil(k, &w, &h, &s);
|
| + h |= 1;
|
| + GrResourceKey key = StencilResource::ComputeKey(w, h, s);
|
| + GrResource* item = cache->find(key);
|
| + if (NULL != item) {
|
| + GrCrash("cache add does not work as expected");
|
| + return;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +class GrResourceCacheBenchAdd : public SkBenchmark {
|
| + enum {
|
| + RESOURCE_COUNT = CACHE_SIZE_COUNT / 2,
|
| + DUPLICATE_COUNT = CACHE_SIZE_COUNT / 4,
|
| + };
|
| +
|
| +public:
|
| + virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
|
| + return backend == kGPU_Backend;
|
| + }
|
| +
|
| +protected:
|
| + virtual const char* onGetName() SK_OVERRIDE {
|
| + return "grresourcecache_add";
|
| + }
|
| +
|
| + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
|
| + GrContext* context = GrUtils::GetGr(canvas);
|
| + GrGpu* gpu = context->getGpu();
|
| +
|
| + for (int i = 0; i < this->getLoops(); ++i) {
|
| + GrResourceCache cache(CACHE_SIZE_COUNT, CACHE_SIZE_BYTES);
|
| + populate_cache(&cache, gpu, DUPLICATE_COUNT);
|
| + populate_cache(&cache, gpu, RESOURCE_COUNT);
|
| +
|
| + // Check that cache works.
|
| + for (int k = 0; k < RESOURCE_COUNT; k += 33) {
|
| + check_cache_contents_or_die(&cache, k);
|
| + }
|
| + cache.purgeAllUnlocked();
|
| + }
|
| + }
|
| +
|
| +private:
|
| + typedef SkBenchmark INHERITED;
|
| +};
|
| +
|
| +
|
| +class GrResourceCacheBenchFind : public SkBenchmark {
|
| + enum {
|
| + RESOURCE_COUNT = (CACHE_SIZE_COUNT / 2) - 100,
|
| + DUPLICATE_COUNT = 100
|
| + };
|
| +
|
| +public:
|
| + virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
|
| + return backend == kGPU_Backend;
|
| + }
|
| +
|
| +protected:
|
| + virtual const char* onGetName() SK_OVERRIDE {
|
| + return "grresourcecache_find";
|
| + }
|
| +
|
| + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
|
| + GrContext* context = GrUtils::GetGr(canvas);
|
| + GrGpu* gpu = context->getGpu();
|
| + GrResourceCache cache(CACHE_SIZE_COUNT, CACHE_SIZE_BYTES);
|
| + populate_cache(&cache, gpu, DUPLICATE_COUNT);
|
| + populate_cache(&cache, gpu, RESOURCE_COUNT);
|
| +
|
| + for (int i = 0; i < this->getLoops(); ++i) {
|
| + for (int k = 0; k < RESOURCE_COUNT; ++k) {
|
| + check_cache_contents_or_die(&cache, k);
|
| + }
|
| + }
|
| + }
|
| +
|
| +private:
|
| + typedef SkBenchmark INHERITED;
|
| +};
|
| +
|
| +DEF_BENCH( return new GrResourceCacheBenchAdd(); )
|
| +DEF_BENCH( return new GrResourceCacheBenchFind(); )
|
| +
|
| +#endif
|
|
|