1 /* 2 * Copyright 2011 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 "SkBitmap.h" 10 #include "SkCanvas.h" 11 #include "SkCommandLineFlags.h" 12 #include "SkPaint.h" 13 #include "SkRandom.h" 14 #include "SkShader.h" 15 #include "SkString.h" 16 17 DEFINE_double(strokeWidth, -1.0, "If set, use this stroke width in RectBench."); 18 19 class RectBench : public Benchmark { 20 public: 21 int fShift, fStroke; 22 enum { 23 W = 640, 24 H = 480, 25 N = 300, 26 }; 27 SkRect fRects[N]; 28 SkColor fColors[N]; 29 30 RectBench(int shift, int stroke = 0) 31 : fShift(shift) 32 , fStroke(stroke) {} 33 34 const char* computeName(const char root[]) { 35 fBaseName.printf("%s_%d", root, fShift); 36 if (fStroke > 0) { 37 fBaseName.appendf("_stroke_%d", fStroke); 38 } 39 return fBaseName.c_str(); 40 } 41 42 bool isVisual() override { return true; } 43 44 protected: 45 46 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) { 47 c->drawRect(r, p); 48 } 49 50 const char* onGetName() override { return computeName("rects"); } 51 52 void onDelayedSetup() override { 53 SkRandom rand; 54 const SkScalar offset = SK_Scalar1/3; 55 for (int i = 0; i < N; i++) { 56 int x = rand.nextU() % W; 57 int y = rand.nextU() % H; 58 int w = rand.nextU() % W; 59 int h = rand.nextU() % H; 60 w >>= fShift; 61 h >>= fShift; 62 x -= w/2; 63 y -= h/2; 64 fRects[i].set(SkIntToScalar(x), SkIntToScalar(y), 65 SkIntToScalar(x+w), SkIntToScalar(y+h)); 66 fRects[i].offset(offset, offset); 67 fColors[i] = rand.nextU() | 0xFF808080; 68 } 69 } 70 71 void onDraw(int loops, SkCanvas* canvas) override { 72 SkPaint paint; 73 if (fStroke > 0) { 74 paint.setStyle(SkPaint::kStroke_Style); 75 paint.setStrokeWidth(SkIntToScalar(fStroke)); 76 } 77 for (int i = 0; i < loops; i++) { 78 paint.setColor(fColors[i % N]); 79 this->setupPaint(&paint); 80 this->drawThisRect(canvas, fRects[i % N], paint); 81 } 82 } 83 84 private: 85 SkString fBaseName; 86 typedef Benchmark INHERITED; 87 }; 88 89 class SrcModeRectBench : public RectBench { 90 public: 91 SrcModeRectBench() : INHERITED(1, 0) { 92 fMode = SkBlendMode::kSrc; 93 } 94 95 protected: 96 void setupPaint(SkPaint* paint) override { 97 this->INHERITED::setupPaint(paint); 98 // srcmode is most interesting when we're not opaque 99 paint->setAlpha(0x80); 100 paint->setBlendMode(fMode); 101 } 102 103 const char* onGetName() override { 104 fName.set(this->INHERITED::onGetName()); 105 fName.prepend("srcmode_"); 106 return fName.c_str(); 107 } 108 109 private: 110 SkBlendMode fMode; 111 SkString fName; 112 113 typedef RectBench INHERITED; 114 }; 115 116 class TransparentRectBench : public RectBench { 117 public: 118 TransparentRectBench() : INHERITED(1, 0) {} 119 120 protected: 121 void setupPaint(SkPaint* paint) override { 122 this->INHERITED::setupPaint(paint); 123 // draw non opaque rect 124 paint->setAlpha(0x80); 125 } 126 127 const char* onGetName() override { 128 fName.set(this->INHERITED::onGetName()); 129 fName.prepend("transparent_"); 130 return fName.c_str(); 131 } 132 133 private: 134 SkString fName; 135 typedef RectBench INHERITED; 136 }; 137 138 139 class OvalBench : public RectBench { 140 public: 141 OvalBench(int shift, int stroke = 0) : RectBench(shift, stroke) {} 142 protected: 143 void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override { 144 c->drawOval(r, p); 145 } 146 const char* onGetName() override { return computeName("ovals"); } 147 }; 148 149 class RRectBench : public RectBench { 150 public: 151 RRectBench(int shift, int stroke = 0) : RectBench(shift, stroke) {} 152 protected: 153 void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override { 154 c->drawRoundRect(r, r.width() / 4, r.height() / 4, p); 155 } 156 const char* onGetName() override { return computeName("rrects"); } 157 }; 158 159 class PointsBench : public RectBench { 160 public: 161 SkCanvas::PointMode fMode; 162 163 PointsBench(SkCanvas::PointMode mode, const char* name) 164 : RectBench(2) 165 , fMode(mode) { 166 fName = name; 167 } 168 169 protected: 170 void onDraw(int loops, SkCanvas* canvas) override { 171 SkScalar gSizes[] = { 172 SkIntToScalar(7), 0 173 }; 174 size_t sizes = SK_ARRAY_COUNT(gSizes); 175 176 if (FLAGS_strokeWidth >= 0) { 177 gSizes[0] = (SkScalar)FLAGS_strokeWidth; 178 sizes = 1; 179 } 180 181 SkPaint paint; 182 paint.setStrokeCap(SkPaint::kRound_Cap); 183 184 for (int loop = 0; loop < loops; loop++) { 185 for (size_t i = 0; i < sizes; i++) { 186 paint.setStrokeWidth(gSizes[i]); 187 this->setupPaint(&paint); 188 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint); 189 paint.setColor(fColors[i % N]); 190 } 191 } 192 } 193 const char* onGetName() override { return fName.c_str(); } 194 195 private: 196 SkString fName; 197 198 }; 199 200 /******************************************************************************* 201 * to bench BlitMask [Opaque, Black, color, shader] 202 *******************************************************************************/ 203 204 class BlitMaskBench : public RectBench { 205 public: 206 enum kMaskType { 207 kMaskOpaque = 0, 208 kMaskBlack, 209 kMaskColor, 210 KMaskShader 211 }; 212 SkCanvas::PointMode fMode; 213 214 BlitMaskBench(SkCanvas::PointMode mode, 215 BlitMaskBench::kMaskType type, const char* name) : 216 RectBench(2), fMode(mode), _type(type) { 217 fName = name; 218 } 219 220 protected: 221 void onDraw(int loops, SkCanvas* canvas) override { 222 SkScalar gSizes[] = { 223 SkIntToScalar(13), SkIntToScalar(24) 224 }; 225 size_t sizes = SK_ARRAY_COUNT(gSizes); 226 227 if (FLAGS_strokeWidth >= 0) { 228 gSizes[0] = (SkScalar)FLAGS_strokeWidth; 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.allocN32Pixels(10, 1); 239 srcBM.eraseColor(0xFF00FF00); 240 241 paint.setShader(SkShader::MakeBitmapShader(srcBM, SkShader::kClamp_TileMode, 242 SkShader::kClamp_TileMode)); 243 } 244 for (int loop = 0; loop < loops; loop++) { 245 for (size_t i = 0; i < sizes; i++) { 246 switch (_type) { 247 case kMaskOpaque: 248 color = fColors[i]; 249 alpha = 0xFF; 250 break; 251 case kMaskBlack: 252 alpha = 0xFF; 253 color = 0xFF000000; 254 break; 255 case kMaskColor: 256 color = fColors[i]; 257 alpha = rand.nextU() & 255; 258 break; 259 case KMaskShader: 260 break; 261 } 262 paint.setStrokeWidth(gSizes[i]); 263 this->setupPaint(&paint); 264 paint.setColor(color); 265 paint.setAlpha(alpha); 266 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint); 267 } 268 } 269 } 270 const char* onGetName() override { return fName.c_str(); } 271 272 private: 273 typedef RectBench INHERITED; 274 kMaskType _type; 275 SkString fName; 276 }; 277 278 DEF_BENCH(return new RectBench(1);) 279 DEF_BENCH(return new RectBench(1, 4);) 280 DEF_BENCH(return new RectBench(3);) 281 DEF_BENCH(return new RectBench(3, 4);) 282 DEF_BENCH(return new OvalBench(1);) 283 DEF_BENCH(return new OvalBench(3);) 284 DEF_BENCH(return new OvalBench(1, 4);) 285 DEF_BENCH(return new OvalBench(3, 4);) 286 DEF_BENCH(return new RRectBench(1);) 287 DEF_BENCH(return new RRectBench(1, 4);) 288 DEF_BENCH(return new RRectBench(3);) 289 DEF_BENCH(return new RRectBench(3, 4);) 290 DEF_BENCH(return new PointsBench(SkCanvas::kPoints_PointMode, "points");) 291 DEF_BENCH(return new PointsBench(SkCanvas::kLines_PointMode, "lines");) 292 DEF_BENCH(return new PointsBench(SkCanvas::kPolygon_PointMode, "polygon");) 293 294 DEF_BENCH(return new SrcModeRectBench();) 295 296 DEF_BENCH(return new TransparentRectBench();) 297 298 /* init the blitmask bench 299 */ 300 DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode, 301 BlitMaskBench::kMaskOpaque, 302 "maskopaque");) 303 DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode, 304 BlitMaskBench::kMaskBlack, 305 "maskblack");) 306 DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode, 307 BlitMaskBench::kMaskColor, 308 "maskcolor");) 309 DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode, 310 BlitMaskBench::KMaskShader, 311 "maskshader");) 312