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