blob: bce1b67513f734d115b174928b6885eca1e41c19 [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;
19static const int NUM_QUERIES = 1000;
20
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000021typedef SkIRect (*MakeRectProc)(SkMWCRandom&, 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 {
48 SkMWCRandom rand;
rileya@google.com981b33a2012-09-05 18:36:17 +000049 for (int i = 0; i < SkBENCHLOOP(100); ++i) {
50 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 {
99 SkMWCRandom rand;
100 for (int j = 0; j < SkBENCHLOOP(NUM_QUERY_RECTS); ++j) {
101 fTree->insert(reinterpret_cast<void*>(j), fProc(rand, j,
102 SkBENCHLOOP(NUM_QUERY_RECTS)), fBulkLoad);
103 }
104 fTree->flushDeferredInserts();
105 }
106
107 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
108 SkMWCRandom rand;
rileya@google.com981b33a2012-09-05 18:36:17 +0000109 for (int i = 0; i < SkBENCHLOOP(NUM_QUERIES); ++i) {
110 SkTDArray<void*> hits;
111 SkIRect query;
112 switch(fQuery) {
113 case kSmall_QueryType:
114 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
115 query.fTop = rand.nextU() % GENERATE_EXTENTS;
116 query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
117 query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
118 break;
119 case kLarge_QueryType:
120 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
121 query.fTop = rand.nextU() % GENERATE_EXTENTS;
122 query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
123 query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
124 break;
125 case kFull_QueryType:
126 query.fLeft = -GENERATE_EXTENTS;
127 query.fTop = -GENERATE_EXTENTS;
128 query.fRight = 2 * GENERATE_EXTENTS;
129 query.fBottom = 2 * GENERATE_EXTENTS;
130 break;
131 default: // fallthrough
132 case kRandom_QueryType:
133 query.fLeft = rand.nextU() % GENERATE_EXTENTS;
134 query.fTop = rand.nextU() % GENERATE_EXTENTS;
135 query.fRight = query.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
136 query.fBottom = query.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
137 break;
138 };
139 fTree->search(query, &hits);
140 }
141 }
142private:
143 SkBBoxHierarchy* fTree;
144 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +0000145 SkString fName;
rileya@google.com981b33a2012-09-05 18:36:17 +0000146 bool fBulkLoad;
147 QueryType fQuery;
148 typedef SkBenchmark INHERITED;
149};
150
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000151static inline SkIRect make_simple_rect(SkMWCRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000152 SkIRect out = {0, 0, GENERATE_EXTENTS, GENERATE_EXTENTS};
153 return out;
154}
155
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000156static inline SkIRect make_concentric_rects_increasing(SkMWCRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000157 SkIRect out = {0, 0, index + 1, index + 1};
158 return out;
159}
160
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000161static inline SkIRect make_concentric_rects_decreasing(SkMWCRandom&, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000162 SkIRect out = {0, 0, numRects - index, numRects - index};
163 return out;
164}
165
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000166static inline SkIRect make_point_rects(SkMWCRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000167 SkIRect out;
168 out.fLeft = rand.nextU() % GENERATE_EXTENTS;
169 out.fTop = rand.nextU() % GENERATE_EXTENTS;
170 out.fRight = out.fLeft + (GENERATE_EXTENTS / 200);
171 out.fBottom = out.fTop + (GENERATE_EXTENTS / 200);
172 return out;
173}
174
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000175static inline SkIRect make_random_rects(SkMWCRandom& rand, int index, int numRects) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000176 SkIRect out;
177 out.fLeft = rand.nextS() % GENERATE_EXTENTS;
178 out.fTop = rand.nextS() % GENERATE_EXTENTS;
179 out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
180 out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
181 return out;
182}
183
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +0000184static inline SkIRect make_large_rects(SkMWCRandom& 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 / 3);
189 out.fBottom = out.fTop + (GENERATE_EXTENTS / 3);
190 return out;
191}
192
193///////////////////////////////////////////////////////////////////////////////
194
humper@google.com05af1af2013-01-07 16:47:43 +0000195static inline SkBenchmark* Fact0(void* p) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000196 return SkNEW_ARGS(BBoxBuildBench, (p, "random", &make_random_rects, true,
197 SkRTree::Create(5, 16)));
198}
humper@google.com05af1af2013-01-07 16:47:43 +0000199static inline SkBenchmark* Fact1(void* p) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000200 return SkNEW_ARGS(BBoxBuildBench, (p, "random", &make_random_rects, false,
201 SkRTree::Create(5, 16)));
202}
humper@google.com05af1af2013-01-07 16:47:43 +0000203static inline SkBenchmark* Fact2(void* p) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000204 return SkNEW_ARGS(BBoxBuildBench, (p, "concentric",
205 &make_concentric_rects_increasing, true, SkRTree::Create(5, 16)));
206}
humper@google.com05af1af2013-01-07 16:47:43 +0000207static inline SkBenchmark* Fact3(void* p) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000208 return SkNEW_ARGS(BBoxQueryBench, (p, "random", &make_random_rects, true,
209 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
210}
humper@google.com05af1af2013-01-07 16:47:43 +0000211static inline SkBenchmark* Fact4(void* p) {
rileya@google.com981b33a2012-09-05 18:36:17 +0000212 return SkNEW_ARGS(BBoxQueryBench, (p, "random", &make_random_rects, false,
213 BBoxQueryBench::kRandom_QueryType, SkRTree::Create(5, 16)));
214}
215
216static BenchRegistry gReg0(Fact0);
217static BenchRegistry gReg1(Fact1);
218static BenchRegistry gReg2(Fact2);
219static BenchRegistry gReg3(Fact3);
220static BenchRegistry gReg4(Fact4);