• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RectBench(int shift,int stroke=0)30     RectBench(int shift, int stroke = 0)
31         : fShift(shift)
32         , fStroke(stroke) {}
33 
computeName(const char root[])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 
isVisual()42     bool isVisual() override { return true; }
43 
44 protected:
45 
drawThisRect(SkCanvas * c,const SkRect & r,const SkPaint & p)46     virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
47         c->drawRect(r, p);
48     }
49 
onGetName()50     const char* onGetName() override { return computeName("rects"); }
51 
onDelayedSetup()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 
onDraw(int loops,SkCanvas * canvas)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:
SrcModeRectBench()91     SrcModeRectBench() : INHERITED(1, 0) {
92         fMode = SkBlendMode::kSrc;
93     }
94 
95 protected:
setupPaint(SkPaint * paint)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 
onGetName()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:
TransparentRectBench()118     TransparentRectBench() : INHERITED(1, 0) {}
119 
120 protected:
setupPaint(SkPaint * paint)121     void setupPaint(SkPaint* paint) override {
122         this->INHERITED::setupPaint(paint);
123         // draw non opaque rect
124         paint->setAlpha(0x80);
125     }
126 
onGetName()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:
OvalBench(int shift,int stroke=0)141     OvalBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
142 protected:
drawThisRect(SkCanvas * c,const SkRect & r,const SkPaint & p)143     void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
144         c->drawOval(r, p);
145     }
onGetName()146     const char* onGetName() override { return computeName("ovals"); }
147 };
148 
149 class RRectBench : public RectBench {
150 public:
RRectBench(int shift,int stroke=0)151     RRectBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
152 protected:
drawThisRect(SkCanvas * c,const SkRect & r,const SkPaint & p)153     void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
154         c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
155     }
onGetName()156     const char* onGetName() override { return computeName("rrects"); }
157 };
158 
159 class PointsBench : public RectBench {
160 public:
161     SkCanvas::PointMode fMode;
162 
PointsBench(SkCanvas::PointMode mode,const char * name)163     PointsBench(SkCanvas::PointMode mode, const char* name)
164         : RectBench(2)
165         , fMode(mode) {
166         fName = name;
167     }
168 
169 protected:
onDraw(int loops,SkCanvas * canvas)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     }
onGetName()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 
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             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     }
onGetName()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