blob: 5b69b57ca2e154824e80be57f07c7d729c28dc68 [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:
mtklein@google.com410e6e82013-09-13 19:52:27 +000026 BBoxBuildBench(const char* name, MakeRectProc proc, bool bulkLoad,
rileya@google.com981b33a2012-09-05 18:36:17 +000027 SkBBoxHierarchy* tree)
mtklein@google.com410e6e82013-09-13 19:52:27 +000028 : fTree(tree)
rileya@google.com981b33a2012-09-05 18:36:17 +000029 , fProc(proc)
rileya@google.com61348d12012-09-06 13:38:53 +000030 , fBulkLoad(bulkLoad) {
31 fName.append("rtree_");
32 fName.append(name);
33 fName.append("_build");
34 if (fBulkLoad) {
35 fName.append("_bulk");
36 }
tomhudson@google.com9dc27132012-09-13 15:50:24 +000037 fIsRendering = false;
rileya@google.com61348d12012-09-06 13:38:53 +000038 }
robertphillips@google.com07a05d52012-09-11 11:54:07 +000039 virtual ~BBoxBuildBench() {
rileya@google.com48134582012-09-11 15:41:50 +000040 fTree->unref();
robertphillips@google.com07a05d52012-09-11 11:54:07 +000041 }
rileya@google.com981b33a2012-09-05 18:36:17 +000042protected:
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000043 virtual const char* onGetName() SK_OVERRIDE {
rileya@google.com61348d12012-09-06 13:38:53 +000044 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +000045 }
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000046 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000047 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +000048 for (int i = 0; i < this->getLoops(); ++i) {
rileya@google.com981b33a2012-09-05 18:36:17 +000049 for (int j = 0; j < NUM_BUILD_RECTS; ++j) {
50 fTree->insert(reinterpret_cast<void*>(j), fProc(rand, j, NUM_BUILD_RECTS),
51 fBulkLoad);
52 }
53 fTree->flushDeferredInserts();
54 fTree->clear();
55 }
56 }
57private:
58 SkBBoxHierarchy* fTree;
59 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +000060 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +000061 bool fBulkLoad;
62 typedef SkBenchmark INHERITED;
63};
64
65// Time how long it takes to perform queries on an R-Tree, bulk-loaded or not
66class BBoxQueryBench : public SkBenchmark {
67public:
68 enum QueryType {
69 kSmall_QueryType, // small queries
70 kLarge_QueryType, // large queries
71 kRandom_QueryType,// randomly sized queries
72 kFull_QueryType // queries that cover everything
73 };
74
mtklein@google.com410e6e82013-09-13 19:52:27 +000075 BBoxQueryBench(const char* name, MakeRectProc proc, bool bulkLoad,
rileya@google.com981b33a2012-09-05 18:36:17 +000076 QueryType q, SkBBoxHierarchy* tree)
mtklein@google.com410e6e82013-09-13 19:52:27 +000077 : fTree(tree)
rileya@google.com981b33a2012-09-05 18:36:17 +000078 , fProc(proc)
rileya@google.com981b33a2012-09-05 18:36:17 +000079 , fBulkLoad(bulkLoad)
80 , fQuery(q) {
rileya@google.com61348d12012-09-06 13:38:53 +000081 fName.append("rtree_");
82 fName.append(name);
83 fName.append("_query");
84 if (fBulkLoad) {
85 fName.append("_bulk");
86 }
tomhudson@google.com9dc27132012-09-13 15:50:24 +000087 fIsRendering = false;
rileya@google.com981b33a2012-09-05 18:36:17 +000088 }
robertphillips@google.com07a05d52012-09-11 11:54:07 +000089 virtual ~BBoxQueryBench() {
rileya@google.com48134582012-09-11 15:41:50 +000090 fTree->unref();
robertphillips@google.com07a05d52012-09-11 11:54:07 +000091 }
rileya@google.com981b33a2012-09-05 18:36:17 +000092protected:
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000093 virtual const char* onGetName() SK_OVERRIDE {
rileya@google.com61348d12012-09-06 13:38:53 +000094 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +000095 }
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000096 virtual void onPreDraw() SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000097 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +000098 for (int j = 0; j < NUM_QUERY_RECTS; ++j) {
99 fTree->insert(reinterpret_cast<void*>(j),
100 fProc(rand, j, NUM_QUERY_RECTS),
101 fBulkLoad);
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000102 }
103 fTree->flushDeferredInserts();
104 }
105
106 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000107 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +0000108 for (int i = 0; i < this->getLoops(); ++i) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000109 SkTDArray<void*> hits;
110 SkIRect query;
111 switch(fQuery) {
112 case kSmall_QueryType:
113 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
114 query.fTop = rand.nextU() % GENERATE_EXTENTS;
115 query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
116 query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
117 break;
118 case kLarge_QueryType:
119 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
120 query.fTop = rand.nextU() % GENERATE_EXTENTS;
121 query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
122 query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
123 break;
124 case kFull_QueryType:
125 query.fLeft = -GENERATE_EXTENTS;
126 query.fTop = -GENERATE_EXTENTS;
127 query.fRight = 2 * GENERATE_EXTENTS;
128 query.fBottom = 2 * GENERATE_EXTENTS;
129 break;
130 default: // fallthrough
131 case kRandom_QueryType:
132 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
133 query.fTop = rand.nextU() % GENERATE_EXTENTS;
134 query.fRight = query.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
135 query.fBottom = query.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
136 break;
137 };
138 fTree->search(query, &hits);
139 }
140 }
141private:
142 SkBBoxHierarchy* fTree;
143 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +0000144 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +0000145 bool fBulkLoad;
146 QueryType fQuery;
147 typedef SkBenchmark INHERITED;
148};
149
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000150static inline SkIRect make_simple_rect(SkRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000151 SkIRect out = {0, 0, GENERATE_EXTENTS, GENERATE_EXTENTS};
152 return out;
153}
154
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000155static inline SkIRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000156 SkIRect out = {0, 0, index + 1, index + 1};
157 return out;
158}
159
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000160static inline SkIRect make_concentric_rects_decreasing(SkRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000161 SkIRect out = {0, 0, numRects - index, numRects - index};
162 return out;
163}
164
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000165static inline SkIRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
sglez@google.com8c902122013-08-30 17:27:47 +0000166 SkIRect out;
167 out.fLeft = index % GRID_WIDTH;
168 out.fTop = index / GRID_WIDTH;
sglez@google.com0d60db62013-08-30 18:54:54 +0000169 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
170 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
sglez@google.com8c902122013-08-30 17:27:47 +0000171 return out;
172}
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000173static inline SkIRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
sglez@google.com8c902122013-08-30 17:27:47 +0000174 SkIRect out;
175 out.fLeft = index / GRID_WIDTH;
176 out.fTop = index % GRID_WIDTH;
sglez@google.com0d60db62013-08-30 18:54:54 +0000177 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
178 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
sglez@google.com8c902122013-08-30 17:27:47 +0000179 return out;
180}
181
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000182static inline SkIRect make_point_rects(SkRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000183 SkIRect out;
184 out.fLeft = rand.nextU() % GENERATE_EXTENTS;
185 out.fTop = rand.nextU() % GENERATE_EXTENTS;
186 out.fRight = out.fLeft + (GENERATE_EXTENTS / 200);
187 out.fBottom = out.fTop + (GENERATE_EXTENTS / 200);
188 return out;
189}
190
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000191static inline SkIRect make_random_rects(SkRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000192 SkIRect out;
193 out.fLeft = rand.nextS() % GENERATE_EXTENTS;
194 out.fTop = rand.nextS() % GENERATE_EXTENTS;
195 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
196 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
197 return out;
198}
199
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000200static inline SkIRect make_large_rects(SkRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000201 SkIRect out;
202 out.fLeft = rand.nextU() % GENERATE_EXTENTS;
203 out.fTop = rand.nextU() % GENERATE_EXTENTS;
204 out.fRight = out.fLeft + (GENERATE_EXTENTS / 3);
205 out.fBottom = out.fTop + (GENERATE_EXTENTS / 3);
206 return out;
207}
208
209///////////////////////////////////////////////////////////////////////////////
210
mtklein@google.com410e6e82013-09-13 19:52:27 +0000211DEF_BENCH(
212 return SkNEW_ARGS(BBoxBuildBench, ("XYordered", &make_XYordered_rects, false,
rileya@google.com981b33a2012-09-05 18:36:17 +0000213 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000214)
215DEF_BENCH(
216 return SkNEW_ARGS(BBoxBuildBench, ("XYordered", &make_XYordered_rects, true,
rileya@google.com981b33a2012-09-05 18:36:17 +0000217 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000218)
219DEF_BENCH(
220 return SkNEW_ARGS(BBoxBuildBench, ("(unsorted)XYordered", &make_XYordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000221 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000222)
223DEF_BENCH(
224 return SkNEW_ARGS(BBoxQueryBench, ("XYordered", &make_XYordered_rects, true,
rileya@google.com981b33a2012-09-05 18:36:17 +0000225 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000226)
227DEF_BENCH(
228 return SkNEW_ARGS(BBoxQueryBench, ("(unsorted)XYordered", &make_XYordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000229 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000230)
rileya@google.com981b33a2012-09-05 18:36:17 +0000231
mtklein@google.com410e6e82013-09-13 19:52:27 +0000232DEF_BENCH(
233 return SkNEW_ARGS(BBoxBuildBench, ("YXordered", &make_YXordered_rects, false,
sglez@google.com8c902122013-08-30 17:27:47 +0000234 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000235)
236DEF_BENCH(
237 return SkNEW_ARGS(BBoxBuildBench, ("YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000238 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000239)
240DEF_BENCH(
241 return SkNEW_ARGS(BBoxBuildBench, ("(unsorted)YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000242 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000243)
244DEF_BENCH(
245 return SkNEW_ARGS(BBoxQueryBench, ("YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000246 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000247)
248DEF_BENCH(
249 return SkNEW_ARGS(BBoxQueryBench, ("(unsorted)YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000250 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000251)
sglez@google.com8c902122013-08-30 17:27:47 +0000252
mtklein@google.com410e6e82013-09-13 19:52:27 +0000253DEF_BENCH(
254 return SkNEW_ARGS(BBoxBuildBench, ("random", &make_random_rects, false,
sglez@google.com8c902122013-08-30 17:27:47 +0000255 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000256)
257DEF_BENCH(
258 return SkNEW_ARGS(BBoxBuildBench, ("random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000259 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000260)
261DEF_BENCH(
262 return SkNEW_ARGS(BBoxBuildBench, ("(unsorted)random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000263 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000264)
265DEF_BENCH(
266 return SkNEW_ARGS(BBoxQueryBench, ("random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000267 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000268)
269DEF_BENCH(
270 return SkNEW_ARGS(BBoxQueryBench, ("(unsorted)random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000271 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000272)
sglez@google.com8c902122013-08-30 17:27:47 +0000273
mtklein@google.com410e6e82013-09-13 19:52:27 +0000274DEF_BENCH(
275 return SkNEW_ARGS(BBoxBuildBench, ("concentric",
sglez@google.com8c902122013-08-30 17:27:47 +0000276 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000277)
278DEF_BENCH(
279 return SkNEW_ARGS(BBoxBuildBench, ("(unsorted)concentric",
sglez@google.com8c902122013-08-30 17:27:47 +0000280 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000281)
282DEF_BENCH(
283 return SkNEW_ARGS(BBoxQueryBench, ("concentric", &make_concentric_rects_increasing, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000284 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000285)
286DEF_BENCH(
287 return SkNEW_ARGS(BBoxQueryBench, ("(unsorted)concentric", &make_concentric_rects_increasing, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000288 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000289)