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