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