BlurRectBench.cpp revision a99a92cebaa46cf792cf86eaad1a4c3f9d6162f7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2013 Google Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkBenchmark.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkCanvas.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkPaint.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkRandom.h" 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "SkShader.h" 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "SkString.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "SkBlurMask.h" 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define SMALL SkIntToScalar(2) 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define REAL SkFloatToScalar(1.5f) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BIG SkIntToScalar(10) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REALBIG SkFloatToScalar(30.5f) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BlurRectBench: public SkBenchmark { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fLoopCount; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar fRadius; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkString fName; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlurRectBench(void *param, SkScalar rad) : INHERITED(param) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fRadius = rad; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fRadius > SkIntToScalar(25)) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fLoopCount = 100; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (fRadius > SkIntToScalar(5)) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fLoopCount = 1000; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fLoopCount = 10000; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual const char* onGetName() { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fName.c_str(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar radius() const { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fRadius; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void setName(const SkString& name) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fName = name; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void onDraw(SkCanvas* canvas) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkPaint paint; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->setupPaint(&paint); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint.setAntiAlias(true); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalar pad = fRadius*3/2 + SK_Scalar1; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preBenchSetup(r); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < SkBENCHLOOP(fLoopCount); i++) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) makeBlurryRect(r); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void makeBlurryRect(const SkRect&) = 0; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void preBenchSetup(const SkRect&) {} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef SkBenchmark INHERITED; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BlurRectDirectBench: public BlurRectBench { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlurRectDirectBench(void *param, SkScalar rad) : INHERITED(param, rad) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkString name; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SkScalarFraction(rad) != 0) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad)); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name.printf("blurrect_direct_%d", SkScalarRoundToInt(rad)); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setName(name); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMask mask; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBlurMask::BlurRect(&mask, r, this->radius(), SkBlurMask::kNormal_Style); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkMask::FreeImage(mask.fImage); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef BlurRectBench INHERITED; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BlurRectSeparableBench: public BlurRectBench { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 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