1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2012 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h" 9cb93a386Sopenharmony_ci#include "src/core/SkRTree.h" 10cb93a386Sopenharmony_ci#include "tests/Test.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_cistatic const int NUM_RECTS = 200; 13cb93a386Sopenharmony_cistatic const size_t NUM_ITERATIONS = 100; 14cb93a386Sopenharmony_cistatic const size_t NUM_QUERIES = 50; 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cistatic SkRect random_rect(SkRandom& rand) { 17cb93a386Sopenharmony_ci SkRect rect = {0,0,0,0}; 18cb93a386Sopenharmony_ci while (rect.isEmpty()) { 19cb93a386Sopenharmony_ci rect.fLeft = rand.nextRangeF(0, 1000); 20cb93a386Sopenharmony_ci rect.fRight = rand.nextRangeF(0, 1000); 21cb93a386Sopenharmony_ci rect.fTop = rand.nextRangeF(0, 1000); 22cb93a386Sopenharmony_ci rect.fBottom = rand.nextRangeF(0, 1000); 23cb93a386Sopenharmony_ci rect.sort(); 24cb93a386Sopenharmony_ci } 25cb93a386Sopenharmony_ci return rect; 26cb93a386Sopenharmony_ci} 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_cistatic bool verify_query(SkRect query, SkRect rects[], const std::vector<int>& found) { 29cb93a386Sopenharmony_ci std::vector<int> expected; 30cb93a386Sopenharmony_ci // manually intersect with every rectangle 31cb93a386Sopenharmony_ci for (int i = 0; i < NUM_RECTS; ++i) { 32cb93a386Sopenharmony_ci if (SkRect::Intersects(query, rects[i])) { 33cb93a386Sopenharmony_ci expected.push_back(i); 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci if (expected.size() != found.size()) { 38cb93a386Sopenharmony_ci return false; 39cb93a386Sopenharmony_ci } 40cb93a386Sopenharmony_ci if (0 == expected.size()) { 41cb93a386Sopenharmony_ci return true; 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci return found == expected; 44cb93a386Sopenharmony_ci} 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_cistatic void run_queries(skiatest::Reporter* reporter, SkRandom& rand, SkRect rects[], 47cb93a386Sopenharmony_ci const SkRTree& tree) { 48cb93a386Sopenharmony_ci for (size_t i = 0; i < NUM_QUERIES; ++i) { 49cb93a386Sopenharmony_ci std::vector<int> hits; 50cb93a386Sopenharmony_ci SkRect query = random_rect(rand); 51cb93a386Sopenharmony_ci tree.search(query, &hits); 52cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, verify_query(query, rects, hits)); 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci} 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ciDEF_TEST(RTree, reporter) { 57cb93a386Sopenharmony_ci int expectedDepthMin = -1; 58cb93a386Sopenharmony_ci int tmp = NUM_RECTS; 59cb93a386Sopenharmony_ci while (tmp > 0) { 60cb93a386Sopenharmony_ci tmp -= static_cast<int>(pow(static_cast<double>(SkRTree::kMaxChildren), 61cb93a386Sopenharmony_ci static_cast<double>(expectedDepthMin + 1))); 62cb93a386Sopenharmony_ci ++expectedDepthMin; 63cb93a386Sopenharmony_ci } 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci int expectedDepthMax = -1; 66cb93a386Sopenharmony_ci tmp = NUM_RECTS; 67cb93a386Sopenharmony_ci while (tmp > 0) { 68cb93a386Sopenharmony_ci tmp -= static_cast<int>(pow(static_cast<double>(SkRTree::kMinChildren), 69cb93a386Sopenharmony_ci static_cast<double>(expectedDepthMax + 1))); 70cb93a386Sopenharmony_ci ++expectedDepthMax; 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci SkRandom rand; 74cb93a386Sopenharmony_ci SkAutoTMalloc<SkRect> rects(NUM_RECTS); 75cb93a386Sopenharmony_ci for (size_t i = 0; i < NUM_ITERATIONS; ++i) { 76cb93a386Sopenharmony_ci SkRTree rtree; 77cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == rtree.getCount()); 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_ci for (int j = 0; j < NUM_RECTS; j++) { 80cb93a386Sopenharmony_ci rects[j] = random_rect(rand); 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci rtree.insert(rects.get(), NUM_RECTS); 84cb93a386Sopenharmony_ci SkASSERT(rects); // SkRTree doesn't take ownership of rects. 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci run_queries(reporter, rand, rects, rtree); 87cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, NUM_RECTS == rtree.getCount()); 88cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, expectedDepthMin <= rtree.getDepth() && 89cb93a386Sopenharmony_ci expectedDepthMax >= rtree.getDepth()); 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci} 92