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 "Benchmark.h"
9 #include "SkRandom.h"
10 #include "SkSize.h"
11 #include "SkTDArray.h"
12 
13 #if SK_SUPPORT_GPU
14 
15 #include "GrRectanizer_pow2.h"
16 #include "GrRectanizer_skyline.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  */
28 class RectanizerBench : public Benchmark {
29 public:
30     static const int kWidth = 1024;
31     static const 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 
66 protected:
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.reset(new GrRectanizerPow2(kWidth, kHeight));
80         } else {
81             SkASSERT(kSkyline_RectanizerType == fRectanizerType);
82             fRectanizer.reset(new 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 
114 private:
115     SkString                    fName;
116     RectanizerType              fRectanizerType;
117     RectType                    fRectType;
118     std::unique_ptr<GrRectanizer> fRectanizer;
119 
120     typedef Benchmark INHERITED;
121 };
122 
123 //////////////////////////////////////////////////////////////////////////////
124 
125 DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
126                                      RectanizerBench::kRand_RectType);)
127 DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
128                                      RectanizerBench::kRandPow2_RectType);)
129 DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
130                                      RectanizerBench::kSmallPow2_RectType);)
131 DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
132                                      RectanizerBench::kRand_RectType);)
133 DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
134                                      RectanizerBench::kRandPow2_RectType);)
135 DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
136                                      RectanizerBench::kSmallPow2_RectType);)
137 
138 #endif
139