1/*
2 * Copyright 2013 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 "SkCanvas.h"
10#include "SkColorFilterImageFilter.h"
11#include "SkColorMatrixFilter.h"
12#include "SkLumaColorFilter.h"
13#include "SkTableColorFilter.h"
14
15#define FILTER_WIDTH_SMALL  SkIntToScalar(32)
16#define FILTER_HEIGHT_SMALL SkIntToScalar(32)
17#define FILTER_WIDTH_LARGE  SkIntToScalar(256)
18#define FILTER_HEIGHT_LARGE SkIntToScalar(256)
19
20class ColorFilterBaseBench : public Benchmark {
21
22public:
23    ColorFilterBaseBench(bool small) : fIsSmall(small) {}
24
25protected:
26    SkRect getFilterRect() const {
27        return isSmall() ? SkRect::MakeWH(FILTER_WIDTH_SMALL, FILTER_HEIGHT_SMALL) :
28                           SkRect::MakeWH(FILTER_WIDTH_LARGE, FILTER_HEIGHT_LARGE);
29    }
30
31    static SkImageFilter* make_brightness(float amount, SkImageFilter* input = NULL) {
32        SkScalar amount255 = SkScalarMul(amount, SkIntToScalar(255));
33        SkScalar matrix[20] = { 1, 0, 0, 0, amount255,
34                                0, 1, 0, 0, amount255,
35                                0, 0, 1, 0, amount255,
36                                0, 0, 0, 1, 0 };
37        SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix));
38        return SkColorFilterImageFilter::Create(filter, input);
39    }
40
41    static SkImageFilter* make_grayscale(SkImageFilter* input = NULL) {
42        SkScalar matrix[20];
43        memset(matrix, 0, 20 * sizeof(SkScalar));
44        matrix[0] = matrix[5] = matrix[10] = 0.2126f;
45        matrix[1] = matrix[6] = matrix[11] = 0.7152f;
46        matrix[2] = matrix[7] = matrix[12] = 0.0722f;
47        matrix[18] = 1.0f;
48        SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix));
49        return SkColorFilterImageFilter::Create(filter, input);
50    }
51
52    static SkImageFilter* make_mode_blue(SkImageFilter* input = NULL) {
53        SkAutoTUnref<SkColorFilter> filter(
54            SkColorFilter::CreateModeFilter(SK_ColorBLUE, SkXfermode::kSrcIn_Mode));
55        return SkColorFilterImageFilter::Create(filter, input);
56    }
57
58    inline bool isSmall() const { return fIsSmall; }
59
60private:
61    bool fIsSmall;
62
63    typedef Benchmark INHERITED;
64};
65
66class ColorFilterDimBrightBench : public ColorFilterBaseBench {
67
68public:
69    ColorFilterDimBrightBench(bool small) : INHERITED(small) {
70    }
71
72protected:
73    const char* onGetName() override {
74        return isSmall() ? "colorfilter_dim_bright_small" : "colorfilter_dim_bright_large";
75    }
76
77    void onDraw(const int loops, SkCanvas* canvas) override {
78        SkRect r = getFilterRect();
79        SkPaint paint;
80        paint.setColor(SK_ColorRED);
81
82        for (int i = 0; i < loops; i++) {
83            for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.4f) {
84                SkAutoTUnref<SkImageFilter> dim(make_brightness(-brightness));
85                SkAutoTUnref<SkImageFilter> bright(make_brightness(brightness, dim));
86                paint.setImageFilter(bright);
87                canvas->drawRect(r, paint);
88            }
89        }
90    }
91
92private:
93    typedef ColorFilterBaseBench INHERITED;
94};
95
96class ColorFilterBrightGrayBench : public ColorFilterBaseBench {
97
98public:
99    ColorFilterBrightGrayBench(bool small) : INHERITED(small) {
100    }
101
102protected:
103    const char* onGetName() override {
104        return isSmall() ? "colorfilter_bright_gray_small" : "colorfilter_bright_gray_large";
105    }
106
107    void onDraw(const int loops, SkCanvas* canvas) override {
108        SkRect r = getFilterRect();
109        SkPaint paint;
110        paint.setColor(SK_ColorRED);
111        for (int i = 0; i < loops; i++) {
112            SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f));
113            SkAutoTUnref<SkImageFilter> grayscale(make_grayscale(brightness));
114            paint.setImageFilter(grayscale);
115            canvas->drawRect(r, paint);
116        }
117    }
118
119private:
120    typedef ColorFilterBaseBench INHERITED;
121};
122
123class ColorFilterGrayBrightBench : public ColorFilterBaseBench {
124
125public:
126    ColorFilterGrayBrightBench(bool small) : INHERITED(small) {
127    }
128
129protected:
130    const char* onGetName() override {
131        return isSmall() ? "colorfilter_gray_bright_small" : "colorfilter_gray_bright_large";
132    }
133
134    void onDraw(const int loops, SkCanvas* canvas) override {
135        SkRect r = getFilterRect();
136        SkPaint paint;
137        paint.setColor(SK_ColorRED);
138        for (int i = 0; i < loops; i++) {
139            SkAutoTUnref<SkImageFilter> grayscale(make_grayscale());
140            SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f, grayscale));
141            paint.setImageFilter(brightness);
142            canvas->drawRect(r, paint);
143        }
144    }
145
146private:
147    typedef ColorFilterBaseBench INHERITED;
148};
149
150class ColorFilterBlueBrightBench : public ColorFilterBaseBench {
151
152public:
153    ColorFilterBlueBrightBench(bool small) : INHERITED(small) {
154    }
155
156protected:
157    const char* onGetName() override {
158        return isSmall() ? "colorfilter_blue_bright_small" : "colorfilter_blue_bright_large";
159    }
160
161    void onDraw(const int loops, SkCanvas* canvas) override {
162        SkRect r = getFilterRect();
163        SkPaint paint;
164        paint.setColor(SK_ColorRED);
165        for (int i = 0; i < loops; i++) {
166            SkAutoTUnref<SkImageFilter> blue(make_mode_blue());
167            SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f, blue));
168            paint.setImageFilter(brightness);
169            canvas->drawRect(r, paint);
170        }
171    }
172
173private:
174    typedef ColorFilterBaseBench INHERITED;
175};
176
177class ColorFilterBrightBlueBench : public ColorFilterBaseBench {
178
179public:
180    ColorFilterBrightBlueBench(bool small) : INHERITED(small) {
181    }
182
183protected:
184    const char* onGetName() override {
185        return isSmall() ? "colorfilter_bright_blue_small" : "colorfilter_bright_blue_large";
186    }
187
188    void onDraw(const int loops, SkCanvas* canvas) override {
189        SkRect r = getFilterRect();
190        SkPaint paint;
191        paint.setColor(SK_ColorRED);
192        for (int i = 0; i < loops; i++) {
193            SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f));
194            SkAutoTUnref<SkImageFilter> blue(make_mode_blue(brightness));
195            paint.setImageFilter(blue);
196            canvas->drawRect(r, paint);
197        }
198    }
199
200private:
201    typedef ColorFilterBaseBench INHERITED;
202};
203
204class ColorFilterBrightBench : public ColorFilterBaseBench {
205
206public:
207    ColorFilterBrightBench(bool small) : INHERITED(small) {
208    }
209
210protected:
211    const char* onGetName() override {
212        return isSmall() ? "colorfilter_bright_small" : "colorfilter_bright_large";
213    }
214
215    void onDraw(const int loops, SkCanvas* canvas) override {
216        SkRect r = getFilterRect();
217        SkPaint paint;
218        paint.setColor(SK_ColorRED);
219        for (int i = 0; i < loops; i++) {
220            SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f));
221            paint.setImageFilter(brightness);
222            canvas->drawRect(r, paint);
223        }
224    }
225
226private:
227    typedef ColorFilterBaseBench INHERITED;
228};
229
230class ColorFilterBlueBench : public ColorFilterBaseBench {
231
232public:
233    ColorFilterBlueBench(bool small) : INHERITED(small) {
234    }
235
236protected:
237    const char* onGetName() override {
238        return isSmall() ? "colorfilter_blue_small" : "colorfilter_blue_large";
239    }
240
241    void onDraw(const int loops, SkCanvas* canvas) override {
242        SkRect r = getFilterRect();
243        SkPaint paint;
244        paint.setColor(SK_ColorRED);
245        for (int i = 0; i < loops; i++) {
246            SkAutoTUnref<SkImageFilter> blue(make_mode_blue());
247            paint.setImageFilter(blue);
248            canvas->drawRect(r, paint);
249        }
250    }
251
252private:
253    typedef ColorFilterBaseBench INHERITED;
254};
255
256class ColorFilterGrayBench : public ColorFilterBaseBench {
257
258public:
259    ColorFilterGrayBench(bool small) : INHERITED(small) {}
260
261protected:
262    const char* onGetName() override {
263        return isSmall() ? "colorfilter_gray_small" : "colorfilter_gray_large";
264    }
265
266    void onDraw(const int loops, SkCanvas* canvas) override {
267        SkRect r = getFilterRect();
268        SkPaint paint;
269        paint.setColor(SK_ColorRED);
270        for (int i = 0; i < loops; i++) {
271            SkAutoTUnref<SkImageFilter> grayscale(make_grayscale());
272            paint.setImageFilter(grayscale);
273            canvas->drawRect(r, paint);
274        }
275    }
276
277private:
278    typedef ColorFilterBaseBench INHERITED;
279};
280
281///////////////////////////////////////////////////////////////////////////////
282
283DEF_BENCH( return new ColorFilterDimBrightBench(true); )
284DEF_BENCH( return new ColorFilterBrightGrayBench(true); )
285DEF_BENCH( return new ColorFilterGrayBrightBench(true); )
286DEF_BENCH( return new ColorFilterBlueBrightBench(true); )
287DEF_BENCH( return new ColorFilterBrightBlueBench(true); )
288DEF_BENCH( return new ColorFilterBrightBench(true); )
289DEF_BENCH( return new ColorFilterBlueBench(true); )
290DEF_BENCH( return new ColorFilterGrayBench(true); )
291
292DEF_BENCH( return new ColorFilterDimBrightBench(false); )
293DEF_BENCH( return new ColorFilterBrightGrayBench(false); )
294DEF_BENCH( return new ColorFilterGrayBrightBench(false); )
295DEF_BENCH( return new ColorFilterBlueBrightBench(false); )
296DEF_BENCH( return new ColorFilterBrightBlueBench(false); )
297DEF_BENCH( return new ColorFilterBrightBench(false); )
298DEF_BENCH( return new ColorFilterBlueBench(false); )
299DEF_BENCH( return new ColorFilterGrayBench(false); )
300