Flutter Engine
The Flutter Engine
rtree_unittests.cc
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#include "flutter/shell/platform/fuchsia/flutter/rtree.h"
6
7#include "flutter/testing/testing.h"
11
12namespace flutter {
13namespace testing {
14
15TEST(RTree, searchNonOverlappingDrawnRectsNoIntersection) {
16 auto rtree_factory = RTreeFactory();
17 auto recorder = std::make_unique<SkPictureRecorder>();
18 auto recording_canvas =
19 recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
20
21 auto rect_paint = SkPaint();
22 rect_paint.setColor(SkColors::kCyan);
23 rect_paint.setStyle(SkPaint::Style::kFill_Style);
24
25 // If no rect is intersected with the query rect, then the result list is
26 // empty.
27 recording_canvas->drawRect(SkRect::MakeLTRB(20, 20, 40, 40), rect_paint);
28 recorder->finishRecordingAsPicture();
29
30 auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
31 SkRect::MakeLTRB(40, 40, 80, 80));
32 ASSERT_TRUE(hits.empty());
33}
34
35TEST(RTree, searchNonOverlappingDrawnRectsSingleRectIntersection) {
36 auto rtree_factory = RTreeFactory();
37 auto recorder = std::make_unique<SkPictureRecorder>();
38 auto recording_canvas =
39 recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
40
41 auto rect_paint = SkPaint();
42 rect_paint.setColor(SkColors::kCyan);
43 rect_paint.setStyle(SkPaint::Style::kFill_Style);
44
45 // Given a single rect A that intersects with the query rect,
46 // the result list contains this rect.
47 recording_canvas->drawRect(SkRect::MakeLTRB(120, 120, 160, 160), rect_paint);
48
49 recorder->finishRecordingAsPicture();
50
51 auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
52 SkRect::MakeLTRB(140, 140, 150, 150));
53 ASSERT_EQ(1UL, hits.size());
54 ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(120, 120, 160, 160));
55}
56
57TEST(RTree, searchNonOverlappingDrawnRectsIgnoresNonDrawingRecords) {
58 auto rtree_factory = RTreeFactory();
59 auto recorder = std::make_unique<SkPictureRecorder>();
60 auto recording_canvas =
61 recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
62
63 auto rect_paint = SkPaint();
64 rect_paint.setColor(SkColors::kCyan);
65 rect_paint.setStyle(SkPaint::Style::kFill_Style);
66
67 // Creates two non drawing records.
68 recording_canvas->translate(100, 100);
69 // The result list should only contain the clipping rect.
70 recording_canvas->clipRect(SkRect::MakeLTRB(40, 40, 50, 50),
72 recording_canvas->drawRect(SkRect::MakeLTRB(20, 20, 80, 80), rect_paint);
73
74 recorder->finishRecordingAsPicture();
75
76 // The rtree has a translate, a clip and a rect record.
77 ASSERT_EQ(3, rtree_factory.getInstance()->getCount());
78
79 auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
80 SkRect::MakeLTRB(0, 0, 1000, 1000));
81 ASSERT_EQ(1UL, hits.size());
82 ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(120, 120, 180, 180));
83}
84
85TEST(RTree, searchNonOverlappingDrawnRectsMultipleRectIntersection) {
86 auto rtree_factory = RTreeFactory();
87 auto recorder = std::make_unique<SkPictureRecorder>();
88 auto recording_canvas =
89 recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
90
91 auto rect_paint = SkPaint();
92 rect_paint.setColor(SkColors::kCyan);
93 rect_paint.setStyle(SkPaint::Style::kFill_Style);
94
95 // Given the A, B that intersect with the query rect,
96 // there should be A and B in the result list since
97 // they don't intersect with each other.
98 //
99 // +-----+ +-----+
100 // | A | | B |
101 // +-----+ +-----+
102 // A
103 recording_canvas->drawRect(SkRect::MakeLTRB(100, 100, 200, 200), rect_paint);
104 // B
105 recording_canvas->drawRect(SkRect::MakeLTRB(300, 100, 400, 200), rect_paint);
106
107 recorder->finishRecordingAsPicture();
108
109 auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
110 SkRect::MakeLTRB(0, 0, 1000, 1050));
111 ASSERT_EQ(2UL, hits.size());
112 ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(100, 100, 200, 200));
113 ASSERT_EQ(*std::next(hits.begin(), 1), SkRect::MakeLTRB(300, 100, 400, 200));
114}
115
116TEST(RTree, searchNonOverlappingDrawnRectsJoinRectsWhenIntersectedCase1) {
117 auto rtree_factory = RTreeFactory();
118 auto recorder = std::make_unique<SkPictureRecorder>();
119 auto recording_canvas =
120 recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
121
122 auto rect_paint = SkPaint();
123 rect_paint.setColor(SkColors::kCyan);
124 rect_paint.setStyle(SkPaint::Style::kFill_Style);
125
126 // Given the A, and B rects, which intersect with the query rect,
127 // the result list contains the three rectangles covering same area.
128 //
129 // +-----+ +-----+
130 // | A | | A |
131 // | +-----+ +---------+
132 // | | | | B |
133 // +---| B | +---+-----+
134 // | | | C |
135 // +-----+ +-----+
136
137 // A
138 recording_canvas->drawRect(SkRect::MakeLTRB(100, 100, 150, 150), rect_paint);
139 // B
140 recording_canvas->drawRect(SkRect::MakeLTRB(125, 125, 175, 175), rect_paint);
141
142 recorder->finishRecordingAsPicture();
143
144 auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
145 SkRect::MakeXYWH(120, 120, 126, 126));
146 ASSERT_EQ(3UL, hits.size());
147 ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(100, 100, 150, 125));
148 ASSERT_EQ(*std::next(hits.begin(), 1), SkRect::MakeLTRB(100, 125, 175, 150));
149 ASSERT_EQ(*std::next(hits.begin(), 2), SkRect::MakeLTRB(125, 150, 175, 175));
150}
151
152TEST(RTree, searchNonOverlappingDrawnRectsJoinRectsWhenIntersectedCase2) {
153 auto rtree_factory = RTreeFactory();
154 auto recorder = std::make_unique<SkPictureRecorder>();
155 auto recording_canvas =
156 recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
157
158 auto rect_paint = SkPaint();
159 rect_paint.setColor(SkColors::kCyan);
160 rect_paint.setStyle(SkPaint::Style::kFill_Style);
161
162 // Given the A, B, and C rects that intersect with the query rect,
163 // there should be only C in the result list,
164 // since A and B are contained in C.
165 //
166 // +---------------------+
167 // | C |
168 // | +-----+ +-----+ |
169 // | | A | | B | |
170 // | +-----+ +-----+ |
171 // +---------------------+
172 // +-----+
173 // | D |
174 // +-----+
175
176 // A
177 recording_canvas->drawRect(SkRect::MakeLTRB(100, 100, 200, 200), rect_paint);
178 // B
179 recording_canvas->drawRect(SkRect::MakeLTRB(300, 100, 400, 200), rect_paint);
180 // C
181 recording_canvas->drawRect(SkRect::MakeLTRB(50, 50, 500, 250), rect_paint);
182 // D
183 recording_canvas->drawRect(SkRect::MakeLTRB(280, 100, 280, 320), rect_paint);
184
185 recorder->finishRecordingAsPicture();
186
187 auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
188 SkRect::MakeLTRB(30, 30, 550, 270));
189 ASSERT_EQ(1UL, hits.size());
190 ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(50, 50, 500, 250));
191}
192
193TEST(RTree, searchNonOverlappingDrawnRectsJoinRectsWhenIntersectedCase3) {
194 auto rtree_factory = RTreeFactory();
195 auto recorder = std::make_unique<SkPictureRecorder>();
196 auto recording_canvas =
197 recorder->beginRecording(SkRect::MakeIWH(1000, 1000), &rtree_factory);
198
199 auto rect_paint = SkPaint();
200 rect_paint.setColor(SkColors::kCyan);
201 rect_paint.setStyle(SkPaint::Style::kFill_Style);
202
203 // Given the A, B, C and D rects that intersect with the query rect,
204 // the result list contains two rects - D and remainder of C
205 // these four rects.
206 //
207 // +------------------------------+
208 // | D |
209 // | +-----+ +-----+ +-----+ |
210 // | | A | | B | | C | |
211 // | +-----+ +-----+ | | |
212 // +----------------------| |-+
213 // +-----+
214 // +-----+
215 // | E |
216 // +-----+
217
218 // A
219 recording_canvas->drawRect(SkRect::MakeLTRB(100, 100, 200, 200), rect_paint);
220 // B
221 recording_canvas->drawRect(SkRect::MakeLTRB(300, 100, 400, 200), rect_paint);
222 // C
223 recording_canvas->drawRect(SkRect::MakeLTRB(500, 100, 600, 300), rect_paint);
224 // D
225 recording_canvas->drawRect(SkRect::MakeLTRB(50, 50, 620, 250), rect_paint);
226 // E
227 recording_canvas->drawRect(SkRect::MakeLTRB(280, 100, 280, 320), rect_paint);
228
229 recorder->finishRecordingAsPicture();
230
231 auto hits = rtree_factory.getInstance()->searchNonOverlappingDrawnRects(
232 SkRect::MakeLTRB(30, 30, 550, 270));
233 ASSERT_EQ(2UL, hits.size());
234 ASSERT_EQ(*hits.begin(), SkRect::MakeLTRB(50, 50, 620, 250));
235 ASSERT_EQ(*std::next(hits.begin(), 1), SkRect::MakeLTRB(500, 250, 600, 300));
236}
237
238} // namespace testing
239} // namespace flutter
static float next(float f)
constexpr SkColor4f kCyan
Definition: SkColor.h:444
TEST(DisplayListComplexity, EmptyDisplayList)
static SkRect MakeIWH(int w, int h)
Definition: SkRect.h:623
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646