1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "Benchmark.h" 9#include "SkCanvas.h" 10#include "SkPaint.h" 11#include "SkRandom.h" 12#include "SkShader.h" 13#include "SkString.h" 14 15enum Flags { 16 kBig_Flag = 1 << 0, 17 kAA_Flag = 1 << 1 18}; 19 20#define FLAGS00 Flags(0) 21#define FLAGS01 Flags(kBig_Flag) 22#define FLAGS10 Flags(kAA_Flag) 23#define FLAGS11 Flags(kBig_Flag | kAA_Flag) 24 25static const int points[] = { 26 10, 10, 15, 5, 20, 20, 27 30, 5, 25, 20, 15, 12, 28 21, 21, 30, 30, 12, 4, 29 32, 28, 20, 18, 12, 10 30}; 31 32static const int kMaxPathSize = 10; 33 34class HairlinePathBench : public Benchmark { 35public: 36 HairlinePathBench(Flags flags) : fFlags(flags) { 37 fPaint.setStyle(SkPaint::kStroke_Style); 38 fPaint.setStrokeWidth(SkIntToScalar(0)); 39 } 40 41 virtual void appendName(SkString*) = 0; 42 virtual void makePath(SkPath*) = 0; 43 44protected: 45 const char* onGetName() override { 46 fName.printf("path_hairline_%s_%s_", 47 fFlags & kBig_Flag ? "big" : "small", 48 fFlags & kAA_Flag ? "AA" : "noAA"); 49 this->appendName(&fName); 50 return fName.c_str(); 51 } 52 53 void onDraw(const int loops, SkCanvas* canvas) override { 54 SkPaint paint(fPaint); 55 this->setupPaint(&paint); 56 57 paint.setAntiAlias(fFlags & kAA_Flag ? true : false); 58 59 SkPath path; 60 this->makePath(&path); 61 if (fFlags & kBig_Flag) { 62 const SkMatrix m = SkMatrix::MakeScale(SkIntToScalar(3), SkIntToScalar(3)); 63 path.transform(m); 64 } 65 66 for (int i = 0; i < loops; i++) { 67 for (int j = 0; j < 100; ++j) { 68 canvas->drawPath(path, paint); 69 } 70 } 71 } 72 73private: 74 SkPaint fPaint; 75 SkString fName; 76 Flags fFlags; 77 typedef Benchmark INHERITED; 78}; 79 80class LinePathBench : public HairlinePathBench { 81public: 82 LinePathBench(Flags flags) : INHERITED(flags) {} 83 84 void appendName(SkString* name) override { 85 name->append("line"); 86 } 87 void makePath(SkPath* path) override { 88 SkRandom rand; 89 int size = SK_ARRAY_COUNT(points); 90 int hSize = size / 2; 91 for (int i = 0; i < kMaxPathSize; ++i) { 92 int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 93 int yTrans = 0; 94 if (i > kMaxPathSize/2 - 1) { 95 yTrans = 40; 96 } 97 int base1 = 2 * rand.nextULessThan(hSize); 98 int base2 = 2 * rand.nextULessThan(hSize); 99 int base3 = 2 * rand.nextULessThan(hSize); 100 path->moveTo(SkIntToScalar(points[base1] + xTrans), 101 SkIntToScalar(points[base1+1] + yTrans)); 102 path->lineTo(SkIntToScalar(points[base2] + xTrans), 103 SkIntToScalar(points[base2+1] + yTrans)); 104 path->lineTo(SkIntToScalar(points[base3] + xTrans), 105 SkIntToScalar(points[base3+1] + yTrans)); 106 } 107 } 108private: 109 typedef HairlinePathBench INHERITED; 110}; 111 112class QuadPathBench : public HairlinePathBench { 113public: 114 QuadPathBench(Flags flags) : INHERITED(flags) {} 115 116 void appendName(SkString* name) override { 117 name->append("quad"); 118 } 119 void makePath(SkPath* path) override { 120 SkRandom rand; 121 int size = SK_ARRAY_COUNT(points); 122 int hSize = size / 2; 123 for (int i = 0; i < kMaxPathSize; ++i) { 124 int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 125 int yTrans = 0; 126 if (i > kMaxPathSize/2 - 1) { 127 yTrans = 40; 128 } 129 int base1 = 2 * rand.nextULessThan(hSize); 130 int base2 = 2 * rand.nextULessThan(hSize); 131 int base3 = 2 * rand.nextULessThan(hSize); 132 path->moveTo(SkIntToScalar(points[base1] + xTrans), 133 SkIntToScalar(points[base1+1] + yTrans)); 134 path->quadTo(SkIntToScalar(points[base2] + xTrans), 135 SkIntToScalar(points[base2+1] + yTrans), 136 SkIntToScalar(points[base3] + xTrans), 137 SkIntToScalar(points[base3+1] + yTrans)); 138 } 139 } 140private: 141 typedef HairlinePathBench INHERITED; 142}; 143 144class ConicPathBench : public HairlinePathBench { 145public: 146 ConicPathBench(Flags flags) : INHERITED(flags) {} 147 148 void appendName(SkString* name) override { 149 name->append("conic"); 150 } 151 void makePath(SkPath* path) override { 152 SkRandom rand; 153 SkRandom randWeight; 154 int size = SK_ARRAY_COUNT(points); 155 int hSize = size / 2; 156 for (int i = 0; i < kMaxPathSize; ++i) { 157 int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 158 int yTrans = 0; 159 if (i > kMaxPathSize/2 - 1) { 160 yTrans = 40; 161 } 162 int base1 = 2 * rand.nextULessThan(hSize); 163 int base2 = 2 * rand.nextULessThan(hSize); 164 int base3 = 2 * rand.nextULessThan(hSize); 165 float weight = randWeight.nextRangeF(0.0f, 2.0f); 166 path->moveTo(SkIntToScalar(points[base1] + xTrans), 167 SkIntToScalar(points[base1+1] + yTrans)); 168 path->conicTo(SkIntToScalar(points[base2] + xTrans), 169 SkIntToScalar(points[base2+1] + yTrans), 170 SkIntToScalar(points[base3] + xTrans), 171 SkIntToScalar(points[base3+1] + yTrans), 172 weight); 173 } 174 } 175 176private: 177 typedef HairlinePathBench INHERITED; 178}; 179 180class CubicPathBench : public HairlinePathBench { 181public: 182 CubicPathBench(Flags flags) : INHERITED(flags) {} 183 184 void appendName(SkString* name) override { 185 name->append("cubic"); 186 } 187 void makePath(SkPath* path) override { 188 SkRandom rand; 189 int size = SK_ARRAY_COUNT(points); 190 int hSize = size / 2; 191 for (int i = 0; i < kMaxPathSize; ++i) { 192 int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 193 int yTrans = 0; 194 if (i > kMaxPathSize/2 - 1) { 195 yTrans = 40; 196 } 197 int base1 = 2 * rand.nextULessThan(hSize); 198 int base2 = 2 * rand.nextULessThan(hSize); 199 int base3 = 2 * rand.nextULessThan(hSize); 200 int base4 = 2 * rand.nextULessThan(hSize); 201 path->moveTo(SkIntToScalar(points[base1] + xTrans), 202 SkIntToScalar(points[base1+1] + yTrans)); 203 path->cubicTo(SkIntToScalar(points[base2] + xTrans), 204 SkIntToScalar(points[base2+1] + yTrans), 205 SkIntToScalar(points[base3] + xTrans), 206 SkIntToScalar(points[base3+1] + yTrans), 207 SkIntToScalar(points[base4] + xTrans), 208 SkIntToScalar(points[base4+1] + yTrans)); 209 } 210 } 211private: 212 typedef HairlinePathBench INHERITED; 213}; 214 215// FLAG00 - no AA, small 216// FLAG01 - no AA, small 217// FLAG10 - AA, big 218// FLAG11 - AA, big 219 220DEF_BENCH( return new LinePathBench(FLAGS00); ) 221DEF_BENCH( return new LinePathBench(FLAGS01); ) 222DEF_BENCH( return new LinePathBench(FLAGS10); ) 223DEF_BENCH( return new LinePathBench(FLAGS11); ) 224 225DEF_BENCH( return new QuadPathBench(FLAGS00); ) 226DEF_BENCH( return new QuadPathBench(FLAGS01); ) 227DEF_BENCH( return new QuadPathBench(FLAGS10); ) 228DEF_BENCH( return new QuadPathBench(FLAGS11); ) 229 230// Don't have default path renderer for conics yet on GPU, so must use AA 231// DEF_BENCH( return new ConicPathBench(FLAGS00); ) 232// DEF_BENCH( return new ConicPathBench(FLAGS01); ) 233DEF_BENCH( return new ConicPathBench(FLAGS10); ) 234DEF_BENCH( return new ConicPathBench(FLAGS11); ) 235 236DEF_BENCH( return new CubicPathBench(FLAGS00); ) 237DEF_BENCH( return new CubicPathBench(FLAGS01); ) 238DEF_BENCH( return new CubicPathBench(FLAGS10); ) 239DEF_BENCH( return new CubicPathBench(FLAGS11); ) 240