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 "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:
     21     DisplacementBaseBench(bool small) : fInitialized(false), fIsSmall(small) { }
     22 
     23 protected:
     24     void onDelayedSetup() override {
     25         if (!fInitialized) {
     26             this->makeBitmap();
     27             this->makeCheckerboard();
     28             fInitialized = true;
     29         }
     30     }
     31 
     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 
     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 
     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 
     80     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:
     93     DisplacementZeroBench(bool small) : INHERITED(small) { }
     94 
     95 protected:
     96     const char* onGetName() override {
     97         return this->isSmall() ? "displacement_zero_small" : "displacement_zero_large";
     98     }
     99 
    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:
    120     DisplacementAlphaBench(bool small) : INHERITED(small) { }
    121 
    122 protected:
    123     const char* onGetName() override {
    124         return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large";
    125     }
    126 
    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:
    146     DisplacementFullBench(bool small) : INHERITED(small) { }
    147 
    148 protected:
    149     const char* onGetName() override {
    150         return isSmall() ? "displacement_full_small" : "displacement_full_large";
    151     }
    152 
    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