1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "SkBenchmark.h" 9 #include "SkCanvas.h" 10 #include "SkPaint.h" 11 #include "SkRandom.h" 12 #include "SkString.h" 13 #include "SkShader.h" 14 15 class RectBench : public SkBenchmark { 16 public: 17 int fShift, fStroke; 18 enum { 19 W = 640, 20 H = 480, 21 N = SkBENCHLOOP(300) 22 }; 23 SkRect fRects[N]; 24 SkColor fColors[N]; 25 26 RectBench(void* param, int shift, int stroke = 0) 27 : INHERITED(param) 28 , fShift(shift) 29 , fStroke(stroke) { 30 SkRandom rand; 31 const SkScalar offset = SK_Scalar1/3; 32 for (int i = 0; i < N; i++) { 33 int x = rand.nextU() % W; 34 int y = rand.nextU() % H; 35 int w = rand.nextU() % W; 36 int h = rand.nextU() % H; 37 w >>= shift; 38 h >>= shift; 39 x -= w/2; 40 y -= h/2; 41 fRects[i].set(SkIntToScalar(x), SkIntToScalar(y), 42 SkIntToScalar(x+w), SkIntToScalar(y+h)); 43 fRects[i].offset(offset, offset); 44 fColors[i] = rand.nextU() | 0xFF808080; 45 } 46 } 47 48 SkString fName; 49 const char* computeName(const char root[]) { 50 fName.printf("%s_%d", root, fShift); 51 if (fStroke > 0) { 52 fName.appendf("_stroke_%d", fStroke); 53 } 54 return fName.c_str(); 55 } 56 57 protected: 58 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) { 59 c->drawRect(r, p); 60 } 61 62 virtual const char* onGetName() { return computeName("rects"); } 63 virtual void onDraw(SkCanvas* canvas) { 64 SkPaint paint; 65 if (fStroke > 0) { 66 paint.setStyle(SkPaint::kStroke_Style); 67 paint.setStrokeWidth(SkIntToScalar(fStroke)); 68 } 69 for (int i = 0; i < N; i++) { 70 paint.setColor(fColors[i]); 71 this->setupPaint(&paint); 72 this->drawThisRect(canvas, fRects[i], paint); 73 } 74 } 75 private: 76 typedef SkBenchmark INHERITED; 77 }; 78 79 class SrcModeRectBench : public RectBench { 80 public: 81 SrcModeRectBench(void* param) : INHERITED(param, 1, 0) { 82 fMode = SkXfermode::Create(SkXfermode::kSrc_Mode); 83 } 84 85 virtual ~SrcModeRectBench() { 86 SkSafeUnref(fMode); 87 } 88 89 protected: 90 virtual void setupPaint(SkPaint* paint) SK_OVERRIDE { 91 this->INHERITED::setupPaint(paint); 92 // srcmode is most interesting when we're not opaque 93 paint->setAlpha(0x80); 94 paint->setXfermode(fMode); 95 } 96 97 virtual const char* onGetName() SK_OVERRIDE { 98 fName.set(this->INHERITED::onGetName()); 99 fName.prepend("srcmode_"); 100 return fName.c_str(); 101 } 102 103 private: 104 SkString fName; 105 SkXfermode* fMode; 106 107 typedef RectBench INHERITED; 108 }; 109 110 class OvalBench : public RectBench { 111 public: 112 OvalBench(void* param, int shift, int stroke = 0) : RectBench(param, shift, stroke) {} 113 protected: 114 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) { 115 c->drawOval(r, p); 116 } 117 virtual const char* onGetName() { return computeName("ovals"); } 118 }; 119 120 class RRectBench : public RectBench { 121 public: 122 RRectBench(void* param, int shift, int stroke = 0) : RectBench(param, shift, stroke) {} 123 protected: 124 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) { 125 c->drawRoundRect(r, r.width() / 4, r.height() / 4, p); 126 } 127 virtual const char* onGetName() { return computeName("rrects"); } 128 }; 129 130 class PointsBench : public RectBench { 131 public: 132 SkCanvas::PointMode fMode; 133 const char* fName; 134 135 PointsBench(void* param, SkCanvas::PointMode mode, const char* name) : 136 RectBench(param, 2), fMode(mode) { 137 fName = name; 138 } 139 140 protected: 141 virtual void onDraw(SkCanvas* canvas) { 142 SkScalar gSizes[] = { 143 SkIntToScalar(7), 0 144 }; 145 size_t sizes = SK_ARRAY_COUNT(gSizes); 146 147 if (this->hasStrokeWidth()) { 148 gSizes[0] = this->getStrokeWidth(); 149 sizes = 1; 150 } 151 152 SkPaint paint; 153 paint.setStrokeCap(SkPaint::kRound_Cap); 154 155 for (size_t i = 0; i < sizes; i++) { 156 paint.setStrokeWidth(gSizes[i]); 157 this->setupPaint(&paint); 158 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint); 159 paint.setColor(fColors[i]); 160 } 161 } 162 virtual const char* onGetName() { return fName; } 163 }; 164 165 class AARectBench : public SkBenchmark { 166 public: 167 enum { 168 W = 640, 169 H = 480, 170 }; 171 172 AARectBench(void* param, bool rotate) : INHERITED(param), fRotate(rotate) {} 173 174 protected: 175 176 virtual const char* onGetName() { 177 if (fRotate) { 178 return "aarects_rotated"; 179 } 180 return "aarects"; 181 } 182 183 virtual void onDraw(SkCanvas* canvas) { 184 static const SkScalar kHalfRectSize = SkFloatToScalar(0.75f); 185 186 SkPaint paint; 187 this->setupPaint(&paint); 188 paint.setAntiAlias(true); 189 paint.setColor(SK_ColorBLACK); 190 SkRect r = { -kHalfRectSize, -kHalfRectSize, kHalfRectSize, kHalfRectSize }; 191 int rot = 0; 192 193 // Draw small aa rects in a grid across the screen 194 for (SkScalar y = kHalfRectSize+SK_Scalar1; y < H; y += 2*kHalfRectSize+2) { 195 for (SkScalar x = kHalfRectSize+SK_Scalar1; x < W; x += 2*kHalfRectSize+2) { 196 canvas->save(); 197 canvas->translate(x, y); 198 199 if (fRotate) { 200 SkMatrix rotate; 201 rotate.setRotate(SkIntToScalar(rot)); 202 canvas->concat(rotate); 203 rot += 10; 204 } 205 206 canvas->drawRect(r, paint); 207 canvas->restore(); 208 } 209 } 210 211 } 212 private: 213 bool fRotate; 214 typedef SkBenchmark INHERITED; 215 }; 216 217 /******************************************************************************* 218 * to bench BlitMask [Opaque, Black, color, shader] 219 *******************************************************************************/ 220 221 class BlitMaskBench : public RectBench { 222 public: 223 enum kMaskType { 224 kMaskOpaque = 0, 225 kMaskBlack, 226 kMaskColor, 227 KMaskShader 228 }; 229 SkCanvas::PointMode fMode; 230 const char* fName; 231 232 BlitMaskBench(void* param, SkCanvas::PointMode mode, 233 BlitMaskBench::kMaskType type, const char* name) : 234 RectBench(param, 2), fMode(mode), _type(type) { 235 fName = name; 236 } 237 238 protected: 239 virtual void onDraw(SkCanvas* canvas) { 240 SkScalar gSizes[] = { 241 SkIntToScalar(13), SkIntToScalar(24) 242 }; 243 size_t sizes = SK_ARRAY_COUNT(gSizes); 244 245 if (this->hasStrokeWidth()) { 246 gSizes[0] = this->getStrokeWidth(); 247 sizes = 1; 248 } 249 SkRandom rand; 250 SkColor color = 0xFF000000; 251 U8CPU alpha = 0xFF; 252 SkPaint paint; 253 paint.setStrokeCap(SkPaint::kRound_Cap); 254 if (_type == KMaskShader) { 255 SkBitmap srcBM; 256 srcBM.setConfig(SkBitmap::kARGB_8888_Config, 10, 1); 257 srcBM.allocPixels(); 258 srcBM.eraseColor(0xFF00FF00); 259 260 SkShader* s; 261 s = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode, 262 SkShader::kClamp_TileMode); 263 paint.setShader(s)->unref(); 264 } 265 for (size_t i = 0; i < sizes; i++) { 266 switch (_type) { 267 case kMaskOpaque: 268 color = fColors[i]; 269 alpha = 0xFF; 270 break; 271 case kMaskBlack: 272 alpha = 0xFF; 273 color = 0xFF000000; 274 break; 275 case kMaskColor: 276 color = fColors[i]; 277 alpha = rand.nextU() & 255; 278 break; 279 case KMaskShader: 280 break; 281 } 282 paint.setStrokeWidth(gSizes[i]); 283 this->setupPaint(&paint); 284 paint.setColor(color); 285 paint.setAlpha(alpha); 286 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint); 287 } 288 } 289 virtual const char* onGetName() { return fName; } 290 private: 291 typedef RectBench INHERITED; 292 kMaskType _type; 293 }; 294 295 296 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1)); ) 297 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1, 4)); ) 298 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3)); ) 299 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3, 4)); ) 300 DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 1)); ) 301 DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 3)); ) 302 DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 1, 4)); ) 303 DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 3, 4)); ) 304 DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 1)); ) 305 DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 1, 4)); ) 306 DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 3)); ) 307 DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 3, 4)); ) 308 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPoints_PointMode, "points")); ) 309 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kLines_PointMode, "lines")); ) 310 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon")); ) 311 312 DEF_BENCH( return SkNEW_ARGS(SrcModeRectBench, (p)); ) 313 314 DEF_BENCH( return SkNEW_ARGS(AARectBench, (p, false)); ) 315 DEF_BENCH( return SkNEW_ARGS(AARectBench, (p, true)); ) 316 317 /* init the blitmask bench 318 */ 319 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench, 320 (p, SkCanvas::kPoints_PointMode, 321 BlitMaskBench::kMaskOpaque, "maskopaque") 322 ); ) 323 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench, 324 (p, SkCanvas::kPoints_PointMode, 325 BlitMaskBench::kMaskBlack, "maskblack") 326 ); ) 327 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench, 328 (p, SkCanvas::kPoints_PointMode, 329 BlitMaskBench::kMaskColor, "maskcolor") 330 ); ) 331 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench, 332 (p, SkCanvas::kPoints_PointMode, 333 BlitMaskBench::KMaskShader, "maskshader") 334 ); ) 335