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 #include "SkBenchmark.h" 8 #include "SkCanvas.h" 9 #include "SkPaint.h" 10 #include "SkRandom.h" 11 #include "SkShader.h" 12 #include "SkString.h" 13 14 enum Flags { 15 kBig_Flag = 1 << 0, 16 kAA_Flag = 1 << 1 17 }; 18 19 #define FLAGS00 Flags(0) 20 #define FLAGS01 Flags(kBig_Flag) 21 #define FLAGS10 Flags(kAA_Flag) 22 #define FLAGS11 Flags(kBig_Flag | kAA_Flag) 23 24 static const int points[] = { 25 10, 10, 15, 5, 20, 20, 26 30, 5, 25, 20, 15, 12, 27 21, 21, 30, 30, 12, 4, 28 32, 28, 20, 18, 12, 10 29 }; 30 31 static const int kMaxPathSize = 10; 32 33 class HairlinePathBench : public SkBenchmark { 34 public: 35 HairlinePathBench(void* param, Flags flags) : INHERITED(param), fFlags(flags) { 36 fPaint.setStyle(SkPaint::kStroke_Style); 37 fPaint.setStrokeWidth(SkIntToScalar(0)); 38 } 39 40 virtual void appendName(SkString*) = 0; 41 virtual void makePath(SkPath*) = 0; 42 43 protected: 44 virtual const char* onGetName() SK_OVERRIDE { 45 fName.printf("path_hairline_%s_%s_", 46 fFlags & kBig_Flag ? "big" : "small", 47 fFlags & kAA_Flag ? "AA" : "noAA"); 48 this->appendName(&fName); 49 return fName.c_str(); 50 } 51 52 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 53 SkPaint paint(fPaint); 54 this->setupPaint(&paint); 55 56 paint.setAntiAlias(fFlags & kAA_Flag ? true : false); 57 58 SkPath path; 59 this->makePath(&path); 60 if (fFlags & kBig_Flag) { 61 SkMatrix m; 62 m.setScale(SkIntToScalar(3), SkIntToScalar(3)); 63 path.transform(m); 64 } 65 66 int count = N; 67 for (int i = 0; i < count; i++) { 68 canvas->drawPath(path, paint); 69 } 70 } 71 72 private: 73 SkPaint fPaint; 74 SkString fName; 75 Flags fFlags; 76 enum { N = SkBENCHLOOP(200) }; 77 typedef SkBenchmark INHERITED; 78 }; 79 80 class LinePathBench : public HairlinePathBench { 81 public: 82 LinePathBench(void* param, Flags flags) : INHERITED(param, flags) {} 83 84 virtual void appendName(SkString* name) SK_OVERRIDE { 85 name->append("line"); 86 } 87 virtual void makePath(SkPath* path) SK_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: 114 QuadPathBench(void* param, Flags flags) : INHERITED(param, flags) {} 115 116 virtual void appendName(SkString* name) SK_OVERRIDE { 117 name->append("quad"); 118 } 119 virtual void makePath(SkPath* path) SK_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: 146 ConicPathBench(void* param, Flags flags) : INHERITED(param, flags) {} 147 148 virtual void appendName(SkString* name) SK_OVERRIDE { 149 name->append("conic"); 150 } 151 virtual void makePath(SkPath* path) SK_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 private: 176 typedef HairlinePathBench INHERITED; 177 }; 178 179 class CubicPathBench : public HairlinePathBench { 180 public: 181 CubicPathBench(void* param, Flags flags) : INHERITED(param, flags) {} 182 183 virtual void appendName(SkString* name) SK_OVERRIDE { 184 name->append("cubic"); 185 } 186 virtual void makePath(SkPath* path) SK_OVERRIDE { 187 SkRandom rand; 188 int size = SK_ARRAY_COUNT(points); 189 int hSize = size / 2; 190 for (int i = 0; i < kMaxPathSize; ++i) { 191 int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 192 int yTrans = 0; 193 if (i > kMaxPathSize/2 - 1) { 194 yTrans = 40; 195 } 196 int base1 = 2 * rand.nextULessThan(hSize); 197 int base2 = 2 * rand.nextULessThan(hSize); 198 int base3 = 2 * rand.nextULessThan(hSize); 199 int base4 = 2 * rand.nextULessThan(hSize); 200 path->moveTo(SkIntToScalar(points[base1] + xTrans), 201 SkIntToScalar(points[base1+1] + yTrans)); 202 path->cubicTo(SkIntToScalar(points[base2] + xTrans), 203 SkIntToScalar(points[base2+1] + yTrans), 204 SkIntToScalar(points[base3] + xTrans), 205 SkIntToScalar(points[base3+1] + yTrans), 206 SkIntToScalar(points[base4] + xTrans), 207 SkIntToScalar(points[base4+1] + yTrans)); 208 } 209 } 210 private: 211 typedef HairlinePathBench INHERITED; 212 }; 213 214 // FLAG00 - no AA, small 215 // FLAG01 - no AA, small 216 // FLAG10 - AA, big 217 // FLAG11 - AA, big 218 219 DEF_BENCH( return new LinePathBench(p, FLAGS00); ) 220 DEF_BENCH( return new LinePathBench(p, FLAGS01); ) 221 DEF_BENCH( return new LinePathBench(p, FLAGS10); ) 222 DEF_BENCH( return new LinePathBench(p, FLAGS11); ) 223 224 DEF_BENCH( return new QuadPathBench(p, FLAGS00); ) 225 DEF_BENCH( return new QuadPathBench(p, FLAGS01); ) 226 DEF_BENCH( return new QuadPathBench(p, FLAGS10); ) 227 DEF_BENCH( return new QuadPathBench(p, FLAGS11); ) 228 229 // Don't have default path renderer for conics yet on GPU, so must use AA 230 // DEF_BENCH( return new ConicPathBench(p, FLAGS00); ) 231 // DEF_BENCH( return new ConicPathBench(p, FLAGS01); ) 232 DEF_BENCH( return new ConicPathBench(p, FLAGS10); ) 233 DEF_BENCH( return new ConicPathBench(p, FLAGS11); ) 234 235 DEF_BENCH( return new CubicPathBench(p, FLAGS00); ) 236 DEF_BENCH( return new CubicPathBench(p, FLAGS01); ) 237 DEF_BENCH( return new CubicPathBench(p, FLAGS10); ) 238 DEF_BENCH( return new CubicPathBench(p, FLAGS11); ) 239