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

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

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

Powered by Google App Engine
This is Rietveld 408576698