Home | History | Annotate | Download | only in bench
      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