1 /* 2 * Copyright 2014 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 "Resources.h" 10 #include "SkBlurImageFilter.h" 11 #include "SkDisplacementMapEffect.h" 12 #include "SkCanvas.h" 13 #include "SkMergeImageFilter.h" 14 15 16 // Exercise a blur filter connected to 5 inputs of the same merge filter. 17 // This bench shows an improvement in performance once cacheing of re-used 18 // nodes is implemented, since the DAG is no longer flattened to a tree. 19 class ImageFilterDAGBench : public Benchmark { 20 public: 21 ImageFilterDAGBench() {} 22 23 protected: 24 const char* onGetName() override { 25 return "image_filter_dag"; 26 } 27 28 void onDraw(int loops, SkCanvas* canvas) override { 29 const SkRect rect = SkRect::Make(SkIRect::MakeWH(400, 400)); 30 31 for (int j = 0; j < loops; j++) { 32 sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(20.0f, 20.0f, nullptr)); 33 sk_sp<SkImageFilter> inputs[kNumInputs]; 34 SkBlendMode modes[kNumInputs]; 35 for (int i = 0; i < kNumInputs; ++i) { 36 inputs[i] = blur; 37 modes[i] = SkBlendMode::kSrcOver; 38 } 39 SkPaint paint; 40 paint.setImageFilter(SkMergeImageFilter::MakeN(inputs, kNumInputs, modes)); 41 canvas->drawRect(rect, paint); 42 } 43 } 44 45 private: 46 static const int kNumInputs = 5; 47 48 typedef Benchmark INHERITED; 49 }; 50 51 class ImageMakeWithFilterDAGBench : public Benchmark { 52 public: 53 ImageMakeWithFilterDAGBench() {} 54 55 protected: 56 const char* onGetName() override { 57 return "image_make_with_filter_dag"; 58 } 59 60 void onDelayedSetup() override { 61 fImage = GetResourceAsImage("mandrill_512.png"); 62 } 63 64 void onDraw(int loops, SkCanvas* canvas) override { 65 SkIRect subset = SkIRect::MakeSize(fImage->dimensions()); 66 SkIPoint offset = SkIPoint::Make(0, 0); 67 SkIRect discardSubset; 68 sk_sp<SkImage> image = fImage; 69 70 for (int j = 0; j < loops; j++) { 71 sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(20.0f, 20.0f, nullptr)); 72 sk_sp<SkImageFilter> inputs[kNumInputs]; 73 SkBlendMode modes[kNumInputs]; 74 for (int i = 0; i < kNumInputs; ++i) { 75 inputs[i] = blur; 76 modes[i] = SkBlendMode::kSrcOver; 77 } 78 sk_sp<SkImageFilter> mergeFilter = SkMergeImageFilter::MakeN(inputs, kNumInputs, modes); 79 image = image->makeWithFilter(mergeFilter.get(), subset, subset, &discardSubset, 80 &offset); 81 SkASSERT(image && image->dimensions() == fImage->dimensions()); 82 } 83 } 84 85 private: 86 static const int kNumInputs = 5; 87 sk_sp<SkImage> fImage; 88 89 typedef Benchmark INHERITED; 90 }; 91 92 // Exercise a blur filter connected to both inputs of an SkDisplacementMapEffect. 93 94 class ImageFilterDisplacedBlur : public Benchmark { 95 public: 96 ImageFilterDisplacedBlur() {} 97 98 protected: 99 const char* onGetName() override { 100 return "image_filter_displaced_blur"; 101 } 102 103 void onDraw(int loops, SkCanvas* canvas) override { 104 for (int j = 0; j < loops; j++) { 105 sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(4.0f, 4.0f, nullptr)); 106 auto xSelector = SkDisplacementMapEffect::kR_ChannelSelectorType; 107 auto ySelector = SkDisplacementMapEffect::kB_ChannelSelectorType; 108 SkScalar scale = 2; 109 110 SkPaint paint; 111 paint.setImageFilter(SkDisplacementMapEffect::Make(xSelector, ySelector, scale, 112 blur, blur)); 113 114 SkRect rect = SkRect::Make(SkIRect::MakeWH(400, 400)); 115 canvas->drawRect(rect, paint); 116 } 117 } 118 119 private: 120 typedef Benchmark INHERITED; 121 }; 122 123 DEF_BENCH(return new ImageFilterDAGBench;) 124 DEF_BENCH(return new ImageMakeWithFilterDAGBench;) 125 DEF_BENCH(return new ImageFilterDisplacedBlur;) 126