Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 "display_hit_test_data_factory_local.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 | |
| 12 namespace viz { | |
| 13 namespace hit_test { | |
| 14 namespace test { | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 constexpr cc::FrameSinkId kDisplayFrameSink(2, 0); | |
| 19 | |
| 20 cc::SurfaceId MakeSurfaceId(const cc::FrameSinkId& frame_sink_id, | |
| 21 uint32_t local_id) { | |
| 22 return cc::SurfaceId( | |
| 23 frame_sink_id, | |
| 24 cc::LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u))); | |
| 25 } | |
| 26 | |
| 27 } // namespace | |
| 28 | |
| 29 using namespace hit_test::mojom; | |
| 30 | |
| 31 class HitTestAggregatorTest : public testing::Test { | |
| 32 public: | |
| 33 HitTestAggregatorTest() | |
| 34 : aggregator_( | |
| 35 base::MakeUnique<hit_test::DisplayHitTestDataFactoryLocal>()) {} | |
| 36 ~HitTestAggregatorTest() override {} | |
| 37 | |
|
varkha
2017/06/20 19:56:59
nit: // testing::Test:
gklassen
2017/06/26 21:55:20
Done.
| |
| 38 void SetUp() override {} | |
| 39 | |
| 40 void TearDown() override { Reset(); } | |
| 41 | |
| 42 HitTestAggregator aggregator_; | |
| 43 | |
| 44 int count() { | |
| 45 DisplayHitTestRegion* start = aggregator_.GetCurrentRegions(); | |
| 46 DisplayHitTestRegion* end = start; | |
| 47 while (end->child_count != kEndOfList) { | |
| 48 end++; | |
| 49 } | |
| 50 int count = end - start; | |
| 51 return count; | |
| 52 } | |
| 53 | |
| 54 DisplayHitTestRegion* RegionAtIndex(int i) { | |
| 55 return aggregator_.GetCurrentRegions() + i; | |
| 56 } | |
| 57 | |
| 58 int GetPendingCount() { return aggregator_.pending_.size(); } | |
| 59 int GetActiveCount() { return aggregator_.active_.size(); } | |
| 60 | |
| 61 int GetPendingRegionCount() { return RegionCount(aggregator_.pending_); } | |
| 62 int GetActiveRegionCount() { return RegionCount(aggregator_.active_); } | |
| 63 | |
| 64 void CallOnSurfaceWillDraw(cc::SurfaceId surface_id) { | |
| 65 aggregator_.OnSurfaceWillDraw(surface_id); | |
| 66 } | |
| 67 | |
| 68 int RegionCount(const HitTestDataMap& map) { | |
| 69 int size = 0; | |
| 70 for (auto const& it : map) { | |
| 71 hit_test::mojom::HitTestData* hit_test_data = it.second.get(); | |
| 72 size += hit_test_data->regions.size(); | |
| 73 } | |
| 74 return size; | |
| 75 } | |
| 76 | |
| 77 void Reset() { | |
| 78 int size = aggregator_.display_hit_test_data_->length; | |
| 79 | |
| 80 aggregator_.display_hit_test_data_->regions[0].child_count = kEndOfList; | |
| 81 aggregator_.display_hit_test_data_->regions[size >> 1].child_count = | |
| 82 kEndOfList; | |
| 83 | |
| 84 aggregator_.pending_.clear(); | |
| 85 aggregator_.active_.clear(); | |
| 86 } | |
| 87 | |
| 88 int GetDisplayHitTestDataLength() { | |
| 89 return aggregator_.display_hit_test_data_->length; | |
| 90 } | |
| 91 | |
| 92 // Creates a hit test data element with 8 children recursively to | |
| 93 // the specified depth. SurfaceIds are generated in sequential order and | |
| 94 // the method returns the next unused id ( also matches the count ). | |
| 95 int CreateAndSubmitHitTestDataWith8Children(int id, int depth) { | |
| 96 cc::SurfaceId surface_id = MakeSurfaceId(kDisplayFrameSink, id); | |
| 97 id++; | |
| 98 | |
| 99 auto hit_test_data = HitTestData::New(); | |
| 100 hit_test_data->surface_id = surface_id; | |
| 101 hit_test_data->flags = kHitTestMine; | |
| 102 hit_test_data->bounds.SetRect(0, 0, 1024, 768); | |
| 103 | |
| 104 for (int i = 0; i < 8; i++) { | |
| 105 auto hit_test_region = HitTestRegion::New(); | |
| 106 hit_test_region->rect.SetRect(100, 100, 100, 100); | |
| 107 | |
| 108 if (depth > 0) { | |
| 109 hit_test_region->flags = kHitTestChildSurface; | |
| 110 hit_test_region->surface_id = MakeSurfaceId(kDisplayFrameSink, id); | |
| 111 id = CreateAndSubmitHitTestDataWith8Children(id, depth - 1); | |
| 112 } else { | |
| 113 hit_test_region->flags = kHitTestMine; | |
| 114 } | |
| 115 hit_test_data->regions.push_back(std::move(hit_test_region)); | |
| 116 } | |
| 117 | |
| 118 aggregator_.SubmitHitTestData(std::move(hit_test_data)); | |
| 119 return id; | |
| 120 } | |
| 121 }; | |
| 122 | |
| 123 // TODO(gklassen): Add tests for 3D use cases as suggested by and with | |
| 124 // input from rjkroege. | |
| 125 | |
| 126 // One surface. | |
| 127 // | |
| 128 // +----------+ | |
| 129 // | | | |
| 130 // | | | |
| 131 // | | | |
| 132 // +----------+ | |
| 133 // | |
| 134 TEST_F(HitTestAggregatorTest, OneSurface) { | |
| 135 EXPECT_EQ(count(), 0); | |
| 136 | |
| 137 cc::SurfaceId display_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | |
| 138 | |
| 139 auto hit_test_data = HitTestData::New(); | |
| 140 hit_test_data->surface_id = display_surface_id; | |
| 141 hit_test_data->flags = kHitTestMine; | |
| 142 hit_test_data->bounds.SetRect(0, 0, 1024, 768); | |
| 143 | |
| 144 aggregator_.SubmitHitTestData(std::move(hit_test_data)); | |
| 145 EXPECT_EQ(count(), 0); | |
| 146 | |
| 147 EXPECT_EQ(GetPendingCount(), 1); | |
| 148 EXPECT_EQ(GetActiveCount(), 0); | |
| 149 | |
| 150 CallOnSurfaceWillDraw(display_surface_id); | |
| 151 | |
| 152 EXPECT_EQ(GetPendingCount(), 0); | |
| 153 EXPECT_EQ(GetActiveCount(), 1); | |
| 154 | |
| 155 aggregator_.Aggregate(display_surface_id); | |
| 156 aggregator_.Swap(); | |
| 157 | |
| 158 // Expect 1 entry routing all events to the one surface ( display root ). | |
| 159 EXPECT_EQ(count(), 1); | |
| 160 | |
| 161 DisplayHitTestRegion* region; | |
| 162 | |
| 163 region = RegionAtIndex(0); | |
| 164 EXPECT_EQ(region->flags, kHitTestMine); | |
| 165 EXPECT_EQ(region->frame_sink_id, display_surface_id.frame_sink_id()); | |
| 166 EXPECT_EQ(region->rect, gfx::Rect(0, 0, 1024, 768)); | |
| 167 EXPECT_EQ(region->child_count, 0); | |
| 168 } | |
| 169 | |
| 170 // One opaque embedder with two regions. | |
| 171 // | |
| 172 // +e-------------+ | |
| 173 // | +r1-+ +r2--+ | | |
| 174 // | | | | | | | |
| 175 // | | | | | | | |
| 176 // | +---+ +----+ | | |
| 177 // +--------------+ | |
| 178 // | |
| 179 TEST_F(HitTestAggregatorTest, OneEmbedderTwoRegions) { | |
| 180 EXPECT_EQ(count(), 0); | |
| 181 | |
| 182 cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | |
| 183 | |
| 184 auto e_hit_test_data = HitTestData::New(); | |
| 185 e_hit_test_data->surface_id = e_surface_id; | |
| 186 e_hit_test_data->flags = kHitTestMine; | |
| 187 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768); | |
| 188 | |
| 189 auto e_hit_test_region_r1 = HitTestRegion::New(); | |
| 190 e_hit_test_region_r1->flags = kHitTestMine; | |
| 191 e_hit_test_region_r1->rect.SetRect(100, 100, 200, 400); | |
| 192 | |
| 193 auto e_hit_test_region_r2 = HitTestRegion::New(); | |
| 194 e_hit_test_region_r2->flags = kHitTestMine; | |
| 195 e_hit_test_region_r2->rect.SetRect(400, 100, 300, 400); | |
| 196 | |
| 197 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_r1)); | |
| 198 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_r2)); | |
| 199 | |
| 200 // Submit HitTestData. | |
| 201 | |
| 202 EXPECT_EQ(GetPendingCount(), 0); | |
| 203 | |
| 204 aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | |
| 205 EXPECT_EQ(GetPendingCount(), 1); | |
| 206 | |
| 207 // Add Surfaces to DisplayFrame ( in unexpected order ). | |
| 208 | |
| 209 EXPECT_EQ(count(), 0); | |
| 210 EXPECT_EQ(GetActiveCount(), 0); | |
| 211 | |
| 212 CallOnSurfaceWillDraw(e_surface_id); | |
| 213 EXPECT_EQ(GetActiveCount(), 1); | |
| 214 | |
| 215 // Aggregate and swap. | |
| 216 | |
| 217 aggregator_.Aggregate(e_surface_id); | |
| 218 EXPECT_EQ(count(), 0); | |
| 219 | |
| 220 aggregator_.Swap(); | |
| 221 EXPECT_EQ(count(), 3); | |
| 222 | |
| 223 DisplayHitTestRegion* region; | |
| 224 | |
| 225 region = RegionAtIndex(0); | |
| 226 EXPECT_EQ(region->flags, kHitTestMine); | |
| 227 EXPECT_EQ(region->frame_sink_id, e_surface_id.frame_sink_id()); | |
| 228 EXPECT_EQ(region->rect, gfx::Rect(0, 0, 1024, 768)); | |
| 229 EXPECT_EQ(region->child_count, 2); | |
| 230 | |
| 231 region = RegionAtIndex(1); | |
| 232 EXPECT_EQ(region->flags, kHitTestMine); | |
| 233 EXPECT_EQ(region->rect, gfx::Rect(100, 100, 200, 400)); | |
| 234 EXPECT_EQ(region->child_count, 0); | |
| 235 | |
| 236 region = RegionAtIndex(2); | |
| 237 EXPECT_EQ(region->flags, kHitTestMine); | |
| 238 EXPECT_EQ(region->rect, gfx::Rect(400, 100, 300, 400)); | |
| 239 EXPECT_EQ(region->child_count, 0); | |
| 240 } | |
| 241 | |
| 242 // One embedder with two children. | |
| 243 // | |
| 244 // +e-------------+ | |
| 245 // | +c1-+ +c2--+ | | |
| 246 // | | | | | | | |
| 247 // | | | | | | | |
| 248 // | +---+ +----+ | | |
| 249 // +--------------+ | |
| 250 // | |
| 251 | |
| 252 TEST_F(HitTestAggregatorTest, OneEmbedderTwoChildren) { | |
| 253 EXPECT_EQ(count(), 0); | |
| 254 | |
| 255 cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | |
| 256 cc::SurfaceId c1_surface_id = MakeSurfaceId(kDisplayFrameSink, 2); | |
| 257 cc::SurfaceId c2_surface_id = MakeSurfaceId(kDisplayFrameSink, 3); | |
| 258 | |
| 259 auto e_hit_test_data = HitTestData::New(); | |
| 260 e_hit_test_data->surface_id = e_surface_id; | |
| 261 e_hit_test_data->flags = kHitTestMine; | |
| 262 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768); | |
| 263 | |
| 264 auto e_hit_test_region_c1 = HitTestRegion::New(); | |
| 265 e_hit_test_region_c1->flags = kHitTestChildSurface; | |
| 266 e_hit_test_region_c1->surface_id = c1_surface_id; | |
| 267 e_hit_test_region_c1->rect.SetRect(100, 100, 200, 300); | |
| 268 | |
| 269 auto e_hit_test_region_c2 = HitTestRegion::New(); | |
| 270 e_hit_test_region_c2->flags = kHitTestChildSurface; | |
| 271 e_hit_test_region_c2->surface_id = c2_surface_id; | |
| 272 e_hit_test_region_c2->rect.SetRect(400, 100, 400, 300); | |
| 273 | |
| 274 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c1)); | |
| 275 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c2)); | |
| 276 | |
| 277 auto c1_hit_test_data = HitTestData::New(); | |
| 278 c1_hit_test_data->surface_id = c1_surface_id; | |
| 279 | |
| 280 auto c2_hit_test_data = HitTestData::New(); | |
| 281 c2_hit_test_data->surface_id = c2_surface_id; | |
| 282 | |
| 283 // Submit ( in unexpected order ). | |
| 284 | |
| 285 EXPECT_EQ(GetPendingCount(), 0); | |
| 286 | |
| 287 aggregator_.SubmitHitTestData(std::move(c1_hit_test_data)); | |
| 288 EXPECT_EQ(GetPendingCount(), 1); | |
| 289 | |
| 290 aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | |
| 291 EXPECT_EQ(GetPendingCount(), 2); | |
| 292 | |
| 293 aggregator_.SubmitHitTestData(std::move(c2_hit_test_data)); | |
| 294 EXPECT_EQ(GetPendingCount(), 3); | |
| 295 | |
| 296 // Surfaces added to DisplayFrame ( in unexpected order ). | |
| 297 | |
| 298 EXPECT_EQ(count(), 0); | |
| 299 | |
| 300 EXPECT_EQ(GetActiveCount(), 0); | |
| 301 | |
| 302 CallOnSurfaceWillDraw(c2_surface_id); | |
| 303 EXPECT_EQ(GetActiveCount(), 1); | |
| 304 | |
| 305 CallOnSurfaceWillDraw(c1_surface_id); | |
| 306 EXPECT_EQ(GetActiveCount(), 2); | |
| 307 | |
| 308 CallOnSurfaceWillDraw(e_surface_id); | |
| 309 EXPECT_EQ(GetActiveCount(), 3); | |
| 310 | |
| 311 // Aggregate and swap. | |
| 312 | |
| 313 aggregator_.Aggregate(e_surface_id); | |
| 314 EXPECT_EQ(count(), 0); | |
| 315 | |
| 316 aggregator_.Swap(); | |
| 317 | |
| 318 EXPECT_EQ(count(), 3); | |
| 319 | |
| 320 DisplayHitTestRegion* region; | |
| 321 | |
| 322 region = RegionAtIndex(0); | |
| 323 EXPECT_EQ(region->flags, kHitTestMine); | |
| 324 EXPECT_EQ(region->frame_sink_id, e_surface_id.frame_sink_id()); | |
| 325 EXPECT_EQ(region->rect, gfx::Rect(0, 0, 1024, 768)); | |
| 326 EXPECT_EQ(region->child_count, 2); | |
| 327 | |
| 328 region = RegionAtIndex(1); | |
| 329 EXPECT_EQ(region->flags, kHitTestChildSurface); | |
| 330 EXPECT_EQ(region->frame_sink_id, c1_surface_id.frame_sink_id()); | |
| 331 EXPECT_EQ(region->rect, gfx::Rect(100, 100, 200, 300)); | |
| 332 EXPECT_EQ(region->child_count, 0); | |
| 333 | |
| 334 region = RegionAtIndex(2); | |
| 335 EXPECT_EQ(region->flags, kHitTestChildSurface); | |
|
riajiang
2017/06/20 23:54:59
Was thinking to make sure that I understand this t
gklassen
2017/06/26 21:55:20
Yes.
| |
| 336 EXPECT_EQ(region->frame_sink_id, c2_surface_id.frame_sink_id()); | |
| 337 EXPECT_EQ(region->rect, gfx::Rect(400, 100, 400, 300)); | |
| 338 EXPECT_EQ(region->child_count, 0); | |
| 339 } | |
| 340 | |
| 341 // Occluded child frame ( OOPIF ). | |
| 342 // | |
| 343 // +e-----------+ | |
| 344 // | +c--+ | | |
| 345 // | | +div-+ | | |
| 346 // | | | | | | |
| 347 // | | +----+ | | |
| 348 // | +---+ | | |
| 349 // +------------+ | |
| 350 // | |
| 351 | |
| 352 TEST_F(HitTestAggregatorTest, OccludedChildFrame) { | |
| 353 EXPECT_EQ(count(), 0); | |
| 354 | |
| 355 cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | |
| 356 cc::SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2); | |
| 357 | |
| 358 auto e_hit_test_data = HitTestData::New(); | |
| 359 e_hit_test_data->surface_id = e_surface_id; | |
| 360 e_hit_test_data->flags = kHitTestMine; | |
| 361 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768); | |
| 362 | |
| 363 auto e_hit_test_region_div = HitTestRegion::New(); | |
| 364 e_hit_test_region_div->flags = kHitTestMine; | |
| 365 e_hit_test_region_div->surface_id = e_surface_id; | |
| 366 e_hit_test_region_div->rect.SetRect(200, 200, 300, 200); | |
| 367 | |
| 368 auto e_hit_test_region_c = HitTestRegion::New(); | |
| 369 e_hit_test_region_c->flags = kHitTestChildSurface; | |
| 370 e_hit_test_region_c->surface_id = c_surface_id; | |
| 371 e_hit_test_region_c->rect.SetRect(100, 100, 200, 500); | |
| 372 | |
| 373 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_div)); | |
| 374 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c)); | |
| 375 | |
| 376 auto c_hit_test_data = HitTestData::New(); | |
| 377 c_hit_test_data->surface_id = c_surface_id; | |
| 378 c_hit_test_data->flags = kHitTestMine; | |
| 379 c_hit_test_data->bounds.SetRect(0, 0, 200, 500); | |
| 380 | |
| 381 // Submit ( in unexpected order ). | |
| 382 | |
| 383 EXPECT_EQ(GetPendingCount(), 0); | |
| 384 | |
| 385 aggregator_.SubmitHitTestData(std::move(c_hit_test_data)); | |
| 386 EXPECT_EQ(GetPendingCount(), 1); | |
| 387 | |
| 388 aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | |
| 389 EXPECT_EQ(GetPendingCount(), 2); | |
| 390 | |
| 391 // Surfaces added to DisplayFrame ( in unexpected order ). | |
| 392 | |
| 393 EXPECT_EQ(count(), 0); | |
| 394 | |
| 395 EXPECT_EQ(GetActiveCount(), 0); | |
| 396 | |
| 397 CallOnSurfaceWillDraw(e_surface_id); | |
| 398 EXPECT_EQ(GetActiveCount(), 1); | |
| 399 | |
| 400 CallOnSurfaceWillDraw(c_surface_id); | |
| 401 EXPECT_EQ(GetActiveCount(), 2); | |
| 402 | |
| 403 // Aggregate and swap. | |
| 404 | |
| 405 aggregator_.Aggregate(e_surface_id); | |
| 406 EXPECT_EQ(count(), 0); | |
| 407 | |
| 408 aggregator_.Swap(); | |
| 409 | |
| 410 EXPECT_EQ(count(), 3); | |
| 411 | |
| 412 DisplayHitTestRegion* region; | |
| 413 | |
| 414 region = RegionAtIndex(0); | |
| 415 EXPECT_EQ(region->flags, kHitTestMine); | |
| 416 EXPECT_EQ(region->frame_sink_id, e_surface_id.frame_sink_id()); | |
| 417 EXPECT_EQ(region->rect, gfx::Rect(0, 0, 1024, 768)); | |
| 418 EXPECT_EQ(region->child_count, 2); | |
| 419 | |
| 420 region = RegionAtIndex(1); | |
| 421 EXPECT_EQ(region->flags, kHitTestMine); | |
| 422 EXPECT_EQ(region->frame_sink_id, e_surface_id.frame_sink_id()); | |
| 423 EXPECT_EQ(region->rect, gfx::Rect(200, 200, 300, 200)); | |
| 424 EXPECT_EQ(region->child_count, 0); | |
| 425 | |
| 426 region = RegionAtIndex(2); | |
| 427 EXPECT_EQ(region->flags, kHitTestChildSurface | kHitTestMine); | |
| 428 EXPECT_EQ(region->frame_sink_id, c_surface_id.frame_sink_id()); | |
| 429 EXPECT_EQ(region->rect, gfx::Rect(100, 100, 200, 500)); | |
| 430 EXPECT_EQ(region->child_count, 0); | |
| 431 } | |
| 432 | |
| 433 // One embedder with a clipped child with a tab and transparent background. | |
| 434 // | |
| 435 // +e-------------+ | |
| 436 // | +c---------| Point maps to | |
| 437 // | 1 |+a--+ | ----- ------- | |
| 438 // | || 2 | 3 | 1 e | |
| 439 // | |+b--------| 2 a | |
| 440 // | || | 3 e ( transparent area in c ) | |
| 441 // | || 4 | 4 b | |
| 442 // +--------------+ | |
| 443 // | |
| 444 | |
| 445 TEST_F(HitTestAggregatorTest, ClippedChildWithTabAndTransparentBackground) { | |
| 446 EXPECT_EQ(count(), 0); | |
| 447 | |
| 448 cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | |
| 449 cc::SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2); | |
| 450 cc::SurfaceId a_surface_id = MakeSurfaceId(kDisplayFrameSink, 3); | |
| 451 cc::SurfaceId b_surface_id = MakeSurfaceId(kDisplayFrameSink, 4); | |
| 452 | |
| 453 auto e_hit_test_data = HitTestData::New(); | |
| 454 e_hit_test_data->surface_id = e_surface_id; | |
| 455 e_hit_test_data->flags = kHitTestMine; | |
| 456 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768); | |
| 457 | |
| 458 auto e_hit_test_region_c = HitTestRegion::New(); | |
| 459 e_hit_test_region_c->flags = kHitTestChildSurface; | |
| 460 e_hit_test_region_c->surface_id = c_surface_id; | |
| 461 e_hit_test_region_c->rect.SetRect(200, 100, 1600, 800); | |
| 462 e_hit_test_region_c->transform.Translate(200, 100); | |
| 463 | |
| 464 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c)); | |
| 465 | |
| 466 auto c_hit_test_data = HitTestData::New(); | |
| 467 c_hit_test_data->surface_id = c_surface_id; | |
| 468 c_hit_test_data->flags = kHitTestIgnore; | |
| 469 c_hit_test_data->bounds.SetRect(0, 0, 1600, 800); | |
| 470 | |
| 471 auto c_hit_test_region_a = HitTestRegion::New(); | |
| 472 c_hit_test_region_a->flags = kHitTestChildSurface; | |
| 473 c_hit_test_region_a->surface_id = a_surface_id; | |
| 474 c_hit_test_region_a->rect.SetRect(0, 0, 200, 100); | |
| 475 | |
| 476 auto c_hit_test_region_b = HitTestRegion::New(); | |
| 477 c_hit_test_region_b->flags = kHitTestChildSurface; | |
| 478 c_hit_test_region_b->surface_id = b_surface_id; | |
| 479 c_hit_test_region_b->rect.SetRect(0, 100, 800, 600); | |
| 480 | |
| 481 c_hit_test_data->regions.push_back(std::move(c_hit_test_region_a)); | |
| 482 c_hit_test_data->regions.push_back(std::move(c_hit_test_region_b)); | |
| 483 | |
| 484 auto a_hit_test_data = HitTestData::New(); | |
| 485 a_hit_test_data->surface_id = a_surface_id; | |
| 486 a_hit_test_data->flags = kHitTestMine; | |
| 487 a_hit_test_data->bounds.SetRect(0, 0, 200, 100); | |
| 488 | |
| 489 auto b_hit_test_data = HitTestData::New(); | |
| 490 b_hit_test_data->surface_id = b_surface_id; | |
| 491 b_hit_test_data->flags = kHitTestMine; | |
| 492 b_hit_test_data->bounds.SetRect(0, 100, 800, 600); | |
| 493 | |
| 494 // Submit ( in unexpected order ). | |
| 495 | |
| 496 EXPECT_EQ(GetPendingCount(), 0); | |
| 497 | |
| 498 aggregator_.SubmitHitTestData(std::move(c_hit_test_data)); | |
| 499 EXPECT_EQ(GetPendingCount(), 1); | |
| 500 | |
| 501 aggregator_.SubmitHitTestData(std::move(a_hit_test_data)); | |
| 502 EXPECT_EQ(GetPendingCount(), 2); | |
| 503 | |
| 504 aggregator_.SubmitHitTestData(std::move(b_hit_test_data)); | |
| 505 EXPECT_EQ(GetPendingCount(), 3); | |
| 506 | |
| 507 aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | |
| 508 EXPECT_EQ(GetPendingCount(), 4); | |
| 509 | |
| 510 // Surfaces added to DisplayFrame ( in unexpected order ). | |
| 511 | |
| 512 EXPECT_EQ(count(), 0); | |
| 513 | |
| 514 EXPECT_EQ(GetActiveCount(), 0); | |
| 515 | |
| 516 CallOnSurfaceWillDraw(c_surface_id); | |
| 517 EXPECT_EQ(GetActiveCount(), 1); | |
| 518 | |
| 519 CallOnSurfaceWillDraw(e_surface_id); | |
| 520 EXPECT_EQ(GetActiveCount(), 2); | |
| 521 | |
| 522 CallOnSurfaceWillDraw(b_surface_id); | |
| 523 EXPECT_EQ(GetActiveCount(), 3); | |
| 524 | |
| 525 CallOnSurfaceWillDraw(a_surface_id); | |
| 526 EXPECT_EQ(GetActiveCount(), 4); | |
| 527 | |
| 528 // Aggregate and swap. | |
| 529 | |
| 530 aggregator_.Aggregate(e_surface_id); | |
| 531 EXPECT_EQ(count(), 0); | |
| 532 | |
| 533 aggregator_.Swap(); | |
| 534 | |
| 535 EXPECT_EQ(count(), 4); | |
| 536 | |
| 537 DisplayHitTestRegion* region; | |
| 538 | |
| 539 region = RegionAtIndex(0); | |
| 540 EXPECT_EQ(region->flags, kHitTestMine); | |
| 541 EXPECT_EQ(region->frame_sink_id, e_surface_id.frame_sink_id()); | |
| 542 EXPECT_EQ(region->rect, gfx::Rect(0, 0, 1024, 768)); | |
| 543 EXPECT_EQ(region->child_count, 3); | |
| 544 | |
| 545 region = RegionAtIndex(1); | |
| 546 EXPECT_EQ(region->flags, kHitTestChildSurface | kHitTestIgnore); | |
| 547 EXPECT_EQ(region->frame_sink_id, c_surface_id.frame_sink_id()); | |
| 548 EXPECT_EQ(region->rect, gfx::Rect(200, 100, 1600, 800)); | |
| 549 EXPECT_EQ(region->child_count, 2); | |
| 550 | |
| 551 gfx::Point point(300, 300); | |
| 552 region->transform.TransformPointReverse(&point); | |
| 553 EXPECT_TRUE(point == gfx::Point(100, 200)); | |
| 554 | |
| 555 region = RegionAtIndex(2); | |
| 556 EXPECT_EQ(region->flags, kHitTestChildSurface | kHitTestMine); | |
| 557 EXPECT_EQ(region->frame_sink_id, a_surface_id.frame_sink_id()); | |
| 558 EXPECT_EQ(region->rect, gfx::Rect(0, 0, 200, 100)); | |
| 559 EXPECT_EQ(region->child_count, 0); | |
| 560 | |
| 561 region = RegionAtIndex(3); | |
| 562 EXPECT_EQ(region->flags, kHitTestChildSurface | kHitTestMine); | |
| 563 EXPECT_EQ(region->frame_sink_id, b_surface_id.frame_sink_id()); | |
| 564 EXPECT_EQ(region->rect, gfx::Rect(0, 100, 800, 600)); | |
| 565 EXPECT_EQ(region->child_count, 0); | |
| 566 } | |
| 567 | |
| 568 // Three children deep. | |
| 569 // | |
| 570 // +e------------+ | |
| 571 // | +c1-------+ | | |
| 572 // | | +c2---+ | | | |
| 573 // | | | +c3-| | | | |
| 574 // | | | | | | | | |
| 575 // | | | +---| | | | |
| 576 // | | +-----+ | | | |
| 577 // | +---------+ | | |
| 578 // +-------------+ | |
| 579 // | |
| 580 | |
| 581 TEST_F(HitTestAggregatorTest, ThreeChildrenDeep) { | |
| 582 EXPECT_EQ(count(), 0); | |
| 583 | |
| 584 cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | |
| 585 cc::SurfaceId c1_surface_id = MakeSurfaceId(kDisplayFrameSink, 2); | |
| 586 cc::SurfaceId c2_surface_id = MakeSurfaceId(kDisplayFrameSink, 3); | |
| 587 cc::SurfaceId c3_surface_id = MakeSurfaceId(kDisplayFrameSink, 4); | |
| 588 | |
| 589 auto e_hit_test_data = HitTestData::New(); | |
| 590 e_hit_test_data->surface_id = e_surface_id; | |
| 591 e_hit_test_data->flags = kHitTestMine; | |
| 592 e_hit_test_data->bounds.SetRect(0, 0, 1024, 768); | |
| 593 | |
| 594 auto e_hit_test_region_c1 = HitTestRegion::New(); | |
| 595 e_hit_test_region_c1->flags = kHitTestChildSurface; | |
| 596 e_hit_test_region_c1->surface_id = c1_surface_id; | |
| 597 e_hit_test_region_c1->rect.SetRect(100, 100, 700, 700); | |
| 598 | |
| 599 e_hit_test_data->regions.push_back(std::move(e_hit_test_region_c1)); | |
| 600 | |
| 601 auto c1_hit_test_data = HitTestData::New(); | |
| 602 c1_hit_test_data->surface_id = c1_surface_id; | |
| 603 c1_hit_test_data->flags = kHitTestMine; | |
| 604 c1_hit_test_data->bounds.SetRect(0, 0, 600, 600); | |
| 605 | |
| 606 auto c1_hit_test_region_c2 = HitTestRegion::New(); | |
| 607 c1_hit_test_region_c2->flags = kHitTestChildSurface; | |
| 608 c1_hit_test_region_c2->surface_id = c2_surface_id; | |
| 609 c1_hit_test_region_c2->rect.SetRect(100, 100, 500, 500); | |
| 610 | |
| 611 c1_hit_test_data->regions.push_back(std::move(c1_hit_test_region_c2)); | |
| 612 | |
| 613 auto c2_hit_test_data = HitTestData::New(); | |
| 614 c2_hit_test_data->surface_id = c2_surface_id; | |
| 615 c2_hit_test_data->flags = kHitTestMine; | |
| 616 c2_hit_test_data->bounds.SetRect(0, 0, 400, 400); | |
| 617 | |
| 618 auto c2_hit_test_region_c3 = HitTestRegion::New(); | |
| 619 c2_hit_test_region_c3->flags = kHitTestChildSurface; | |
| 620 c2_hit_test_region_c3->surface_id = c3_surface_id; | |
| 621 c2_hit_test_region_c3->rect.SetRect(100, 100, 300, 300); | |
| 622 | |
| 623 c2_hit_test_data->regions.push_back(std::move(c2_hit_test_region_c3)); | |
| 624 | |
| 625 auto c3_hit_test_data = HitTestData::New(); | |
| 626 c3_hit_test_data->surface_id = c3_surface_id; | |
| 627 c3_hit_test_data->flags = kHitTestMine; | |
| 628 c3_hit_test_data->bounds.SetRect(0, 0, 200, 200); | |
| 629 | |
| 630 // Submit ( in unexpected order ). | |
| 631 | |
| 632 EXPECT_EQ(GetPendingCount(), 0); | |
| 633 | |
| 634 aggregator_.SubmitHitTestData(std::move(c1_hit_test_data)); | |
| 635 EXPECT_EQ(GetPendingCount(), 1); | |
| 636 | |
| 637 aggregator_.SubmitHitTestData(std::move(c3_hit_test_data)); | |
| 638 EXPECT_EQ(GetPendingCount(), 2); | |
| 639 | |
| 640 aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | |
| 641 EXPECT_EQ(GetPendingCount(), 3); | |
| 642 | |
| 643 aggregator_.SubmitHitTestData(std::move(c2_hit_test_data)); | |
| 644 EXPECT_EQ(GetPendingCount(), 4); | |
| 645 | |
| 646 // Surfaces added to DisplayFrame ( in unexpected order ). | |
| 647 | |
| 648 EXPECT_EQ(count(), 0); | |
| 649 | |
| 650 EXPECT_EQ(GetActiveCount(), 0); | |
| 651 | |
| 652 CallOnSurfaceWillDraw(c2_surface_id); | |
| 653 EXPECT_EQ(GetActiveCount(), 1); | |
| 654 | |
| 655 CallOnSurfaceWillDraw(c1_surface_id); | |
| 656 EXPECT_EQ(GetActiveCount(), 2); | |
| 657 | |
| 658 CallOnSurfaceWillDraw(e_surface_id); | |
| 659 EXPECT_EQ(GetActiveCount(), 3); | |
| 660 | |
| 661 CallOnSurfaceWillDraw(c3_surface_id); | |
| 662 EXPECT_EQ(GetActiveCount(), 4); | |
| 663 | |
| 664 // Aggregate and swap. | |
| 665 | |
| 666 aggregator_.Aggregate(e_surface_id); | |
| 667 EXPECT_EQ(count(), 0); | |
| 668 | |
| 669 aggregator_.Swap(); | |
| 670 | |
| 671 EXPECT_EQ(count(), 4); | |
| 672 | |
| 673 DisplayHitTestRegion* region; | |
| 674 | |
| 675 region = RegionAtIndex(0); | |
| 676 EXPECT_EQ(region->flags, kHitTestMine); | |
| 677 EXPECT_EQ(region->frame_sink_id, e_surface_id.frame_sink_id()); | |
| 678 EXPECT_EQ(region->rect, gfx::Rect(0, 0, 1024, 768)); | |
| 679 EXPECT_EQ(region->child_count, 3); | |
| 680 | |
| 681 region = RegionAtIndex(1); | |
| 682 EXPECT_EQ(region->flags, kHitTestChildSurface | kHitTestMine); | |
| 683 EXPECT_EQ(region->frame_sink_id, c1_surface_id.frame_sink_id()); | |
| 684 EXPECT_EQ(region->rect, gfx::Rect(100, 100, 700, 700)); | |
| 685 EXPECT_EQ(region->child_count, 2); | |
| 686 | |
| 687 region = RegionAtIndex(2); | |
| 688 EXPECT_EQ(region->flags, kHitTestChildSurface | kHitTestMine); | |
| 689 EXPECT_EQ(region->frame_sink_id, c2_surface_id.frame_sink_id()); | |
| 690 EXPECT_EQ(region->rect, gfx::Rect(100, 100, 500, 500)); | |
| 691 EXPECT_EQ(region->child_count, 1); | |
| 692 | |
| 693 region = RegionAtIndex(3); | |
| 694 EXPECT_EQ(region->flags, kHitTestChildSurface | kHitTestMine); | |
| 695 EXPECT_EQ(region->frame_sink_id, c3_surface_id.frame_sink_id()); | |
| 696 EXPECT_EQ(region->rect, gfx::Rect(100, 100, 300, 300)); | |
| 697 EXPECT_EQ(region->child_count, 0); | |
|
riajiang
2017/06/20 23:54:59
Can we maybe add a test case where e has two child
gklassen
2017/06/26 21:55:20
Good call, thank you. Test Added. Done.
| |
| 698 } | |
| 699 | |
| 700 // Exceed limits to ensure that bounds and resize work. | |
| 701 // | |
| 702 // A tree of embedders each with 8 children and 4 levels deep = 4096 regions. | |
| 703 // This will exceed initial allocation and force a resize. | |
| 704 // | |
| 705 // +e--------------------------------------------------------+ | |
| 706 // | +c1----------++c2----------++c3----------++c4----------+| | |
| 707 // | | +c1--------|| +c1--------|| +c1--------|| +c1--------|| | |
| 708 // | | | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | |
| 709 // | | | | || || | | || || | | || || | | || || | |
| 710 // | | | +---++---|| | +---++---|| | +---++---|| | +---++---|| | |
| 711 // | +------------++------------++------------++------------+| | |
| 712 // | +c5----------++c6----------++c7----------++c8----------+| | |
| 713 // | | +c1--------|| +c1--------|| +c1--------|| +c1--------|| | |
| 714 // | | | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | |
| 715 // | | | | || || | | || || | | || || | | || || | |
| 716 // | | | +---++---|| | +---++---|| | +---++---|| | +---++---|| | |
| 717 // | +------------++------------++------------++------------+| | |
| 718 // +---------------------------------------------------------+ | |
| 719 // | |
| 720 | |
| 721 TEST_F(HitTestAggregatorTest, ExceedLimits) { | |
| 722 EXPECT_EQ(count(), 0); | |
| 723 | |
| 724 EXPECT_LT(GetDisplayHitTestDataLength(), 4096); | |
| 725 | |
| 726 cc::SurfaceId display_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | |
| 727 | |
| 728 int next_surface_id = CreateAndSubmitHitTestDataWith8Children(1, 3); | |
| 729 int surface_count = next_surface_id - 1; | |
| 730 | |
| 731 int region_count = GetPendingRegionCount(); | |
| 732 | |
| 733 // Expect 4680 regions: | |
| 734 // 8 children 4 levels deep 8*8*8*8 is 4096 | |
| 735 // 1 region for each embedder/surface + 584 | |
| 736 // ----- | |
| 737 // 4680. | |
| 738 EXPECT_EQ(region_count, 4680); | |
| 739 | |
| 740 EXPECT_EQ(GetPendingCount(), surface_count); | |
| 741 | |
| 742 // Mark Surfaces as added to DisplayFrame ( in unexpected order ). | |
| 743 | |
| 744 EXPECT_EQ(count(), 0); | |
| 745 EXPECT_EQ(GetActiveCount(), 0); | |
| 746 | |
| 747 for (int i = 1; i <= surface_count; i++) { | |
| 748 cc::SurfaceId surface_id = MakeSurfaceId(kDisplayFrameSink, i); | |
| 749 CallOnSurfaceWillDraw(surface_id); | |
| 750 } | |
| 751 | |
| 752 EXPECT_EQ(GetActiveCount(), surface_count); | |
| 753 | |
| 754 // Aggregate and swap. | |
| 755 | |
| 756 aggregator_.Aggregate(display_surface_id); | |
| 757 EXPECT_EQ(count(), 0); | |
| 758 | |
| 759 aggregator_.Swap(); | |
| 760 | |
| 761 EXPECT_EQ(count(), region_count + 1); | |
| 762 | |
| 763 EXPECT_GE(GetDisplayHitTestDataLength(), region_count); | |
| 764 } | |
| 765 | |
| 766 } // namespace test | |
| 767 } // namespace hit_test | |
| 768 } // namespace viz | |
| OLD | NEW |