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