Flutter Engine
 
Loading...
Searching...
No Matches
dl_rtree.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_DISPLAY_LIST_GEOMETRY_DL_RTREE_H_
6#define FLUTTER_DISPLAY_LIST_GEOMETRY_DL_RTREE_H_
7
8#include <list>
9#include <optional>
10#include <vector>
11
13#include "flutter/fml/logging.h"
14#include "third_party/skia/include/core/SkRefCnt.h"
15
16namespace flutter {
17
18/// An R-Tree that stores a list of bounding rectangles with optional
19/// associated IDs.
20///
21/// The R-Tree can be searched in one of two ways:
22/// - Query for a list of hits among the original rectangles
23/// @see |search|
24/// - Query for a set of non-overlapping rectangles that are joined
25/// from the original rectangles that intersect a query rect
26/// @see |searchAndConsolidateRects|
27class DlRTree : public SkRefCnt {
28 private:
29 static constexpr int kMaxChildren = 11;
30
31 // Leaf nodes at start of vector have an ID,
32 // Internal nodes after that have child index and count.
33 struct Node {
34 DlRect bounds;
35 union {
36 struct {
37 uint32_t index;
38 uint32_t count;
39 } child;
40 int id;
41 };
42 };
43
44 public:
45 /// Construct an R-Tree from the list of rectangles respecting the
46 /// order in which they appear in the list. An optional array of
47 /// IDs can be provided to tag each rectangle with information needed
48 /// by the caller as well as an optional predicate that can filter
49 /// out rectangles with IDs that should not be stored in the R-Tree.
50 ///
51 /// If an array of IDs is not specified then all leaf nodes will be
52 /// represented by the |invalid_id| (which defaults to -1).
53 ///
54 /// Invalid rects that are empty or contain a NaN value will not be
55 /// stored in the R-Tree. And, if a |predicate| function is provided,
56 /// that function will be called to query if the rectangle associated
57 /// with the ID should be included.
58 ///
59 /// Duplicate rectangles and IDs are allowed and not processed in any
60 /// way except to eliminate invalid rectangles and IDs that are rejected
61 /// by the optional predicate function.
62 DlRTree(
63 const DlRect rects[],
64 int N,
65 const int ids[] = nullptr,
66 bool predicate(int id) = [](int) { return true; },
67 int invalid_id = -1);
68
69 /// Search the rectangles and return a vector of leaf node indices for
70 /// rectangles that intersect the query.
71 ///
72 /// Note that the indices are internal indices of the stored data
73 /// and not the index of the rectangles or ids in the constructor.
74 /// The returned indices may not themselves be in numerical order,
75 /// but they will represent the rectangles and IDs in the order in
76 /// which they were passed into the constructor. The actual rectangle
77 /// and ID associated with each index can be retrieved using the
78 /// |DlRTree::id| and |DlRTree::bounds| methods.
79 void search(const DlRect& query, std::vector<int>* results) const;
80
81 /// Return the ID for the indicated result of a query or
82 /// invalid_id if the index is not a valid leaf node index.
83 int id(int result_index) const {
84 return (result_index >= 0 && result_index < leaf_count_)
85 ? nodes_[result_index].id
86 : invalid_id_;
87 }
88
89 /// Returns maximum and minimum axis values of rectangles in this R-Tree.
90 /// If R-Tree is empty returns an empty DlRect.
91 const DlRect& bounds() const;
92
93 /// Return the rectangle bounds for the indicated result of a query
94 /// or an empty rect if the index is not a valid leaf node index.
95 const DlRect& bounds(int result_index) const {
96 return (result_index >= 0 && result_index < leaf_count_)
97 ? nodes_[result_index].bounds
98 : kEmpty;
99 }
100
101 /// Returns the bytes used by the object and all of its node data.
102 size_t bytes_used() const {
103 return sizeof(DlRTree) + sizeof(Node) * nodes_.size();
104 }
105
106 /// Returns the number of leaf nodes corresponding to non-empty
107 /// rectangles that were passed in the constructor and not filtered
108 /// out by the predicate.
109 int leaf_count() const { return leaf_count_; }
110
111 /// Return the total number of nodes used in the R-Tree, both leaf
112 /// and internal consolidation nodes.
113 int node_count() const { return nodes_.size(); }
114
115 /// Finds the rects in the tree that intersect with the query rect.
116 ///
117 /// The returned list of rectangles will be non-overlapping.
118 /// In other words, the bounds of each rect in the result list are mutually
119 /// exclusive.
120 ///
121 /// If |deband| is true, then matching rectangles from adjacent DlRegion
122 /// spanlines will be joined together. This reduces the number of
123 /// rectangles returned, but requires some extra computation.
124 std::list<DlRect> searchAndConsolidateRects(const DlRect& query,
125 bool deband = true) const;
126
127 /// Returns DlRegion that represents the union of all rectangles in the
128 /// R-Tree.
129 const DlRegion& region() const;
130
131 /// Returns DlRegion that represents the union of all rectangles in the
132 /// R-Tree intersected with the query rect.
133 DlRegion region(const DlRect& query) const {
136 }
137
138 private:
139 static constexpr DlRect kEmpty = DlRect();
140
141 void search(const Node& parent,
142 const DlRect& query,
143 std::vector<int>* results) const;
144
145 std::vector<Node> nodes_;
146 int leaf_count_ = 0;
147 int invalid_id_;
148 mutable std::optional<DlRegion> region_;
149};
150
151} // namespace flutter
152
153#endif // FLUTTER_DISPLAY_LIST_GEOMETRY_DL_RTREE_H_
const DlRect & bounds(int result_index) const
Definition dl_rtree.h:95
int id(int result_index) const
Definition dl_rtree.h:83
DlRegion region(const DlRect &query) const
Definition dl_rtree.h:133
int node_count() const
Definition dl_rtree.h:113
const DlRegion & region() const
Definition dl_rtree.cc:203
size_t bytes_used() const
Returns the bytes used by the object and all of its node data.
Definition dl_rtree.h:102
void search(const DlRect &query, std::vector< int > *results) const
Definition dl_rtree.cc:142
std::list< DlRect > searchAndConsolidateRects(const DlRect &query, bool deband=true) const
Definition dl_rtree.cc:163
int leaf_count() const
Definition dl_rtree.h:109
const DlRect & bounds() const
Definition dl_rtree.cc:215
static DlRegion MakeIntersection(const DlRegion &a, const DlRegion &b)
Definition dl_region.cc:496
impeller::Rect DlRect
RoundOut(const TRect< U > &r)
Definition rect.h:679
const uintptr_t id