BlurRectBench.cpp revision 77472f06f88b85e85fb690584c85d0a42e74b685
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 21class BlurRectBench: public SkBenchmark { 22 int fLoopCount; 23 SkScalar fRadius; 24 SkString fName; 25 26public: 27 BlurRectBench(void *param, SkScalar rad) : INHERITED(param) { 28 fRadius = rad; 29 30 if (fRadius > SkIntToScalar(25)) { 31 fLoopCount = 100; 32 } else if (fRadius > SkIntToScalar(5)) { 33 fLoopCount = 1000; 34 } else { 35 fLoopCount = 10000; 36 } 37 } 38 39protected: 40 virtual const char* onGetName() { 41 return fName.c_str(); 42 } 43 44 SkScalar radius() const { 45 return fRadius; 46 } 47 48 void setName(const SkString& name) { 49 fName = name; 50 } 51 52 virtual void onDraw(SkCanvas*) { 53 SkPaint paint; 54 this->setupPaint(&paint); 55 56 paint.setAntiAlias(true); 57 58 SkScalar pad = fRadius*3/2 + SK_Scalar1; 59 SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1); 60 61 preBenchSetup(r); 62 63 for (int i = 0; i < SkBENCHLOOP(fLoopCount); i++) { 64 makeBlurryRect(r); 65 } 66 } 67 68 virtual void makeBlurryRect(const SkRect&) = 0; 69 virtual void preBenchSetup(const SkRect&) {} 70private: 71 typedef SkBenchmark INHERITED; 72}; 73 74 75class BlurRectDirectBench: public BlurRectBench { 76 public: 77 BlurRectDirectBench(void *param, SkScalar rad) : INHERITED(param, rad) { 78 SkString name; 79 80 if (SkScalarFraction(rad) != 0) { 81 name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad)); 82 } else { 83 name.printf("blurrect_direct_%d", SkScalarRoundToInt(rad)); 84 } 85 86 setName(name); 87 } 88protected: 89 virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE { 90 SkMask mask; 91 SkBlurMask::BlurRect(&mask, r, this->radius(), SkBlurMask::kNormal_Style); 92 SkMask::FreeImage(mask.fImage); 93 } 94private: 95 typedef BlurRectBench INHERITED; 96}; 97 98class BlurRectSeparableBench: public BlurRectBench { 99 100public: 101 BlurRectSeparableBench(void *param, SkScalar rad) : INHERITED(param, rad) { 102 fSrcMask.fImage = NULL; 103 } 104 105 ~BlurRectSeparableBench() { 106 SkMask::FreeImage(fSrcMask.fImage); 107 } 108 109protected: 110 virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE { 111 SkMask::FreeImage(fSrcMask.fImage); 112 113 r.roundOut(&fSrcMask.fBounds); 114 fSrcMask.fFormat = SkMask::kA8_Format; 115 fSrcMask.fRowBytes = fSrcMask.fBounds.width(); 116 fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize()); 117 118 memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize()); 119 } 120 121 SkMask fSrcMask; 122private: 123 typedef BlurRectBench INHERITED; 124}; 125 126class BlurRectBoxFilterBench: public BlurRectSeparableBench { 127public: 128 BlurRectBoxFilterBench(void *param, SkScalar rad) : INHERITED(param, rad) { 129 SkString name; 130 if (SkScalarFraction(rad) != 0) { 131 name.printf("blurrect_boxfilter_%.2f", SkScalarToFloat(rad)); 132 } else { 133 name.printf("blurrect_boxfilter_%d", SkScalarRoundToInt(rad)); 134 } 135 setName(name); 136 } 137 138protected: 139 140 virtual void makeBlurryRect(const SkRect&) SK_OVERRIDE { 141 SkMask mask; 142 mask.fImage = NULL; 143 SkBlurMask::BlurSeparable(&mask, fSrcMask, this->radius(), 144 SkBlurMask::kNormal_Style, 145 SkBlurMask::kHigh_Quality); 146 SkMask::FreeImage(mask.fImage); 147 } 148private: 149 typedef BlurRectSeparableBench INHERITED; 150}; 151 152class BlurRectGaussianBench: public BlurRectSeparableBench { 153public: 154 BlurRectGaussianBench(void *param, SkScalar rad) : INHERITED(param, rad) { 155 SkString name; 156 if (SkScalarFraction(rad) != 0) { 157 name.printf("blurrect_gaussian_%.2f", SkScalarToFloat(rad)); 158 } else { 159 name.printf("blurrect_gaussian_%d", SkScalarRoundToInt(rad)); 160 } 161 setName(name); 162 } 163 164protected: 165 166 virtual void makeBlurryRect(const SkRect&) SK_OVERRIDE { 167 SkMask mask; 168 mask.fImage = NULL; 169 SkBlurMask::BlurGroundTruth(&mask, fSrcMask, this->radius(), 170 SkBlurMask::kNormal_Style); 171 SkMask::FreeImage(mask.fImage); 172 } 173private: 174 typedef BlurRectSeparableBench INHERITED; 175}; 176 177DEF_BENCH(return new BlurRectBoxFilterBench(p, SMALL);) 178DEF_BENCH(return new BlurRectBoxFilterBench(p, BIG);) 179DEF_BENCH(return new BlurRectBoxFilterBench(p, REALBIG);) 180DEF_BENCH(return new BlurRectBoxFilterBench(p, REAL);) 181DEF_BENCH(return new BlurRectGaussianBench(p, SMALL);) 182DEF_BENCH(return new BlurRectGaussianBench(p, BIG);) 183DEF_BENCH(return new BlurRectGaussianBench(p, REALBIG);) 184DEF_BENCH(return new BlurRectGaussianBench(p, REAL);) 185DEF_BENCH(return new BlurRectDirectBench(p, SMALL);) 186DEF_BENCH(return new BlurRectDirectBench(p, BIG);) 187DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);) 188DEF_BENCH(return new BlurRectDirectBench(p, REAL);) 189 190DEF_BENCH(return new BlurRectDirectBench(p, SkIntToScalar(5));) 191DEF_BENCH(return new BlurRectDirectBench(p, SkIntToScalar(20));) 192 193DEF_BENCH(return new BlurRectBoxFilterBench(p, SkIntToScalar(5));) 194DEF_BENCH(return new BlurRectBoxFilterBench(p, SkIntToScalar(20));) 195 196#if 0 197// disable Gaussian benchmarks; the algorithm works well enough 198// and serves as a baseline for ground truth, but it's too slow 199// to use in production for non-trivial radii, so no real point 200// in having the bots benchmark it all the time. 201 202DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(1));) 203DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(2));) 204DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(3));) 205DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(4));) 206DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(5));) 207DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(6));) 208DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(7));) 209DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(8));) 210DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(9));) 211DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(10));) 212DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(11));) 213DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(12));) 214DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(13));) 215DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(14));) 216DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(15));) 217DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(16));) 218DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(17));) 219DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(18));) 220DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(19));) 221DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(20));) 222#endif 223