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