1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2019 Google LLC 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/SkBitmap.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkCanvasPriv.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCanvas.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrOpsTypes.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SkGr.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceDrawContext.h" 21*c8dee2aaSAndroid Build Coastguard Worker 22*c8dee2aaSAndroid Build Coastguard Worker // Benchmarks that exercise the bulk image and solid color quad APIs, under a variety of patterns: 23*c8dee2aaSAndroid Build Coastguard Worker enum class ImageMode { 24*c8dee2aaSAndroid Build Coastguard Worker kShared, // 1. One shared image referenced by every rectangle 25*c8dee2aaSAndroid Build Coastguard Worker kUnique, // 2. Unique image for every rectangle 26*c8dee2aaSAndroid Build Coastguard Worker kNone // 3. No image, solid color shading per rectangle 27*c8dee2aaSAndroid Build Coastguard Worker }; 28*c8dee2aaSAndroid Build Coastguard Worker // X 29*c8dee2aaSAndroid Build Coastguard Worker enum class DrawMode { 30*c8dee2aaSAndroid Build Coastguard Worker kBatch, // Bulk API submission, one call to draw every rectangle 31*c8dee2aaSAndroid Build Coastguard Worker kRef, // One standard SkCanvas draw call per rectangle 32*c8dee2aaSAndroid Build Coastguard Worker kQuad // One experimental draw call per rectangle, only for solid color draws 33*c8dee2aaSAndroid Build Coastguard Worker }; 34*c8dee2aaSAndroid Build Coastguard Worker // X 35*c8dee2aaSAndroid Build Coastguard Worker enum class RectangleLayout { 36*c8dee2aaSAndroid Build Coastguard Worker kRandom, // Random overlapping rectangles 37*c8dee2aaSAndroid Build Coastguard Worker kGrid // Small, non-overlapping rectangles in a grid covering the output surface 38*c8dee2aaSAndroid Build Coastguard Worker }; 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker // Benchmark runner that can be configured by template arguments. 41*c8dee2aaSAndroid Build Coastguard Worker template<int kRectCount, RectangleLayout kLayout, ImageMode kImageMode, DrawMode kDrawMode> 42*c8dee2aaSAndroid Build Coastguard Worker class BulkRectBench : public Benchmark { 43*c8dee2aaSAndroid Build Coastguard Worker public: 44*c8dee2aaSAndroid Build Coastguard Worker static_assert(kImageMode == ImageMode::kNone || kDrawMode != DrawMode::kQuad, 45*c8dee2aaSAndroid Build Coastguard Worker "kQuad only supported for solid color draws"); 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr int kWidth = 1024; 48*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr int kHeight = 1024; 49*c8dee2aaSAndroid Build Coastguard Worker 50*c8dee2aaSAndroid Build Coastguard Worker // There will either be 0 images, 1 image, or 1 image per rect 51*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr int kImageCount = kImageMode == ImageMode::kShared ? 52*c8dee2aaSAndroid Build Coastguard Worker 1 : (kImageMode == ImageMode::kNone ? 0 : kRectCount); 53*c8dee2aaSAndroid Build Coastguard Worker isSuitableFor(Backend backend)54*c8dee2aaSAndroid Build Coastguard Worker bool isSuitableFor(Backend backend) override { 55*c8dee2aaSAndroid Build Coastguard Worker if (kDrawMode == DrawMode::kBatch && kImageMode == ImageMode::kNone) { 56*c8dee2aaSAndroid Build Coastguard Worker // Currently the bulk color quad API is only available on 57*c8dee2aaSAndroid Build Coastguard Worker // skgpu::ganesh::SurfaceDrawContext 58*c8dee2aaSAndroid Build Coastguard Worker return backend == Backend::kGanesh; 59*c8dee2aaSAndroid Build Coastguard Worker } else { 60*c8dee2aaSAndroid Build Coastguard Worker return this->INHERITED::isSuitableFor(backend); 61*c8dee2aaSAndroid Build Coastguard Worker } 62*c8dee2aaSAndroid Build Coastguard Worker } 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker protected: 65*c8dee2aaSAndroid Build Coastguard Worker SkRect fRects[kRectCount]; 66*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> fImages[kImageCount > 0 ? kImageCount : 1]; 67*c8dee2aaSAndroid Build Coastguard Worker SkColor4f fColors[kRectCount]; 68*c8dee2aaSAndroid Build Coastguard Worker SkString fName; 69*c8dee2aaSAndroid Build Coastguard Worker computeName()70*c8dee2aaSAndroid Build Coastguard Worker void computeName() { 71*c8dee2aaSAndroid Build Coastguard Worker fName = "bulkrect"; 72*c8dee2aaSAndroid Build Coastguard Worker fName.appendf("_%d", kRectCount); 73*c8dee2aaSAndroid Build Coastguard Worker if (kLayout == RectangleLayout::kRandom) { 74*c8dee2aaSAndroid Build Coastguard Worker fName.append("_random"); 75*c8dee2aaSAndroid Build Coastguard Worker } else { 76*c8dee2aaSAndroid Build Coastguard Worker fName.append("_grid"); 77*c8dee2aaSAndroid Build Coastguard Worker } 78*c8dee2aaSAndroid Build Coastguard Worker if (kImageMode == ImageMode::kShared) { 79*c8dee2aaSAndroid Build Coastguard Worker fName.append("_sharedimage"); 80*c8dee2aaSAndroid Build Coastguard Worker } else if (kImageMode == ImageMode::kUnique) { 81*c8dee2aaSAndroid Build Coastguard Worker fName.append("_uniqueimages"); 82*c8dee2aaSAndroid Build Coastguard Worker } else { 83*c8dee2aaSAndroid Build Coastguard Worker fName.append("_solidcolor"); 84*c8dee2aaSAndroid Build Coastguard Worker } 85*c8dee2aaSAndroid Build Coastguard Worker if (kDrawMode == DrawMode::kBatch) { 86*c8dee2aaSAndroid Build Coastguard Worker fName.append("_batch"); 87*c8dee2aaSAndroid Build Coastguard Worker } else if (kDrawMode == DrawMode::kRef) { 88*c8dee2aaSAndroid Build Coastguard Worker fName.append("_ref"); 89*c8dee2aaSAndroid Build Coastguard Worker } else { 90*c8dee2aaSAndroid Build Coastguard Worker fName.append("_quad"); 91*c8dee2aaSAndroid Build Coastguard Worker } 92*c8dee2aaSAndroid Build Coastguard Worker } 93*c8dee2aaSAndroid Build Coastguard Worker drawImagesBatch(SkCanvas * canvas) const94*c8dee2aaSAndroid Build Coastguard Worker void drawImagesBatch(SkCanvas* canvas) const { 95*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(kImageMode != ImageMode::kNone); 96*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(kDrawMode == DrawMode::kBatch); 97*c8dee2aaSAndroid Build Coastguard Worker 98*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::ImageSetEntry batch[kRectCount]; 99*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kRectCount; ++i) { 100*c8dee2aaSAndroid Build Coastguard Worker int imageIndex = kImageMode == ImageMode::kShared ? 0 : i; 101*c8dee2aaSAndroid Build Coastguard Worker batch[i].fImage = fImages[imageIndex]; 102*c8dee2aaSAndroid Build Coastguard Worker batch[i].fSrcRect = SkRect::MakeIWH(fImages[imageIndex]->width(), 103*c8dee2aaSAndroid Build Coastguard Worker fImages[imageIndex]->height()); 104*c8dee2aaSAndroid Build Coastguard Worker batch[i].fDstRect = fRects[i]; 105*c8dee2aaSAndroid Build Coastguard Worker batch[i].fAAFlags = SkCanvas::kAll_QuadAAFlags; 106*c8dee2aaSAndroid Build Coastguard Worker } 107*c8dee2aaSAndroid Build Coastguard Worker 108*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 109*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 110*c8dee2aaSAndroid Build Coastguard Worker 111*c8dee2aaSAndroid Build Coastguard Worker canvas->experimental_DrawEdgeAAImageSet(batch, kRectCount, nullptr, nullptr, 112*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions(SkFilterMode::kLinear), &paint, 113*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::kFast_SrcRectConstraint); 114*c8dee2aaSAndroid Build Coastguard Worker } 115*c8dee2aaSAndroid Build Coastguard Worker drawImagesRef(SkCanvas * canvas) const116*c8dee2aaSAndroid Build Coastguard Worker void drawImagesRef(SkCanvas* canvas) const { 117*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(kImageMode != ImageMode::kNone); 118*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(kDrawMode == DrawMode::kRef); 119*c8dee2aaSAndroid Build Coastguard Worker 120*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 121*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 122*c8dee2aaSAndroid Build Coastguard Worker 123*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kRectCount; ++i) { 124*c8dee2aaSAndroid Build Coastguard Worker int imageIndex = kImageMode == ImageMode::kShared ? 0 : i; 125*c8dee2aaSAndroid Build Coastguard Worker SkRect srcRect = SkRect::MakeIWH(fImages[imageIndex]->width(), 126*c8dee2aaSAndroid Build Coastguard Worker fImages[imageIndex]->height()); 127*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImageRect(fImages[imageIndex].get(), srcRect, fRects[i], 128*c8dee2aaSAndroid Build Coastguard Worker SkSamplingOptions(SkFilterMode::kLinear), &paint, 129*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::kFast_SrcRectConstraint); 130*c8dee2aaSAndroid Build Coastguard Worker } 131*c8dee2aaSAndroid Build Coastguard Worker } 132*c8dee2aaSAndroid Build Coastguard Worker drawSolidColorsBatch(SkCanvas * canvas) const133*c8dee2aaSAndroid Build Coastguard Worker void drawSolidColorsBatch(SkCanvas* canvas) const { 134*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(kImageMode == ImageMode::kNone); 135*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(kDrawMode == DrawMode::kBatch); 136*c8dee2aaSAndroid Build Coastguard Worker 137*c8dee2aaSAndroid Build Coastguard Worker auto context = canvas->recordingContext(); 138*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(context); 139*c8dee2aaSAndroid Build Coastguard Worker 140*c8dee2aaSAndroid Build Coastguard Worker GrQuadSetEntry batch[kRectCount]; 141*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kRectCount; ++i) { 142*c8dee2aaSAndroid Build Coastguard Worker batch[i].fRect = fRects[i]; 143*c8dee2aaSAndroid Build Coastguard Worker batch[i].fColor = fColors[i].premul(); 144*c8dee2aaSAndroid Build Coastguard Worker batch[i].fLocalMatrix = SkMatrix::I(); 145*c8dee2aaSAndroid Build Coastguard Worker batch[i].fAAFlags = GrQuadAAFlags::kAll; 146*c8dee2aaSAndroid Build Coastguard Worker } 147*c8dee2aaSAndroid Build Coastguard Worker 148*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 149*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorWHITE); 150*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 151*c8dee2aaSAndroid Build Coastguard Worker 152*c8dee2aaSAndroid Build Coastguard Worker auto sdc = skgpu::ganesh::TopDeviceSurfaceDrawContext(canvas); 153*c8dee2aaSAndroid Build Coastguard Worker SkMatrix view = canvas->getLocalToDeviceAs3x3(); 154*c8dee2aaSAndroid Build Coastguard Worker SkSurfaceProps props; 155*c8dee2aaSAndroid Build Coastguard Worker GrPaint grPaint; 156*c8dee2aaSAndroid Build Coastguard Worker SkPaintToGrPaint(context, sdc->colorInfo(), paint, view, props, &grPaint); 157*c8dee2aaSAndroid Build Coastguard Worker sdc->drawQuadSet(nullptr, std::move(grPaint), view, batch, kRectCount); 158*c8dee2aaSAndroid Build Coastguard Worker } 159*c8dee2aaSAndroid Build Coastguard Worker drawSolidColorsRef(SkCanvas * canvas) const160*c8dee2aaSAndroid Build Coastguard Worker void drawSolidColorsRef(SkCanvas* canvas) const { 161*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(kImageMode == ImageMode::kNone); 162*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(kDrawMode == DrawMode::kRef || kDrawMode == DrawMode::kQuad); 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 165*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 166*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kRectCount; ++i) { 167*c8dee2aaSAndroid Build Coastguard Worker if (kDrawMode == DrawMode::kRef) { 168*c8dee2aaSAndroid Build Coastguard Worker paint.setColor4f(fColors[i]); 169*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(fRects[i], paint); 170*c8dee2aaSAndroid Build Coastguard Worker } else { 171*c8dee2aaSAndroid Build Coastguard Worker canvas->experimental_DrawEdgeAAQuad(fRects[i], nullptr, SkCanvas::kAll_QuadAAFlags, 172*c8dee2aaSAndroid Build Coastguard Worker fColors[i], SkBlendMode::kSrcOver); 173*c8dee2aaSAndroid Build Coastguard Worker } 174*c8dee2aaSAndroid Build Coastguard Worker } 175*c8dee2aaSAndroid Build Coastguard Worker } 176*c8dee2aaSAndroid Build Coastguard Worker onGetName()177*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override { 178*c8dee2aaSAndroid Build Coastguard Worker if (fName.isEmpty()) { 179*c8dee2aaSAndroid Build Coastguard Worker this->computeName(); 180*c8dee2aaSAndroid Build Coastguard Worker } 181*c8dee2aaSAndroid Build Coastguard Worker return fName.c_str(); 182*c8dee2aaSAndroid Build Coastguard Worker } 183*c8dee2aaSAndroid Build Coastguard Worker onDelayedSetup()184*c8dee2aaSAndroid Build Coastguard Worker void onDelayedSetup() override { 185*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kMinRectSize = 0.2f; 186*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kMaxRectSize = 300.f; 187*c8dee2aaSAndroid Build Coastguard Worker 188*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand; 189*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kRectCount; i++) { 190*c8dee2aaSAndroid Build Coastguard Worker if (kLayout == RectangleLayout::kRandom) { 191*c8dee2aaSAndroid Build Coastguard Worker SkScalar w = rand.nextF() * (kMaxRectSize - kMinRectSize) + kMinRectSize; 192*c8dee2aaSAndroid Build Coastguard Worker SkScalar h = rand.nextF() * (kMaxRectSize - kMinRectSize) + kMinRectSize; 193*c8dee2aaSAndroid Build Coastguard Worker 194*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = rand.nextF() * (kWidth - w); 195*c8dee2aaSAndroid Build Coastguard Worker SkScalar y = rand.nextF() * (kHeight - h); 196*c8dee2aaSAndroid Build Coastguard Worker 197*c8dee2aaSAndroid Build Coastguard Worker fRects[i].setXYWH(x, y, w, h); 198*c8dee2aaSAndroid Build Coastguard Worker } else { 199*c8dee2aaSAndroid Build Coastguard Worker int gridSize = SkScalarCeilToInt(SkScalarSqrt(kRectCount)); 200*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(gridSize * gridSize >= kRectCount); 201*c8dee2aaSAndroid Build Coastguard Worker 202*c8dee2aaSAndroid Build Coastguard Worker SkScalar w = (kWidth - 1.f) / gridSize; 203*c8dee2aaSAndroid Build Coastguard Worker SkScalar h = (kHeight - 1.f) / gridSize; 204*c8dee2aaSAndroid Build Coastguard Worker 205*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = (i % gridSize) * w + 0.5f; // Offset to ensure AA doesn't get disabled 206*c8dee2aaSAndroid Build Coastguard Worker SkScalar y = (i / gridSize) * h + 0.5f; 207*c8dee2aaSAndroid Build Coastguard Worker 208*c8dee2aaSAndroid Build Coastguard Worker fRects[i].setXYWH(x, y, w, h); 209*c8dee2aaSAndroid Build Coastguard Worker } 210*c8dee2aaSAndroid Build Coastguard Worker 211*c8dee2aaSAndroid Build Coastguard Worker // Make sure we don't extend outside the render target, don't want to include clipping 212*c8dee2aaSAndroid Build Coastguard Worker // in the benchmark. 213*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(SkRect::MakeWH(kWidth, kHeight).contains(fRects[i])); 214*c8dee2aaSAndroid Build Coastguard Worker 215*c8dee2aaSAndroid Build Coastguard Worker fColors[i] = {rand.nextF(), rand.nextF(), rand.nextF(), 1.f}; 216*c8dee2aaSAndroid Build Coastguard Worker } 217*c8dee2aaSAndroid Build Coastguard Worker } 218*c8dee2aaSAndroid Build Coastguard Worker onPerCanvasPreDraw(SkCanvas * canvas)219*c8dee2aaSAndroid Build Coastguard Worker void onPerCanvasPreDraw(SkCanvas* canvas) override { 220*c8dee2aaSAndroid Build Coastguard Worker // Push the skimages to the GPU when using the GPU backend so that the texture creation is 221*c8dee2aaSAndroid Build Coastguard Worker // not part of the bench measurements. Always remake the images since they are so simple, 222*c8dee2aaSAndroid Build Coastguard Worker // and since they are context-specific, this works when the bench runs multiple GPU backends 223*c8dee2aaSAndroid Build Coastguard Worker auto direct = GrAsDirectContext(canvas->recordingContext()); 224*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kImageCount; ++i) { 225*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bm; 226*c8dee2aaSAndroid Build Coastguard Worker bm.allocN32Pixels(256, 256); 227*c8dee2aaSAndroid Build Coastguard Worker bm.eraseColor(fColors[i].toSkColor()); 228*c8dee2aaSAndroid Build Coastguard Worker auto image = bm.asImage(); 229*c8dee2aaSAndroid Build Coastguard Worker 230*c8dee2aaSAndroid Build Coastguard Worker if (direct) { 231*c8dee2aaSAndroid Build Coastguard Worker fImages[i] = SkImages::TextureFromImage(direct, image); 232*c8dee2aaSAndroid Build Coastguard Worker } else { 233*c8dee2aaSAndroid Build Coastguard Worker fImages[i] = std::move(image); 234*c8dee2aaSAndroid Build Coastguard Worker } 235*c8dee2aaSAndroid Build Coastguard Worker } 236*c8dee2aaSAndroid Build Coastguard Worker } 237*c8dee2aaSAndroid Build Coastguard Worker onPerCanvasPostDraw(SkCanvas * canvas)238*c8dee2aaSAndroid Build Coastguard Worker void onPerCanvasPostDraw(SkCanvas* canvas) override { 239*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kImageCount; ++i) { 240*c8dee2aaSAndroid Build Coastguard Worker // For Vulkan we need to make sure the bench isn't holding onto any refs to the 241*c8dee2aaSAndroid Build Coastguard Worker // GrContext when we go to delete the vulkan context (which happens before the bench is 242*c8dee2aaSAndroid Build Coastguard Worker // deleted). So reset all the images here so they aren't holding GrContext refs. 243*c8dee2aaSAndroid Build Coastguard Worker fImages[i].reset(); 244*c8dee2aaSAndroid Build Coastguard Worker } 245*c8dee2aaSAndroid Build Coastguard Worker } 246*c8dee2aaSAndroid Build Coastguard Worker onDraw(int loops,SkCanvas * canvas)247*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas* canvas) override { 248*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; i++) { 249*c8dee2aaSAndroid Build Coastguard Worker if (kImageMode == ImageMode::kNone) { 250*c8dee2aaSAndroid Build Coastguard Worker if (kDrawMode == DrawMode::kBatch) { 251*c8dee2aaSAndroid Build Coastguard Worker this->drawSolidColorsBatch(canvas); 252*c8dee2aaSAndroid Build Coastguard Worker } else { 253*c8dee2aaSAndroid Build Coastguard Worker this->drawSolidColorsRef(canvas); 254*c8dee2aaSAndroid Build Coastguard Worker } 255*c8dee2aaSAndroid Build Coastguard Worker } else { 256*c8dee2aaSAndroid Build Coastguard Worker if (kDrawMode == DrawMode::kBatch) { 257*c8dee2aaSAndroid Build Coastguard Worker this->drawImagesBatch(canvas); 258*c8dee2aaSAndroid Build Coastguard Worker } else { 259*c8dee2aaSAndroid Build Coastguard Worker this->drawImagesRef(canvas); 260*c8dee2aaSAndroid Build Coastguard Worker } 261*c8dee2aaSAndroid Build Coastguard Worker } 262*c8dee2aaSAndroid Build Coastguard Worker } 263*c8dee2aaSAndroid Build Coastguard Worker } 264*c8dee2aaSAndroid Build Coastguard Worker onGetSize()265*c8dee2aaSAndroid Build Coastguard Worker SkISize onGetSize() override { 266*c8dee2aaSAndroid Build Coastguard Worker return { kWidth, kHeight }; 267*c8dee2aaSAndroid Build Coastguard Worker } 268*c8dee2aaSAndroid Build Coastguard Worker 269*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark; 270*c8dee2aaSAndroid Build Coastguard Worker }; 271*c8dee2aaSAndroid Build Coastguard Worker 272*c8dee2aaSAndroid Build Coastguard Worker // constructor call is wrapped in () so the macro doesn't break parsing the commas in the template 273*c8dee2aaSAndroid Build Coastguard Worker #define ADD_BENCH(n, layout, imageMode, drawMode) \ 274*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return (new BulkRectBench<n, layout, imageMode, drawMode>()); ) 275*c8dee2aaSAndroid Build Coastguard Worker 276*c8dee2aaSAndroid Build Coastguard Worker #define ADD_BENCH_FAMILY(n, layout) \ 277*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH(n, layout, ImageMode::kShared, DrawMode::kBatch) \ 278*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH(n, layout, ImageMode::kShared, DrawMode::kRef) \ 279*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH(n, layout, ImageMode::kUnique, DrawMode::kBatch) \ 280*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH(n, layout, ImageMode::kUnique, DrawMode::kRef) \ 281*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH(n, layout, ImageMode::kNone, DrawMode::kBatch) \ 282*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH(n, layout, ImageMode::kNone, DrawMode::kRef) \ 283*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH(n, layout, ImageMode::kNone, DrawMode::kQuad) 284*c8dee2aaSAndroid Build Coastguard Worker 285*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH_FAMILY(1000, RectangleLayout::kRandom) 286*c8dee2aaSAndroid Build Coastguard Worker ADD_BENCH_FAMILY(1000, RectangleLayout::kGrid) 287*c8dee2aaSAndroid Build Coastguard Worker 288*c8dee2aaSAndroid Build Coastguard Worker #undef ADD_BENCH_FAMILY 289*c8dee2aaSAndroid Build Coastguard Worker #undef ADD_BENCH 290