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) : RectBench(param, shift) {} 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) : RectBench(param, shift) {} 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) : INHERITED(param) {} 173 174 protected: 175 176 virtual const char* onGetName() { return "aarects"; } 177 178 virtual void onDraw(SkCanvas* canvas) { 179 SkPaint paint; 180 this->setupPaint(&paint); 181 paint.setAntiAlias(true); 182 paint.setColor(SK_ColorBLACK); 183 SkRect r; 184 185 // Draw small aa rects in a grid across the screen 186 for (SkScalar y = SK_ScalarHalf; y < H; y += SkIntToScalar(2)) { 187 for (SkScalar x = SK_ScalarHalf; x < W; x += SkIntToScalar(2)) { 188 r.set(x, y, 189 x+SkFloatToScalar(1.5f), y+SkFloatToScalar(1.5f)); 190 canvas->drawRect(r, paint); 191 } 192 } 193 194 } 195 private: 196 typedef SkBenchmark INHERITED; 197 }; 198 199 /******************************************************************************* 200 * to bench BlitMask [Opaque, Black, color, shader] 201 *******************************************************************************/ 202 203 class BlitMaskBench : public RectBench { 204 public: 205 enum kMaskType { 206 kMaskOpaque = 0, 207 kMaskBlack, 208 kMaskColor, 209 KMaskShader 210 }; 211 SkCanvas::PointMode fMode; 212 const char* fName; 213 214 BlitMaskBench(void* param, SkCanvas::PointMode mode, 215 BlitMaskBench::kMaskType type, const char* name) : 216 RectBench(param, 2), fMode(mode), _type(type) { 217 fName = name; 218 } 219 220 protected: 221 virtual void onDraw(SkCanvas* canvas) { 222 SkScalar gSizes[] = { 223 SkIntToScalar(13), SkIntToScalar(24) 224 }; 225 size_t sizes = SK_ARRAY_COUNT(gSizes); 226 227 if (this->hasStrokeWidth()) { 228 gSizes[0] = this->getStrokeWidth(); 229 sizes = 1; 230 } 231 SkRandom rand; 232 SkColor color = 0xFF000000; 233 U8CPU alpha = 0xFF; 234 SkPaint paint; 235 paint.setStrokeCap(SkPaint::kRound_Cap); 236 if (_type == KMaskShader) { 237 SkBitmap srcBM; 238 srcBM.setConfig(SkBitmap::kARGB_8888_Config, 10, 1); 239 srcBM.allocPixels(); 240 srcBM.eraseColor(0xFF00FF00); 241 242 SkShader* s; 243 s = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode, 244 SkShader::kClamp_TileMode); 245 paint.setShader(s)->unref(); 246 } 247 for (size_t i = 0; i < sizes; i++) { 248 switch (_type) { 249 case kMaskOpaque: 250 color = fColors[i]; 251 alpha = 0xFF; 252 break; 253 case kMaskBlack: 254 alpha = 0xFF; 255 color = 0xFF000000; 256 break; 257 case kMaskColor: 258 color = fColors[i]; 259 alpha = rand.nextU() & 255; 260 break; 261 case KMaskShader: 262 break; 263 } 264 paint.setStrokeWidth(gSizes[i]); 265 this->setupPaint(&paint); 266 paint.setColor(color); 267 paint.setAlpha(alpha); 268 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint); 269 } 270 } 271 virtual const char* onGetName() { return fName; } 272 private: 273 typedef RectBench INHERITED; 274 kMaskType _type; 275 }; 276 277 278 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1)); ) 279 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1, 4)); ) 280 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3)); ) 281 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3, 4)); ) 282 DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 1)); ) 283 DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 3)); ) 284 DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 1)); ) 285 DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 3)); ) 286 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPoints_PointMode, "points")); ) 287 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kLines_PointMode, "lines")); ) 288 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon")); ) 289 290 DEF_BENCH( return SkNEW_ARGS(SrcModeRectBench, (p)); ) 291 DEF_BENCH( return SkNEW_ARGS(AARectBench, (p)); ) 292 293 /* init the blitmask bench 294 */ 295 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench, 296 (p, SkCanvas::kPoints_PointMode, 297 BlitMaskBench::kMaskOpaque, "maskopaque") 298 ); ) 299 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench, 300 (p, SkCanvas::kPoints_PointMode, 301 BlitMaskBench::kMaskBlack, "maskblack") 302 ); ) 303 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench, 304 (p, SkCanvas::kPoints_PointMode, 305 BlitMaskBench::kMaskColor, "maskcolor") 306 ); ) 307 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench, 308 (p, SkCanvas::kPoints_PointMode, 309 BlitMaskBench::KMaskShader, "maskshader") 310 ); ) 311