1/*
2 * Copyright 2012 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#include "SkBenchmark.h"
8#include "SkCanvas.h"
9#include "SkPaint.h"
10#include "SkRandom.h"
11#include "SkShader.h"
12#include "SkString.h"
13#include "SkMorphologyImageFilter.h"
14
15#define SMALL   SkIntToScalar(2)
16#define REAL    SkFloatToScalar(1.5f)
17#define BIG     SkIntToScalar(10)
18
19namespace {
20
21enum MorphologyType {
22    kErode_MT,
23    kDilate_MT
24};
25
26}
27
28static const char* gStyleName[] = {
29    "erode",
30    "dilate"
31};
32
33class MorphologyBench : public SkBenchmark {
34    SkScalar       fRadius;
35    MorphologyType fStyle;
36    SkString       fName;
37
38public:
39    MorphologyBench(void* param, SkScalar rad, MorphologyType style)
40        :  INHERITED(param) {
41        fRadius = rad;
42        fStyle = style;
43        const char* name = rad > 0 ? gStyleName[style] : "none";
44        if (SkScalarFraction(rad) != 0) {
45            fName.printf("morph_%.2f_%s", SkScalarToFloat(rad), name);
46        } else {
47            fName.printf("morph_%d_%s", SkScalarRound(rad), name);
48        }
49    }
50
51protected:
52    virtual const char* onGetName() {
53        return fName.c_str();
54    }
55
56    virtual void onDraw(SkCanvas* canvas) {
57        SkPaint paint;
58        this->setupPaint(&paint);
59
60        paint.setAntiAlias(true);
61
62        SkRandom rand;
63        for (int i = 0; i < SkBENCHLOOP(3); i++) {
64            SkRect r = SkRect::MakeWH(rand.nextUScalar1() * 400,
65                                      rand.nextUScalar1() * 400);
66            r.offset(fRadius, fRadius);
67
68            if (fRadius > 0) {
69                SkMorphologyImageFilter* mf = NULL;
70                switch (fStyle) {
71                case kDilate_MT:
72                    mf = new SkDilateImageFilter(SkScalarFloorToInt(fRadius),
73                                                 SkScalarFloorToInt(fRadius));
74                    break;
75                case kErode_MT:
76                    mf = new SkErodeImageFilter(SkScalarFloorToInt(fRadius),
77                                                SkScalarFloorToInt(fRadius));
78                    break;
79                }
80                paint.setImageFilter(mf)->unref();
81            }
82            canvas->drawOval(r, paint);
83        }
84    }
85
86private:
87    typedef SkBenchmark INHERITED;
88};
89
90static SkBenchmark* Fact00(void* p) { return new MorphologyBench(p, SMALL, kErode_MT); }
91static SkBenchmark* Fact01(void* p) { return new MorphologyBench(p, SMALL, kDilate_MT); }
92
93static SkBenchmark* Fact10(void* p) { return new MorphologyBench(p, BIG, kErode_MT); }
94static SkBenchmark* Fact11(void* p) { return new MorphologyBench(p, BIG, kDilate_MT); }
95
96static SkBenchmark* Fact20(void* p) { return new MorphologyBench(p, REAL, kErode_MT); }
97static SkBenchmark* Fact21(void* p) { return new MorphologyBench(p, REAL, kDilate_MT); }
98
99static SkBenchmark* FactNone(void* p) { return new MorphologyBench(p, 0, kErode_MT); }
100
101// Fixed point can be 100x slower than float on these tests, causing
102// bench to timeout.
103#ifndef SK_SCALAR_IS_FIXED
104
105static BenchRegistry gReg00(Fact00);
106static BenchRegistry gReg01(Fact01);
107
108static BenchRegistry gReg10(Fact10);
109static BenchRegistry gReg11(Fact11);
110
111static BenchRegistry gReg20(Fact20);
112static BenchRegistry gReg21(Fact21);
113
114static BenchRegistry gRegNone(FactNone);
115
116#endif
117