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 "SkBenchmark.h" 9 #include "SkCanvas.h" 10 #include "SkPaint.h" 11 #include "SkRandom.h" 12 #include "SkShader.h" 13 #include "SkString.h" 14 #include "SkBlurMask.h" 15 16 #define SMALL SkIntToScalar(2) 17 #define REAL SkFloatToScalar(1.5f) 18 #define BIG SkIntToScalar(10) 19 #define REALBIG SkFloatToScalar(30.5f) 20 21 class BlurRectBench: public SkBenchmark { 22 SkScalar fRadius; 23 SkString fName; 24 25 public: 26 BlurRectBench(void *param, SkScalar rad) : INHERITED(param) { 27 fRadius = rad; 28 } 29 30 protected: 31 virtual const char* onGetName() { 32 return fName.c_str(); 33 } 34 35 SkScalar radius() const { 36 return fRadius; 37 } 38 39 void setName(const SkString& name) { 40 fName = name; 41 } 42 43 virtual void onDraw(SkCanvas* canvas) { 44 SkPaint paint; 45 this->setupPaint(&paint); 46 47 paint.setAntiAlias(true); 48 49 SkScalar pad = fRadius*3/2 + SK_Scalar1; 50 SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1); 51 52 int loop_count; 53 54 if (fRadius > SkIntToScalar(25)) { 55 loop_count = 100; 56 } else if (fRadius > SkIntToScalar(5)) { 57 loop_count = 1000; 58 } else { 59 loop_count = 10000; 60 } 61 62 preBenchSetup(r); 63 64 for (int i = 0; i < SkBENCHLOOP(loop_count); i++) { 65 makeBlurryRect(r); 66 } 67 } 68 69 virtual void makeBlurryRect(const SkRect&) = 0; 70 virtual void preBenchSetup(const SkRect&) {} 71 private: 72 typedef SkBenchmark INHERITED; 73 }; 74 75 76 class BlurRectDirectBench: public BlurRectBench { 77 public: 78 BlurRectDirectBench(void *param, SkScalar rad) : BlurRectBench(param, rad) { 79 SkString name; 80 81 if (SkScalarFraction(rad) != 0) { 82 name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad)); 83 } else { 84 name.printf("blurrect_direct_%d", SkScalarRound(rad)); 85 } 86 87 setName(name); 88 } 89 protected: 90 virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE { 91 SkMask mask; 92 SkBlurMask::BlurRect(&mask, r, radius(), SkBlurMask::kNormal_Style, 93 SkBlurMask::kHigh_Quality); 94 SkMask::FreeImage(mask.fImage); 95 } 96 }; 97 98 class BlurRectSeparableBench: public BlurRectBench { 99 SkMask fSrcMask; 100 public: 101 BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench(param, rad) { 102 SkString name; 103 if (SkScalarFraction(rad) != 0) { 104 name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad)); 105 } else { 106 name.printf("blurrect_separable_%d", SkScalarRound(rad)); 107 } 108 setName(name); 109 fSrcMask.fImage = NULL; 110 } 111 112 ~BlurRectSeparableBench() { 113 SkMask::FreeImage(fSrcMask.fImage); 114 } 115 116 protected: 117 virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE { 118 SkMask::FreeImage(fSrcMask.fImage); 119 120 r.roundOut(&fSrcMask.fBounds); 121 fSrcMask.fFormat = SkMask::kA8_Format; 122 fSrcMask.fRowBytes = fSrcMask.fBounds.width(); 123 fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize()); 124 125 memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize()); 126 } 127 128 virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE { 129 SkMask mask; 130 SkBlurMask::BlurSeparable(&mask, fSrcMask, radius(), 131 SkBlurMask::kNormal_Style, 132 SkBlurMask::kHigh_Quality); 133 SkMask::FreeImage(mask.fImage); 134 } 135 }; 136 137 DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);) 138 DEF_BENCH(return new BlurRectSeparableBench(p, BIG);) 139 DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);) 140 DEF_BENCH(return new BlurRectSeparableBench(p, REAL);) 141 DEF_BENCH(return new BlurRectDirectBench(p, SMALL);) 142 DEF_BENCH(return new BlurRectDirectBench(p, BIG);) 143 DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);) 144 DEF_BENCH(return new BlurRectDirectBench(p, REAL);) 145