• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkFont.h"
11 #include "SkDisplacementMapEffect.h"
12 #include "SkImageSource.h"
13 #include "SkSurface.h"
14 
15 #define FILTER_WIDTH_SMALL  32
16 #define FILTER_HEIGHT_SMALL 32
17 #define FILTER_WIDTH_LARGE  256
18 #define FILTER_HEIGHT_LARGE 256
19 
20 class DisplacementBaseBench : public Benchmark {
21 public:
DisplacementBaseBench(bool small)22     DisplacementBaseBench(bool small) : fInitialized(false), fIsSmall(small) { }
23 
24 protected:
onDelayedSetup()25     void onDelayedSetup() override {
26         if (!fInitialized) {
27             this->makeBitmap();
28             this->makeCheckerboard();
29             fInitialized = true;
30         }
31     }
32 
makeBitmap()33     void makeBitmap() {
34         const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
35         const int h = this->isSmall() ? FILTER_HEIGHT_SMALL : FILTER_HEIGHT_LARGE;
36         fBitmap.allocN32Pixels(w, h);
37         SkCanvas canvas(fBitmap);
38         canvas.clear(0x00000000);
39         SkPaint paint;
40         paint.setColor(0xFF884422);
41 
42         SkFont font;
43         font.setSize(SkIntToScalar(96));
44         canvas.drawSimpleText("g", 1, kUTF8_SkTextEncoding, SkIntToScalar(15), SkIntToScalar(55), font, paint);
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(SkSurface::MakeRasterN32Premul(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->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
75                                           SkIntToScalar(fBitmap.width()),
76                                           SkIntToScalar(fBitmap.height())));
77         canvas->drawBitmap(fBitmap, SkIntToScalar(x), SkIntToScalar(y), &paint);
78         canvas->restore();
79     }
80 
isSmall() const81     inline bool isSmall() const { return fIsSmall; }
82 
83     SkBitmap fBitmap;
84     sk_sp<SkImage> fCheckerboard;
85 
86 private:
87     bool fInitialized;
88     bool fIsSmall;
89     typedef Benchmark INHERITED;
90 };
91 
92 class DisplacementZeroBench : public DisplacementBaseBench {
93 public:
DisplacementZeroBench(bool small)94     DisplacementZeroBench(bool small) : INHERITED(small) { }
95 
96 protected:
onGetName()97     const char* onGetName() override {
98         return this->isSmall() ? "displacement_zero_small" : "displacement_zero_large";
99     }
100 
onDraw(int loops,SkCanvas * canvas)101     void onDraw(int loops, SkCanvas* canvas) override {
102         SkPaint paint;
103         sk_sp<SkImageFilter> displ(SkImageSource::Make(fCheckerboard));
104         // No displacement effect
105         paint.setImageFilter(SkDisplacementMapEffect::Make(
106                                                 SkDisplacementMapEffect::kR_ChannelSelectorType,
107                                                 SkDisplacementMapEffect::kG_ChannelSelectorType,
108                                                 0.0f, std::move(displ), nullptr));
109 
110         for (int i = 0; i < loops; i++) {
111             this->drawClippedBitmap(canvas, 0, 0, paint);
112         }
113     }
114 
115 private:
116     typedef DisplacementBaseBench INHERITED;
117 };
118 
119 class DisplacementAlphaBench : public DisplacementBaseBench {
120 public:
DisplacementAlphaBench(bool small)121     DisplacementAlphaBench(bool small) : INHERITED(small) { }
122 
123 protected:
onGetName()124     const char* onGetName() override {
125         return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large";
126     }
127 
onDraw(int loops,SkCanvas * canvas)128     void onDraw(int loops, SkCanvas* canvas) override {
129         SkPaint paint;
130         sk_sp<SkImageFilter> displ(SkImageSource::Make(fCheckerboard));
131         // Displacement, with 1 alpha component (which isn't pre-multiplied)
132         paint.setImageFilter(SkDisplacementMapEffect::Make(
133                                                 SkDisplacementMapEffect::kB_ChannelSelectorType,
134                                                 SkDisplacementMapEffect::kA_ChannelSelectorType,
135                                                 16.0f, std::move(displ), nullptr));
136         for (int i = 0; i < loops; i++) {
137             this->drawClippedBitmap(canvas, 100, 0, paint);
138         }
139     }
140 
141 private:
142     typedef DisplacementBaseBench INHERITED;
143 };
144 
145 class DisplacementFullBench : public DisplacementBaseBench {
146 public:
DisplacementFullBench(bool small)147     DisplacementFullBench(bool small) : INHERITED(small) { }
148 
149 protected:
onGetName()150     const char* onGetName() override {
151         return isSmall() ? "displacement_full_small" : "displacement_full_large";
152     }
153 
onDraw(int loops,SkCanvas * canvas)154     void onDraw(int loops, SkCanvas* canvas) override {
155         SkPaint paint;
156         sk_sp<SkImageFilter> displ(SkImageSource::Make(fCheckerboard));
157         // Displacement, with 2 non-alpha components
158         paint.setImageFilter(SkDisplacementMapEffect::Make(
159                                                 SkDisplacementMapEffect::kR_ChannelSelectorType,
160                                                 SkDisplacementMapEffect::kB_ChannelSelectorType,
161                                                 32.0f, std::move(displ), nullptr));
162         for (int i = 0; i < loops; ++i) {
163             this->drawClippedBitmap(canvas, 200, 0, paint);
164         }
165     }
166 
167 private:
168     typedef DisplacementBaseBench INHERITED;
169 };
170 
171 ///////////////////////////////////////////////////////////////////////////////
172 
173 DEF_BENCH( return new DisplacementZeroBench(true); )
174 DEF_BENCH( return new DisplacementAlphaBench(true); )
175 DEF_BENCH( return new DisplacementFullBench(true); )
176 DEF_BENCH( return new DisplacementZeroBench(false); )
177 DEF_BENCH( return new DisplacementAlphaBench(false); )
178 DEF_BENCH( return new DisplacementFullBench(false); )
179