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