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) : INHERITED(param), fShift(shift), fStroke(stroke) { 27 SkRandom rand; 28 const SkScalar offset = SK_Scalar1/3; 29 for (int i = 0; i < N; i++) { 30 int x = rand.nextU() % W; 31 int y = rand.nextU() % H; 32 int w = rand.nextU() % W; 33 int h = rand.nextU() % H; 34 w >>= shift; 35 h >>= shift; 36 x -= w/2; 37 y -= h/2; 38 fRects[i].set(SkIntToScalar(x), SkIntToScalar(y), 39 SkIntToScalar(x+w), SkIntToScalar(y+h)); 40 fRects[i].offset(offset, offset); 41 fColors[i] = rand.nextU() | 0xFF808080; 42 } 43 } 44 45 SkString fName; 46 const char* computeName(const char root[]) { 47 fName.printf("%s_%d", root, fShift); 48 if (fStroke > 0) { 49 fName.appendf("_stroke_%d", fStroke); 50 } 51 return fName.c_str(); 52 } 53 54 protected: 55 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) { 56 c->drawRect(r, p); 57 } 58 59 virtual const char* onGetName() { return computeName("rects"); } 60 virtual void onDraw(SkCanvas* canvas) { 61 SkPaint paint; 62 if (fStroke > 0) { 63 paint.setStyle(SkPaint::kStroke_Style); 64 paint.setStrokeWidth(SkIntToScalar(fStroke)); 65 } 66 for (int i = 0; i < N; i++) { 67 paint.setColor(fColors[i]); 68 this->setupPaint(&paint); 69 this->drawThisRect(canvas, fRects[i], paint); 70 } 71 } 72 private: 73 typedef SkBenchmark INHERITED; 74 }; 75 76 class OvalBench : public RectBench { 77 public: 78 OvalBench(void* param, int shift) : RectBench(param, shift) {} 79 protected: 80 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) { 81 c->drawOval(r, p); 82 } 83 virtual const char* onGetName() { return computeName("ovals"); } 84 }; 85 86 class RRectBench : public RectBench { 87 public: 88 RRectBench(void* param, int shift) : RectBench(param, shift) {} 89 protected: 90 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) { 91 c->drawRoundRect(r, r.width() / 4, r.height() / 4, p); 92 } 93 virtual const char* onGetName() { return computeName("rrects"); } 94 }; 95 96 class PointsBench : public RectBench { 97 public: 98 SkCanvas::PointMode fMode; 99 const char* fName; 100 101 PointsBench(void* param, SkCanvas::PointMode mode, const char* name) : 102 RectBench(param, 2), fMode(mode) { 103 fName = name; 104 } 105 106 protected: 107 virtual void onDraw(SkCanvas* canvas) { 108 SkScalar gSizes[] = { 109 SkIntToScalar(7), 0 110 }; 111 size_t sizes = SK_ARRAY_COUNT(gSizes); 112 113 if (this->hasStrokeWidth()) { 114 gSizes[0] = this->getStrokeWidth(); 115 sizes = 1; 116 } 117 118 SkPaint paint; 119 paint.setStrokeCap(SkPaint::kRound_Cap); 120 121 for (size_t i = 0; i < sizes; i++) { 122 paint.setStrokeWidth(gSizes[i]); 123 this->setupPaint(&paint); 124 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint); 125 paint.setColor(fColors[i]); 126 } 127 } 128 virtual const char* onGetName() { return fName; } 129 }; 130 131 /******************************************************************************* 132 * to bench BlitMask [Opaque, Black, color, shader] 133 *******************************************************************************/ 134 135 class BlitMaskBench : public RectBench { 136 public: 137 enum kMaskType { 138 kMaskOpaque = 0, 139 kMaskBlack, 140 kMaskColor, 141 KMaskShader 142 }; 143 SkCanvas::PointMode fMode; 144 const char* fName; 145 146 BlitMaskBench(void* param, SkCanvas::PointMode mode, 147 BlitMaskBench::kMaskType type, const char* name) : 148 RectBench(param, 2), fMode(mode), _type(type) { 149 fName = name; 150 } 151 152 protected: 153 virtual void onDraw(SkCanvas* canvas) { 154 SkScalar gSizes[] = { 155 SkIntToScalar(13), SkIntToScalar(24) 156 }; 157 size_t sizes = SK_ARRAY_COUNT(gSizes); 158 159 if (this->hasStrokeWidth()) { 160 gSizes[0] = this->getStrokeWidth(); 161 sizes = 1; 162 } 163 SkRandom rand; 164 SkColor color = 0xFF000000; 165 U8CPU alpha = 0xFF; 166 SkPaint paint; 167 paint.setStrokeCap(SkPaint::kRound_Cap); 168 if (_type == KMaskShader) { 169 SkBitmap srcBM; 170 srcBM.setConfig(SkBitmap::kARGB_8888_Config, 10, 1); 171 srcBM.allocPixels(); 172 srcBM.eraseColor(0xFF00FF00); 173 174 SkShader* s; 175 s = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode, 176 SkShader::kClamp_TileMode); 177 paint.setShader(s)->unref(); 178 } 179 for (size_t i = 0; i < sizes; i++) { 180 switch (_type) { 181 case kMaskOpaque: 182 color = fColors[i]; 183 alpha = 0xFF; 184 break; 185 case kMaskBlack: 186 alpha = 0xFF; 187 color = 0xFF000000; 188 break; 189 case kMaskColor: 190 color = fColors[i]; 191 alpha = rand.nextU() & 255; 192 break; 193 case KMaskShader: 194 break; 195 } 196 paint.setStrokeWidth(gSizes[i]); 197 this->setupPaint(&paint); 198 paint.setColor(color); 199 paint.setAlpha(alpha); 200 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint); 201 } 202 } 203 virtual const char* onGetName() { return fName; } 204 private: 205 typedef RectBench INHERITED; 206 kMaskType _type; 207 }; 208 209 210 static SkBenchmark* RectFactory1F(void* p) { return SkNEW_ARGS(RectBench, (p, 1)); } 211 static SkBenchmark* RectFactory1S(void* p) { return SkNEW_ARGS(RectBench, (p, 1, 4)); } 212 static SkBenchmark* RectFactory2F(void* p) { return SkNEW_ARGS(RectBench, (p, 3)); } 213 static SkBenchmark* RectFactory2S(void* p) { return SkNEW_ARGS(RectBench, (p, 3, 4)); } 214 static SkBenchmark* OvalFactory1(void* p) { return SkNEW_ARGS(OvalBench, (p, 1)); } 215 static SkBenchmark* OvalFactory2(void* p) { return SkNEW_ARGS(OvalBench, (p, 3)); } 216 static SkBenchmark* RRectFactory1(void* p) { return SkNEW_ARGS(RRectBench, (p, 1)); } 217 static SkBenchmark* RRectFactory2(void* p) { return SkNEW_ARGS(RRectBench, (p, 3)); } 218 static SkBenchmark* PointsFactory(void* p) { 219 return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPoints_PointMode, "points")); 220 } 221 static SkBenchmark* LinesFactory(void* p) { 222 return SkNEW_ARGS(PointsBench, (p, SkCanvas::kLines_PointMode, "lines")); 223 } 224 static SkBenchmark* PolygonFactory(void* p) { 225 return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon")); 226 } 227 228 /* init the blitmask bench 229 */ 230 static SkBenchmark* BlitMaskOpaqueFactory(void* p) { 231 return SkNEW_ARGS(BlitMaskBench, 232 (p, SkCanvas::kPoints_PointMode, 233 BlitMaskBench::kMaskOpaque, "maskopaque") 234 ); 235 } 236 static SkBenchmark* BlitMaskBlackFactory(void* p) { 237 return SkNEW_ARGS(BlitMaskBench, 238 (p, SkCanvas::kPoints_PointMode, 239 BlitMaskBench::kMaskBlack, "maskblack") 240 ); 241 } 242 static SkBenchmark* BlitMaskColorFactory(void* p) { 243 return SkNEW_ARGS(BlitMaskBench, 244 (p, SkCanvas::kPoints_PointMode, 245 BlitMaskBench::kMaskColor, "maskcolor") 246 ); 247 } 248 static SkBenchmark* BlitMaskShaderFactory(void* p) { 249 return SkNEW_ARGS(BlitMaskBench, 250 (p, SkCanvas::kPoints_PointMode, 251 BlitMaskBench::KMaskShader, "maskshader") 252 ); 253 } 254 255 static BenchRegistry gRectReg1F(RectFactory1F); 256 static BenchRegistry gRectReg1S(RectFactory1S); 257 static BenchRegistry gRectReg2F(RectFactory2F); 258 static BenchRegistry gRectReg2S(RectFactory2S); 259 static BenchRegistry gOvalReg1(OvalFactory1); 260 static BenchRegistry gOvalReg2(OvalFactory2); 261 static BenchRegistry gRRectReg1(RRectFactory1); 262 static BenchRegistry gRRectReg2(RRectFactory2); 263 static BenchRegistry gPointsReg(PointsFactory); 264 static BenchRegistry gLinesReg(LinesFactory); 265 static BenchRegistry gPolygonReg(PolygonFactory); 266 static BenchRegistry gRectRegOpaque(BlitMaskOpaqueFactory); 267 static BenchRegistry gRectRegBlack(BlitMaskBlackFactory); 268 static BenchRegistry gRectRegColor(BlitMaskColorFactory); 269 static BenchRegistry gRectRegShader(BlitMaskShaderFactory); 270