BlurRectBench.cpp revision d454ec135eeef48edea7ebc47a61ff39bd654576
12363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver/* 22363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver * Copyright 2013 Google Inc. 32363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver * 42363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver * Use of this source code is governed by a BSD-style license that can be 52363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver * found in the LICENSE file. 62363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver */ 72363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 82363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkBenchmark.h" 92363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkCanvas.h" 102363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkPaint.h" 112363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkRandom.h" 122363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkShader.h" 132363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkString.h" 142363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkBlurMask.h" 152363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 162363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#define SMALL SkIntToScalar(2) 172363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#define REAL SkFloatToScalar(1.5f) 182363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#define BIG SkIntToScalar(10) 192363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#define REALBIG SkFloatToScalar(30.5f) 202363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 212363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruverclass BlurRectBench: public SkBenchmark { 222363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver int fLoopCount; 232363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver SkScalar fRadius; 242363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver SkString fName; 252363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 262363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruverpublic: 272363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver BlurRectBench(void *param, SkScalar rad) : INHERITED(param) { 282363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver fRadius = rad; 292363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 302363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver if (fRadius > SkIntToScalar(25)) { 312363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver fLoopCount = 100; 322363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver } else if (fRadius > SkIntToScalar(5)) { 332363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver fLoopCount = 1000; 342363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver } else { 352363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver fLoopCount = 10000; 362363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver } 372363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver } 382363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 392363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruverprotected: 402363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver virtual const char* onGetName() { 41d7cd52308e6120e6750c4f46d7357e8e5033619cBen Gruver return fName.c_str(); 422363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver } 43d7cd52308e6120e6750c4f46d7357e8e5033619cBen Gruver 442363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver SkScalar radius() const { 452363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver return fRadius; 462363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver } 472363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 482363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver void setName(const SkString& name) { 492363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver fName = name; 502363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver } 512363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 522363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver virtual void onDraw(SkCanvas* canvas) { 532363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver SkPaint paint; 542363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver this->setupPaint(&paint); 552363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 56d7cd52308e6120e6750c4f46d7357e8e5033619cBen Gruver paint.setAntiAlias(true); 572363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver 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& r) 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& r) 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