blob: 99f8ca8f1234e0ca05950bab38cbb2f10919dc04 [file] [log] [blame]
rileya@google.com981b33a2012-09-05 18:36:17 +00001
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "SkBenchmark.h"
10#include "SkCanvas.h"
11#include "SkRTree.h"
12#include "SkRandom.h"
13#include "SkString.h"
14
15// confine rectangles to a smallish area, so queries generally hit something, and overlap occurs:
16static const int GENERATE_EXTENTS = 1000;
17static const int NUM_BUILD_RECTS = 500;
18static const int NUM_QUERY_RECTS = 5000;
sglez@google.com8c902122013-08-30 17:27:47 +000019static const int GRID_WIDTH = 100;
rileya@google.com981b33a2012-09-05 18:36:17 +000020
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000021typedef SkIRect (*MakeRectProc)(SkRandom&, int, int);
rileya@google.com981b33a2012-09-05 18:36:17 +000022
23// Time how long it takes to build an R-Tree either bulk-loaded or not
24class BBoxBuildBench : public SkBenchmark {
25public:
26 BBoxBuildBench(void* param, const char* name, MakeRectProc proc, bool bulkLoad,
27 SkBBoxHierarchy* tree)
skia.committer@gmail.com6c778162012-09-06 02:01:13 +000028 : INHERITED(param)
rileya@google.com981b33a2012-09-05 18:36:17 +000029 , fTree(tree)
30 , fProc(proc)
rileya@google.com61348d12012-09-06 13:38:53 +000031 , fBulkLoad(bulkLoad) {
32 fName.append("rtree_");
33 fName.append(name);
34 fName.append("_build");
35 if (fBulkLoad) {
36 fName.append("_bulk");
37 }
tomhudson@google.com9dc27132012-09-13 15:50:24 +000038 fIsRendering = false;
rileya@google.com61348d12012-09-06 13:38:53 +000039 }
robertphillips@google.com07a05d52012-09-11 11:54:07 +000040 virtual ~BBoxBuildBench() {
rileya@google.com48134582012-09-11 15:41:50 +000041 fTree->unref();
robertphillips@google.com07a05d52012-09-11 11:54:07 +000042 }
rileya@google.com981b33a2012-09-05 18:36:17 +000043protected:
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000044 virtual const char* onGetName() SK_OVERRIDE {
rileya@google.com61348d12012-09-06 13:38:53 +000045 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +000046 }
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000047 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000048 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +000049 for (int i = 0; i < this->getLoops(); ++i) {
rileya@google.com981b33a2012-09-05 18:36:17 +000050 for (int j = 0; j < NUM_BUILD_RECTS; ++j) {
51 fTree->insert(reinterpret_cast<void*>(j), fProc(rand, j, NUM_BUILD_RECTS),
52 fBulkLoad);
53 }
54 fTree->flushDeferredInserts();
55 fTree->clear();
56 }
57 }
58private:
59 SkBBoxHierarchy* fTree;
60 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +000061 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +000062 bool fBulkLoad;
63 typedef SkBenchmark INHERITED;
64};
65
66// Time how long it takes to perform queries on an R-Tree, bulk-loaded or not
67class BBoxQueryBench : public SkBenchmark {
68public:
69 enum QueryType {
70 kSmall_QueryType, // small queries
71 kLarge_QueryType, // large queries
72 kRandom_QueryType,// randomly sized queries
73 kFull_QueryType // queries that cover everything
74 };
75
skia.committer@gmail.com6c778162012-09-06 02:01:13 +000076 BBoxQueryBench(void* param, const char* name, MakeRectProc proc, bool bulkLoad,
rileya@google.com981b33a2012-09-05 18:36:17 +000077 QueryType q, SkBBoxHierarchy* tree)
skia.committer@gmail.com6c778162012-09-06 02:01:13 +000078 : INHERITED(param)
rileya@google.com981b33a2012-09-05 18:36:17 +000079 , fTree(tree)
80 , fProc(proc)
rileya@google.com981b33a2012-09-05 18:36:17 +000081 , fBulkLoad(bulkLoad)
82 , fQuery(q) {
rileya@google.com61348d12012-09-06 13:38:53 +000083 fName.append("rtree_");
84 fName.append(name);
85 fName.append("_query");
86 if (fBulkLoad) {
87 fName.append("_bulk");
88 }
tomhudson@google.com9dc27132012-09-13 15:50:24 +000089 fIsRendering = false;
rileya@google.com981b33a2012-09-05 18:36:17 +000090 }
robertphillips@google.com07a05d52012-09-11 11:54:07 +000091 virtual ~BBoxQueryBench() {
rileya@google.com48134582012-09-11 15:41:50 +000092 fTree->unref();
robertphillips@google.com07a05d52012-09-11 11:54:07 +000093 }
rileya@google.com981b33a2012-09-05 18:36:17 +000094protected:
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000095 virtual const char* onGetName() SK_OVERRIDE {
rileya@google.com61348d12012-09-06 13:38:53 +000096 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +000097 }
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000098 virtual void onPreDraw() SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000099 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +0000100 for (int j = 0; j < NUM_QUERY_RECTS; ++j) {
101 fTree->insert(reinterpret_cast<void*>(j),
102 fProc(rand, j, NUM_QUERY_RECTS),
103 fBulkLoad);
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000104 }
105 fTree->flushDeferredInserts();
106 }
107
108 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000109 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +0000110 for (int i = 0; i < this->getLoops(); ++i) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000111 SkTDArray<void*> hits;
112 SkIRect query;
113 switch(fQuery) {
114 case kSmall_QueryType:
115 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
116 query.fTop = rand.nextU() % GENERATE_EXTENTS;
117 query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
118 query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
119 break;
120 case kLarge_QueryType:
121 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
122 query.fTop = rand.nextU() % GENERATE_EXTENTS;
123 query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
124 query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
125 break;
126 case kFull_QueryType:
127 query.fLeft = -GENERATE_EXTENTS;
128 query.fTop = -GENERATE_EXTENTS;
129 query.fRight = 2 * GENERATE_EXTENTS;
130 query.fBottom = 2 * GENERATE_EXTENTS;
131 break;
132 default: // fallthrough
133 case kRandom_QueryType:
134 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
135 query.fTop = rand.nextU() % GENERATE_EXTENTS;
136 query.fRight = query.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
137 query.fBottom = query.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
138 break;
139 };
140 fTree->search(query, &hits);
141 }
142 }
143private:
144 SkBBoxHierarchy* fTree;
145 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +0000146 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +0000147 bool fBulkLoad;
148 QueryType fQuery;
149 typedef SkBenchmark INHERITED;
150};
151
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000152static inline SkIRect make_simple_rect(SkRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000153 SkIRect out = {0, 0, GENERATE_EXTENTS, GENERATE_EXTENTS};
154 return out;
155}
156
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000157static inline SkIRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000158 SkIRect out = {0, 0, index + 1, index + 1};
159 return out;
160}
161
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000162static inline SkIRect make_concentric_rects_decreasing(SkRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000163 SkIRect out = {0, 0, numRects - index, numRects - index};
164 return out;
165}
166
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000167static inline SkIRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
sglez@google.com8c902122013-08-30 17:27:47 +0000168 SkIRect out;
169 out.fLeft = index % GRID_WIDTH;
170 out.fTop = index / GRID_WIDTH;
sglez@google.com0d60db62013-08-30 18:54:54 +0000171 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
172 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
sglez@google.com8c902122013-08-30 17:27:47 +0000173 return out;
174}
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000175static inline SkIRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
sglez@google.com8c902122013-08-30 17:27:47 +0000176 SkIRect out;
177 out.fLeft = index / GRID_WIDTH;
178 out.fTop = index % GRID_WIDTH;
sglez@google.com0d60db62013-08-30 18:54:54 +0000179 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
180 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
sglez@google.com8c902122013-08-30 17:27:47 +0000181 return out;
182}
183
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000184static inline SkIRect make_point_rects(SkRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000185 SkIRect out;
186 out.fLeft = rand.nextU() % GENERATE_EXTENTS;
187 out.fTop = rand.nextU() % GENERATE_EXTENTS;
188 out.fRight = out.fLeft + (GENERATE_EXTENTS / 200);
189 out.fBottom = out.fTop + (GENERATE_EXTENTS / 200);
190 return out;
191}
192
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000193static inline SkIRect make_random_rects(SkRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000194 SkIRect out;
195 out.fLeft = rand.nextS() % GENERATE_EXTENTS;
196 out.fTop = rand.nextS() % GENERATE_EXTENTS;
197 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
198 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
199 return out;
200}
201
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000202static inline SkIRect make_large_rects(SkRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000203 SkIRect out;
204 out.fLeft = rand.nextU() % GENERATE_EXTENTS;
205 out.fTop = rand.nextU() % GENERATE_EXTENTS;
206 out.fRight = out.fLeft + (GENERATE_EXTENTS / 3);
207 out.fBottom = out.fTop + (GENERATE_EXTENTS / 3);
208 return out;
209}
210
211///////////////////////////////////////////////////////////////////////////////
212
humper@google.com05af1af2013-01-07 16:47:43 +0000213static inline SkBenchmark* Fact0(void* p) {
sglez@google.com8c902122013-08-30 17:27:47 +0000214 return SkNEW_ARGS(BBoxBuildBench, (p, "XYordered", &make_XYordered_rects, false,
rileya@google.com981b33a2012-09-05 18:36:17 +0000215 SkRTree::Create(5, 16)));
216}
humper@google.com05af1af2013-01-07 16:47:43 +0000217static inline SkBenchmark* Fact1(void* p) {
sglez@google.com8c902122013-08-30 17:27:47 +0000218 return SkNEW_ARGS(BBoxBuildBench, (p, "XYordered", &make_XYordered_rects, true,
rileya@google.com981b33a2012-09-05 18:36:17 +0000219 SkRTree::Create(5, 16)));
220}
humper@google.com05af1af2013-01-07 16:47:43 +0000221static inline SkBenchmark* Fact2(void* p) {
sglez@google.com8c902122013-08-30 17:27:47 +0000222 return SkNEW_ARGS(BBoxBuildBench, (p, "(unsorted)XYordered", &make_XYordered_rects, true,
223 SkRTree::Create(5, 16, 1, false)));
rileya@google.com981b33a2012-09-05 18:36:17 +0000224}
humper@google.com05af1af2013-01-07 16:47:43 +0000225static inline SkBenchmark* Fact3(void* p) {
sglez@google.com8c902122013-08-30 17:27:47 +0000226 return SkNEW_ARGS(BBoxQueryBench, (p, "XYordered", &make_XYordered_rects, true,
rileya@google.com981b33a2012-09-05 18:36:17 +0000227 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
228}
humper@google.com05af1af2013-01-07 16:47:43 +0000229static inline SkBenchmark* Fact4(void* p) {
sglez@google.com8c902122013-08-30 17:27:47 +0000230 return SkNEW_ARGS(BBoxQueryBench, (p, "(unsorted)XYordered", &make_XYordered_rects, true,
231 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
rileya@google.com981b33a2012-09-05 18:36:17 +0000232}
233
sglez@google.com8c902122013-08-30 17:27:47 +0000234static inline SkBenchmark* Fact5(void* p) {
235 return SkNEW_ARGS(BBoxBuildBench, (p, "YXordered", &make_YXordered_rects, false,
236 SkRTree::Create(5, 16)));
237}
238static inline SkBenchmark* Fact6(void* p) {
239 return SkNEW_ARGS(BBoxBuildBench, (p, "YXordered", &make_YXordered_rects, true,
240 SkRTree::Create(5, 16)));
241}
242static inline SkBenchmark* Fact7(void* p) {
243 return SkNEW_ARGS(BBoxBuildBench, (p, "(unsorted)YXordered", &make_YXordered_rects, true,
244 SkRTree::Create(5, 16, 1, false)));
245}
246static inline SkBenchmark* Fact8(void* p) {
247 return SkNEW_ARGS(BBoxQueryBench, (p, "YXordered", &make_YXordered_rects, true,
248 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
249}
250static inline SkBenchmark* Fact9(void* p) {
251 return SkNEW_ARGS(BBoxQueryBench, (p, "(unsorted)YXordered", &make_YXordered_rects, true,
252 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
253}
254
255static inline SkBenchmark* Fact10(void* p) {
256 return SkNEW_ARGS(BBoxBuildBench, (p, "random", &make_random_rects, false,
257 SkRTree::Create(5, 16)));
258}
259static inline SkBenchmark* Fact11(void* p) {
260 return SkNEW_ARGS(BBoxBuildBench, (p, "random", &make_random_rects, true,
261 SkRTree::Create(5, 16)));
262}
263static inline SkBenchmark* Fact12(void* p) {
264 return SkNEW_ARGS(BBoxBuildBench, (p, "(unsorted)random", &make_random_rects, true,
265 SkRTree::Create(5, 16, 1, false)));
266}
267static inline SkBenchmark* Fact13(void* p) {
268 return SkNEW_ARGS(BBoxQueryBench, (p, "random", &make_random_rects, true,
269 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
270}
271static inline SkBenchmark* Fact14(void* p) {
272 return SkNEW_ARGS(BBoxQueryBench, (p, "(unsorted)random", &make_random_rects, true,
273 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
274}
275
276static inline SkBenchmark* Fact15(void* p) {
277 return SkNEW_ARGS(BBoxBuildBench, (p, "concentric",
278 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16)));
279}
280static inline SkBenchmark* Fact16(void* p) {
281 return SkNEW_ARGS(BBoxBuildBench, (p, "(unsorted)concentric",
282 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16, 1, false)));
283}
284static inline SkBenchmark* Fact17(void* p) {
285 return SkNEW_ARGS(BBoxQueryBench, (p, "concentric", &make_concentric_rects_increasing, true,
286 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
287}
288static inline SkBenchmark* Fact18(void* p) {
289 return SkNEW_ARGS(BBoxQueryBench, (p, "(unsorted)concentric", &make_concentric_rects_increasing, true,
290 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
291}
292
293static BenchRegistry gReg18(Fact18);
294static BenchRegistry gReg17(Fact17);
295static BenchRegistry gReg16(Fact16);
296static BenchRegistry gReg15(Fact15);
297static BenchRegistry gReg14(Fact14);
298static BenchRegistry gReg13(Fact13);
299static BenchRegistry gReg12(Fact12);
300static BenchRegistry gReg11(Fact11);
301static BenchRegistry gReg10(Fact10);
302static BenchRegistry gReg9(Fact9);
303static BenchRegistry gReg8(Fact8);
304static BenchRegistry gReg7(Fact7);
305static BenchRegistry gReg6(Fact6);
306static BenchRegistry gReg5(Fact5);
rileya@google.com981b33a2012-09-05 18:36:17 +0000307static BenchRegistry gReg4(Fact4);
sglez@google.com8c902122013-08-30 17:27:47 +0000308static BenchRegistry gReg3(Fact3);
309static BenchRegistry gReg2(Fact2);
310static BenchRegistry gReg1(Fact1);
311static BenchRegistry gReg0(Fact0);