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 "SkPaint.h"
11#include "SkRandom.h"
12#include "SkString.h"
13#include "SkShader.h"
14
15class RectBench : public SkBenchmark {
16public:
17    int fShift, fStroke;
18    enum {
19        W = 640,
20        H = 480,
21        N = SkBENCHLOOP(300)
22    };
23    SkRect  fRects[N];
24    SkColor fColors[N];
25
26    RectBench(void* param, int shift, int stroke = 0) : INHERITED(param), fShift(shift), fStroke(stroke) {
27        SkRandom rand;
28        const SkScalar offset = SK_Scalar1/3;
29        for (int i = 0; i < N; i++) {
30            int x = rand.nextU() % W;
31            int y = rand.nextU() % H;
32            int w = rand.nextU() % W;
33            int h = rand.nextU() % H;
34            w >>= shift;
35            h >>= shift;
36            x -= w/2;
37            y -= h/2;
38            fRects[i].set(SkIntToScalar(x), SkIntToScalar(y),
39                          SkIntToScalar(x+w), SkIntToScalar(y+h));
40            fRects[i].offset(offset, offset);
41            fColors[i] = rand.nextU() | 0xFF808080;
42        }
43    }
44
45    SkString fName;
46    const char* computeName(const char root[]) {
47        fName.printf("%s_%d", root, fShift);
48        if (fStroke > 0) {
49            fName.appendf("_stroke_%d", fStroke);
50        }
51        return fName.c_str();
52    }
53
54protected:
55    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
56        c->drawRect(r, p);
57    }
58
59    virtual const char* onGetName() { return computeName("rects"); }
60    virtual void onDraw(SkCanvas* canvas) {
61        SkPaint paint;
62        if (fStroke > 0) {
63            paint.setStyle(SkPaint::kStroke_Style);
64            paint.setStrokeWidth(SkIntToScalar(fStroke));
65        }
66        for (int i = 0; i < N; i++) {
67            paint.setColor(fColors[i]);
68            this->setupPaint(&paint);
69            this->drawThisRect(canvas, fRects[i], paint);
70        }
71    }
72private:
73    typedef SkBenchmark INHERITED;
74};
75
76class OvalBench : public RectBench {
77public:
78    OvalBench(void* param, int shift) : RectBench(param, shift) {}
79protected:
80    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
81        c->drawOval(r, p);
82    }
83    virtual const char* onGetName() { return computeName("ovals"); }
84};
85
86class RRectBench : public RectBench {
87public:
88    RRectBench(void* param, int shift) : RectBench(param, shift) {}
89protected:
90    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
91        c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
92    }
93    virtual const char* onGetName() { return computeName("rrects"); }
94};
95
96class PointsBench : public RectBench {
97public:
98    SkCanvas::PointMode fMode;
99    const char* fName;
100
101    PointsBench(void* param, SkCanvas::PointMode mode, const char* name) :
102        RectBench(param, 2), fMode(mode) {
103        fName = name;
104    }
105
106protected:
107    virtual void onDraw(SkCanvas* canvas) {
108        SkScalar gSizes[] = {
109            SkIntToScalar(7), 0
110        };
111        size_t sizes = SK_ARRAY_COUNT(gSizes);
112
113        if (this->hasStrokeWidth()) {
114            gSizes[0] = this->getStrokeWidth();
115            sizes = 1;
116        }
117
118        SkPaint paint;
119        paint.setStrokeCap(SkPaint::kRound_Cap);
120
121        for (size_t i = 0; i < sizes; i++) {
122            paint.setStrokeWidth(gSizes[i]);
123            this->setupPaint(&paint);
124            canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
125            paint.setColor(fColors[i]);
126        }
127    }
128    virtual const char* onGetName() { return fName; }
129};
130
131/*******************************************************************************
132 * to bench BlitMask [Opaque, Black, color, shader]
133 *******************************************************************************/
134
135class BlitMaskBench : public RectBench {
136public:
137    enum kMaskType {
138        kMaskOpaque = 0,
139        kMaskBlack,
140        kMaskColor,
141        KMaskShader
142    };
143    SkCanvas::PointMode fMode;
144    const char* fName;
145
146    BlitMaskBench(void* param, SkCanvas::PointMode mode,
147                  BlitMaskBench::kMaskType type, const char* name) :
148                  RectBench(param, 2), fMode(mode), _type(type) {
149        fName = name;
150    }
151
152protected:
153    virtual void onDraw(SkCanvas* canvas) {
154        SkScalar gSizes[] = {
155            SkIntToScalar(13), SkIntToScalar(24)
156        };
157        size_t sizes = SK_ARRAY_COUNT(gSizes);
158
159        if (this->hasStrokeWidth()) {
160            gSizes[0] = this->getStrokeWidth();
161            sizes = 1;
162        }
163        SkRandom rand;
164        SkColor color = 0xFF000000;
165        U8CPU alpha = 0xFF;
166        SkPaint paint;
167        paint.setStrokeCap(SkPaint::kRound_Cap);
168        if (_type == KMaskShader) {
169            SkBitmap srcBM;
170            srcBM.setConfig(SkBitmap::kARGB_8888_Config, 10, 1);
171            srcBM.allocPixels();
172            srcBM.eraseColor(0xFF00FF00);
173
174            SkShader* s;
175            s  = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode,
176                                              SkShader::kClamp_TileMode);
177            paint.setShader(s)->unref();
178        }
179        for (size_t i = 0; i < sizes; i++) {
180            switch (_type) {
181                case kMaskOpaque:
182                    color = fColors[i];
183                    alpha = 0xFF;
184                    break;
185                case kMaskBlack:
186                    alpha = 0xFF;
187                    color = 0xFF000000;
188                    break;
189                case kMaskColor:
190                    color = fColors[i];
191                    alpha = rand.nextU() & 255;
192                    break;
193                case KMaskShader:
194                    break;
195            }
196            paint.setStrokeWidth(gSizes[i]);
197            this->setupPaint(&paint);
198            paint.setColor(color);
199            paint.setAlpha(alpha);
200            canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
201       }
202    }
203    virtual const char* onGetName() { return fName; }
204private:
205	typedef RectBench INHERITED;
206	kMaskType _type;
207};
208
209
210static SkBenchmark* RectFactory1F(void* p) { return SkNEW_ARGS(RectBench, (p, 1)); }
211static SkBenchmark* RectFactory1S(void* p) { return SkNEW_ARGS(RectBench, (p, 1, 4)); }
212static SkBenchmark* RectFactory2F(void* p) { return SkNEW_ARGS(RectBench, (p, 3)); }
213static SkBenchmark* RectFactory2S(void* p) { return SkNEW_ARGS(RectBench, (p, 3, 4)); }
214static SkBenchmark* OvalFactory1(void* p) { return SkNEW_ARGS(OvalBench, (p, 1)); }
215static SkBenchmark* OvalFactory2(void* p) { return SkNEW_ARGS(OvalBench, (p, 3)); }
216static SkBenchmark* RRectFactory1(void* p) { return SkNEW_ARGS(RRectBench, (p, 1)); }
217static SkBenchmark* RRectFactory2(void* p) { return SkNEW_ARGS(RRectBench, (p, 3)); }
218static SkBenchmark* PointsFactory(void* p) {
219    return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPoints_PointMode, "points"));
220}
221static SkBenchmark* LinesFactory(void* p) {
222    return SkNEW_ARGS(PointsBench, (p, SkCanvas::kLines_PointMode, "lines"));
223}
224static SkBenchmark* PolygonFactory(void* p) {
225    return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon"));
226}
227
228/* init the blitmask bench
229 */
230static SkBenchmark* BlitMaskOpaqueFactory(void* p) {
231    return SkNEW_ARGS(BlitMaskBench,
232                      (p, SkCanvas::kPoints_PointMode,
233                      BlitMaskBench::kMaskOpaque, "maskopaque")
234                      );
235}
236static SkBenchmark* BlitMaskBlackFactory(void* p) {
237    return SkNEW_ARGS(BlitMaskBench,
238                      (p, SkCanvas::kPoints_PointMode,
239                      BlitMaskBench::kMaskBlack, "maskblack")
240                      );
241}
242static SkBenchmark* BlitMaskColorFactory(void* p) {
243    return SkNEW_ARGS(BlitMaskBench,
244                      (p, SkCanvas::kPoints_PointMode,
245                      BlitMaskBench::kMaskColor, "maskcolor")
246                      );
247}
248static SkBenchmark* BlitMaskShaderFactory(void* p) {
249    return SkNEW_ARGS(BlitMaskBench,
250                     (p, SkCanvas::kPoints_PointMode,
251                     BlitMaskBench::KMaskShader, "maskshader")
252                     );
253}
254
255static BenchRegistry gRectReg1F(RectFactory1F);
256static BenchRegistry gRectReg1S(RectFactory1S);
257static BenchRegistry gRectReg2F(RectFactory2F);
258static BenchRegistry gRectReg2S(RectFactory2S);
259static BenchRegistry gOvalReg1(OvalFactory1);
260static BenchRegistry gOvalReg2(OvalFactory2);
261static BenchRegistry gRRectReg1(RRectFactory1);
262static BenchRegistry gRRectReg2(RRectFactory2);
263static BenchRegistry gPointsReg(PointsFactory);
264static BenchRegistry gLinesReg(LinesFactory);
265static BenchRegistry gPolygonReg(PolygonFactory);
266static BenchRegistry gRectRegOpaque(BlitMaskOpaqueFactory);
267static BenchRegistry gRectRegBlack(BlitMaskBlackFactory);
268static BenchRegistry gRectRegColor(BlitMaskColorFactory);
269static BenchRegistry gRectRegShader(BlitMaskShaderFactory);
270