xref: /aosp_15_r20/external/skia/bench/DisplacementBench.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 "bench/Benchmark.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkFont.h"
12 #include "include/core/SkSurface.h"
13 #include "include/effects/SkImageFilters.h"
14 #include "tools/fonts/FontToolUtils.h"
15 
16 #define FILTER_WIDTH_SMALL  32
17 #define FILTER_HEIGHT_SMALL 32
18 #define FILTER_WIDTH_LARGE  256
19 #define FILTER_HEIGHT_LARGE 256
20 
21 class DisplacementBaseBench : public Benchmark {
22 public:
DisplacementBaseBench(bool small)23     DisplacementBaseBench(bool small) : fInitialized(false), fIsSmall(small) { }
24 
25 protected:
onDelayedSetup()26     void onDelayedSetup() override {
27         if (!fInitialized) {
28             this->makeBitmap();
29             this->makeCheckerboard();
30             fInitialized = true;
31         }
32     }
33 
makeBitmap()34     void makeBitmap() {
35         const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
36         const int h = this->isSmall() ? FILTER_HEIGHT_SMALL : FILTER_HEIGHT_LARGE;
37         auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(w, h));
38         SkPaint paint;
39         paint.setColor(0xFF884422);
40 
41         SkFont font = ToolUtils::DefaultFont();
42         font.setSize(SkIntToScalar(96));
43         surf->getCanvas()->drawSimpleText("g", 1, SkTextEncoding::kUTF8, 15, 55, font, paint);
44         fImage = surf->makeImageSnapshot();
45     }
46 
makeCheckerboard()47     void makeCheckerboard() {
48         const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
49         const int h = this->isSmall() ? FILTER_HEIGHT_SMALL : FILTER_HEIGHT_LARGE;
50         auto surface(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(w, h)));
51         SkCanvas* canvas = surface->getCanvas();
52         canvas->clear(0x00000000);
53         SkPaint darkPaint;
54         darkPaint.setColor(0xFF804020);
55         SkPaint lightPaint;
56         lightPaint.setColor(0xFF244484);
57         for (int y = 0; y < h; y += 16) {
58             for (int x = 0; x < w; x += 16) {
59                 canvas->save();
60                 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
61                 canvas->drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
62                 canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
63                 canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
64                 canvas->drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
65                 canvas->restore();
66             }
67         }
68 
69         fCheckerboard = surface->makeImageSnapshot();
70     }
71 
drawClippedBitmap(SkCanvas * canvas,int x,int y,const SkPaint & paint)72     void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) {
73         canvas->save();
74         canvas->clipIRect(fImage->bounds().makeOffset(x, y));
75         canvas->drawImage(fImage, SkIntToScalar(x), SkIntToScalar(y), SkSamplingOptions(), &paint);
76         canvas->restore();
77     }
78 
isSmall() const79     inline bool isSmall() const { return fIsSmall; }
80 
81     sk_sp<SkImage> fImage, fCheckerboard;
82 
83 private:
84     bool fInitialized;
85     bool fIsSmall;
86     using INHERITED = Benchmark;
87 };
88 
89 class DisplacementZeroBench : public DisplacementBaseBench {
90 public:
DisplacementZeroBench(bool small)91     DisplacementZeroBench(bool small) : INHERITED(small) { }
92 
93 protected:
onGetName()94     const char* onGetName() override {
95         return this->isSmall() ? "displacement_zero_small" : "displacement_zero_large";
96     }
97 
onDraw(int loops,SkCanvas * canvas)98     void onDraw(int loops, SkCanvas* canvas) override {
99         SkPaint paint;
100         sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard, SkFilterMode::kLinear));
101         // No displacement effect
102         paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kG,
103                                                              0.0f, std::move(displ), nullptr));
104 
105         for (int i = 0; i < loops; i++) {
106             this->drawClippedBitmap(canvas, 0, 0, paint);
107         }
108     }
109 
110 private:
111     using INHERITED = DisplacementBaseBench;
112 };
113 
114 class DisplacementAlphaBench : public DisplacementBaseBench {
115 public:
DisplacementAlphaBench(bool small)116     DisplacementAlphaBench(bool small) : INHERITED(small) { }
117 
118 protected:
onGetName()119     const char* onGetName() override {
120         return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large";
121     }
122 
onDraw(int loops,SkCanvas * canvas)123     void onDraw(int loops, SkCanvas* canvas) override {
124         SkPaint paint;
125         sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard, SkFilterMode::kLinear));
126         // Displacement, with 1 alpha component (which isn't pre-multiplied)
127         paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kB, SkColorChannel::kA,
128                                                              16.0f, std::move(displ), nullptr));
129         for (int i = 0; i < loops; i++) {
130             this->drawClippedBitmap(canvas, 100, 0, paint);
131         }
132     }
133 
134 private:
135     using INHERITED = DisplacementBaseBench;
136 };
137 
138 class DisplacementFullBench : public DisplacementBaseBench {
139 public:
DisplacementFullBench(bool small)140     DisplacementFullBench(bool small) : INHERITED(small) { }
141 
142 protected:
onGetName()143     const char* onGetName() override {
144         return isSmall() ? "displacement_full_small" : "displacement_full_large";
145     }
146 
onDraw(int loops,SkCanvas * canvas)147     void onDraw(int loops, SkCanvas* canvas) override {
148         SkPaint paint;
149         sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard, SkFilterMode::kLinear));
150         // Displacement, with 2 non-alpha components
151         paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kB,
152                                                              32.0f, std::move(displ), nullptr));
153         for (int i = 0; i < loops; ++i) {
154             this->drawClippedBitmap(canvas, 200, 0, paint);
155         }
156     }
157 
158 private:
159     using INHERITED = DisplacementBaseBench;
160 };
161 
162 ///////////////////////////////////////////////////////////////////////////////
163 
164 DEF_BENCH( return new DisplacementZeroBench(true); )
165 DEF_BENCH( return new DisplacementAlphaBench(true); )
166 DEF_BENCH( return new DisplacementFullBench(true); )
167 DEF_BENCH( return new DisplacementZeroBench(false); )
168 DEF_BENCH( return new DisplacementAlphaBench(false); )
169 DEF_BENCH( return new DisplacementFullBench(false); )
170