1/*
2* Copyright 2014 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 <memory>
9
10#include "bench/Benchmark.h"
11#include "include/core/SkSize.h"
12#include "include/private/SkTDArray.h"
13#include "include/utils/SkRandom.h"
14
15#include "src/gpu/GrRectanizerPow2.h"
16#include "src/gpu/GrRectanizerSkyline.h"
17
18/**
19 * This bench exercises Ganesh' GrRectanizer classes. It exercises the following
20 * rectanizers:
21 *      Pow2 Rectanizer
22 *      Skyline Rectanizer
23 * in the following cases:
24 *      random rects (e.g., pull-save-layers forward use case)
25 *      random power of two rects
26 *      small constant sized power of 2 rects (e.g., glyph cache use case)
27 */
28class RectanizerBench : public Benchmark {
29public:
30    inline static constexpr int kWidth = 1024;
31    inline static constexpr int kHeight = 1024;
32
33    enum RectanizerType {
34        kPow2_RectanizerType,
35        kSkyline_RectanizerType,
36    };
37
38    enum RectType {
39        kRand_RectType,
40        kRandPow2_RectType,
41        kSmallPow2_RectType
42    };
43
44    RectanizerBench(RectanizerType rectanizerType, RectType rectType)
45        : fName("rectanizer_")
46        , fRectanizerType(rectanizerType)
47        , fRectType(rectType) {
48
49        if (kPow2_RectanizerType == fRectanizerType) {
50            fName.append("pow2_");
51        } else {
52            SkASSERT(kSkyline_RectanizerType == fRectanizerType);
53            fName.append("skyline_");
54        }
55
56        if (kRand_RectType == fRectType) {
57            fName.append("rand");
58        } else if (kRandPow2_RectType == fRectType) {
59            fName.append("rand2");
60        } else {
61            SkASSERT(kSmallPow2_RectType == fRectType);
62            fName.append("sm2");
63        }
64    }
65
66protected:
67    bool isSuitableFor(Backend backend) override {
68        return kNonRendering_Backend == backend;
69    }
70
71    const char* onGetName() override {
72        return fName.c_str();
73    }
74
75    void onDelayedSetup() override {
76        SkASSERT(nullptr == fRectanizer.get());
77
78        if (kPow2_RectanizerType == fRectanizerType) {
79            fRectanizer = std::make_unique<GrRectanizerPow2>(kWidth, kHeight);
80        } else {
81            SkASSERT(kSkyline_RectanizerType == fRectanizerType);
82            fRectanizer = std::make_unique<GrRectanizerSkyline>(kWidth, kHeight);
83        }
84    }
85
86    void onDraw(int loops, SkCanvas* canvas) override {
87        SkRandom rand;
88        SkIPoint16 loc;
89        SkISize size;
90
91        for (int i = 0; i < loops; ++i) {
92            if (kRand_RectType == fRectType) {
93                size = SkISize::Make(rand.nextRangeU(1, kWidth / 2),
94                                     rand.nextRangeU(1, kHeight / 2));
95            } else if (kRandPow2_RectType == fRectType) {
96                size = SkISize::Make(GrNextPow2(rand.nextRangeU(1, kWidth / 2)),
97                                     GrNextPow2(rand.nextRangeU(1, kHeight / 2)));
98            } else {
99                SkASSERT(kSmallPow2_RectType == fRectType);
100                size = SkISize::Make(128, 128);
101            }
102
103            if (!fRectanizer->addRect(size.fWidth, size.fHeight, &loc)) {
104                // insert failed so clear out the rectanizer and give the
105                // current rect another try
106                fRectanizer->reset();
107                i--;
108            }
109        }
110
111        fRectanizer->reset();
112    }
113
114private:
115    SkString                    fName;
116    RectanizerType              fRectanizerType;
117    RectType                    fRectType;
118    std::unique_ptr<GrRectanizer> fRectanizer;
119
120    using INHERITED = Benchmark;
121};
122
123//////////////////////////////////////////////////////////////////////////////
124
125DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
126                                     RectanizerBench::kRand_RectType);)
127DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
128                                     RectanizerBench::kRandPow2_RectType);)
129DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
130                                     RectanizerBench::kSmallPow2_RectType);)
131DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
132                                     RectanizerBench::kRand_RectType);)
133DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
134                                     RectanizerBench::kRandPow2_RectType);)
135DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
136                                     RectanizerBench::kSmallPow2_RectType);)
137