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 "bench/Benchmark.h"
8#include "include/core/SkCanvas.h"
9#include "include/core/SkPaint.h"
10#include "include/core/SkString.h"
11#include "include/core/SkTileMode.h"
12#include "include/effects/SkImageFilters.h"
13#include "include/utils/SkRandom.h"
14
15#include "tools/ToolUtils.h"
16
17class MatrixConvolutionBench : public Benchmark {
18public:
19    MatrixConvolutionBench(bool bigKernel, SkTileMode tileMode, bool convolveAlpha)
20        : fName(SkStringPrintf("matrixconvolution_%s%s%s",
21                               bigKernel ? "bigKernel_" : "",
22                               ToolUtils::tilemode_name(tileMode),
23                               convolveAlpha ? "" : "_noConvolveAlpha")) {
24        if (bigKernel) {
25            SkISize kernelSize = SkISize::Make(9, 9);
26            SkScalar kernel[81];
27            for (int i = 0; i < 81; i++) {
28                kernel[i] = SkIntToScalar(1);
29            }
30            kernel[40] = SkIntToScalar(-79);
31            SkScalar gain = 0.3f, bias = SkIntToScalar(100);
32            SkIPoint kernelOffset = SkIPoint::Make(4, 4);
33            fFilter = SkImageFilters::MatrixConvolution(kernelSize, kernel, gain, bias,
34                                                        kernelOffset, tileMode, convolveAlpha,
35                                                        nullptr);
36        } else {
37            SkISize kernelSize = SkISize::Make(3, 3);
38            SkScalar kernel[9] = {
39                SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
40                SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1),
41                SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
42            };
43            SkScalar gain = 0.3f, bias = SkIntToScalar(100);
44            SkIPoint kernelOffset = SkIPoint::Make(1, 1);
45            fFilter = SkImageFilters::MatrixConvolution(kernelSize, kernel, gain, bias,
46                                                        kernelOffset, tileMode, convolveAlpha,
47                                                        nullptr);
48        }
49    }
50
51protected:
52    const char* onGetName() override {
53        return fName.c_str();
54    }
55
56    void onDraw(int loops, SkCanvas* canvas) override {
57        SkPaint paint;
58        this->setupPaint(&paint);
59        paint.setImageFilter(fFilter);
60        paint.setAntiAlias(true);
61
62        SkRandom rand;
63        for (int i = 0; i < loops; i++) {
64            SkRect r = SkRect::MakeWH(rand.nextUScalar1() * 400,
65                                      rand.nextUScalar1() * 400);
66            canvas->drawOval(r, paint);
67        }
68    }
69
70private:
71    sk_sp<SkImageFilter> fFilter;
72    SkString fName;
73
74    using INHERITED = Benchmark;
75};
76
77DEF_BENCH( return new MatrixConvolutionBench(false, SkTileMode::kClamp, true); )
78DEF_BENCH( return new MatrixConvolutionBench(false, SkTileMode::kRepeat, true); )
79DEF_BENCH( return new MatrixConvolutionBench(false, SkTileMode::kMirror, true); )
80DEF_BENCH( return new MatrixConvolutionBench(false, SkTileMode::kDecal, true); )
81DEF_BENCH( return new MatrixConvolutionBench(false, SkTileMode::kDecal, false); )
82
83DEF_BENCH( return new MatrixConvolutionBench(true, SkTileMode::kClamp, true); )
84DEF_BENCH( return new MatrixConvolutionBench(true, SkTileMode::kRepeat, true); )
85DEF_BENCH( return new MatrixConvolutionBench(true, SkTileMode::kMirror, true); )
86DEF_BENCH( return new MatrixConvolutionBench(true, SkTileMode::kDecal, true); )
87DEF_BENCH( return new MatrixConvolutionBench(true, SkTileMode::kDecal, false); )
88