14a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton/* 24a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton * Copyright 2016 Google Inc. 34a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton * 44a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton * Use of this source code is governed by a BSD-style license that can be 54a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton * found in the LICENSE file. 64a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton */ 74a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 84a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include "Benchmark.h" 94a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include "SkCanvas.h" 104a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include "SkCommandLineFlags.h" 114a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include "SkPaint.h" 124a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include "SkRandom.h" 134a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include "SkRRect.h" 144a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include "SkString.h" 154a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include <stdio.h> 164a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include <stdlib.h> 174a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#include <functional> 184a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 194a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#define ENABLE_COMMAND_LINE_SHAPES_BENCH 0 204a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 214a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#if ENABLE_COMMAND_LINE_SHAPES_BENCH 224a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEFINE_string(shapesType, "mixed", "Type of shape to use in ShapesBench. Must be one of: " 234a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton "rect, oval, rrect, mixed."); 244a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEFINE_string(innerShapesType, "none", "Type of inner shape to use in ShapesBench. Must be one of: " 254a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton "none, rect, oval, rrect, mixed."); 264a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEFINE_int32(numShapes, 10000, "Number of shapes to draw in ShapesBench."); 274a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEFINE_string(shapesSize, "32x32", "Size of shapes to draw in ShapesBench."); 284a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEFINE_bool(shapesPersp, false, "Use slight perspective tilt in ShapesBench?"); 294a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#endif 304a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 314a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton/* 324a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton * This class is used for several benchmarks that draw different primitive Skia shapes at various 334a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton * sizes. It is used to test both CPU-bound and GPU-bound rendering situations. It draws large 344a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton * amounts of shapes internally (rather than relying on nanobench selecting lots of loops) in order 354a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton * to take advantage of instanced rendering approaches. 364a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton */ 374a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonclass ShapesBench : public Benchmark { 384a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonpublic: 394a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton enum ShapesType { 404a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton kNone_ShapesType, 414a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton kRect_ShapesType, 424a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton kOval_ShapesType, 434a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton kRRect_ShapesType, 444a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton kMixed_ShapesType 454a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton }; 464a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 474a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton ShapesBench(ShapesType shapesType, ShapesType innerShapesType, 484a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton int numShapes, const SkISize& shapesSize, bool perspective) 494a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton : fShapesType(shapesType) 504a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton , fInnerShapesType(innerShapesType) 514a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton , fNumShapes(numShapes) 524a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton , fShapesSize(shapesSize) 534a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton , fPerspective(perspective) { 544a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton clampShapeSize(); 554a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 564a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 574a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#if ENABLE_COMMAND_LINE_SHAPES_BENCH 584a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton ShapesBench() { 594a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (!strcmp(FLAGS_shapesType[0], "rect")) { 604a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapesType = kRect_ShapesType; 614a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else if (!strcmp(FLAGS_shapesType[0], "oval")) { 624a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapesType = kOval_ShapesType; 634a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else if (!strcmp(FLAGS_shapesType[0], "rrect")) { 644a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapesType = kRRect_ShapesType; 654a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else if (!strcmp(FLAGS_shapesType[0], "mixed")) { 664a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapesType = kMixed_ShapesType; 674a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else { 684a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkDebugf("Invalid shapesType \"%s\". Must be one of: rect, oval, rrect, mixed.", 694a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton FLAGS_shapesType[0]); 704a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton exit(-1); 714a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 724a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (!strcmp(FLAGS_innerShapesType[0], "none")) { 734a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fInnerShapesType = kNone_ShapesType; 744a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else if (!strcmp(FLAGS_innerShapesType[0], "rect")) { 754a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fInnerShapesType = kRect_ShapesType; 764a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else if (!strcmp(FLAGS_innerShapesType[0], "oval")) { 774a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fInnerShapesType = kOval_ShapesType; 784a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else if (!strcmp(FLAGS_innerShapesType[0], "rrect")) { 794a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fInnerShapesType = kRRect_ShapesType; 804a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else if (!strcmp(FLAGS_innerShapesType[0], "mixed")) { 814a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fInnerShapesType = kMixed_ShapesType; 824a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else { 834a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkDebugf("Invalid innerShapesType \"%s\". Must be one of: " 844a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton "none, rect, oval, rrect, mixed.", FLAGS_innerShapesType[0]); 854a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton exit(-1); 864a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 874a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (2 != sscanf(FLAGS_shapesSize[0], "%ix%i", &fShapesSize.fWidth, &fShapesSize.fHeight)) { 884a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkDebugf("Could not parse shapesSize from \"%s\". Expected \"%%ix%%i\"\n", 894a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton FLAGS_shapesSize[0]); 904a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton exit(-1); 914a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 924a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 934a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fNumShapes = FLAGS_numShapes; 944a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fPerspective = FLAGS_shapesPersp; 954a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 964a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton clampShapeSize(); 974a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 984a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#endif 994a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1004a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton bool isVisual() override { return true; } 1014a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1024a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonprivate: 1034a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton void clampShapeSize() { 1044a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton float maxDiagonal = static_cast<float>(SkTMin(kBenchWidth, kBenchHeight)); 1054a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton float diagonal = sqrtf(static_cast<float>(fShapesSize.width() * fShapesSize.width()) + 1064a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton static_cast<float>(fShapesSize.height() * fShapesSize.height())); 1074a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (diagonal > maxDiagonal) { 1084a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapesSize.fWidth = static_cast<int>(fShapesSize.width() * maxDiagonal / diagonal); 1094a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapesSize.fHeight = static_cast<int>(fShapesSize.height() * maxDiagonal / diagonal); 1104a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1114a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1124a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1134a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton const char* onGetName() override { 1144a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton const char* shapeTypeNames[] = { 1154a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton "none", "rect", "oval", "rrect", "mixed" 1164a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton }; 1174a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1184a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fName.printf("shapes_%s", shapeTypeNames[fShapesType]); 1194a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1204a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (kNone_ShapesType != fInnerShapesType) { 1214a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fName.appendf("_inner_%s", shapeTypeNames[fInnerShapesType]); 1224a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1234a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1244a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fName.appendf("_%i_%ix%i", fNumShapes, fShapesSize.width(), fShapesSize.height()); 1254a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1264a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (fPerspective) { 1274a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fName.append("_persp"); 1284a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1294a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1304a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton return fName.c_str(); 1314a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1324a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkIPoint onGetSize() override { return SkIPoint::Make(kBenchWidth, kBenchHeight); } 1334a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1344a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton void onDelayedSetup() override { 1354a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkScalar w = SkIntToScalar(fShapesSize.width()); 1364a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkScalar h = SkIntToScalar(fShapesSize.height()); 1374a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1384a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fRect.setRect(SkRect::MakeXYWH(-w / 2, -h / 2, w, h)); 1394a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fOval.setOval(fRect.rect()); 1404a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fRRect.setNinePatch(fRect.rect(), w / 8, h / 13, w / 11, h / 7); 1414a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1424a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (kNone_ShapesType != fInnerShapesType) { 1434a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fRect.inset(w / 7, h / 11, &fInnerRect); 1444a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fInnerRect.offset(w / 28, h / 44); 1454a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fInnerOval.setOval(fInnerRect.rect()); 1464a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fInnerRRect.setRectXY(fInnerRect.rect(), w / 13, w / 7); 1474a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1484a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 1494a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkRandom rand; 1504a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes.push_back_n(fNumShapes); 1514a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton for (int i = 0; i < fNumShapes; i++) { 1524a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton float pad = sqrtf(static_cast<float>(fShapesSize.width() * fShapesSize.width()) + 1534a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton static_cast<float>(fShapesSize.height() * fShapesSize.height())); 1544a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fMatrix.setTranslate(0.5f * pad + rand.nextF() * (kBenchWidth - pad), 1554a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 0.5f * pad + rand.nextF() * (kBenchHeight - pad)); 1564a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fMatrix.preRotate(rand.nextF() * 360.0f); 1574a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (fPerspective) { 1584a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fMatrix.setPerspX(0.00015f); 1594a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fMatrix.setPerspY(-0.00015f); 1604a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1614a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fColor = rand.nextU() | 0xff808080; 1624a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1634a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton for (int i = 0; i < fNumShapes; i++) { 1644a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton // Do this in a separate loop so mixed shapes get the same random numbers during 1654a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton // placement as non-mixed do. 1664a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton int shapeType = fShapesType; 1674a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (kMixed_ShapesType == shapeType) { 1684a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton shapeType = rand.nextRangeU(kRect_ShapesType, kRRect_ShapesType); 1694a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1704a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton int innerShapeType = fInnerShapesType; 1714a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (kMixed_ShapesType == innerShapeType) { 1724a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton innerShapeType = rand.nextRangeU(kRect_ShapesType, kRRect_ShapesType); 1734a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1744a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton if (kNone_ShapesType == innerShapeType) { 1754a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton switch (shapeType) { 1764a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton using namespace std; 1774a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton using namespace std::placeholders; 1784a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kRect_ShapesType: 1794a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fDraw = bind(&SkCanvas::drawRect, _1, cref(fRect.rect()), _2); 1804a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton break; 1814a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kOval_ShapesType: 1824a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fDraw = bind(&SkCanvas::drawOval, _1, cref(fOval.rect()), _2); 1834a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton break; 1844a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kRRect_ShapesType: 1854a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fDraw = bind(&SkCanvas::drawRRect, _1, cref(fRRect), _2); 1864a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton break; 1874a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1884a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } else { 1894a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton const SkRRect* outer; 1904a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton switch (shapeType) { 1914a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kRect_ShapesType: outer = &fRect; break; 1924a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kOval_ShapesType: outer = &fOval; break; 1934a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kRRect_ShapesType: outer = &fRRect; break; 1944a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 1954a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton const SkRRect* inner; 1964a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton switch (innerShapeType) { 1974a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kRect_ShapesType: inner = &fInnerRect; break; 1984a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kOval_ShapesType: inner = &fInnerOval; break; 1994a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton case kRRect_ShapesType: inner = &fInnerRRect; break; 2004a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 2014a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fDraw = std::bind(&SkCanvas::drawDRRect, std::placeholders::_1, 2024a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton std::cref(*outer), std::cref(*inner), 2034a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton std::placeholders::_2); 2044a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 2054a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 2064a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 2074a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 2084a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton void onDraw(int loops, SkCanvas* canvas) override { 2094a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkPaint paint; 2104a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton this->setupPaint(&paint); 2114a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton for (int j = 0; j < loops; j++) { 2124a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton for (int i = 0; i < fNumShapes; i++) { 2134a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton canvas->save(); 2144a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton canvas->setMatrix(fShapes[i].fMatrix); 2154a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton paint.setColor(fShapes[i].fColor); 2164a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton fShapes[i].fDraw(canvas, paint); 2174a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton canvas->restore(); 2184a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 2194a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 2204a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton } 2214a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 2224a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton enum { 2234a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton kBenchWidth = 1000, 2244a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton kBenchHeight = 1000 2254a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton }; 2264a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 2274a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton struct ShapeInfo { 2284a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkMatrix fMatrix; 2294a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkColor fColor; 2304a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton std::function<void(SkCanvas*, const SkPaint&)> fDraw; 2314a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton }; 2324a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 2334a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton ShapesType fShapesType; 2344a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton ShapesType fInnerShapesType; 2354a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton int fNumShapes; 2364a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkISize fShapesSize; 2374a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton bool fPerspective; 2384a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkString fName; 2394a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkRRect fRect; 2404a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkRRect fOval; 2414a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkRRect fRRect; 2424a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkRRect fInnerRect; 2434a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkRRect fInnerOval; 2444a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkRRect fInnerRRect; 2454a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton SkTArray<ShapeInfo> fShapes; 2464a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 2474a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 2484a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton typedef Benchmark INHERITED; 2494a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton}; 2504a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 251a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#if ENABLE_COMMAND_LINE_SHAPES_BENCH 252a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdaltonDEF_BENCH(return new ShapesBench;) 253a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton#else 2544a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton// Small primitives (CPU bound, in theory): 2554a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kRect_ShapesType, ShapesBench::kNone_ShapesType, 2564a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 10000, SkISize::Make(32, 32), false);) 2574a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType, 2584a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 10000, SkISize::Make(32, 32), false);) 2594a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType, 2604a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 10000, SkISize::Make(32, 33), false);) 2614a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kNone_ShapesType, 2624a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 10000, SkISize::Make(32, 32), false);) 2634a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kMixed_ShapesType, ShapesBench::kNone_ShapesType, 2644a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 10000, SkISize::Make(32, 33), false);) 2654a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 2664a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton// Large primitives (GPU bound, in theory): 2674a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kRect_ShapesType, ShapesBench::kNone_ShapesType, 26832f1908f4c9a64e4862152bde6482f16d096f95fbrianosman 100, SkISize::Make(500, 500), false);) 2694a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType, 27032f1908f4c9a64e4862152bde6482f16d096f95fbrianosman 100, SkISize::Make(500, 500), false);) 2714a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType, 27232f1908f4c9a64e4862152bde6482f16d096f95fbrianosman 100, SkISize::Make(500, 501), false);) 2734a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kNone_ShapesType, 27432f1908f4c9a64e4862152bde6482f16d096f95fbrianosman 100, SkISize::Make(500, 500), false);) 2754a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kMixed_ShapesType, ShapesBench::kNone_ShapesType, 27632f1908f4c9a64e4862152bde6482f16d096f95fbrianosman 100, SkISize::Make(500, 501), false);) 2774a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton 2784a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton// Donuts (small and large). These fall-back to path rendering due to non-orthogonal rotation 2794a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton// making them quite slow. Thus, reduce the counts substantially: 2804a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kRect_ShapesType, ShapesBench::kRect_ShapesType, 281b8c97ba80be1276b79f18475600cee10c737cfbfbrianosman 500, SkISize::Make(32, 32), false);) 2824a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kRRect_ShapesType, 283b8c97ba80be1276b79f18475600cee10c737cfbfbrianosman 500, SkISize::Make(32, 32), false);) 2844a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kRect_ShapesType, ShapesBench::kRect_ShapesType, 285b8c97ba80be1276b79f18475600cee10c737cfbfbrianosman 50, SkISize::Make(500, 500), false);) 2864a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdaltonDEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kRRect_ShapesType, 287b8c97ba80be1276b79f18475600cee10c737cfbfbrianosman 50, SkISize::Make(500, 500), false);) 2884a6e40d9d2e0eb81e00d8b2bd20532aa28f61afbcdalton#endif 289