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