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