• 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/SkCanvas.h"
10  #include "include/core/SkFont.h"
11  #include "include/core/SkSurface.h"
12  #include "include/effects/SkImageFilters.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_SMALL : FILTER_HEIGHT_LARGE;
35          fBitmap.allocN32Pixels(w, h);
36          SkCanvas canvas(fBitmap);
37          canvas.clear(0x00000000);
38          SkPaint paint;
39          paint.setColor(0xFF884422);
40  
41          SkFont font;
42          font.setSize(SkIntToScalar(96));
43          canvas.drawSimpleText("g", 1, SkTextEncoding::kUTF8, SkIntToScalar(15), SkIntToScalar(55), font, 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_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->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(SkImageFilters::Image(fCheckerboard));
103          // No displacement effect
104          paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kG,
105                                                               0.0f, std::move(displ), nullptr));
106  
107          for (int i = 0; i < loops; i++) {
108              this->drawClippedBitmap(canvas, 0, 0, paint);
109          }
110      }
111  
112  private:
113      typedef DisplacementBaseBench INHERITED;
114  };
115  
116  class DisplacementAlphaBench : public DisplacementBaseBench {
117  public:
DisplacementAlphaBench(bool small)118      DisplacementAlphaBench(bool small) : INHERITED(small) { }
119  
120  protected:
onGetName()121      const char* onGetName() override {
122          return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large";
123      }
124  
onDraw(int loops,SkCanvas * canvas)125      void onDraw(int loops, SkCanvas* canvas) override {
126          SkPaint paint;
127          sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard));
128          // Displacement, with 1 alpha component (which isn't pre-multiplied)
129          paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kB, SkColorChannel::kA,
130                                                               16.0f, std::move(displ), nullptr));
131          for (int i = 0; i < loops; i++) {
132              this->drawClippedBitmap(canvas, 100, 0, paint);
133          }
134      }
135  
136  private:
137      typedef DisplacementBaseBench INHERITED;
138  };
139  
140  class DisplacementFullBench : public DisplacementBaseBench {
141  public:
DisplacementFullBench(bool small)142      DisplacementFullBench(bool small) : INHERITED(small) { }
143  
144  protected:
onGetName()145      const char* onGetName() override {
146          return isSmall() ? "displacement_full_small" : "displacement_full_large";
147      }
148  
onDraw(int loops,SkCanvas * canvas)149      void onDraw(int loops, SkCanvas* canvas) override {
150          SkPaint paint;
151          sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard));
152          // Displacement, with 2 non-alpha components
153          paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kB,
154                                                               32.0f, std::move(displ), nullptr));
155          for (int i = 0; i < loops; ++i) {
156              this->drawClippedBitmap(canvas, 200, 0, paint);
157          }
158      }
159  
160  private:
161      typedef DisplacementBaseBench INHERITED;
162  };
163  
164  ///////////////////////////////////////////////////////////////////////////////
165  
166  DEF_BENCH( return new DisplacementZeroBench(true); )
167  DEF_BENCH( return new DisplacementAlphaBench(true); )
168  DEF_BENCH( return new DisplacementFullBench(true); )
169  DEF_BENCH( return new DisplacementZeroBench(false); )
170  DEF_BENCH( return new DisplacementAlphaBench(false); )
171  DEF_BENCH( return new DisplacementFullBench(false); )
172