1b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon/* 2b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * Copyright 2016 Google Inc. 3b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * 4b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * Use of this source code is governed by a BSD-style license that can be 5b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * found in the LICENSE file. 6b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon */ 7b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 8b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon#include "Benchmark.h" 9b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon#include "sk_tool_utils.h" 10b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon#include "SkCanvas.h" 11b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon#include "SkImage.h" 12b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon#include "SkSurface.h" 13b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 149f1f6e2c28066c7d7ff26727ce7d7504c7d032bdbrianosman#if SK_SUPPORT_GPU 159f1f6e2c28066c7d7ff26727ce7d7504c7d032bdbrianosman 169f1f6e2c28066c7d7ff26727ce7d7504c7d032bdbrianosman#include "GrContext.h" 179f1f6e2c28066c7d7ff26727ce7d7504c7d032bdbrianosman 18b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon/** These benchmarks were designed to measure changes to GrResourceCache's replacement policy */ 19b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 20b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon////////////////////////////////////////////////////////////////////////////// 21b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 22b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon// The width/height of the images to draw. The small size underestimates the value of a good 23b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon// replacement strategy since the texture uploads are quite small. However, the effects are still 24b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon// significant and this lets the benchmarks complete a lot faster, especially on mobile. 25b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonstatic constexpr int kS = 25; 26b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 27b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonstatic void make_images(sk_sp<SkImage> imgs[], int cnt) { 28b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int i = 0; i < cnt; ++i) { 29b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkBitmap bmp = sk_tool_utils::create_checkerboard_bitmap(kS, kS, SK_ColorBLACK, 30b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SK_ColorCYAN, 10); 31b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon imgs[i] = SkImage::MakeFromBitmap(bmp); 32b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 33b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon} 34b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 35b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonstatic void draw_image(SkCanvas* canvas, SkImage* img) { 36b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // Make the paint transparent to avoid any issues of deferred tiler blending 37b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // optmizations 38b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkPaint paint; 39b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon paint.setAlpha(0x10); 40b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon canvas->drawImage(img, 0, 0, &paint); 41b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon} 42b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 43b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonvoid set_cache_budget(SkCanvas* canvas, int approxImagesInBudget) { 44b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // This is inexact but we attempt to figure out a baseline number of resources GrContext needs 45b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // to render an SkImage and add one additional resource for each image we'd like to fit. 46b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon GrContext* context = canvas->getGrContext(); 47b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkASSERT(context); 48b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->flush(); 49b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->purgeAllUnlockedResources(); 50b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon sk_sp<SkImage> image; 51b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon make_images(&image, 1); 52b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon draw_image(canvas, image.get()); 53b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->flush(); 54b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int baselineCount; 55b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->getResourceCacheUsage(&baselineCount, nullptr); 56b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon baselineCount -= 1; // for the image's textures. 57b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->setResourceCacheLimits(baselineCount + approxImagesInBudget, 1 << 30); 58b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->purgeAllUnlockedResources(); 59b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon} 60b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 61b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon////////////////////////////////////////////////////////////////////////////// 62b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 63b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon/** 64b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * Tests repeatedly drawing the same set of images in each frame. Different instances of the bench 65b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * run with different cache sizes and either repeat the image order each frame or use a random 66b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * order. Every variation of this bench draws the same image set, only the budget and order of 67b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * images differs. Since the total fill is the same they can be cross-compared. 68b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon */ 69b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonclass ImageCacheBudgetBench : public Benchmark { 70b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonpublic: 71b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon /** budgetSize is the number of images that can fit in the cache. 100 images will be drawn. */ 72b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon ImageCacheBudgetBench(int budgetSize, bool shuffle) 73b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon : fBudgetSize(budgetSize) 74b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon , fShuffle(shuffle) 75b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon , fIndices(nullptr) { 76b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon float imagesOverBudget = float(kImagesToDraw) / budgetSize; 77b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // Make the benchmark name contain the percentage of the budget that is used in each 78b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // simulated frame. 79b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon fName.printf("image_cache_budget_%.0f%s", imagesOverBudget * 100, 80b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon (shuffle ? "_shuffle" : "")); 81b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 82b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 83b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon bool isSuitableFor(Backend backend) override { return kGPU_Backend == backend; } 84b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 85b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonprotected: 86b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon const char* onGetName() override { 87b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon return fName.c_str(); 88b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 89b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 90b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon void onPerCanvasPreDraw(SkCanvas* canvas) override { 91b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon GrContext* context = canvas->getGrContext(); 92b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkASSERT(context); 93b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->getResourceCacheLimits(&fOldCount, &fOldBytes); 94b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon set_cache_budget(canvas, fBudgetSize); 95b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon make_images(fImages, kImagesToDraw); 96b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon if (fShuffle) { 97b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkRandom random; 98b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon fIndices.reset(new int[kSimulatedFrames * kImagesToDraw]); 99b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int frame = 0; frame < kSimulatedFrames; ++frame) { 100b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int* base = fIndices.get() + frame * kImagesToDraw; 101b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int i = 0; i < kImagesToDraw; ++i) { 102b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon base[i] = i; 103b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 104b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int i = 0; i < kImagesToDraw - 1; ++i) { 105b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int other = random.nextULessThan(kImagesToDraw - i) + i; 106b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkTSwap(base[i], base[other]); 107b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 108b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 109b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 110b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 111b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 112b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon void onPerCanvasPostDraw(SkCanvas* canvas) override { 113b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon GrContext* context = canvas->getGrContext(); 114b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkASSERT(context); 115b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->setResourceCacheLimits(fOldCount, fOldBytes); 116b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int i = 0; i < kImagesToDraw; ++i) { 117b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon fImages[i].reset(); 118b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 119b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon fIndices.reset(nullptr); 120b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 121b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 122b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon void onDraw(int loops, SkCanvas* canvas) override { 123b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int i = 0; i < loops; ++i) { 124b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int frame = 0; frame < kSimulatedFrames; ++frame) { 125b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int j = 0; j < kImagesToDraw; ++j) { 126b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int idx; 127b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon if (fShuffle) { 128b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon idx = fIndices[frame * kImagesToDraw + j]; 129b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } else { 130b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon idx = j; 131b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 132b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon draw_image(canvas, fImages[idx].get()); 133b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 134b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // Simulate a frame boundary by flushing. This should notify GrResourceCache. 135b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon canvas->flush(); 136b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 137b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 138b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 139b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 140b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonprivate: 141b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon static constexpr int kImagesToDraw = 100; 142b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon static constexpr int kSimulatedFrames = 5; 143b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 144b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int fBudgetSize; 145b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon bool fShuffle; 146b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkString fName; 147b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon sk_sp<SkImage> fImages[kImagesToDraw]; 1487ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner std::unique_ptr<int[]> fIndices; 149b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon size_t fOldBytes; 150b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int fOldCount; 151b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 152b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon typedef Benchmark INHERITED; 153b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon}; 154b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 155b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetBench(105, false); ) 156b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 157b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetBench(90, false); ) 158b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 159b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetBench(80, false); ) 160b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 161b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetBench(50, false); ) 162b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 163b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetBench(105, true); ) 164b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 165b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetBench(90, true); ) 166b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 167b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetBench(80, true); ) 168b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 169b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetBench(50, true); ) 170b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 171b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon////////////////////////////////////////////////////////////////////////////// 172b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 173b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon/** 174b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * Similar to above but changes between being over and under budget by varying the number of images 175b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon * rendered. This is not directly comparable to the non-dynamic benchmarks. 176b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon */ 177b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonclass ImageCacheBudgetDynamicBench : public Benchmark { 178b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonpublic: 179b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon enum class Mode { 180b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // Increase from min to max images drawn gradually over simulated frames and then back. 181b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon kPingPong, 182b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // Alternate between under and over budget every other simulated frame. 183b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon kFlipFlop 184b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon }; 185b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 186b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon ImageCacheBudgetDynamicBench(Mode mode) : fMode(mode) {} 187b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 188b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon bool isSuitableFor(Backend backend) override { return kGPU_Backend == backend; } 189b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 190b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonprotected: 191b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon const char* onGetName() override { 192b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon switch (fMode) { 193b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon case Mode::kPingPong: 194b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon return "image_cache_budget_dynamic_ping_pong"; 195b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon case Mode::kFlipFlop: 196b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon return "image_cache_budget_dynamic_flip_flop"; 197b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 198b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon return ""; 199b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 200b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 201b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon void onPerCanvasPreDraw(SkCanvas* canvas) override { 202b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon GrContext* context = canvas->getGrContext(); 203b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkASSERT(context); 204b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->getResourceCacheLimits(&fOldCount, &fOldBytes); 205b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon make_images(fImages, kMaxImagesToDraw); 206b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon set_cache_budget(canvas, kImagesInBudget); 207b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 208b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 209b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon void onPerCanvasPostDraw(SkCanvas* canvas) override { 210b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon GrContext* context = canvas->getGrContext(); 211b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon SkASSERT(context); 212b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon context->setResourceCacheLimits(fOldCount, fOldBytes); 213b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int i = 0; i < kMaxImagesToDraw; ++i) { 214b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon fImages[i].reset(); 215b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 216b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 217b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 218b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon void onDraw(int loops, SkCanvas* canvas) override { 219b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int delta = 0; 220b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon switch (fMode) { 221b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon case Mode::kPingPong: 222b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon delta = 1; 223b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon break; 224b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon case Mode::kFlipFlop: 225b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon delta = kMaxImagesToDraw - kMinImagesToDraw; 226b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon break; 227b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 228b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int i = 0; i < loops; ++i) { 229b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int imgsToDraw = kMinImagesToDraw; 230b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int frame = 0; frame < kSimulatedFrames; ++frame) { 231b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon for (int j = 0; j < imgsToDraw; ++j) { 232b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon draw_image(canvas, fImages[j].get()); 233b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 234b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon imgsToDraw += delta; 235b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon if (imgsToDraw > kMaxImagesToDraw || imgsToDraw < kMinImagesToDraw) { 236b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon delta = -delta; 237b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon imgsToDraw += 2 * delta; 238b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 239b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon // Simulate a frame boundary by flushing. This should notify GrResourceCache. 240b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon canvas->flush(); 241b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 242b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 243b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon } 244b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 245b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonprivate: 246b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon static constexpr int kImagesInBudget = 25; 247b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon static constexpr int kMinImagesToDraw = 15; 248b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon static constexpr int kMaxImagesToDraw = 35; 249b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon static constexpr int kSimulatedFrames = 80; 250b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 251b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon Mode fMode; 252b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon sk_sp<SkImage> fImages[kMaxImagesToDraw]; 253b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon size_t fOldBytes; 254b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon int fOldCount; 255b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 256b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon typedef Benchmark INHERITED; 257b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon}; 258b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomon 259b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetDynamicBench(ImageCacheBudgetDynamicBench::Mode::kPingPong); ) 260b3cb2142725f9d0cd88a7200770536bc21f73b14bsalomonDEF_BENCH( return new ImageCacheBudgetDynamicBench(ImageCacheBudgetDynamicBench::Mode::kFlipFlop); ) 2619f1f6e2c28066c7d7ff26727ce7d7504c7d032bdbrianosman 2629f1f6e2c28066c7d7ff26727ce7d7504c7d032bdbrianosman#endif 263