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