Home | History | Annotate | Download | only in bench
      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:
     22     DisplacementBaseBench(bool small) : fInitialized(false), fIsSmall(small) { }
     23 
     24 protected:
     25     void onDelayedSetup() override {
     26         if (!fInitialized) {
     27             this->makeBitmap();
     28             this->makeCheckerboard();
     29             fInitialized = true;
     30         }
     31     }
     32 
     33     void makeBitmap() {
     34         const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
     35         const int h = this->isSmall() ? FILTER_HEIGHT_LARGE : 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 
     47     void makeCheckerboard() {
     48         const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
     49         const int h = this->isSmall() ? FILTER_HEIGHT_LARGE : 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 
     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 
     81     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:
     94     DisplacementZeroBench(bool small) : INHERITED(small) { }
     95 
     96 protected:
     97     const char* onGetName() override {
     98         return this->isSmall() ? "displacement_zero_small" : "displacement_zero_large";
     99     }
    100 
    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:
    121     DisplacementAlphaBench(bool small) : INHERITED(small) { }
    122 
    123 protected:
    124     const char* onGetName() override {
    125         return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large";
    126     }
    127 
    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:
    147     DisplacementFullBench(bool small) : INHERITED(small) { }
    148 
    149 protected:
    150     const char* onGetName() override {
    151         return isSmall() ? "displacement_full_small" : "displacement_full_large";
    152     }
    153 
    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