• 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 "Benchmark.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 Benchmark {
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 
isVisual()42     bool isVisual() override { return true; }
43 
44 protected:
drawThisRect(SkCanvas * c,const SkRect & r,const SkPaint & p)45     virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
46         c->drawRect(r, p);
47     }
48 
onGetName()49     const char* onGetName() override { return computeName("rects"); }
50 
onDelayedSetup()51     void onDelayedSetup() override {
52         SkRandom rand;
53         const SkScalar offset = SK_Scalar1/3;
54         for (int i = 0; i < N; i++) {
55             int x = rand.nextU() % W;
56             int y = rand.nextU() % H;
57             int w = rand.nextU() % W;
58             int h = rand.nextU() % H;
59             w >>= fShift;
60             h >>= fShift;
61             x -= w/2;
62             y -= h/2;
63             fRects[i].set(SkIntToScalar(x), SkIntToScalar(y),
64                           SkIntToScalar(x+w), SkIntToScalar(y+h));
65             fRects[i].offset(offset, offset);
66             fColors[i] = rand.nextU() | 0xFF808080;
67         }
68     }
69 
onDraw(int loops,SkCanvas * canvas)70     void onDraw(int loops, SkCanvas* canvas) override {
71         SkPaint paint;
72         if (fStroke > 0) {
73             paint.setStyle(SkPaint::kStroke_Style);
74             paint.setStrokeWidth(SkIntToScalar(fStroke));
75         }
76         for (int i = 0; i < loops; i++) {
77             paint.setColor(fColors[i % N]);
78             this->setupPaint(&paint);
79             this->drawThisRect(canvas, fRects[i % N], paint);
80         }
81     }
82 private:
83     typedef Benchmark INHERITED;
84 };
85 
86 class SrcModeRectBench : public RectBench {
87 public:
SrcModeRectBench()88     SrcModeRectBench() : INHERITED(1, 0) {
89         fMode = SkXfermode::Create(SkXfermode::kSrc_Mode);
90     }
91 
~SrcModeRectBench()92     virtual ~SrcModeRectBench() {
93         SkSafeUnref(fMode);
94     }
95 
96 protected:
setupPaint(SkPaint * paint)97     void setupPaint(SkPaint* paint) override {
98         this->INHERITED::setupPaint(paint);
99         // srcmode is most interesting when we're not opaque
100         paint->setAlpha(0x80);
101         paint->setXfermode(fMode);
102     }
103 
onGetName()104     const char* onGetName() override {
105         fName.set(this->INHERITED::onGetName());
106         fName.prepend("srcmode_");
107         return fName.c_str();
108     }
109 
110 private:
111     SkString fName;
112     SkXfermode* fMode;
113 
114     typedef RectBench INHERITED;
115 };
116 
117 class TransparentRectBench : public RectBench {
118 public:
TransparentRectBench()119     TransparentRectBench() : INHERITED(1, 0) {}
120 
121 protected:
setupPaint(SkPaint * paint)122     void setupPaint(SkPaint* paint) override {
123         this->INHERITED::setupPaint(paint);
124         // draw non opaque rect
125         paint->setAlpha(0x80);
126     }
127 
onGetName()128     const char* onGetName() override {
129         fName.set(this->INHERITED::onGetName());
130         fName.prepend("transparent_");
131         return fName.c_str();
132     }
133 
134 private:
135     SkString fName;
136 
137     typedef RectBench INHERITED;
138 };
139 
140 
141 class OvalBench : public RectBench {
142 public:
OvalBench(int shift,int stroke=0)143     OvalBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
144 protected:
drawThisRect(SkCanvas * c,const SkRect & r,const SkPaint & p)145     void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
146         c->drawOval(r, p);
147     }
onGetName()148     const char* onGetName() override { return computeName("ovals"); }
149 };
150 
151 class RRectBench : public RectBench {
152 public:
RRectBench(int shift,int stroke=0)153     RRectBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
154 protected:
drawThisRect(SkCanvas * c,const SkRect & r,const SkPaint & p)155     void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
156         c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
157     }
onGetName()158     const char* onGetName() override { return computeName("rrects"); }
159 };
160 
161 class PointsBench : public RectBench {
162 public:
163     SkCanvas::PointMode fMode;
164     const char* fName;
165 
PointsBench(SkCanvas::PointMode mode,const char * name)166     PointsBench(SkCanvas::PointMode mode, const char* name)
167         : RectBench(2)
168         , fMode(mode) {
169         fName = name;
170     }
171 
172 protected:
onDraw(int loops,SkCanvas * canvas)173     void onDraw(int loops, SkCanvas* canvas) override {
174         SkScalar gSizes[] = {
175             SkIntToScalar(7), 0
176         };
177         size_t sizes = SK_ARRAY_COUNT(gSizes);
178 
179         if (FLAGS_strokeWidth >= 0) {
180             gSizes[0] = (SkScalar)FLAGS_strokeWidth;
181             sizes = 1;
182         }
183 
184         SkPaint paint;
185         paint.setStrokeCap(SkPaint::kRound_Cap);
186 
187         for (int loop = 0; loop < loops; loop++) {
188             for (size_t i = 0; i < sizes; i++) {
189                 paint.setStrokeWidth(gSizes[i]);
190                 this->setupPaint(&paint);
191                 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
192                 paint.setColor(fColors[i % N]);
193             }
194         }
195     }
onGetName()196     const char* onGetName() override { return fName; }
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 
BlitMaskBench(SkCanvas::PointMode mode,BlitMaskBench::kMaskType type,const char * name)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:
onDraw(int loops,SkCanvas * canvas)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             SkShader* s;
242             s  = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode,
243                                               SkShader::kClamp_TileMode);
244             paint.setShader(s)->unref();
245         }
246         for (int loop = 0; loop < loops; loop++) {
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     }
onGetName()272     const char* onGetName() override { return fName; }
273 private:
274     typedef RectBench INHERITED;
275     kMaskType _type;
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