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

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

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

Powered by Google App Engine
This is Rietveld 408576698