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

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

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

Powered by Google App Engine
This is Rietveld 408576698