blob: b8d93bff59fd4e191bd42fcd7d89a850de0437f4 [file] [log] [blame]
rileya@google.com981b33a2012-09-05 18:36:17 +00001/*
2 * Copyright 2012 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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "bench/Benchmark.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkString.h"
John Stiles9d5461f2020-07-27 15:53:49 -040011#include "include/private/SkTemplates.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/utils/SkRandom.h"
13#include "src/core/SkRTree.h"
rileya@google.com981b33a2012-09-05 18:36:17 +000014
15// confine rectangles to a smallish area, so queries generally hit something, and overlap occurs:
mtklein533eb782014-08-27 10:39:42 -070016static const SkScalar GENERATE_EXTENTS = 1000.0f;
rileya@google.com981b33a2012-09-05 18:36:17 +000017static 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
mtklein533eb782014-08-27 10:39:42 -070021typedef SkRect (*MakeRectProc)(SkRandom&, int, int);
rileya@google.com981b33a2012-09-05 18:36:17 +000022
mtkleina06a9532014-11-18 09:27:49 -080023// Time how long it takes to build an R-Tree.
tfarinaf168b862014-06-19 12:32:29 -070024class RTreeBuildBench : public Benchmark {
rileya@google.com981b33a2012-09-05 18:36:17 +000025public:
mtkleina06a9532014-11-18 09:27:49 -080026 RTreeBuildBench(const char* name, MakeRectProc proc) : fProc(proc) {
mtklein4477c3c2014-10-27 10:27:10 -070027 fName.printf("rtree_%s_build", name);
rileya@google.com61348d12012-09-06 13:38:53 +000028 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000029
mtklein36352bf2015-03-25 18:17:31 -070030 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000031 return backend == kNonRendering_Backend;
32 }
33
rileya@google.com981b33a2012-09-05 18:36:17 +000034protected:
mtklein36352bf2015-03-25 18:17:31 -070035 const char* onGetName() override {
rileya@google.com61348d12012-09-06 13:38:53 +000036 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +000037 }
mtkleina1ebeb22015-10-01 09:43:39 -070038 void onDraw(int loops, SkCanvas* canvas) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000039 SkRandom rand;
mtklein4477c3c2014-10-27 10:27:10 -070040 SkAutoTMalloc<SkRect> rects(NUM_BUILD_RECTS);
41 for (int i = 0; i < NUM_BUILD_RECTS; ++i) {
42 rects[i] = fProc(rand, i, NUM_BUILD_RECTS);
43 }
44
commit-bot@chromium.org33614712013-12-03 18:17:16 +000045 for (int i = 0; i < loops; ++i) {
mtkleina06a9532014-11-18 09:27:49 -080046 SkRTree tree;
mtkleinbfd5bff2015-02-10 13:44:27 -080047 tree.insert(rects.get(), NUM_BUILD_RECTS);
halcanary96fcdcc2015-08-27 07:41:13 -070048 SkASSERT(rects != nullptr); // It'd break this bench if the tree took ownership of rects.
rileya@google.com981b33a2012-09-05 18:36:17 +000049 }
50 }
51private:
rileya@google.com981b33a2012-09-05 18:36:17 +000052 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +000053 SkString fName;
John Stiles7571f9e2020-09-02 22:42:33 -040054 using INHERITED = Benchmark;
rileya@google.com981b33a2012-09-05 18:36:17 +000055};
56
mtkleina06a9532014-11-18 09:27:49 -080057// Time how long it takes to perform queries on an R-Tree.
tfarinaf168b862014-06-19 12:32:29 -070058class RTreeQueryBench : public Benchmark {
rileya@google.com981b33a2012-09-05 18:36:17 +000059public:
mtkleina06a9532014-11-18 09:27:49 -080060 RTreeQueryBench(const char* name, MakeRectProc proc) : fProc(proc) {
mtklein4477c3c2014-10-27 10:27:10 -070061 fName.printf("rtree_%s_query", name);
rileya@google.com981b33a2012-09-05 18:36:17 +000062 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000063
mtklein36352bf2015-03-25 18:17:31 -070064 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000065 return backend == kNonRendering_Backend;
66 }
rileya@google.com981b33a2012-09-05 18:36:17 +000067protected:
mtklein36352bf2015-03-25 18:17:31 -070068 const char* onGetName() override {
rileya@google.com61348d12012-09-06 13:38:53 +000069 return fName.c_str();
rileya@google.com981b33a2012-09-05 18:36:17 +000070 }
joshualitt8a6697a2015-09-30 12:11:07 -070071 void onDelayedSetup() override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000072 SkRandom rand;
mtklein4477c3c2014-10-27 10:27:10 -070073 SkAutoTMalloc<SkRect> rects(NUM_QUERY_RECTS);
74 for (int i = 0; i < NUM_QUERY_RECTS; ++i) {
75 rects[i] = fProc(rand, i, NUM_QUERY_RECTS);
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000076 }
mtkleinbfd5bff2015-02-10 13:44:27 -080077 fTree.insert(rects.get(), NUM_QUERY_RECTS);
commit-bot@chromium.org7fb83c82013-08-01 15:58:07 +000078 }
79
mtkleina1ebeb22015-10-01 09:43:39 -070080 void onDraw(int loops, SkCanvas* canvas) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000081 SkRandom rand;
commit-bot@chromium.org33614712013-12-03 18:17:16 +000082 for (int i = 0; i < loops; ++i) {
Mike Klein508fd322020-02-12 09:45:41 -060083 std::vector<int> hits;
mtklein533eb782014-08-27 10:39:42 -070084 SkRect query;
mtklein4477c3c2014-10-27 10:27:10 -070085 query.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
86 query.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
87 query.fRight = query.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/2);
88 query.fBottom = query.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/2);
mtkleina06a9532014-11-18 09:27:49 -080089 fTree.search(query, &hits);
rileya@google.com981b33a2012-09-05 18:36:17 +000090 }
91 }
92private:
mtkleina06a9532014-11-18 09:27:49 -080093 SkRTree fTree;
rileya@google.com981b33a2012-09-05 18:36:17 +000094 MakeRectProc fProc;
rileya@google.com61348d12012-09-06 13:38:53 +000095 SkString fName;
John Stiles7571f9e2020-09-02 22:42:33 -040096 using INHERITED = Benchmark;
rileya@google.com981b33a2012-09-05 18:36:17 +000097};
98
mtklein533eb782014-08-27 10:39:42 -070099static inline SkRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
100 SkRect out;
101 out.fLeft = SkIntToScalar(index % GRID_WIDTH);
102 out.fTop = SkIntToScalar(index / GRID_WIDTH);
103 out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
104 out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
sglez@google.com8c902122013-08-30 17:27:47 +0000105 return out;
106}
mtklein533eb782014-08-27 10:39:42 -0700107static inline SkRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
108 SkRect out;
109 out.fLeft = SkIntToScalar(index / GRID_WIDTH);
110 out.fTop = SkIntToScalar(index % GRID_WIDTH);
111 out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
112 out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
sglez@google.com8c902122013-08-30 17:27:47 +0000113 return out;
114}
115
mtklein533eb782014-08-27 10:39:42 -0700116static inline SkRect make_random_rects(SkRandom& rand, int index, int numRects) {
117 SkRect out;
118 out.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
119 out.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
120 out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/5);
121 out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/5);
rileya@google.com981b33a2012-09-05 18:36:17 +0000122 return out;
123}
124
mtkleina06a9532014-11-18 09:27:49 -0800125static inline SkRect make_concentric_rects(SkRandom&, int index, int numRects) {
126 return SkRect::MakeWH(SkIntToScalar(index+1), SkIntToScalar(index+1));
127}
128
rileya@google.com981b33a2012-09-05 18:36:17 +0000129///////////////////////////////////////////////////////////////////////////////
130
halcanary385fe4d2015-08-26 13:07:48 -0700131DEF_BENCH(return new RTreeBuildBench("XY", &make_XYordered_rects));
132DEF_BENCH(return new RTreeBuildBench("YX", &make_YXordered_rects));
133DEF_BENCH(return new RTreeBuildBench("random", &make_random_rects));
134DEF_BENCH(return new RTreeBuildBench("concentric", &make_concentric_rects));
rileya@google.com981b33a2012-09-05 18:36:17 +0000135
halcanary385fe4d2015-08-26 13:07:48 -0700136DEF_BENCH(return new RTreeQueryBench("XY", &make_XYordered_rects));
137DEF_BENCH(return new RTreeQueryBench("YX", &make_YXordered_rects));
138DEF_BENCH(return new RTreeQueryBench("random", &make_random_rects));
139DEF_BENCH(return new RTreeQueryBench("concentric", &make_concentric_rects));