• 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 "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 
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         auto surf = SkSurface::MakeRasterN32Premul(w, h);
37         SkPaint paint;
38         paint.setColor(0xFF884422);
39 
40         SkFont font;
41         font.setSize(SkIntToScalar(96));
42         surf->getCanvas()->drawSimpleText("g", 1, SkTextEncoding::kUTF8, 15, 55, font, paint);
43         fImage = surf->makeImageSnapshot();
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_SMALL : 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->clipIRect(fImage->bounds().makeOffset(x, y));
74         canvas->drawImage(fImage, SkIntToScalar(x), SkIntToScalar(y), SkSamplingOptions(), &paint);
75         canvas->restore();
76     }
77 
isSmall() const78     inline bool isSmall() const { return fIsSmall; }
79 
80     sk_sp<SkImage> fImage, fCheckerboard;
81 
82 private:
83     bool fInitialized;
84     bool fIsSmall;
85     using INHERITED = Benchmark;
86 };
87 
88 class DisplacementZeroBench : public DisplacementBaseBench {
89 public:
DisplacementZeroBench(bool small)90     DisplacementZeroBench(bool small) : INHERITED(small) { }
91 
92 protected:
onGetName()93     const char* onGetName() override {
94         return this->isSmall() ? "displacement_zero_small" : "displacement_zero_large";
95     }
96 
onDraw(int loops,SkCanvas * canvas)97     void onDraw(int loops, SkCanvas* canvas) override {
98         SkPaint paint;
99         sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard));
100         // No displacement effect
101         paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kG,
102                                                              0.0f, std::move(displ), nullptr));
103 
104         for (int i = 0; i < loops; i++) {
105             this->drawClippedBitmap(canvas, 0, 0, paint);
106         }
107     }
108 
109 private:
110     using INHERITED = DisplacementBaseBench;
111 };
112 
113 class DisplacementAlphaBench : public DisplacementBaseBench {
114 public:
DisplacementAlphaBench(bool small)115     DisplacementAlphaBench(bool small) : INHERITED(small) { }
116 
117 protected:
onGetName()118     const char* onGetName() override {
119         return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large";
120     }
121 
onDraw(int loops,SkCanvas * canvas)122     void onDraw(int loops, SkCanvas* canvas) override {
123         SkPaint paint;
124         sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard));
125         // Displacement, with 1 alpha component (which isn't pre-multiplied)
126         paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kB, SkColorChannel::kA,
127                                                              16.0f, std::move(displ), nullptr));
128         for (int i = 0; i < loops; i++) {
129             this->drawClippedBitmap(canvas, 100, 0, paint);
130         }
131     }
132 
133 private:
134     using INHERITED = DisplacementBaseBench;
135 };
136 
137 class DisplacementFullBench : public DisplacementBaseBench {
138 public:
DisplacementFullBench(bool small)139     DisplacementFullBench(bool small) : INHERITED(small) { }
140 
141 protected:
onGetName()142     const char* onGetName() override {
143         return isSmall() ? "displacement_full_small" : "displacement_full_large";
144     }
145 
onDraw(int loops,SkCanvas * canvas)146     void onDraw(int loops, SkCanvas* canvas) override {
147         SkPaint paint;
148         sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard));
149         // Displacement, with 2 non-alpha components
150         paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kB,
151                                                              32.0f, std::move(displ), nullptr));
152         for (int i = 0; i < loops; ++i) {
153             this->drawClippedBitmap(canvas, 200, 0, paint);
154         }
155     }
156 
157 private:
158     using INHERITED = DisplacementBaseBench;
159 };
160 
161 ///////////////////////////////////////////////////////////////////////////////
162 
163 DEF_BENCH( return new DisplacementZeroBench(true); )
164 DEF_BENCH( return new DisplacementAlphaBench(true); )
165 DEF_BENCH( return new DisplacementFullBench(true); )
166 DEF_BENCH( return new DisplacementZeroBench(false); )
167 DEF_BENCH( return new DisplacementAlphaBench(false); )
168 DEF_BENCH( return new DisplacementFullBench(false); )
169