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