blob: b51cc4c6a90b4dc552e9e3fda499bdf4a33c7dee [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 }
37 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000038
39 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
40 return backend == kNonRendering_Backend;
41 }
42
robertphillips@google.com07a05d52012-09-11 11:54:07 +000043 virtual ~BBoxBuildBench() {
rileya@google.com48134582012-09-11 15:41:50 +000044 fTree->unref();
robertphillips@google.com07a05d52012-09-11 11:54:07 +000045 }
rileya@google.com981b33a2012-09-05 18:36:17 +000046protected:
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000047 virtual const char* onGetName() SK_OVERRIDE {
rileya@google.com61348d12012-09-06 13:38:53 +000048 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +000049 }
commit-bot@chromium.org33614712013-12-03 18:17:16 +000050 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000051 SkRandom rand;
commit-bot@chromium.org33614712013-12-03 18:17:16 +000052 for (int i = 0; i < loops; ++i) {
rileya@google.com981b33a2012-09-05 18:36:17 +000053 for (int j = 0; j < NUM_BUILD_RECTS; ++j) {
54 fTree->insert(reinterpret_cast<void*>(j), fProc(rand, j, NUM_BUILD_RECTS),
55 fBulkLoad);
56 }
57 fTree->flushDeferredInserts();
58 fTree->clear();
59 }
60 }
61private:
62 SkBBoxHierarchy* fTree;
63 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +000064 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +000065 bool fBulkLoad;
66 typedef SkBenchmark INHERITED;
67};
68
69// Time how long it takes to perform queries on an R-Tree, bulk-loaded or not
70class BBoxQueryBench : public SkBenchmark {
71public:
72 enum QueryType {
73 kSmall_QueryType, // small queries
74 kLarge_QueryType, // large queries
75 kRandom_QueryType,// randomly sized queries
76 kFull_QueryType // queries that cover everything
77 };
78
mtklein@google.com410e6e82013-09-13 19:52:27 +000079 BBoxQueryBench(const char* name, MakeRectProc proc, bool bulkLoad,
rileya@google.com981b33a2012-09-05 18:36:17 +000080 QueryType q, SkBBoxHierarchy* tree)
mtklein@google.com410e6e82013-09-13 19:52:27 +000081 : fTree(tree)
rileya@google.com981b33a2012-09-05 18:36:17 +000082 , fProc(proc)
rileya@google.com981b33a2012-09-05 18:36:17 +000083 , fBulkLoad(bulkLoad)
84 , fQuery(q) {
rileya@google.com61348d12012-09-06 13:38:53 +000085 fName.append("rtree_");
86 fName.append(name);
87 fName.append("_query");
88 if (fBulkLoad) {
89 fName.append("_bulk");
90 }
rileya@google.com981b33a2012-09-05 18:36:17 +000091 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000092
93 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
94 return backend == kNonRendering_Backend;
95 }
96
robertphillips@google.com07a05d52012-09-11 11:54:07 +000097 virtual ~BBoxQueryBench() {
rileya@google.com48134582012-09-11 15:41:50 +000098 fTree->unref();
robertphillips@google.com07a05d52012-09-11 11:54:07 +000099 }
rileya@google.com981b33a2012-09-05 18:36:17 +0000100protected:
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000101 virtual const char* onGetName() SK_OVERRIDE {
rileya@google.com61348d12012-09-06 13:38:53 +0000102 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +0000103 }
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000104 virtual void onPreDraw() SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000105 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +0000106 for (int j = 0; j < NUM_QUERY_RECTS; ++j) {
107 fTree->insert(reinterpret_cast<void*>(j),
108 fProc(rand, j, NUM_QUERY_RECTS),
109 fBulkLoad);
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000110 }
111 fTree->flushDeferredInserts();
112 }
113
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000114 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000115 SkRandom rand;
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000116 for (int i = 0; i < loops; ++i) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000117 SkTDArray<void*> hits;
118 SkIRect query;
119 switch(fQuery) {
120 case kSmall_QueryType:
121 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
122 query.fTop = rand.nextU() % GENERATE_EXTENTS;
123 query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
124 query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
125 break;
126 case kLarge_QueryType:
127 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
128 query.fTop = rand.nextU() % GENERATE_EXTENTS;
129 query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
130 query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
131 break;
132 case kFull_QueryType:
133 query.fLeft = -GENERATE_EXTENTS;
134 query.fTop = -GENERATE_EXTENTS;
135 query.fRight = 2 * GENERATE_EXTENTS;
136 query.fBottom = 2 * GENERATE_EXTENTS;
137 break;
138 default: // fallthrough
139 case kRandom_QueryType:
140 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
141 query.fTop = rand.nextU() % GENERATE_EXTENTS;
142 query.fRight = query.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
143 query.fBottom = query.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
144 break;
145 };
146 fTree->search(query, &hits);
147 }
148 }
149private:
150 SkBBoxHierarchy* fTree;
151 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +0000152 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +0000153 bool fBulkLoad;
154 QueryType fQuery;
155 typedef SkBenchmark INHERITED;
156};
157
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000158static inline SkIRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000159 SkIRect out = {0, 0, index + 1, index + 1};
160 return out;
161}
162
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000163static inline SkIRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
sglez@google.com8c902122013-08-30 17:27:47 +0000164 SkIRect out;
165 out.fLeft = index % GRID_WIDTH;
166 out.fTop = index / GRID_WIDTH;
sglez@google.com0d60db62013-08-30 18:54:54 +0000167 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
168 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
sglez@google.com8c902122013-08-30 17:27:47 +0000169 return out;
170}
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000171static inline SkIRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
sglez@google.com8c902122013-08-30 17:27:47 +0000172 SkIRect out;
173 out.fLeft = index / GRID_WIDTH;
174 out.fTop = index % GRID_WIDTH;
sglez@google.com0d60db62013-08-30 18:54:54 +0000175 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
176 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
sglez@google.com8c902122013-08-30 17:27:47 +0000177 return out;
178}
179
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000180static inline SkIRect make_random_rects(SkRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000181 SkIRect out;
182 out.fLeft = rand.nextS() % GENERATE_EXTENTS;
183 out.fTop = rand.nextS() % GENERATE_EXTENTS;
184 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
185 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
186 return out;
187}
188
rileya@google.com981b33a2012-09-05 18:36:17 +0000189///////////////////////////////////////////////////////////////////////////////
190
mtklein@google.com410e6e82013-09-13 19:52:27 +0000191DEF_BENCH(
192 return SkNEW_ARGS(BBoxBuildBench, ("XYordered", &make_XYordered_rects, false,
rileya@google.com981b33a2012-09-05 18:36:17 +0000193 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000194)
195DEF_BENCH(
196 return SkNEW_ARGS(BBoxBuildBench, ("XYordered", &make_XYordered_rects, true,
rileya@google.com981b33a2012-09-05 18:36:17 +0000197 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000198)
199DEF_BENCH(
200 return SkNEW_ARGS(BBoxBuildBench, ("(unsorted)XYordered", &make_XYordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000201 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000202)
203DEF_BENCH(
204 return SkNEW_ARGS(BBoxQueryBench, ("XYordered", &make_XYordered_rects, true,
rileya@google.com981b33a2012-09-05 18:36:17 +0000205 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000206)
207DEF_BENCH(
208 return SkNEW_ARGS(BBoxQueryBench, ("(unsorted)XYordered", &make_XYordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000209 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000210)
rileya@google.com981b33a2012-09-05 18:36:17 +0000211
mtklein@google.com410e6e82013-09-13 19:52:27 +0000212DEF_BENCH(
213 return SkNEW_ARGS(BBoxBuildBench, ("YXordered", &make_YXordered_rects, false,
sglez@google.com8c902122013-08-30 17:27:47 +0000214 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000215)
216DEF_BENCH(
217 return SkNEW_ARGS(BBoxBuildBench, ("YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000218 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000219)
220DEF_BENCH(
221 return SkNEW_ARGS(BBoxBuildBench, ("(unsorted)YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000222 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000223)
224DEF_BENCH(
225 return SkNEW_ARGS(BBoxQueryBench, ("YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000226 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000227)
228DEF_BENCH(
229 return SkNEW_ARGS(BBoxQueryBench, ("(unsorted)YXordered", &make_YXordered_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000230 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000231)
sglez@google.com8c902122013-08-30 17:27:47 +0000232
mtklein@google.com410e6e82013-09-13 19:52:27 +0000233DEF_BENCH(
234 return SkNEW_ARGS(BBoxBuildBench, ("random", &make_random_rects, false,
sglez@google.com8c902122013-08-30 17:27:47 +0000235 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000236)
237DEF_BENCH(
238 return SkNEW_ARGS(BBoxBuildBench, ("random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000239 SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000240)
241DEF_BENCH(
242 return SkNEW_ARGS(BBoxBuildBench, ("(unsorted)random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000243 SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000244)
245DEF_BENCH(
246 return SkNEW_ARGS(BBoxQueryBench, ("random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000247 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000248)
249DEF_BENCH(
250 return SkNEW_ARGS(BBoxQueryBench, ("(unsorted)random", &make_random_rects, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000251 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000252)
sglez@google.com8c902122013-08-30 17:27:47 +0000253
mtklein@google.com410e6e82013-09-13 19:52:27 +0000254DEF_BENCH(
255 return SkNEW_ARGS(BBoxBuildBench, ("concentric",
sglez@google.com8c902122013-08-30 17:27:47 +0000256 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000257)
258DEF_BENCH(
259 return SkNEW_ARGS(BBoxBuildBench, ("(unsorted)concentric",
sglez@google.com8c902122013-08-30 17:27:47 +0000260 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000261)
262DEF_BENCH(
263 return SkNEW_ARGS(BBoxQueryBench, ("concentric", &make_concentric_rects_increasing, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000264 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000265)
266DEF_BENCH(
267 return SkNEW_ARGS(BBoxQueryBench, ("(unsorted)concentric", &make_concentric_rects_increasing, true,
sglez@google.com8c902122013-08-30 17:27:47 +0000268 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16, 1, false)));
mtklein@google.com410e6e82013-09-13 19:52:27 +0000269)