2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
13 static const size_t MIN_CHILDREN = 6;
14 static const size_t MAX_CHILDREN = 11;
16 static const int NUM_RECTS = 200;
17 static const size_t NUM_ITERATIONS = 100;
18 static const size_t NUM_QUERIES = 50;
20 static SkRect random_rect(SkRandom& rand) {
21 SkRect rect = {0,0,0,0};
22 while (rect.isEmpty()) {
23 rect.fLeft = rand.nextRangeF(0, 1000);
24 rect.fRight = rand.nextRangeF(0, 1000);
25 rect.fTop = rand.nextRangeF(0, 1000);
26 rect.fBottom = rand.nextRangeF(0, 1000);
32 static bool verify_query(SkRect query, SkRect rects[], SkTDArray<unsigned>& found) {
33 // TODO(mtklein): no need to do this after everything's SkRects
36 SkTDArray<unsigned> expected;
38 // manually intersect with every rectangle
39 for (int i = 0; i < NUM_RECTS; ++i) {
40 if (SkRect::Intersects(query, rects[i])) {
45 if (expected.count() != found.count()) {
49 if (0 == expected.count()) {
53 // skia:2834. RTree doesn't always return results in order.
54 SkTQSort(expected.begin(), expected.end() -1);
55 SkTQSort(found.begin(), found.end() -1);
56 return found == expected;
59 static void run_queries(skiatest::Reporter* reporter, SkRandom& rand, SkRect rects[],
61 for (size_t i = 0; i < NUM_QUERIES; ++i) {
62 SkTDArray<unsigned> hits;
63 SkRect query = random_rect(rand);
64 tree.search(query, &hits);
65 REPORTER_ASSERT(reporter, verify_query(query, rects, hits));
69 static void rtree_test_main(SkRTree* rtree, skiatest::Reporter* reporter) {
72 int expectedDepthMin = -1;
73 int expectedDepthMax = -1;
77 tmp -= static_cast<int>(pow(static_cast<double>(MAX_CHILDREN),
78 static_cast<double>(expectedDepthMin + 1)));
84 tmp -= static_cast<int>(pow(static_cast<double>(MIN_CHILDREN),
85 static_cast<double>(expectedDepthMax + 1)));
90 SkAutoTMalloc<SkRect> rects(NUM_RECTS);
91 for (size_t i = 0; i < NUM_ITERATIONS; ++i) {
93 REPORTER_ASSERT(reporter, 0 == rtree->getCount());
95 for (int j = 0; j < NUM_RECTS; j++) {
96 rects[j] = random_rect(rand);
99 rtree->insert(&rects, NUM_RECTS);
100 SkASSERT(rects); // SkRTree doesn't take ownership of rects.
102 run_queries(reporter, rand, rects, *rtree);
103 REPORTER_ASSERT(reporter, NUM_RECTS == rtree->getCount());
104 REPORTER_ASSERT(reporter, expectedDepthMin <= rtree->getDepth() &&
105 expectedDepthMax >= rtree->getDepth());
109 DEF_TEST(RTree, reporter) {
110 SkRTree* rtree = SkRTree::Create(MIN_CHILDREN, MAX_CHILDREN);
111 SkAutoUnref au(rtree);
112 rtree_test_main(rtree, reporter);
114 // Rtree that orders input rectangles on deferred insert.
115 SkRTree* unsortedRtree = SkRTree::Create(MIN_CHILDREN, MAX_CHILDREN, 1, false);
116 SkAutoUnref auo(unsortedRtree);
117 rtree_test_main(unsortedRtree, reporter);