Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: components/viz/service/hit_test/hit_test_aggregator_unittest.cc

Issue 2938953002: Implement HitTestAggregator (Closed)
Patch Set: correct mojom include directory and improvements based on reviewer comments Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium 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 "components/viz/service/hit_test/hit_test_aggregator.h"
6
7 #include "components/viz/common/surfaces/frame_sink_id.h"
8 #include "components/viz/common/surfaces/local_surface_id.h"
9 #include "components/viz/common/surfaces/surface_id.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace viz {
13
14 namespace {
15
16 constexpr FrameSinkId kDisplayFrameSink(2, 0);
17
18 SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id, uint32_t local_id) {
19 return SurfaceId(
20 frame_sink_id,
21 LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u)));
22 }
23
24 } // namespace
25
26 class TestHitTestAggregator : public HitTestAggregator {
27 public:
28 TestHitTestAggregator() = default;
29 ~TestHitTestAggregator() = default;
30
31 void CallOnSurfaceWillDraw(SurfaceId surface_id) {
32 OnSurfaceWillDraw(surface_id);
33 }
34 void CallOnSurfaceDiscarded(SurfaceId surface_id) {
35 OnSurfaceDiscarded(surface_id);
36 }
37
38 int Count() {
39 AggregatedHitTestRegion* start =
40 static_cast<AggregatedHitTestRegion*>(read_buffer_.get());
41 AggregatedHitTestRegion* end = start;
42 while (end->child_count != kEndOfList)
43 end++;
44
45 int count = end - start;
46 return count;
47 }
48 int GetPendingCount() { return pending_.size(); }
49 int GetActiveCount() { return active_.size(); }
50 int GetActiveRegionCount() { return active_region_count_; }
51 int GetHitTestRegionListSize() { return read_size_; }
52 AggregatedHitTestRegion* GetRegions() {
53 return static_cast<AggregatedHitTestRegion*>(read_buffer_.get());
54 }
55
56 void Reset() {
57 AggregatedHitTestRegion* regions =
58 static_cast<AggregatedHitTestRegion*>(write_buffer_.get());
59 regions[0].child_count = kEndOfList;
60
61 regions = static_cast<AggregatedHitTestRegion*>(read_buffer_.get());
62 regions[0].child_count = kEndOfList;
63
64 pending_.clear();
65 active_.clear();
66 }
67 };
68
69 class HitTestAggregatorTest : public testing::Test {
70 public:
71 HitTestAggregatorTest() = default;
72 ~HitTestAggregatorTest() override = default;
73
74 // testing::Test:
75 void SetUp() override {}
76 void TearDown() override { aggregator_.Reset(); }
77
78 TestHitTestAggregator aggregator_;
79
80 // Creates a hit test data element with 8 children recursively to
81 // the specified depth. SurfaceIds are generated in sequential order and
82 // the method returns the next unused id.
83 int CreateAndSubmitHitTestRegionListWith8Children(int id, int depth) {
84 SurfaceId surface_id = MakeSurfaceId(kDisplayFrameSink, id);
85 id++;
86
87 auto hit_test_region_list = mojom::HitTestRegionList::New();
88 hit_test_region_list->surface_id = surface_id;
89 hit_test_region_list->flags = mojom::kHitTestMine;
90 hit_test_region_list->bounds.SetRect(0, 0, 1024, 768);
91
92 for (int i = 0; i < 8; i++) {
93 auto hit_test_region = mojom::HitTestRegion::New();
94 hit_test_region->rect.SetRect(100, 100, 100, 100);
95
96 if (depth > 0) {
97 hit_test_region->flags = mojom::kHitTestChildSurface;
98 hit_test_region->surface_id = MakeSurfaceId(kDisplayFrameSink, id);
99 id = CreateAndSubmitHitTestRegionListWith8Children(id, depth - 1);
100 } else {
101 hit_test_region->flags = mojom::kHitTestMine;
102 }
103 hit_test_region_list->regions.push_back(std::move(hit_test_region));
104 }
105
106 aggregator_.SubmitHitTestRegionList(std::move(hit_test_region_list));
107 return id;
108 }
109 };
110
111 // TODO(gklassen): Add tests for 3D use cases as suggested by and with
112 // input from rjkroege.
113
114 // One surface.
115 //
116 // +----------+
117 // | |
118 // | |
119 // | |
120 // +----------+
121 //
122 TEST_F(HitTestAggregatorTest, OneSurface) {
123 EXPECT_EQ(0, aggregator_.Count());
124
125 SurfaceId display_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
126
127 auto hit_test_region_list = mojom::HitTestRegionList::New();
128 hit_test_region_list->surface_id = display_surface_id;
129 hit_test_region_list->flags = mojom::kHitTestMine;
130 hit_test_region_list->bounds.SetRect(0, 0, 1024, 768);
131
132 aggregator_.SubmitHitTestRegionList(std::move(hit_test_region_list));
133 EXPECT_EQ(0, aggregator_.Count());
134
135 EXPECT_EQ(1, aggregator_.GetPendingCount());
136 EXPECT_EQ(0, aggregator_.GetActiveCount());
137
138 aggregator_.CallOnSurfaceWillDraw(display_surface_id);
139
140 EXPECT_EQ(0, aggregator_.GetPendingCount());
141 EXPECT_EQ(1, aggregator_.GetActiveCount());
142
143 aggregator_.Aggregate(display_surface_id);
144 aggregator_.Swap();
145
146 // Expect 1 entry routing all events to the one surface (display root).
147 EXPECT_EQ(1, aggregator_.Count());
148
149 AggregatedHitTestRegion* regions = aggregator_.GetRegions();
150
151 AggregatedHitTestRegion* region = nullptr;
152
153 region = &regions[0];
154 EXPECT_EQ(mojom::kHitTestMine, region->flags);
155 EXPECT_EQ(display_surface_id.frame_sink_id(), region->frame_sink_id);
156 EXPECT_EQ(gfx::Rect(0, 0, 1024, 768), region->rect);
157 EXPECT_EQ(0, region->child_count);
158 }
159
160 // One opaque embedder with two regions.
161 //
162 // +e-------------+
163 // | +r1-+ +r2--+ |
164 // | | | | | |
165 // | | | | | |
166 // | +---+ +----+ |
167 // +--------------+
168 //
169 TEST_F(HitTestAggregatorTest, OneEmbedderTwoRegions) {
170 EXPECT_EQ(0, aggregator_.Count());
171
172 SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
173
174 auto e_hit_test_data = mojom::HitTestRegionList::New();
175 e_hit_test_data->surface_id = e_surface_id;
176 e_hit_test_data->flags = mojom::kHitTestMine;
177 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768);
178
179 auto e_hit_test_region_r1 = mojom::HitTestRegion::New();
180 e_hit_test_region_r1->flags = mojom::kHitTestMine;
181 e_hit_test_region_r1->rect.SetRect(100, 100, 200, 400);
182
183 auto e_hit_test_region_r2 = mojom::HitTestRegion::New();
184 e_hit_test_region_r2->flags = mojom::kHitTestMine;
185 e_hit_test_region_r2->rect.SetRect(400, 100, 300, 400);
186
187 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_r1));
188 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_r2));
189
190 // Submit mojom::HitTestRegionList.
191
192 EXPECT_EQ(0, aggregator_.GetPendingCount());
193
194 aggregator_.SubmitHitTestRegionList(std::move(e_hit_test_data));
195 EXPECT_EQ(1, aggregator_.GetPendingCount());
196
197 // Add Surfaces to DisplayFrame in unexpected order.
198
199 EXPECT_EQ(0, aggregator_.Count());
200 EXPECT_EQ(0, aggregator_.GetActiveCount());
201
202 aggregator_.CallOnSurfaceWillDraw(e_surface_id);
203 EXPECT_EQ(1, aggregator_.GetActiveCount());
204
205 // Aggregate and swap.
206
207 aggregator_.Aggregate(e_surface_id);
208 EXPECT_EQ(0, aggregator_.Count());
209
210 aggregator_.Swap();
211 EXPECT_EQ(3, aggregator_.Count());
212
213 AggregatedHitTestRegion* regions = aggregator_.GetRegions();
214
215 AggregatedHitTestRegion* region = nullptr;
216
217 region = &regions[0];
218 EXPECT_EQ(mojom::kHitTestMine, region->flags);
219 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
220 EXPECT_EQ(gfx::Rect(0, 0, 1024, 768), region->rect);
221 EXPECT_EQ(2, region->child_count);
222
223 region = &regions[1];
224 EXPECT_EQ(mojom::kHitTestMine, region->flags);
225 EXPECT_EQ(gfx::Rect(100, 100, 200, 400), region->rect);
226 EXPECT_EQ(0, region->child_count);
227
228 region = &regions[2];
229 EXPECT_EQ(mojom::kHitTestMine, region->flags);
230 EXPECT_EQ(gfx::Rect(400, 100, 300, 400), region->rect);
231 EXPECT_EQ(0, region->child_count);
232 }
233
234 // One embedder with two children.
235 //
236 // +e-------------+
237 // | +c1-+ +c2--+ |
238 // | | | | | |
239 // | | | | | |
240 // | +---+ +----+ |
241 // +--------------+
242 //
243
244 TEST_F(HitTestAggregatorTest, OneEmbedderTwoChildren) {
245 EXPECT_EQ(0, aggregator_.Count());
246
247 SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
248 SurfaceId c1_surface_id = MakeSurfaceId(kDisplayFrameSink, 2);
249 SurfaceId c2_surface_id = MakeSurfaceId(kDisplayFrameSink, 3);
250
251 auto e_hit_test_data = mojom::HitTestRegionList::New();
252 e_hit_test_data->surface_id = e_surface_id;
253 e_hit_test_data->flags = mojom::kHitTestMine;
254 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768);
255
256 auto e_hit_test_region_c1 = mojom::HitTestRegion::New();
257 e_hit_test_region_c1->flags = mojom::kHitTestChildSurface;
258 e_hit_test_region_c1->surface_id = c1_surface_id;
259 e_hit_test_region_c1->rect.SetRect(100, 100, 200, 300);
260
261 auto e_hit_test_region_c2 = mojom::HitTestRegion::New();
262 e_hit_test_region_c2->flags = mojom::kHitTestChildSurface;
263 e_hit_test_region_c2->surface_id = c2_surface_id;
264 e_hit_test_region_c2->rect.SetRect(400, 100, 400, 300);
265
266 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c1));
267 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c2));
268
269 auto c1_hit_test_data = mojom::HitTestRegionList::New();
270 c1_hit_test_data->surface_id = c1_surface_id;
271
272 auto c2_hit_test_data = mojom::HitTestRegionList::New();
273 c2_hit_test_data->surface_id = c2_surface_id;
274
275 // Submit in unexpected order.
276
277 EXPECT_EQ(0, aggregator_.GetPendingCount());
278
279 aggregator_.SubmitHitTestRegionList(std::move(c1_hit_test_data));
280 EXPECT_EQ(1, aggregator_.GetPendingCount());
281
282 aggregator_.SubmitHitTestRegionList(std::move(e_hit_test_data));
283 EXPECT_EQ(2, aggregator_.GetPendingCount());
284
285 aggregator_.SubmitHitTestRegionList(std::move(c2_hit_test_data));
286 EXPECT_EQ(3, aggregator_.GetPendingCount());
287
288 // Surfaces added to DisplayFrame in unexpected order.
289
290 EXPECT_EQ(0, aggregator_.Count());
291
292 EXPECT_EQ(0, aggregator_.GetActiveCount());
293
294 aggregator_.CallOnSurfaceWillDraw(c2_surface_id);
295 EXPECT_EQ(1, aggregator_.GetActiveCount());
296
297 aggregator_.CallOnSurfaceWillDraw(c1_surface_id);
298 EXPECT_EQ(2, aggregator_.GetActiveCount());
299
300 aggregator_.CallOnSurfaceWillDraw(e_surface_id);
301 EXPECT_EQ(3, aggregator_.GetActiveCount());
302
303 // Aggregate and swap.
304
305 aggregator_.Aggregate(e_surface_id);
306 EXPECT_EQ(0, aggregator_.Count());
307
308 aggregator_.Swap();
309
310 EXPECT_EQ(3, aggregator_.Count());
311
312 AggregatedHitTestRegion* regions = aggregator_.GetRegions();
313
314 AggregatedHitTestRegion* region = nullptr;
315
316 region = &regions[0];
317 EXPECT_EQ(mojom::kHitTestMine, region->flags);
318 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
319 EXPECT_EQ(gfx::Rect(0, 0, 1024, 768), region->rect);
320 EXPECT_EQ(2, region->child_count);
321
322 region = &regions[1];
323 EXPECT_EQ(mojom::kHitTestChildSurface, region->flags);
324 EXPECT_EQ(c1_surface_id.frame_sink_id(), region->frame_sink_id);
325 EXPECT_EQ(gfx::Rect(100, 100, 200, 300), region->rect);
326 EXPECT_EQ(0, region->child_count);
327
328 region = &regions[2];
329 EXPECT_EQ(mojom::kHitTestChildSurface, region->flags);
330 EXPECT_EQ(c2_surface_id.frame_sink_id(), region->frame_sink_id);
331 EXPECT_EQ(gfx::Rect(400, 100, 400, 300), region->rect);
332 EXPECT_EQ(0, region->child_count);
333 }
334
335 // Occluded child frame (OOPIF).
336 //
337 // +e-----------+
338 // | +c--+ |
339 // | | +div-+ |
340 // | | | | |
341 // | | +----+ |
342 // | +---+ |
343 // +------------+
344 //
345
346 TEST_F(HitTestAggregatorTest, OccludedChildFrame) {
347 EXPECT_EQ(0, aggregator_.Count());
348
349 SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
350 SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2);
351
352 auto e_hit_test_data = mojom::HitTestRegionList::New();
353 e_hit_test_data->surface_id = e_surface_id;
354 e_hit_test_data->flags = mojom::kHitTestMine;
355 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768);
356
357 auto e_hit_test_region_div = mojom::HitTestRegion::New();
358 e_hit_test_region_div->flags = mojom::kHitTestMine;
359 e_hit_test_region_div->surface_id = e_surface_id;
360 e_hit_test_region_div->rect.SetRect(200, 200, 300, 200);
361
362 auto e_hit_test_region_c = mojom::HitTestRegion::New();
363 e_hit_test_region_c->flags = mojom::kHitTestChildSurface;
364 e_hit_test_region_c->surface_id = c_surface_id;
365 e_hit_test_region_c->rect.SetRect(100, 100, 200, 500);
366
367 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_div));
368 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c));
369
370 auto c_hit_test_data = mojom::HitTestRegionList::New();
371 c_hit_test_data->surface_id = c_surface_id;
372 c_hit_test_data->flags = mojom::kHitTestMine;
373 c_hit_test_data->bounds.SetRect(0, 0, 200, 500);
374
375 // Submit in unexpected order.
376
377 EXPECT_EQ(0, aggregator_.GetPendingCount());
378
379 aggregator_.SubmitHitTestRegionList(std::move(c_hit_test_data));
380 EXPECT_EQ(1, aggregator_.GetPendingCount());
381
382 aggregator_.SubmitHitTestRegionList(std::move(e_hit_test_data));
383 EXPECT_EQ(2, aggregator_.GetPendingCount());
384
385 // Surfaces added to DisplayFrame in unexpected order.
386
387 EXPECT_EQ(0, aggregator_.Count());
388
389 EXPECT_EQ(0, aggregator_.GetActiveCount());
390
391 aggregator_.CallOnSurfaceWillDraw(e_surface_id);
392 EXPECT_EQ(1, aggregator_.GetActiveCount());
393
394 aggregator_.CallOnSurfaceWillDraw(c_surface_id);
395 EXPECT_EQ(2, aggregator_.GetActiveCount());
396
397 // Aggregate and swap.
398
399 aggregator_.Aggregate(e_surface_id);
400 EXPECT_EQ(0, aggregator_.Count());
401
402 aggregator_.Swap();
403
404 EXPECT_EQ(3, aggregator_.Count());
405
406 AggregatedHitTestRegion* regions = aggregator_.GetRegions();
407
408 AggregatedHitTestRegion* region = nullptr;
409
410 region = &regions[0];
411 EXPECT_EQ(mojom::kHitTestMine, region->flags);
412 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
413 EXPECT_EQ(gfx::Rect(0, 0, 1024, 768), region->rect);
414 EXPECT_EQ(2, region->child_count);
415
416 region = &regions[1];
417 EXPECT_EQ(mojom::kHitTestMine, region->flags);
418 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
419 EXPECT_EQ(gfx::Rect(200, 200, 300, 200), region->rect);
420 EXPECT_EQ(0, region->child_count);
421
422 region = &regions[2];
423 EXPECT_EQ(region->flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
424 EXPECT_EQ(c_surface_id.frame_sink_id(), region->frame_sink_id);
425 EXPECT_EQ(gfx::Rect(100, 100, 200, 500), region->rect);
426 EXPECT_EQ(0, region->child_count);
427 }
428
429 // Foreground child frame (OOPIF).
430 // Same as the previous test except the child is foreground.
431 //
432 // +e-----------+
433 // | +c--+ |
434 // | | |div-+ |
435 // | | | | |
436 // | | |----+ |
437 // | +---+ |
438 // +------------+
439 //
440
441 TEST_F(HitTestAggregatorTest, ForegroundChildFrame) {
442 EXPECT_EQ(0, aggregator_.Count());
443
444 SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
445 SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2);
446
447 auto e_hit_test_data = mojom::HitTestRegionList::New();
448 e_hit_test_data->surface_id = e_surface_id;
449 e_hit_test_data->flags = mojom::kHitTestMine;
450 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768);
451
452 auto e_hit_test_region_div = mojom::HitTestRegion::New();
453 e_hit_test_region_div->flags = mojom::kHitTestMine;
454 e_hit_test_region_div->surface_id = e_surface_id;
455 e_hit_test_region_div->rect.SetRect(200, 200, 300, 200);
456
457 auto e_hit_test_region_c = mojom::HitTestRegion::New();
458 e_hit_test_region_c->flags = mojom::kHitTestChildSurface;
459 e_hit_test_region_c->surface_id = c_surface_id;
460 e_hit_test_region_c->rect.SetRect(100, 100, 200, 500);
461
462 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c));
463 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_div));
464
465 auto c_hit_test_data = mojom::HitTestRegionList::New();
466 c_hit_test_data->surface_id = c_surface_id;
467 c_hit_test_data->flags = mojom::kHitTestMine;
468 c_hit_test_data->bounds.SetRect(0, 0, 200, 500);
469
470 // Submit in unexpected order.
471
472 EXPECT_EQ(0, aggregator_.GetPendingCount());
473
474 aggregator_.SubmitHitTestRegionList(std::move(c_hit_test_data));
475 EXPECT_EQ(1, aggregator_.GetPendingCount());
476
477 aggregator_.SubmitHitTestRegionList(std::move(e_hit_test_data));
478 EXPECT_EQ(2, aggregator_.GetPendingCount());
479
480 // Surfaces added to DisplayFrame in unexpected order.
481
482 EXPECT_EQ(0, aggregator_.Count());
483
484 EXPECT_EQ(0, aggregator_.GetActiveCount());
485
486 aggregator_.CallOnSurfaceWillDraw(e_surface_id);
487 EXPECT_EQ(1, aggregator_.GetActiveCount());
488
489 aggregator_.CallOnSurfaceWillDraw(c_surface_id);
490 EXPECT_EQ(2, aggregator_.GetActiveCount());
491
492 // Aggregate and swap.
493
494 aggregator_.Aggregate(e_surface_id);
495 EXPECT_EQ(0, aggregator_.Count());
496
497 aggregator_.Swap();
498
499 EXPECT_EQ(3, aggregator_.Count());
500
501 AggregatedHitTestRegion* regions = aggregator_.GetRegions();
502
503 AggregatedHitTestRegion* region = nullptr;
504
505 region = &regions[0];
506 EXPECT_EQ(mojom::kHitTestMine, region->flags);
507 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
508 EXPECT_EQ(gfx::Rect(0, 0, 1024, 768), region->rect);
509 EXPECT_EQ(2, region->child_count);
510
511 region = &regions[1];
512 EXPECT_EQ(region->flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
513 EXPECT_EQ(c_surface_id.frame_sink_id(), region->frame_sink_id);
514 EXPECT_EQ(gfx::Rect(100, 100, 200, 500), region->rect);
515 EXPECT_EQ(0, region->child_count);
516
517 region = &regions[2];
518 EXPECT_EQ(mojom::kHitTestMine, region->flags);
519 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
520 EXPECT_EQ(gfx::Rect(200, 200, 300, 200), region->rect);
521 EXPECT_EQ(0, region->child_count);
522 }
523
524 // One embedder with a clipped child with a tab and transparent background.
525 //
526 // +e-------------+
527 // | +c---------| Point maps to
528 // | 1 |+a--+ | ----- -------
529 // | || 2 | 3 | 1 e
530 // | |+b--------| 2 a
531 // | || | 3 e (transparent area in c)
532 // | || 4 | 4 b
533 // +--------------+
534 //
535
536 TEST_F(HitTestAggregatorTest, ClippedChildWithTabAndTransparentBackground) {
537 EXPECT_EQ(0, aggregator_.Count());
538
539 SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
540 SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2);
541 SurfaceId a_surface_id = MakeSurfaceId(kDisplayFrameSink, 3);
542 SurfaceId b_surface_id = MakeSurfaceId(kDisplayFrameSink, 4);
543
544 auto e_hit_test_data = mojom::HitTestRegionList::New();
545 e_hit_test_data->surface_id = e_surface_id;
546 e_hit_test_data->flags = mojom::kHitTestMine;
547 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768);
548
549 auto e_hit_test_region_c = mojom::HitTestRegion::New();
550 e_hit_test_region_c->flags = mojom::kHitTestChildSurface;
551 e_hit_test_region_c->surface_id = c_surface_id;
552 e_hit_test_region_c->rect.SetRect(200, 100, 1600, 800);
553 e_hit_test_region_c->transform.Translate(200, 100);
554
555 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c));
556
557 auto c_hit_test_data = mojom::HitTestRegionList::New();
558 c_hit_test_data->surface_id = c_surface_id;
559 c_hit_test_data->flags = mojom::kHitTestIgnore;
560 c_hit_test_data->bounds.SetRect(0, 0, 1600, 800);
561
562 auto c_hit_test_region_a = mojom::HitTestRegion::New();
563 c_hit_test_region_a->flags = mojom::kHitTestChildSurface;
564 c_hit_test_region_a->surface_id = a_surface_id;
565 c_hit_test_region_a->rect.SetRect(0, 0, 200, 100);
566
567 auto c_hit_test_region_b = mojom::HitTestRegion::New();
568 c_hit_test_region_b->flags = mojom::kHitTestChildSurface;
569 c_hit_test_region_b->surface_id = b_surface_id;
570 c_hit_test_region_b->rect.SetRect(0, 100, 800, 600);
571
572 c_hit_test_data->regions.push_back(std::move(c_hit_test_region_a));
573 c_hit_test_data->regions.push_back(std::move(c_hit_test_region_b));
574
575 auto a_hit_test_data = mojom::HitTestRegionList::New();
576 a_hit_test_data->surface_id = a_surface_id;
577 a_hit_test_data->flags = mojom::kHitTestMine;
578 a_hit_test_data->bounds.SetRect(0, 0, 200, 100);
579
580 auto b_hit_test_data = mojom::HitTestRegionList::New();
581 b_hit_test_data->surface_id = b_surface_id;
582 b_hit_test_data->flags = mojom::kHitTestMine;
583 b_hit_test_data->bounds.SetRect(0, 100, 800, 600);
584
585 // Submit in unexpected order.
586
587 EXPECT_EQ(0, aggregator_.GetPendingCount());
588
589 aggregator_.SubmitHitTestRegionList(std::move(c_hit_test_data));
590 EXPECT_EQ(1, aggregator_.GetPendingCount());
591
592 aggregator_.SubmitHitTestRegionList(std::move(a_hit_test_data));
593 EXPECT_EQ(2, aggregator_.GetPendingCount());
594
595 aggregator_.SubmitHitTestRegionList(std::move(b_hit_test_data));
596 EXPECT_EQ(3, aggregator_.GetPendingCount());
597
598 aggregator_.SubmitHitTestRegionList(std::move(e_hit_test_data));
599 EXPECT_EQ(4, aggregator_.GetPendingCount());
600
601 // Surfaces added to DisplayFrame in unexpected order.
602
603 EXPECT_EQ(0, aggregator_.Count());
604
605 EXPECT_EQ(0, aggregator_.GetActiveCount());
606
607 aggregator_.CallOnSurfaceWillDraw(c_surface_id);
608 EXPECT_EQ(1, aggregator_.GetActiveCount());
609
610 aggregator_.CallOnSurfaceWillDraw(e_surface_id);
611 EXPECT_EQ(2, aggregator_.GetActiveCount());
612
613 aggregator_.CallOnSurfaceWillDraw(b_surface_id);
614 EXPECT_EQ(3, aggregator_.GetActiveCount());
615
616 aggregator_.CallOnSurfaceWillDraw(a_surface_id);
617 EXPECT_EQ(4, aggregator_.GetActiveCount());
618
619 // Aggregate and swap.
620
621 aggregator_.Aggregate(e_surface_id);
622 EXPECT_EQ(0, aggregator_.Count());
623
624 aggregator_.Swap();
625
626 EXPECT_EQ(4, aggregator_.Count());
627
628 AggregatedHitTestRegion* regions = aggregator_.GetRegions();
629
630 AggregatedHitTestRegion* region = nullptr;
631
632 region = &regions[0];
633 EXPECT_EQ(mojom::kHitTestMine, region->flags);
634 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
635 EXPECT_EQ(gfx::Rect(0, 0, 1024, 768), region->rect);
636 EXPECT_EQ(3, region->child_count);
637
638 region = &regions[1];
639 EXPECT_EQ(region->flags, mojom::kHitTestChildSurface | mojom::kHitTestIgnore);
640 EXPECT_EQ(c_surface_id.frame_sink_id(), region->frame_sink_id);
641 EXPECT_EQ(gfx::Rect(200, 100, 1600, 800), region->rect);
642 EXPECT_EQ(2, region->child_count);
643
644 gfx::Point point(300, 300);
645 region->transform.TransformPointReverse(&point);
646 EXPECT_TRUE(point == gfx::Point(100, 200));
647
648 region = &regions[2];
649 EXPECT_EQ(region->flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
650 EXPECT_EQ(a_surface_id.frame_sink_id(), region->frame_sink_id);
651 EXPECT_EQ(gfx::Rect(0, 0, 200, 100), region->rect);
652 EXPECT_EQ(0, region->child_count);
653
654 region = &regions[3];
655 EXPECT_EQ(region->flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
656 EXPECT_EQ(b_surface_id.frame_sink_id(), region->frame_sink_id);
657 EXPECT_EQ(gfx::Rect(0, 100, 800, 600), region->rect);
658 EXPECT_EQ(0, region->child_count);
659 }
660
661 // Three children deep.
662 //
663 // +e------------+
664 // | +c1-------+ |
665 // | | +c2---+ | |
666 // | | | +c3-| | |
667 // | | | | | | |
668 // | | | +---| | |
669 // | | +-----+ | |
670 // | +---------+ |
671 // +-------------+
672 //
673
674 TEST_F(HitTestAggregatorTest, ThreeChildrenDeep) {
675 EXPECT_EQ(0, aggregator_.Count());
676
677 SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
678 SurfaceId c1_surface_id = MakeSurfaceId(kDisplayFrameSink, 2);
679 SurfaceId c2_surface_id = MakeSurfaceId(kDisplayFrameSink, 3);
680 SurfaceId c3_surface_id = MakeSurfaceId(kDisplayFrameSink, 4);
681
682 auto e_hit_test_data = mojom::HitTestRegionList::New();
683 e_hit_test_data->surface_id = e_surface_id;
684 e_hit_test_data->flags = mojom::kHitTestMine;
685 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768);
686
687 auto e_hit_test_region_c1 = mojom::HitTestRegion::New();
688 e_hit_test_region_c1->flags = mojom::kHitTestChildSurface;
689 e_hit_test_region_c1->surface_id = c1_surface_id;
690 e_hit_test_region_c1->rect.SetRect(100, 100, 700, 700);
691
692 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c1));
693
694 auto c1_hit_test_data = mojom::HitTestRegionList::New();
695 c1_hit_test_data->surface_id = c1_surface_id;
696 c1_hit_test_data->flags = mojom::kHitTestMine;
697 c1_hit_test_data->bounds.SetRect(0, 0, 600, 600);
698
699 auto c1_hit_test_region_c2 = mojom::HitTestRegion::New();
700 c1_hit_test_region_c2->flags = mojom::kHitTestChildSurface;
701 c1_hit_test_region_c2->surface_id = c2_surface_id;
702 c1_hit_test_region_c2->rect.SetRect(100, 100, 500, 500);
703
704 c1_hit_test_data->regions.push_back(std::move(c1_hit_test_region_c2));
705
706 auto c2_hit_test_data = mojom::HitTestRegionList::New();
707 c2_hit_test_data->surface_id = c2_surface_id;
708 c2_hit_test_data->flags = mojom::kHitTestMine;
709 c2_hit_test_data->bounds.SetRect(0, 0, 400, 400);
710
711 auto c2_hit_test_region_c3 = mojom::HitTestRegion::New();
712 c2_hit_test_region_c3->flags = mojom::kHitTestChildSurface;
713 c2_hit_test_region_c3->surface_id = c3_surface_id;
714 c2_hit_test_region_c3->rect.SetRect(100, 100, 300, 300);
715
716 c2_hit_test_data->regions.push_back(std::move(c2_hit_test_region_c3));
717
718 auto c3_hit_test_data = mojom::HitTestRegionList::New();
719 c3_hit_test_data->surface_id = c3_surface_id;
720 c3_hit_test_data->flags = mojom::kHitTestMine;
721 c3_hit_test_data->bounds.SetRect(0, 0, 200, 200);
722
723 // Submit in unexpected order.
724
725 EXPECT_EQ(0, aggregator_.GetPendingCount());
726
727 aggregator_.SubmitHitTestRegionList(std::move(c1_hit_test_data));
728 EXPECT_EQ(1, aggregator_.GetPendingCount());
729
730 aggregator_.SubmitHitTestRegionList(std::move(c3_hit_test_data));
731 EXPECT_EQ(2, aggregator_.GetPendingCount());
732
733 aggregator_.SubmitHitTestRegionList(std::move(e_hit_test_data));
734 EXPECT_EQ(3, aggregator_.GetPendingCount());
735
736 aggregator_.SubmitHitTestRegionList(std::move(c2_hit_test_data));
737 EXPECT_EQ(4, aggregator_.GetPendingCount());
738
739 // Surfaces added to DisplayFrame in unexpected order.
740
741 EXPECT_EQ(0, aggregator_.Count());
742
743 EXPECT_EQ(0, aggregator_.GetActiveCount());
744
745 aggregator_.CallOnSurfaceWillDraw(c2_surface_id);
746 EXPECT_EQ(1, aggregator_.GetActiveCount());
747
748 aggregator_.CallOnSurfaceWillDraw(c1_surface_id);
749 EXPECT_EQ(2, aggregator_.GetActiveCount());
750
751 aggregator_.CallOnSurfaceWillDraw(e_surface_id);
752 EXPECT_EQ(3, aggregator_.GetActiveCount());
753
754 aggregator_.CallOnSurfaceWillDraw(c3_surface_id);
755 EXPECT_EQ(4, aggregator_.GetActiveCount());
756
757 // Aggregate and swap.
758
759 aggregator_.Aggregate(e_surface_id);
760 EXPECT_EQ(0, aggregator_.Count());
761
762 aggregator_.Swap();
763
764 EXPECT_EQ(4, aggregator_.Count());
765
766 AggregatedHitTestRegion* regions = aggregator_.GetRegions();
767
768 AggregatedHitTestRegion* region = nullptr;
769
770 region = &regions[0];
771 EXPECT_EQ(mojom::kHitTestMine, region->flags);
772 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
773 EXPECT_EQ(gfx::Rect(0, 0, 1024, 768), region->rect);
774 EXPECT_EQ(3, region->child_count);
775
776 region = &regions[1];
777 EXPECT_EQ(region->flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
778 EXPECT_EQ(c1_surface_id.frame_sink_id(), region->frame_sink_id);
779 EXPECT_EQ(gfx::Rect(100, 100, 700, 700), region->rect);
780 EXPECT_EQ(2, region->child_count);
781
782 region = &regions[2];
783 EXPECT_EQ(region->flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
784 EXPECT_EQ(c2_surface_id.frame_sink_id(), region->frame_sink_id);
785 EXPECT_EQ(gfx::Rect(100, 100, 500, 500), region->rect);
786 EXPECT_EQ(1, region->child_count);
787
788 region = &regions[3];
789 EXPECT_EQ(region->flags, mojom::kHitTestChildSurface | mojom::kHitTestMine);
790 EXPECT_EQ(c3_surface_id.frame_sink_id(), region->frame_sink_id);
791 EXPECT_EQ(gfx::Rect(100, 100, 300, 300), region->rect);
792 EXPECT_EQ(0, region->child_count);
793 }
794
795 // Missing / late child.
796 //
797 // +e-----------+
798 // | +c--+ |
799 // | | |div-+ |
800 // | | | | |
801 // | | |----+ |
802 // | +---+ |
803 // +------------+
804 //
805
806 TEST_F(HitTestAggregatorTest, MissingChildFrame) {
807 EXPECT_EQ(0, aggregator_.Count());
808
809 SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
810 SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2);
811
812 auto e_hit_test_data = mojom::HitTestRegionList::New();
813 e_hit_test_data->surface_id = e_surface_id;
814 e_hit_test_data->flags = mojom::kHitTestMine;
815 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768);
816
817 auto e_hit_test_region_div = mojom::HitTestRegion::New();
818 e_hit_test_region_div->flags = mojom::kHitTestMine;
819 e_hit_test_region_div->surface_id = e_surface_id;
820 e_hit_test_region_div->rect.SetRect(200, 200, 300, 200);
821
822 auto e_hit_test_region_c = mojom::HitTestRegion::New();
823 e_hit_test_region_c->flags = mojom::kHitTestChildSurface;
824 e_hit_test_region_c->surface_id = c_surface_id;
825 e_hit_test_region_c->rect.SetRect(100, 100, 200, 500);
826
827 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c));
828 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_div));
829
830 auto c_hit_test_data = mojom::HitTestRegionList::New();
831 c_hit_test_data->surface_id = c_surface_id;
832 c_hit_test_data->flags = mojom::kHitTestMine;
833 c_hit_test_data->bounds.SetRect(0, 0, 200, 500);
834
835 // Submit in unexpected order, but not the child.
836
837 EXPECT_EQ(0, aggregator_.GetPendingCount());
838
839 aggregator_.SubmitHitTestRegionList(std::move(e_hit_test_data));
840 EXPECT_EQ(1, aggregator_.GetPendingCount());
841
842 // Surfaces added to DisplayFrame in unexpected order.
843
844 EXPECT_EQ(0, aggregator_.Count());
845
846 EXPECT_EQ(0, aggregator_.GetActiveCount());
847
848 aggregator_.CallOnSurfaceWillDraw(e_surface_id);
849 EXPECT_EQ(1, aggregator_.GetActiveCount());
850
851 // Aggregate and swap.
852
853 aggregator_.Aggregate(e_surface_id);
854 EXPECT_EQ(0, aggregator_.Count());
855
856 aggregator_.Swap();
857
858 EXPECT_EQ(2, aggregator_.Count());
859
860 AggregatedHitTestRegion* regions = aggregator_.GetRegions();
861
862 AggregatedHitTestRegion* region = nullptr;
863
864 region = &regions[0];
865 EXPECT_EQ(mojom::kHitTestMine, region->flags);
866 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
867 EXPECT_EQ(gfx::Rect(0, 0, 1024, 768), region->rect);
868 EXPECT_EQ(1, region->child_count);
869
870 // Child would exist here but it was not included in the Display Frame.
871
872 region = &regions[1];
873 EXPECT_EQ(mojom::kHitTestMine, region->flags);
874 EXPECT_EQ(e_surface_id.frame_sink_id(), region->frame_sink_id);
875 EXPECT_EQ(gfx::Rect(200, 200, 300, 200), region->rect);
876 EXPECT_EQ(0, region->child_count);
877 }
878
879 // Exceed limits to ensure that bounds and resize work.
880 //
881 // A tree of embedders each with 8 children and 4 levels deep = 4096 regions.
882 // This will exceed initial allocation and force a resize.
883 //
884 // +e--------------------------------------------------------+
885 // | +c1----------++c2----------++c3----------++c4----------+|
886 // | | +c1--------|| +c1--------|| +c1--------|| +c1--------||
887 // | | | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-||
888 // | | | | || || | | || || | | || || | | || ||
889 // | | | +---++---|| | +---++---|| | +---++---|| | +---++---||
890 // | +------------++------------++------------++------------+|
891 // | +c5----------++c6----------++c7----------++c8----------+|
892 // | | +c1--------|| +c1--------|| +c1--------|| +c1--------||
893 // | | | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-||
894 // | | | | || || | | || || | | || || | | || ||
895 // | | | +---++---|| | +---++---|| | +---++---|| | +---++---||
896 // | +------------++------------++------------++------------+|
897 // +---------------------------------------------------------+
898 //
899
900 TEST_F(HitTestAggregatorTest, ExceedLimits) {
901 EXPECT_EQ(0, aggregator_.Count());
902
903 EXPECT_LT(aggregator_.GetHitTestRegionListSize(), 4096);
904
905 SurfaceId display_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
906
907 int next_surface_id = CreateAndSubmitHitTestRegionListWith8Children(1, 3);
908 int surface_count = next_surface_id - 1;
909
910 EXPECT_EQ(surface_count, aggregator_.GetPendingCount());
911
912 // Mark Surfaces as added to DisplayFrame in unexpected order.
913
914 EXPECT_EQ(0, aggregator_.Count());
915 EXPECT_EQ(0, aggregator_.GetActiveCount());
916
917 for (int i = 1; i <= surface_count; i++) {
918 SurfaceId surface_id = MakeSurfaceId(kDisplayFrameSink, i);
919 aggregator_.CallOnSurfaceWillDraw(surface_id);
920 }
921
922 EXPECT_EQ(surface_count, aggregator_.GetActiveCount());
923
924 // Aggregate and swap.
925 aggregator_.Aggregate(display_surface_id);
926 EXPECT_EQ(0, aggregator_.Count());
927
928 aggregator_.Swap();
929
930 // Expect 4680 regions:
931 // 8 children 4 levels deep 8*8*8*8 is 4096
932 // 1 region for each embedder/surface + 584
933 // 1 root + 1
934 // -----
935 // 4681.
936 EXPECT_EQ(4681, aggregator_.Count());
937
938 EXPECT_GE(aggregator_.GetHitTestRegionListSize(), 4681);
939 }
940
941 TEST_F(HitTestAggregatorTest, ActiveRegionCount) {
942 EXPECT_EQ(0, aggregator_.GetActiveRegionCount());
943
944 SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
945 SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2);
946
947 auto e_hit_test_data = mojom::HitTestRegionList::New();
948 e_hit_test_data->surface_id = e_surface_id;
949 e_hit_test_data->flags = mojom::kHitTestMine;
950 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768);
951
952 auto e_hit_test_region_div = mojom::HitTestRegion::New();
953 e_hit_test_region_div->flags = mojom::kHitTestMine;
954 e_hit_test_region_div->surface_id = e_surface_id;
955 e_hit_test_region_div->rect.SetRect(200, 200, 300, 200);
956
957 auto e_hit_test_region_c = mojom::HitTestRegion::New();
958 e_hit_test_region_c->flags = mojom::kHitTestChildSurface;
959 e_hit_test_region_c->surface_id = c_surface_id;
960 e_hit_test_region_c->rect.SetRect(100, 100, 200, 500);
961
962 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c));
963 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_div));
964
965 auto c_hit_test_data = mojom::HitTestRegionList::New();
966 c_hit_test_data->surface_id = c_surface_id;
967 c_hit_test_data->flags = mojom::kHitTestMine;
968 c_hit_test_data->bounds.SetRect(0, 0, 200, 500);
969
970 EXPECT_EQ(0, aggregator_.GetActiveRegionCount());
971
972 // Submit in unexpected order.
973
974 EXPECT_EQ(0, aggregator_.GetPendingCount());
975
976 aggregator_.SubmitHitTestRegionList(std::move(c_hit_test_data));
977 EXPECT_EQ(1, aggregator_.GetPendingCount());
978
979 aggregator_.SubmitHitTestRegionList(std::move(e_hit_test_data));
980 EXPECT_EQ(2, aggregator_.GetPendingCount());
981
982 EXPECT_EQ(0, aggregator_.GetActiveRegionCount());
983
984 // Surfaces added to DisplayFrame in unexpected order.
985
986 EXPECT_EQ(0, aggregator_.Count());
987 EXPECT_EQ(0, aggregator_.GetActiveCount());
988
989 aggregator_.CallOnSurfaceWillDraw(e_surface_id);
990 EXPECT_EQ(1, aggregator_.GetActiveCount());
991 EXPECT_EQ(2, aggregator_.GetActiveRegionCount());
992
993 aggregator_.CallOnSurfaceWillDraw(c_surface_id);
994 EXPECT_EQ(2, aggregator_.GetActiveCount());
995 EXPECT_EQ(2, aggregator_.GetActiveRegionCount());
996
997 // Aggregate and swap.
998
999 aggregator_.Aggregate(e_surface_id);
1000 EXPECT_EQ(0, aggregator_.Count());
1001 EXPECT_EQ(2, aggregator_.GetActiveRegionCount());
1002
1003 aggregator_.Swap();
1004
1005 EXPECT_EQ(3, aggregator_.Count());
1006 EXPECT_EQ(2, aggregator_.GetActiveRegionCount());
1007
1008 // Discard Surface and ensure active count goes down.
1009
1010 aggregator_.CallOnSurfaceDiscarded(c_surface_id);
1011 EXPECT_EQ(2, aggregator_.GetActiveRegionCount());
1012
1013 aggregator_.CallOnSurfaceDiscarded(e_surface_id);
1014 EXPECT_EQ(0, aggregator_.GetActiveRegionCount());
1015 }
1016
1017 } // namespace viz
OLDNEW
« no previous file with comments | « components/viz/service/hit_test/hit_test_aggregator.cc ('k') | services/viz/hit_test/public/interfaces/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698