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