1 /*
2  * Copyright 2014 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 "bench/Benchmark.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkImageFilter.h"
12 #include "include/core/SkSurface.h"
13 #include "include/effects/SkGradientShader.h"
14 #include "include/effects/SkImageFilters.h"
15 
16 // Chains several matrix color filters image filter or several
17 // table filter image filters and draws a bitmap.
18 // This bench shows an improvement in performance and memory
19 // when collapsing matrices or tables is implemented since all
20 // the passes are collapsed in one.
21 
22 class BaseImageFilterCollapseBench : public Benchmark {
23 public:
BaseImageFilterCollapseBench()24     BaseImageFilterCollapseBench() {}
25 
26 protected:
doPreDraw(sk_sp<SkColorFilter> colorFilters[],int nFilters)27     void doPreDraw(sk_sp<SkColorFilter> colorFilters[], int nFilters) {
28         SkASSERT(!fImageFilter);
29 
30         // Create a chain of ImageFilters from colorFilters
31         for(int i = nFilters; i --> 0;) {
32             fImageFilter = SkImageFilters::ColorFilter(colorFilters[i], fImageFilter);
33         }
34     }
35 
onDraw(int loops,SkCanvas * canvas)36     void onDraw(int loops, SkCanvas* canvas) override {
37         makeBitmap();
38 
39         for(int i = 0; i < loops; i++) {
40             SkPaint paint;
41             paint.setImageFilter(fImageFilter);
42             canvas->drawImage(fImage, 0, 0, SkSamplingOptions(), &paint);
43         }
44     }
45 
46 private:
47     sk_sp<SkImageFilter> fImageFilter;
48     sk_sp<SkImage> fImage;
49 
makeBitmap()50     void makeBitmap() {
51         int W = 400;
52         int H = 400;
53         auto surf = SkSurface::MakeRasterN32Premul(W, H);
54 
55         SkPaint paint;
56         SkPoint pts[] = { {0, 0}, {SkIntToScalar(W), SkIntToScalar(H)} };
57         SkColor colors[] = {
58             SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN,
59             SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE
60         };
61         paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, std::size(colors),
62                                                      SkTileMode::kClamp));
63         surf->getCanvas()->drawPaint(paint);
64         fImage = surf->makeImageSnapshot();       // shader->makeImage()
65     }
66 };
67 
68 class TableCollapseBench: public BaseImageFilterCollapseBench {
69 protected:
onGetName()70     const char* onGetName() override {
71         return "image_filter_collapse_table";
72     }
73 
onDelayedSetup()74     void onDelayedSetup() override {
75         for (int i = 0; i < 256; ++i) {
76             int n = i >> 5;
77             table1[i] = (n << 5) | (n << 2) | (n >> 1);
78 
79             table2[i] = i * i / 255;
80 
81             float fi = i / 255.0f;
82             table3[i] = static_cast<uint8_t>(sqrtf(fi) * 255);
83         }
84 
85         sk_sp<SkColorFilter> colorFilters[] = {
86             SkColorFilters::Table(table1),
87             SkColorFilters::Table(table2),
88             SkColorFilters::Table(table3),
89         };
90 
91         this->doPreDraw(colorFilters, std::size(colorFilters));
92     }
93 
94 private:
95     uint8_t table1[256], table2[256], table3[256];
96 };
97 
make_brightness(float amount)98 static sk_sp<SkColorFilter> make_brightness(float amount) {
99     SkScalar matrix[20] = { 1, 0, 0, 0, amount,
100                             0, 1, 0, 0, amount,
101                             0, 0, 1, 0, amount,
102                             0, 0, 0, 1, 0 };
103     return SkColorFilters::Matrix(matrix);
104 }
105 
make_grayscale()106 static sk_sp<SkColorFilter> make_grayscale() {
107     float matrix[20];
108     memset(matrix, 0, 20 * sizeof(float));
109     matrix[0] = matrix[5] = matrix[10] = 0.2126f;
110     matrix[1] = matrix[6] = matrix[11] = 0.7152f;
111     matrix[2] = matrix[7] = matrix[12] = 0.0722f;
112     matrix[18] = 1.0f;
113     return SkColorFilters::Matrix(matrix);
114 }
115 
116 class MatrixCollapseBench: public BaseImageFilterCollapseBench {
117 protected:
onGetName()118     const char* onGetName() override {
119         return "image_filter_collapse_matrix";
120     }
121 
onDelayedSetup()122     void onDelayedSetup() override {
123         sk_sp<SkColorFilter> colorFilters[] = {
124             make_brightness(0.1f),
125             make_grayscale(),
126             make_brightness(-0.1f),
127         };
128 
129         this->doPreDraw(colorFilters, std::size(colorFilters));
130     }
131 };
132 
133 DEF_BENCH(return new TableCollapseBench;)
134 DEF_BENCH(return new MatrixCollapseBench;)
135