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: 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_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 makeCheckerboard()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 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(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: DisplacementAlphaBench(bool small)120 DisplacementAlphaBench(bool small) : INHERITED(small) { } 121 122 protected: onGetName()123 const char* onGetName() override { 124 return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large"; 125 } 126 onDraw(int loops,SkCanvas * canvas)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: DisplacementFullBench(bool small)146 DisplacementFullBench(bool small) : INHERITED(small) { } 147 148 protected: onGetName()149 const char* onGetName() override { 150 return isSmall() ? "displacement_full_small" : "displacement_full_large"; 151 } 152 onDraw(int loops,SkCanvas * canvas)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