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