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 15 enum 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 25 static 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 32 static const int kMaxPathSize = 10; 33 34 class HairlinePathBench : public Benchmark { 35 public: HairlinePathBench(Flags flags)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 44 protected: onGetName()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 onDraw(const int loops,SkCanvas * canvas)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 73 private: 74 SkPaint fPaint; 75 SkString fName; 76 Flags fFlags; 77 typedef Benchmark INHERITED; 78 }; 79 80 class LinePathBench : public HairlinePathBench { 81 public: LinePathBench(Flags flags)82 LinePathBench(Flags flags) : INHERITED(flags) {} 83 appendName(SkString * name)84 void appendName(SkString* name) override { 85 name->append("line"); 86 } makePath(SkPath * path)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 } 108 private: 109 typedef HairlinePathBench INHERITED; 110 }; 111 112 class QuadPathBench : public HairlinePathBench { 113 public: QuadPathBench(Flags flags)114 QuadPathBench(Flags flags) : INHERITED(flags) {} 115 appendName(SkString * name)116 void appendName(SkString* name) override { 117 name->append("quad"); 118 } makePath(SkPath * path)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 } 140 private: 141 typedef HairlinePathBench INHERITED; 142 }; 143 144 class ConicPathBench : public HairlinePathBench { 145 public: ConicPathBench(Flags flags)146 ConicPathBench(Flags flags) : INHERITED(flags) {} 147 appendName(SkString * name)148 void appendName(SkString* name) override { 149 name->append("conic"); 150 } makePath(SkPath * path)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 176 private: 177 typedef HairlinePathBench INHERITED; 178 }; 179 180 class CubicPathBench : public HairlinePathBench { 181 public: CubicPathBench(Flags flags)182 CubicPathBench(Flags flags) : INHERITED(flags) {} 183 appendName(SkString * name)184 void appendName(SkString* name) override { 185 name->append("cubic"); 186 } makePath(SkPath * path)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 } 211 private: 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 220 DEF_BENCH( return new LinePathBench(FLAGS00); ) 221 DEF_BENCH( return new LinePathBench(FLAGS01); ) 222 DEF_BENCH( return new LinePathBench(FLAGS10); ) 223 DEF_BENCH( return new LinePathBench(FLAGS11); ) 224 225 DEF_BENCH( return new QuadPathBench(FLAGS00); ) 226 DEF_BENCH( return new QuadPathBench(FLAGS01); ) 227 DEF_BENCH( return new QuadPathBench(FLAGS10); ) 228 DEF_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); ) 233 DEF_BENCH( return new ConicPathBench(FLAGS10); ) 234 DEF_BENCH( return new ConicPathBench(FLAGS11); ) 235 236 DEF_BENCH( return new CubicPathBench(FLAGS00); ) 237 DEF_BENCH( return new CubicPathBench(FLAGS01); ) 238 DEF_BENCH( return new CubicPathBench(FLAGS10); ) 239 DEF_BENCH( return new CubicPathBench(FLAGS11); ) 240