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