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 #include "tools/fonts/FontToolUtils.h" 15 16 #define FILTER_WIDTH_SMALL 32 17 #define FILTER_HEIGHT_SMALL 32 18 #define FILTER_WIDTH_LARGE 256 19 #define FILTER_HEIGHT_LARGE 256 20 21 class DisplacementBaseBench : public Benchmark { 22 public: DisplacementBaseBench(bool small)23 DisplacementBaseBench(bool small) : fInitialized(false), fIsSmall(small) { } 24 25 protected: onDelayedSetup()26 void onDelayedSetup() override { 27 if (!fInitialized) { 28 this->makeBitmap(); 29 this->makeCheckerboard(); 30 fInitialized = true; 31 } 32 } 33 makeBitmap()34 void makeBitmap() { 35 const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE; 36 const int h = this->isSmall() ? FILTER_HEIGHT_SMALL : FILTER_HEIGHT_LARGE; 37 auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(w, h)); 38 SkPaint paint; 39 paint.setColor(0xFF884422); 40 41 SkFont font = ToolUtils::DefaultFont(); 42 font.setSize(SkIntToScalar(96)); 43 surf->getCanvas()->drawSimpleText("g", 1, SkTextEncoding::kUTF8, 15, 55, font, paint); 44 fImage = surf->makeImageSnapshot(); 45 } 46 makeCheckerboard()47 void makeCheckerboard() { 48 const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE; 49 const int h = this->isSmall() ? FILTER_HEIGHT_SMALL : FILTER_HEIGHT_LARGE; 50 auto surface(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(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 drawClippedBitmap(SkCanvas * canvas,int x,int y,const SkPaint & paint)72 void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) { 73 canvas->save(); 74 canvas->clipIRect(fImage->bounds().makeOffset(x, y)); 75 canvas->drawImage(fImage, SkIntToScalar(x), SkIntToScalar(y), SkSamplingOptions(), &paint); 76 canvas->restore(); 77 } 78 isSmall() const79 inline bool isSmall() const { return fIsSmall; } 80 81 sk_sp<SkImage> fImage, fCheckerboard; 82 83 private: 84 bool fInitialized; 85 bool fIsSmall; 86 using INHERITED = Benchmark; 87 }; 88 89 class DisplacementZeroBench : public DisplacementBaseBench { 90 public: DisplacementZeroBench(bool small)91 DisplacementZeroBench(bool small) : INHERITED(small) { } 92 93 protected: onGetName()94 const char* onGetName() override { 95 return this->isSmall() ? "displacement_zero_small" : "displacement_zero_large"; 96 } 97 onDraw(int loops,SkCanvas * canvas)98 void onDraw(int loops, SkCanvas* canvas) override { 99 SkPaint paint; 100 sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard, SkFilterMode::kLinear)); 101 // No displacement effect 102 paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kG, 103 0.0f, std::move(displ), nullptr)); 104 105 for (int i = 0; i < loops; i++) { 106 this->drawClippedBitmap(canvas, 0, 0, paint); 107 } 108 } 109 110 private: 111 using INHERITED = DisplacementBaseBench; 112 }; 113 114 class DisplacementAlphaBench : public DisplacementBaseBench { 115 public: DisplacementAlphaBench(bool small)116 DisplacementAlphaBench(bool small) : INHERITED(small) { } 117 118 protected: onGetName()119 const char* onGetName() override { 120 return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large"; 121 } 122 onDraw(int loops,SkCanvas * canvas)123 void onDraw(int loops, SkCanvas* canvas) override { 124 SkPaint paint; 125 sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard, SkFilterMode::kLinear)); 126 // Displacement, with 1 alpha component (which isn't pre-multiplied) 127 paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kB, SkColorChannel::kA, 128 16.0f, std::move(displ), nullptr)); 129 for (int i = 0; i < loops; i++) { 130 this->drawClippedBitmap(canvas, 100, 0, paint); 131 } 132 } 133 134 private: 135 using INHERITED = DisplacementBaseBench; 136 }; 137 138 class DisplacementFullBench : public DisplacementBaseBench { 139 public: DisplacementFullBench(bool small)140 DisplacementFullBench(bool small) : INHERITED(small) { } 141 142 protected: onGetName()143 const char* onGetName() override { 144 return isSmall() ? "displacement_full_small" : "displacement_full_large"; 145 } 146 onDraw(int loops,SkCanvas * canvas)147 void onDraw(int loops, SkCanvas* canvas) override { 148 SkPaint paint; 149 sk_sp<SkImageFilter> displ(SkImageFilters::Image(fCheckerboard, SkFilterMode::kLinear)); 150 // Displacement, with 2 non-alpha components 151 paint.setImageFilter(SkImageFilters::DisplacementMap(SkColorChannel::kR, SkColorChannel::kB, 152 32.0f, std::move(displ), nullptr)); 153 for (int i = 0; i < loops; ++i) { 154 this->drawClippedBitmap(canvas, 200, 0, paint); 155 } 156 } 157 158 private: 159 using INHERITED = DisplacementBaseBench; 160 }; 161 162 /////////////////////////////////////////////////////////////////////////////// 163 164 DEF_BENCH( return new DisplacementZeroBench(true); ) 165 DEF_BENCH( return new DisplacementAlphaBench(true); ) 166 DEF_BENCH( return new DisplacementFullBench(true); ) 167 DEF_BENCH( return new DisplacementZeroBench(false); ) 168 DEF_BENCH( return new DisplacementAlphaBench(false); ) 169 DEF_BENCH( return new DisplacementFullBench(false); ) 170