| Index: components/viz/hit_test/hit_test_aggregator_unittest.cc | 
| diff --git a/components/viz/hit_test/hit_test_aggregator_unittest.cc b/components/viz/hit_test/hit_test_aggregator_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..7769a395537eb4fa7360238b641e020ef6dcd149 | 
| --- /dev/null | 
| +++ b/components/viz/hit_test/hit_test_aggregator_unittest.cc | 
| @@ -0,0 +1,848 @@ | 
| +// Copyright 2017 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "hit_test_aggregator.h" | 
| +#include "cc/surfaces/frame_sink_id.h" | 
| +#include "cc/surfaces/local_surface_id.h" | 
| +#include "cc/surfaces/surface_id.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +namespace viz { | 
| +namespace hit_test { | 
| +namespace test { | 
| + | 
| +namespace { | 
| + | 
| +constexpr cc::FrameSinkId kDisplayFrameSink(2, 0); | 
| + | 
| +cc::SurfaceId MakeSurfaceId(const cc::FrameSinkId& frame_sink_id, | 
| +                            uint32_t local_id) { | 
| +  return cc::SurfaceId( | 
| +      frame_sink_id, | 
| +      cc::LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u))); | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +using namespace hit_test::mojom; | 
| + | 
| +class HitTestAggregatorTest : public testing::Test { | 
| + public: | 
| +  HitTestAggregatorTest() {} | 
| +  ~HitTestAggregatorTest() override {} | 
| + | 
| +  void SetUp() override {} | 
| + | 
| +  void TearDown() override {} | 
| + | 
| +  HitTestAggregator aggregator_; | 
| + | 
| +  int count() { | 
| +    DisplayHitTestRegion* start = aggregator_.GetCurrentRegions(); | 
| +    DisplayHitTestRegion* end = start; | 
| +    while (end->child_count_ != kEndOfList) { | 
| +      end++; | 
| +    } | 
| +    int count = end - start; | 
| +    return count; | 
| +  } | 
| + | 
| +  DisplayHitTestRegion* RegionAtIndex(int i) { | 
| +    return aggregator_.GetCurrentRegions() + i; | 
| +  } | 
| + | 
| +  int GetPendingCount() { return aggregator_.pending_.size(); } | 
| +  int GetActiveCount() { return aggregator_.active_.size(); } | 
| + | 
| +  int GetPendingRegionCount() { return RegionCount(aggregator_.pending_); } | 
| +  int GetActiveRegionCount() { return RegionCount(aggregator_.active_); } | 
| + | 
| +  int RegionCount(const HitTestDataMap& map) { | 
| +    int size = 0; | 
| +    for (auto const& it : map) { | 
| +      hit_test::mojom::HitTestData* hit_test_data = it.second.get(); | 
| +      size += hit_test_data->regions_.size(); | 
| +    } | 
| +    return size; | 
| +  } | 
| + | 
| +  void Reset() { | 
| +    int size = aggregator_.display_hit_test_data_->length_; | 
| + | 
| +    aggregator_.display_hit_test_data_->regions_[0].child_count_ = kEndOfList; | 
| +    aggregator_.display_hit_test_data_->regions_[size >> 1].child_count_ = | 
| +        kEndOfList; | 
| + | 
| +    aggregator_.pending_.clear(); | 
| +    aggregator_.active_.clear(); | 
| +  } | 
| + | 
| +  int GetDisplayHitTestDataLength() { | 
| +    return aggregator_.display_hit_test_data_->length_; | 
| +  } | 
| + | 
| +  // Creates a hit test data element with 8 children recursively to | 
| +  // the specified depth.  SurfaceIds are generated in sequential order and | 
| +  // the method returns the next unused id ( also matches the count ). | 
| +  int CreateAndSubmitHitTestDataWith8Children(int id, int depth) { | 
| +    cc::SurfaceId surface_id = MakeSurfaceId(kDisplayFrameSink, id); | 
| +    id++; | 
| + | 
| +    auto hit_test_data = HitTestData::New(); | 
| +    hit_test_data->surface_id_ = surface_id; | 
| + | 
| +    for (int i = 0; i < 8; i++) { | 
| +      auto hit_test_region = HitTestRegion::New(); | 
| +      hit_test_region->rect_.SetRect(100, 100, 100, 100); | 
| + | 
| +      if (depth > 0) { | 
| +        hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +        hit_test_region->surface_id_ = MakeSurfaceId(kDisplayFrameSink, id); | 
| +        id = CreateAndSubmitHitTestDataWith8Children(id, depth - 1); | 
| +      } else { | 
| +        hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +      } | 
| +      hit_test_data->regions_.push_back(std::move(hit_test_region)); | 
| +    } | 
| + | 
| +    aggregator_.SubmitHitTestData(std::move(hit_test_data)); | 
| +    return id; | 
| +  } | 
| +}; | 
| + | 
| +// One surface. | 
| +// | 
| +//  +----------+ | 
| +//  |          | | 
| +//  |          | | 
| +//  |          | | 
| +//  +----------+ | 
| +// | 
| +TEST_F(HitTestAggregatorTest, OneSurface) { | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  cc::SurfaceId display_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | 
| + | 
| +  auto hit_test_data = HitTestData::New(); | 
| +  hit_test_data->surface_id_ = display_surface_id; | 
| + | 
| +  auto hit_test_region = HitTestRegion::New(); | 
| +  hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  hit_test_region->surface_id_ = display_surface_id; | 
| +  hit_test_region->rect_.SetRect(0, 0, 1024, 768); | 
| + | 
| +  hit_test_data->regions_.push_back(std::move(hit_test_region)); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(hit_test_data)); | 
| + | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  EXPECT_TRUE(GetPendingCount() == 1); | 
| +  EXPECT_TRUE(GetActiveCount() == 0); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(display_surface_id); | 
| + | 
| +  EXPECT_TRUE(GetPendingCount() == 0); | 
| +  EXPECT_TRUE(GetActiveCount() == 1); | 
| + | 
| +  aggregator_.Aggregate(display_surface_id); | 
| +  aggregator_.Swap(); | 
| + | 
| +  // Expect 1 entry routing all events to the one surface ( display root ). | 
| +  EXPECT_TRUE(count() == 1); | 
| + | 
| +  DisplayHitTestRegion* region; | 
| + | 
| +  region = RegionAtIndex(0); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == display_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 1024, 768)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| +} | 
| + | 
| +// One opaque embedder with two regions. | 
| +// | 
| +//  +e------------+ | 
| +//  | +r1-+ +r2-+ | | 
| +//  | |   | |   | | | 
| +//  | |   | |   | | | 
| +//  | +---+ +---+ | | 
| +//  +-------------+ | 
| +// | 
| +TEST_F(HitTestAggregatorTest, OneEmbedderTwoRegions) { | 
| +  Reset(); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | 
| + | 
| +  auto e_hit_test_data = HitTestData::New(); | 
| +  e_hit_test_data->surface_id_ = e_surface_id; | 
| + | 
| +  auto e_hit_test_region = HitTestRegion::New(); | 
| +  e_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  e_hit_test_region->surface_id_ = e_surface_id; | 
| +  e_hit_test_region->rect_.SetRect(0, 0, 1024, 768); | 
| + | 
| +  auto e_hit_test_region_r1 = HitTestRegion::New(); | 
| +  e_hit_test_region_r1->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  e_hit_test_region_r1->rect_.SetRect(0, 0, 512, 512); | 
| + | 
| +  auto e_hit_test_region_r2 = HitTestRegion::New(); | 
| +  e_hit_test_region_r2->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  e_hit_test_region_r2->rect_.SetRect(0, 0, 512, 512); | 
| + | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region_r1)); | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region_r2)); | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region)); | 
| + | 
| +  // Submit HitTestData. | 
| + | 
| +  EXPECT_TRUE(GetPendingCount() == 0); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 1); | 
| + | 
| +  // Add Surfaces to DisplayFrame ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(count() == 0); | 
| +  EXPECT_TRUE(GetActiveCount() == 0); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(e_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 1); | 
| + | 
| +  // Aggregate and swap. | 
| + | 
| +  aggregator_.Aggregate(e_surface_id); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  aggregator_.Swap(); | 
| +  EXPECT_TRUE(count() == 3); | 
| + | 
| +  DisplayHitTestRegion* region; | 
| + | 
| +  region = RegionAtIndex(0); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 512, 512)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(1); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 512, 512)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(2); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == e_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 1024, 768)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| +} | 
| + | 
| +// One embedder with two children. | 
| +// | 
| +//  +e------------+ | 
| +//  | +c1-+ +c2-+ | | 
| +//  | |   | |   | | | 
| +//  | |   | |   | | | 
| +//  | +---+ +---+ | | 
| +//  +-------------+ | 
| +// | 
| + | 
| +TEST_F(HitTestAggregatorTest, OneEmbedderTwoChildren) { | 
| +  Reset(); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | 
| +  cc::SurfaceId c1_surface_id = MakeSurfaceId(kDisplayFrameSink, 2); | 
| +  cc::SurfaceId c2_surface_id = MakeSurfaceId(kDisplayFrameSink, 3); | 
| + | 
| +  auto e_hit_test_data = HitTestData::New(); | 
| +  e_hit_test_data->surface_id_ = e_surface_id; | 
| + | 
| +  auto e_hit_test_region = HitTestRegion::New(); | 
| +  e_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  e_hit_test_region->surface_id_ = e_surface_id; | 
| +  e_hit_test_region->rect_.SetRect(0, 0, 500, 500); | 
| + | 
| +  auto e_hit_test_region_c1 = HitTestRegion::New(); | 
| +  e_hit_test_region_c1->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  e_hit_test_region_c1->surface_id_ = c1_surface_id; | 
| +  e_hit_test_region_c1->rect_.SetRect(100, 100, 200, 200); | 
| + | 
| +  auto e_hit_test_region_c2 = HitTestRegion::New(); | 
| +  e_hit_test_region_c2->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  e_hit_test_region_c2->surface_id_ = c2_surface_id; | 
| +  e_hit_test_region_c2->rect_.SetRect(300, 300, 400, 400); | 
| + | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region_c1)); | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region_c2)); | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region)); | 
| + | 
| +  auto c1_hit_test_data = HitTestData::New(); | 
| +  c1_hit_test_data->surface_id_ = c1_surface_id; | 
| + | 
| +  auto c2_hit_test_data = HitTestData::New(); | 
| +  c2_hit_test_data->surface_id_ = c2_surface_id; | 
| + | 
| +  // Submit ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(GetPendingCount() == 0); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(c1_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 1); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 2); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(c2_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 3); | 
| + | 
| +  // Surfaces added to DisplayFrame ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  EXPECT_TRUE(GetActiveCount() == 0); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(c2_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 1); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(c1_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 2); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(e_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 3); | 
| + | 
| +  // Aggregate and swap. | 
| + | 
| +  aggregator_.Aggregate(e_surface_id); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  aggregator_.Swap(); | 
| + | 
| +  EXPECT_TRUE(count() == 3); | 
| + | 
| +  DisplayHitTestRegion* region; | 
| + | 
| +  region = RegionAtIndex(0); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c1_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(100, 100, 200, 200)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(1); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c2_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(300, 300, 400, 400)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(2); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == e_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 500, 500)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| +} | 
| + | 
| +// Occluded child frame ( OOPIF ). | 
| +// | 
| +//  +e-----------+ | 
| +//  | +c--+      | | 
| +//  | | +div-+   | | 
| +//  | | |    |   | | 
| +//  | | +----+   | | 
| +//  | +---+      | | 
| +//  +------------+ | 
| +// | 
| + | 
| +TEST_F(HitTestAggregatorTest, OccludedChildFrame) { | 
| +  Reset(); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | 
| +  cc::SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2); | 
| + | 
| +  auto e_hit_test_data = HitTestData::New(); | 
| +  e_hit_test_data->surface_id_ = e_surface_id; | 
| + | 
| +  auto e_hit_test_region = HitTestRegion::New(); | 
| +  e_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  e_hit_test_region->surface_id_ = e_surface_id; | 
| +  e_hit_test_region->rect_.SetRect(0, 0, 500, 500); | 
| + | 
| +  auto e_hit_test_region_div = HitTestRegion::New(); | 
| +  e_hit_test_region_div->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  e_hit_test_region_div->rect_.SetRect(100, 100, 400, 400); | 
| + | 
| +  auto e_hit_test_region_c = HitTestRegion::New(); | 
| +  e_hit_test_region_c->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  e_hit_test_region_c->surface_id_ = c_surface_id; | 
| +  e_hit_test_region_c->rect_.SetRect(200, 200, 500, 200); | 
| + | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region_div)); | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region_c)); | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region)); | 
| + | 
| +  auto c_hit_test_data = HitTestData::New(); | 
| +  c_hit_test_data->surface_id_ = c_surface_id; | 
| + | 
| +  auto c_hit_test_region = HitTestRegion::New(); | 
| +  c_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  c_hit_test_region->surface_id_ = c_surface_id; | 
| +  c_hit_test_region->rect_.SetRect(0, 0, 300, 300); | 
| + | 
| +  c_hit_test_data->regions_.push_back(std::move(c_hit_test_region)); | 
| + | 
| +  // Submit ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(GetPendingCount() == 0); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(c_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 1); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 2); | 
| + | 
| +  // Surfaces added to DisplayFrame ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  EXPECT_TRUE(GetActiveCount() == 0); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(e_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 1); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(c_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 2); | 
| + | 
| +  // Aggregate and swap. | 
| + | 
| +  aggregator_.Aggregate(e_surface_id); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  aggregator_.Swap(); | 
| + | 
| +  EXPECT_TRUE(count() == 4); | 
| + | 
| +  DisplayHitTestRegion* region; | 
| + | 
| +  region = RegionAtIndex(0); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(100, 100, 400, 400)); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(1); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(200, 200, 500, 200)); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->child_count_ == 1); | 
| + | 
| +  region = RegionAtIndex(2); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 300, 300)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(3); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == e_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 500, 500)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| +} | 
| + | 
| +// One embedder with a clipped child with a tab and transparent background. | 
| +// | 
| +//  +e-------------+ | 
| +//  |   +c---------|     Point   maps to | 
| +//  | 1 |+a--+     |     -----   ------- | 
| +//  |   || 2 |  3  |       1        e | 
| +//  |   |+b--------|       2        a | 
| +//  |   ||         |       3        e ( transparent area in c ) | 
| +//  |   ||   4     |       4        b | 
| +//  +--------------+ | 
| +// | 
| + | 
| +TEST_F(HitTestAggregatorTest, ClippedChildWithTabAndTransparentBackground) { | 
| +  Reset(); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | 
| +  cc::SurfaceId c_surface_id = MakeSurfaceId(kDisplayFrameSink, 2); | 
| +  cc::SurfaceId a_surface_id = MakeSurfaceId(kDisplayFrameSink, 3); | 
| +  cc::SurfaceId b_surface_id = MakeSurfaceId(kDisplayFrameSink, 4); | 
| + | 
| +  auto e_hit_test_data = HitTestData::New(); | 
| +  e_hit_test_data->surface_id_ = e_surface_id; | 
| + | 
| +  auto e_hit_test_region_c = HitTestRegion::New(); | 
| +  e_hit_test_region_c->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  e_hit_test_region_c->surface_id_ = c_surface_id; | 
| +  e_hit_test_region_c->rect_.SetRect(200, 100, 800, 800); | 
| +  e_hit_test_region_c->transform_.Translate(200, 100); | 
| + | 
| +  auto e_hit_test_region = HitTestRegion::New(); | 
| +  e_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  e_hit_test_region->surface_id_ = e_surface_id; | 
| +  e_hit_test_region->rect_.SetRect(0, 0, 600, 600); | 
| + | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region_c)); | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region)); | 
| + | 
| +  auto c_hit_test_data = HitTestData::New(); | 
| +  c_hit_test_data->surface_id_ = c_surface_id; | 
| + | 
| +  auto c_hit_test_region_a = HitTestRegion::New(); | 
| +  c_hit_test_region_a->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  c_hit_test_region_a->surface_id_ = a_surface_id; | 
| +  c_hit_test_region_a->rect_.SetRect(0, 0, 200, 100); | 
| + | 
| +  auto c_hit_test_region_b = HitTestRegion::New(); | 
| +  c_hit_test_region_b->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  c_hit_test_region_b->surface_id_ = b_surface_id; | 
| +  c_hit_test_region_b->rect_.SetRect(0, 100, 800, 600); | 
| + | 
| +  c_hit_test_data->regions_.push_back(std::move(c_hit_test_region_a)); | 
| +  c_hit_test_data->regions_.push_back(std::move(c_hit_test_region_b)); | 
| + | 
| +  auto a_hit_test_data = HitTestData::New(); | 
| +  a_hit_test_data->surface_id_ = a_surface_id; | 
| + | 
| +  auto a_hit_test_region = HitTestRegion::New(); | 
| +  a_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  a_hit_test_region->surface_id_ = a_surface_id; | 
| +  a_hit_test_region->rect_.SetRect(0, 0, 200, 100); | 
| + | 
| +  a_hit_test_data->regions_.push_back(std::move(a_hit_test_region)); | 
| + | 
| +  auto b_hit_test_data = HitTestData::New(); | 
| +  b_hit_test_data->surface_id_ = b_surface_id; | 
| + | 
| +  auto b_hit_test_region = HitTestRegion::New(); | 
| +  b_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  b_hit_test_region->surface_id_ = b_surface_id; | 
| +  b_hit_test_region->rect_.SetRect(0, 0, 800, 600); | 
| + | 
| +  b_hit_test_data->regions_.push_back(std::move(b_hit_test_region)); | 
| + | 
| +  // Submit ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(GetPendingCount() == 0); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(c_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 1); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(a_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 2); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(b_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 3); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 4); | 
| + | 
| +  // Surfaces added to DisplayFrame ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  EXPECT_TRUE(GetActiveCount() == 0); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(c_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 1); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(e_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 2); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(b_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 3); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(a_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 4); | 
| + | 
| +  // Aggregate and swap. | 
| + | 
| +  aggregator_.Aggregate(e_surface_id); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  aggregator_.Swap(); | 
| + | 
| +  EXPECT_TRUE(count() == 6); | 
| + | 
| +  DisplayHitTestRegion* region; | 
| + | 
| +  region = RegionAtIndex(0); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(200, 100, 800, 800)); | 
| +  EXPECT_TRUE(region->child_count_ == 4); | 
| + | 
| +  gfx::Point point(300, 300); | 
| +  region->transform_.TransformPointReverse(&point); | 
| +  EXPECT_TRUE(point == gfx::Point(100, 200)); | 
| + | 
| +  region = RegionAtIndex(1); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == a_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 200, 100)); | 
| +  EXPECT_TRUE(region->child_count_ == 1); | 
| + | 
| +  region = RegionAtIndex(2); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == a_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 200, 100)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(3); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == b_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 100, 800, 600)); | 
| +  EXPECT_TRUE(region->child_count_ == 1); | 
| + | 
| +  region = RegionAtIndex(4); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == b_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 800, 600)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(5); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == e_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 600, 600)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| +} | 
| + | 
| +// Three children deep. | 
| +// | 
| +//  +e------------+ | 
| +//  | +c1-------+ | | 
| +//  | | +c2---+ | | | 
| +//  | | | +c3-| | | | 
| +//  | | | |   | | | | 
| +//  | | | +---| | | | 
| +//  | | +-----+ | | | 
| +//  | +---------+ | | 
| +//  +-------------+ | 
| +// | 
| + | 
| +TEST_F(HitTestAggregatorTest, ThreeChildrenDeep) { | 
| +  Reset(); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  cc::SurfaceId e_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | 
| +  cc::SurfaceId c1_surface_id = MakeSurfaceId(kDisplayFrameSink, 2); | 
| +  cc::SurfaceId c2_surface_id = MakeSurfaceId(kDisplayFrameSink, 3); | 
| +  cc::SurfaceId c3_surface_id = MakeSurfaceId(kDisplayFrameSink, 4); | 
| + | 
| +  auto e_hit_test_data = HitTestData::New(); | 
| +  e_hit_test_data->surface_id_ = e_surface_id; | 
| + | 
| +  auto e_hit_test_region_c1 = HitTestRegion::New(); | 
| +  e_hit_test_region_c1->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  e_hit_test_region_c1->surface_id_ = c1_surface_id; | 
| +  e_hit_test_region_c1->rect_.SetRect(100, 100, 700, 700); | 
| + | 
| +  auto e_hit_test_region = HitTestRegion::New(); | 
| +  e_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  e_hit_test_region->surface_id_ = e_surface_id; | 
| +  e_hit_test_region->rect_.SetRect(0, 0, 800, 800); | 
| + | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region_c1)); | 
| +  e_hit_test_data->regions_.push_back(std::move(e_hit_test_region)); | 
| + | 
| +  auto c1_hit_test_data = HitTestData::New(); | 
| +  c1_hit_test_data->surface_id_ = c1_surface_id; | 
| + | 
| +  auto c1_hit_test_region_c2 = HitTestRegion::New(); | 
| +  c1_hit_test_region_c2->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  c1_hit_test_region_c2->surface_id_ = c2_surface_id; | 
| +  c1_hit_test_region_c2->rect_.SetRect(100, 100, 500, 500); | 
| + | 
| +  auto c1_hit_test_region = HitTestRegion::New(); | 
| +  c1_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  c1_hit_test_region->surface_id_ = c1_surface_id; | 
| +  c1_hit_test_region->rect_.SetRect(0, 0, 600, 600); | 
| + | 
| +  c1_hit_test_data->regions_.push_back(std::move(c1_hit_test_region_c2)); | 
| +  c1_hit_test_data->regions_.push_back(std::move(c1_hit_test_region)); | 
| + | 
| +  auto c2_hit_test_data = HitTestData::New(); | 
| +  c2_hit_test_data->surface_id_ = c2_surface_id; | 
| + | 
| +  auto c2_hit_test_region_c3 = HitTestRegion::New(); | 
| +  c2_hit_test_region_c3->flags_ = HitTestRegionFlags::HIT_TEST_CHILD_SURFACE; | 
| +  c2_hit_test_region_c3->surface_id_ = c3_surface_id; | 
| +  c2_hit_test_region_c3->rect_.SetRect(100, 100, 300, 300); | 
| + | 
| +  auto c2_hit_test_region = HitTestRegion::New(); | 
| +  c2_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  c2_hit_test_region->surface_id_ = c2_surface_id; | 
| +  c2_hit_test_region->rect_.SetRect(0, 0, 400, 400); | 
| + | 
| +  c2_hit_test_data->regions_.push_back(std::move(c2_hit_test_region_c3)); | 
| +  c2_hit_test_data->regions_.push_back(std::move(c2_hit_test_region)); | 
| + | 
| +  auto c3_hit_test_data = HitTestData::New(); | 
| +  c3_hit_test_data->surface_id_ = c3_surface_id; | 
| + | 
| +  auto c3_hit_test_region = HitTestRegion::New(); | 
| +  c3_hit_test_region->flags_ = HitTestRegionFlags::HIT_TEST_MINE; | 
| +  c3_hit_test_region->surface_id_ = c3_surface_id; | 
| +  c3_hit_test_region->rect_.SetRect(0, 0, 200, 200); | 
| + | 
| +  c3_hit_test_data->regions_.push_back(std::move(c3_hit_test_region)); | 
| + | 
| +  // Submit ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(GetPendingCount() == 0); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(c1_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 1); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(c3_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 2); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(e_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 3); | 
| + | 
| +  aggregator_.SubmitHitTestData(std::move(c2_hit_test_data)); | 
| +  EXPECT_TRUE(GetPendingCount() == 4); | 
| + | 
| +  // Surfaces added to DisplayFrame ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  EXPECT_TRUE(GetActiveCount() == 0); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(c2_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 1); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(c1_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 2); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(e_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 3); | 
| + | 
| +  aggregator_.OnSurfaceWillDraw(c3_surface_id); | 
| +  EXPECT_TRUE(GetActiveCount() == 4); | 
| + | 
| +  // Aggregate and swap. | 
| + | 
| +  aggregator_.Aggregate(e_surface_id); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  aggregator_.Swap(); | 
| + | 
| +  EXPECT_TRUE(count() == 7); | 
| + | 
| +  DisplayHitTestRegion* region; | 
| + | 
| +  region = RegionAtIndex(0); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c1_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(100, 100, 700, 700)); | 
| +  EXPECT_TRUE(region->child_count_ == 5); | 
| + | 
| +  region = RegionAtIndex(1); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c2_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(100, 100, 500, 500)); | 
| +  EXPECT_TRUE(region->child_count_ == 3); | 
| + | 
| +  region = RegionAtIndex(2); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c3_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(100, 100, 300, 300)); | 
| +  EXPECT_TRUE(region->child_count_ == 1); | 
| + | 
| +  region = RegionAtIndex(3); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c3_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 200, 200)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(4); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c2_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 400, 400)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(5); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == c1_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 600, 600)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| + | 
| +  region = RegionAtIndex(6); | 
| +  EXPECT_TRUE(region->flags_ == HitTestRegionFlags::HIT_TEST_MINE); | 
| +  EXPECT_TRUE(region->frame_sink_id_ == e_surface_id.frame_sink_id()); | 
| +  EXPECT_TRUE(region->rect_ == gfx::Rect(0, 0, 800, 800)); | 
| +  EXPECT_TRUE(region->child_count_ == 0); | 
| +} | 
| + | 
| +// Exceed limits to ensure that bounds and resize work. | 
| +// | 
| +// A tree of embedders each with 8 children and 4 levels deep = 4096 regions. | 
| +// This will exceed initial allocation and force a resize. | 
| +// | 
| +//  +e--------------------------------------------------------+ | 
| +//  | +c1----------++c2----------++c3----------++c4----------+| | 
| +//  | | +c1--------|| +c1--------|| +c1--------|| +c1--------|| | 
| +//  | | | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | 
| +//  | | | |   ||   || | |   ||   || | |   ||   || | |   ||   || | 
| +//  | | | +---++---|| | +---++---|| | +---++---|| | +---++---|| | 
| +//  | +------------++------------++------------++------------+| | 
| +//  | +c5----------++c6----------++c7----------++c8----------+| | 
| +//  | | +c1--------|| +c1--------|| +c1--------|| +c1--------|| | 
| +//  | | | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | +c1-++c2-|| | 
| +//  | | | |   ||   || | |   ||   || | |   ||   || | |   ||   || | 
| +//  | | | +---++---|| | +---++---|| | +---++---|| | +---++---|| | 
| +//  | +------------++------------++------------++------------+| | 
| +//  +---------------------------------------------------------+ | 
| +// | 
| + | 
| +TEST_F(HitTestAggregatorTest, ExceedLimits) { | 
| +  Reset(); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  EXPECT_TRUE(GetDisplayHitTestDataLength() < 4096); | 
| + | 
| +  cc::SurfaceId display_surface_id = MakeSurfaceId(kDisplayFrameSink, 1); | 
| + | 
| +  int next_surface_id = CreateAndSubmitHitTestDataWith8Children(1, 3); | 
| +  int surface_count = next_surface_id - 1; | 
| + | 
| +  int region_count = GetPendingRegionCount(); | 
| + | 
| +  // Expect 4680 regions: | 
| +  //  8 children 4 levels deep 8*8*8*8 is  4096 | 
| +  //  1 region for each embedder/surface +  584 | 
| +  //                                      ----- | 
| +  //                                       4680. | 
| +  EXPECT_TRUE(region_count == 4680); | 
| + | 
| +  EXPECT_TRUE(GetPendingCount() == surface_count); | 
| + | 
| +  // Mark Surfaces as added to DisplayFrame ( in unexpected order ). | 
| + | 
| +  EXPECT_TRUE(count() == 0); | 
| +  EXPECT_TRUE(GetActiveCount() == 0); | 
| + | 
| +  for (int i = 1; i <= surface_count; i++) { | 
| +    cc::SurfaceId surface_id = MakeSurfaceId(kDisplayFrameSink, i); | 
| +    aggregator_.OnSurfaceWillDraw(surface_id); | 
| +  } | 
| + | 
| +  EXPECT_TRUE(GetActiveCount() == surface_count); | 
| + | 
| +  // Aggregate and swap. | 
| + | 
| +  aggregator_.Aggregate(display_surface_id); | 
| +  EXPECT_TRUE(count() == 0); | 
| + | 
| +  aggregator_.Swap(); | 
| + | 
| +  EXPECT_TRUE(count() == region_count); | 
| + | 
| +  EXPECT_TRUE(GetDisplayHitTestDataLength() >= region_count); | 
| +} | 
| + | 
| +}  // namespace test | 
| +}  // namespace hit_test | 
| +}  // namespace viz | 
|  |