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

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

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

Powered by Google App Engine
This is Rietveld 408576698