diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 17:21:03 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 16:25:15 +0000 |
commit | c551f43206405019121bd2b2c93714319a0a3300 (patch) | |
tree | 1f48c30631c421fd4bbb3c36da20183c8a2ed7d7 /chromium/cc/trees | |
parent | 7961cea6d1041e3e454dae6a1da660b453efd238 (diff) | |
download | qtwebengine-chromium-c551f43206405019121bd2b2c93714319a0a3300.tar.gz |
BASELINE: Update Chromium to 79.0.3945.139
Change-Id: I336b7182fab9bca80b709682489c07db112eaca5
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc/trees')
70 files changed, 7683 insertions, 11406 deletions
diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc index 743b681dc6a..e56e3311013 100644 --- a/chromium/cc/trees/damage_tracker.cc +++ b/chromium/cc/trees/damage_tracker.cc @@ -15,7 +15,6 @@ #include "cc/layers/render_surface_impl.h" #include "cc/paint/filter_operations.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -25,13 +24,10 @@ std::unique_ptr<DamageTracker> DamageTracker::Create() { return base::WrapUnique(new DamageTracker()); } -DamageTracker::DamageTracker() : mailboxId_(0) {} - +DamageTracker::DamageTracker() = default; DamageTracker::~DamageTracker() = default; -void DamageTracker::UpdateDamageTracking( - LayerTreeImpl* layer_tree_impl, - const RenderSurfaceList& render_surface_list) { +void DamageTracker::UpdateDamageTracking(LayerTreeImpl* layer_tree_impl) { // // This function computes the "damage rect" of each target surface, and // updates the state that is used to correctly track damage across frames. The @@ -105,7 +101,7 @@ void DamageTracker::UpdateDamageTracking( // erased from map. // - for (RenderSurfaceImpl* render_surface : render_surface_list) { + for (auto* render_surface : layer_tree_impl->GetRenderSurfaceList()) { render_surface->damage_tracker()->PrepareForUpdate(); } @@ -171,8 +167,6 @@ void DamageTracker::ComputeSurfaceDamage(RenderSurfaceImpl* render_surface) { // These functions cannot be bypassed with early-exits, even if we know what // the damage will be for this frame, because we need to update the damage // tracker state to correctly track the next frame. - DamageAccumulator damage_from_surface_mask = - TrackDamageFromSurfaceMask(render_surface->MaskLayer()); DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects(); // True if any layer is removed. has_damage_from_contributing_content_ |= @@ -186,7 +180,6 @@ void DamageTracker::ComputeSurfaceDamage(RenderSurfaceImpl* render_surface) { } else { // TODO(shawnsingh): can we clamp this damage to the surface's content rect? // (affects performance, but not correctness) - damage_for_this_update_.Union(damage_from_surface_mask); damage_for_this_update_.Union(damage_from_leftover_rects); gfx::Rect damage_rect; @@ -240,24 +233,6 @@ DamageTracker::SurfaceRectMapData& DamageTracker::RectDataForSurface( return *it; } -DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask( - LayerImpl* target_surface_mask_layer) { - DamageAccumulator damage; - - if (!target_surface_mask_layer) - return damage; - - // Currently, if there is any change to the mask, we choose to damage the - // entire surface. This could potentially be optimized later, but it is not - // expected to be a common case. - if (target_surface_mask_layer->LayerPropertyChanged() || - !target_surface_mask_layer->update_rect().IsEmpty()) { - damage.Union(gfx::Rect(target_surface_mask_layer->bounds())); - } - - return damage; -} - void DamageTracker::PrepareForUpdate() { mailboxId_++; damage_for_this_update_ = DamageAccumulator(); diff --git a/chromium/cc/trees/damage_tracker.h b/chromium/cc/trees/damage_tracker.h index bda7579c9d9..2515a563f04 100644 --- a/chromium/cc/trees/damage_tracker.h +++ b/chromium/cc/trees/damage_tracker.h @@ -34,9 +34,7 @@ class CC_EXPORT DamageTracker { DamageTracker& operator=(const DamageTracker&) = delete; - static void UpdateDamageTracking( - LayerTreeImpl* layer_tree_impl, - const RenderSurfaceList& render_surface_list); + static void UpdateDamageTracking(LayerTreeImpl* layer_tree_impl); void DidDrawDamagedArea() { current_damage_ = DamageAccumulator(); @@ -91,8 +89,6 @@ class CC_EXPORT DamageTracker { int bottom_ = 0; }; - DamageAccumulator TrackDamageFromSurfaceMask( - LayerImpl* target_surface_mask_layer); DamageAccumulator TrackDamageFromLeftoverRects(); // These helper functions are used only during UpdateDamageTracking(). @@ -148,10 +144,10 @@ class CC_EXPORT DamageTracker { SortedRectMapForLayers rect_history_for_layers_; SortedRectMapForSurfaces rect_history_for_surfaces_; - unsigned int mailboxId_; + unsigned int mailboxId_ = 0; DamageAccumulator current_damage_; // Damage from contributing render surface and layer - bool has_damage_from_contributing_content_; + bool has_damage_from_contributing_content_ = false; // Damage accumulated since the last call to PrepareForUpdate(). DamageAccumulator damage_for_this_update_; diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc index f5bb60b229d..d2636625dfb 100644 --- a/chromium/cc/trees/damage_tracker_unittest.cc +++ b/chromium/cc/trees/damage_tracker_unittest.cc @@ -10,12 +10,10 @@ #include "cc/layers/layer_impl.h" #include "cc/paint/filter_operation.h" #include "cc/paint/filter_operations.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_host_impl.h" +#include "cc/test/fake_picture_layer_impl.h" +#include "cc/test/fake_raster_source.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" -#include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_host_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" @@ -28,7 +26,10 @@ namespace { class TestLayerImpl : public LayerImpl { public: - TestLayerImpl(LayerTreeImpl* tree_impl, int id); + static std::unique_ptr<TestLayerImpl> Create(LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new TestLayerImpl(tree_impl, id)); + } void AddDamageRect(const gfx::Rect& damage_rect); @@ -37,6 +38,8 @@ class TestLayerImpl : public LayerImpl { void ResetChangeTracking() override; private: + TestLayerImpl(LayerTreeImpl* tree_impl, int id); + gfx::Rect damage_rect_; }; @@ -56,21 +59,6 @@ void TestLayerImpl::ResetChangeTracking() { damage_rect_.SetRect(0, 0, 0, 0); } -void ExecuteCalculateDrawProperties(LayerImpl* root, - float device_scale_factor, - RenderSurfaceList* render_surface_list) { - // Sanity check: The test itself should create the root layer's render - // surface, so that the surface (and its damage tracker) can - // persist across multiple calls to this function. - ASSERT_FALSE(render_surface_list->size()); - - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Rect(root->bounds()), device_scale_factor, - render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - ASSERT_TRUE(GetRenderSurface(root)); -} - void ClearDamageForAllSurfaces(LayerImpl* root) { for (auto* layer : *root->layer_tree_impl()) { if (GetRenderSurface(layer)) @@ -78,48 +66,29 @@ void ClearDamageForAllSurfaces(LayerImpl* root) { } } -void EmulateDrawingOneFrame(LayerImpl* root, float device_scale_factor = 1.f) { - // This emulates only steps that are relevant to testing the damage tracker: - // 1. computing the render passes and layerlists - // 2. updating all damage trackers in the correct order - // 3. resetting all update_rects and property_changed flags for all layers - // and surfaces. - - RenderSurfaceList render_surface_list; - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); - - DamageTracker::UpdateDamageTracking(root->layer_tree_impl(), - render_surface_list); - - root->layer_tree_impl()->ResetAllChangeTracking(); -} - -class DamageTrackerTest : public testing::Test { +class DamageTrackerTest : public LayerTreeImplTestBase, public testing::Test { public: - DamageTrackerTest() - : host_impl_(&task_runner_provider_, &task_graph_runner_) {} - LayerImpl* CreateTestTreeWithOneSurface(int number_of_children) { - host_impl_.active_tree()->DetachLayers(); - auto root = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 1); + ClearLayersAndProperties(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(500, 500)); + root->layer_tree_impl()->SetDeviceViewportRect(gfx::Rect(root->bounds())); root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; + SetupRootProperties(root); + child_layers_.resize(number_of_children); for (int i = 0; i < number_of_children; ++i) { - auto child = - std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 2 + i); - child->test_properties()->position = gfx::PointF(100.f, 100.f); + auto* child = AddLayer<TestLayerImpl>(); child->SetBounds(gfx::Size(30, 30)); child->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child)); + child_layers_[i] = child; + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); } - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_.active_tree()->SetElementIdsForTesting(); + SetElementIdsForTesting(); - return host_impl_.active_tree()->root_layer_for_testing(); + return root; } LayerImpl* CreateTestTreeWithTwoSurfaces() { @@ -127,47 +96,47 @@ class DamageTrackerTest : public testing::Test { // child1. Additionally, the root has a second child layer, and child1 has // two children of its own. - host_impl_.active_tree()->DetachLayers(); - auto root = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 1); - auto child1 = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 2); - auto child2 = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 3); - auto grand_child1 = - std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 4); - auto grand_child2 = - std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 5); + ClearLayersAndProperties(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(500, 500)); + root->layer_tree_impl()->SetDeviceViewportRect(gfx::Rect(root->bounds())); root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; + SetupRootProperties(root); - child1->test_properties()->position = gfx::PointF(100.f, 100.f); - child1->SetBounds(gfx::Size(30, 30)); + child1_ = AddLayer<TestLayerImpl>(); + grand_child1_ = AddLayer<TestLayerImpl>(); + grand_child2_ = AddLayer<TestLayerImpl>(); + child2_ = AddLayer<TestLayerImpl>(); + SetElementIdsForTesting(); + + child1_->SetBounds(gfx::Size(30, 30)); // With a child that draws_content, opacity will cause the layer to create // its own RenderSurface. This layer does not draw, but is intended to // create its own RenderSurface. - child1->SetDrawsContent(false); - child1->test_properties()->force_render_surface = true; - - child2->test_properties()->position = gfx::PointF(11.f, 11.f); - child2->SetBounds(gfx::Size(18, 18)); - child2->SetDrawsContent(true); - - grand_child1->test_properties()->position = gfx::PointF(200.f, 200.f); - grand_child1->SetBounds(gfx::Size(6, 8)); - grand_child1->SetDrawsContent(true); - - grand_child2->test_properties()->position = gfx::PointF(190.f, 190.f); - grand_child2->SetBounds(gfx::Size(6, 8)); - grand_child2->SetDrawsContent(true); + child1_->SetDrawsContent(false); + CopyProperties(root, child1_); + CreateTransformNode(child1_).post_translation = + gfx::Vector2dF(100.f, 100.f); + CreateEffectNode(child1_).render_surface_reason = + RenderSurfaceReason::kTest; + + grand_child1_->SetBounds(gfx::Size(6, 8)); + grand_child1_->SetDrawsContent(true); + CopyProperties(child1_, grand_child1_); + grand_child1_->SetOffsetToTransformParent(gfx::Vector2dF(200.f, 200.f)); + + grand_child2_->SetBounds(gfx::Size(6, 8)); + grand_child2_->SetDrawsContent(true); + CopyProperties(child1_, grand_child2_); + grand_child2_->SetOffsetToTransformParent(gfx::Vector2dF(190.f, 190.f)); + + child2_->SetBounds(gfx::Size(18, 18)); + child2_->SetDrawsContent(true); + CopyProperties(root, child2_); + child2_->SetOffsetToTransformParent(gfx::Vector2dF(11.f, 11.f)); - child1->test_properties()->AddChild(std::move(grand_child1)); - child1->test_properties()->AddChild(std::move(grand_child2)); - root->test_properties()->AddChild(std::move(child1)); - root->test_properties()->AddChild(std::move(child2)); - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_.active_tree()->SetElementIdsForTesting(); - - return host_impl_.active_tree()->root_layer_for_testing(); + return root; } LayerImpl* CreateAndSetUpTestTreeWithOneSurface(int number_of_children = 1) { @@ -175,7 +144,6 @@ class DamageTrackerTest : public testing::Test { // Setup includes going past the first frame which always damages // everything, so that we can actually perform specific tests. - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); return root; @@ -186,16 +154,44 @@ class DamageTrackerTest : public testing::Test { // Setup includes going past the first frame which always damages // everything, so that we can actually perform specific tests. - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); return root; } + void EmulateDrawingOneFrame(LayerImpl* root, + float device_scale_factor = 1.f) { + // This emulates only steps that are relevant to testing the damage tracker: + // 1. computing the render passes and layerlists + // 2. updating all damage trackers in the correct order + // 3. resetting all update_rects and property_changed flags for all layers + // and surfaces. + + root->layer_tree_impl()->SetDeviceScaleFactor(device_scale_factor); + root->layer_tree_impl()->set_needs_update_draw_properties(); + UpdateDrawProperties(root->layer_tree_impl()); + + DamageTracker::UpdateDamageTracking(root->layer_tree_impl()); + + root->layer_tree_impl()->ResetAllChangeTracking(); + } + protected: - FakeImplTaskRunnerProvider task_runner_provider_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; + void ClearLayersAndProperties() { + host_impl()->active_tree()->DetachLayersKeepingRootLayerForTesting(); + host_impl()->active_tree()->property_trees()->clear(); + child_layers_.clear(); + child1_ = child2_ = grand_child1_ = grand_child2_ = nullptr; + } + + // Stores result of CreateTestTreeWithOneSurface(). + std::vector<TestLayerImpl*> child_layers_; + + // Store result of CreateTestTreeWithTwoSurfaces(). + TestLayerImpl* child1_ = nullptr; + TestLayerImpl* child2_ = nullptr; + TestLayerImpl* grand_child1_ = nullptr; + TestLayerImpl* grand_child2_ = nullptr; }; TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { @@ -203,7 +199,7 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { // render surfaces. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; EXPECT_EQ(2, GetRenderSurface(root)->num_contributors()); EXPECT_TRUE(root->contributes_to_drawn_render_surface()); @@ -225,23 +221,20 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - gfx::Rect child_damage_rect; - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_NE(GetRenderSurface(child1), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(child2), GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(child1_), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(child2_), GetRenderSurface(root)); EXPECT_EQ(3, GetRenderSurface(root)->num_contributors()); - EXPECT_EQ(2, GetRenderSurface(child1)->num_contributors()); + EXPECT_EQ(2, GetRenderSurface(child1_)->num_contributors()); - // The render surface for child1 only has a content_rect that encloses - // grand_child1 and grand_child2, because child1 does not draw content. + // The render surface for child1_ only has a content_rect that encloses + // grand_child1_ and grand_child2_, because child1_ does not draw content. EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), child_damage_rect.ToString()); EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); @@ -249,20 +242,19 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // CASE 1: Setting the update rect should cause the corresponding damage to // the surface. ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of update_rect (10, 11) @@ -277,7 +269,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // damage. ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -288,7 +279,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // update region, but no additional exposed old region. ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(20, 25, 1, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of update_rect (20, 25) @@ -303,14 +293,12 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - auto* child = - static_cast<TestLayerImpl*>(root->test_properties()->children[0]); + TestLayerImpl* child = child_layers_[0]; // CASE 1: Adding the layer damage rect should cause the corresponding damage // to the surface. ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(10, 11, 12, 13)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of layer damage_rect @@ -324,7 +312,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { // damage. ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(10, 11, 12, 13)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -334,7 +321,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { // new damaged region, but no additional exposed old region. ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(20, 25, 1, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of layer damage_rect @@ -348,7 +334,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(20, 25, 1, 2)); child->AddDamageRect(gfx::Rect(10, 15, 3, 4)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of layer damage_rect @@ -364,15 +349,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - auto* child = - static_cast<TestLayerImpl*>(root->test_properties()->children[0]); + TestLayerImpl* child = child_layers_[0]; // CASE 1: Adding the layer damage rect and update rect should cause the // corresponding damage to the surface. ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(5, 6, 12, 13)); child->SetUpdateRect(gfx::Rect(15, 16, 14, 10)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of unified layer @@ -388,7 +371,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(10, 11, 12, 13)); child->SetUpdateRect(gfx::Rect(10, 11, 14, 15)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -399,7 +381,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(20, 25, 2, 3)); child->SetUpdateRect(gfx::Rect(5, 10, 7, 8)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of unified layer damage @@ -414,12 +395,11 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // CASE 1: The layer's property changed flag takes priority over update rect. // - child->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); @@ -448,7 +428,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { // Cycle one frame of no change, just to sanity check that the next rect is // not because of the old damage state. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -456,6 +435,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { // Then, test the actual layer movement. ClearDamageForAllSurfaces(root); + CreateTransformNode(child).post_translation = + child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); gfx::Transform translation; translation.Translate(100.f, 130.f); root->layer_tree_impl()->SetTransformMutated(child->element_id(), @@ -470,57 +452,53 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - // Transform from browser animation should not be considered as damage from - // contributing layer since it is applied to the whole layer which has a - // render surface. - EXPECT_FALSE(GetRenderSurface(child) - ->damage_tracker() - ->has_damage_from_contributing_content()); + // TODO(crbug.com/1001882): Transform from browser animation should not be + // considered as damage from contributing layer since it is applied to the + // whole layer which has a render surface. + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForPropertyChangesFromContributingContents) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - LayerImpl* grandchild1 = child1->test_properties()->children[0]; - // CASE 1: The child1's opacity changed. + // CASE 1: child1_'s opacity changed. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(child1->element_id(), 0.5f); + root->layer_tree_impl()->SetOpacityMutated(child1_->element_id(), 0.5f); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child1) + EXPECT_FALSE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - // CASE 2: The layer2's opacity changed. - child2->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + // CASE 2: layer2_'s opacity changed. + CreateEffectNode(child2_).render_surface_reason = RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(child2->element_id(), 0.5f); + root->layer_tree_impl()->SetOpacityMutated(child2_->element_id(), 0.5f); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child1) + EXPECT_FALSE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - // CASE 3: The grandchild1's opacity changed. - grandchild1->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + // CASE 3: grand_child1_'s opacity changed. + CreateEffectNode(grand_child1_).render_surface_reason = + RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(grandchild1->element_id(), 0.5f); + root->layer_tree_impl()->SetOpacityMutated(grand_child1_->element_id(), 0.5f); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } @@ -528,11 +506,12 @@ TEST_F(DamageTrackerTest, // Regression test for http://crbug.com/923794 TEST_F(DamageTrackerTest, EffectPropertyChangeNoSurface) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // Create a separate effect node for the child, but no render surface. - child->test_properties()->opacity = 0.5; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + auto& effect_node = CreateEffectNode(child); + effect_node.opacity = 0.5; + effect_node.has_potential_opacity_animation = true; EmulateDrawingOneFrame(root); EXPECT_EQ(root->transform_tree_index(), child->transform_tree_index()); @@ -550,13 +529,12 @@ TEST_F(DamageTrackerTest, EffectPropertyChangeNoSurface) { // Regression test for http://crbug.com/923794 TEST_F(DamageTrackerTest, TransformPropertyChangeNoSurface) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // Create a separate transform node for the child, but no render surface. gfx::Transform trans1; trans1.Scale(2, 1); - child->test_properties()->transform = trans1; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateTransformNode(child).local = trans1; EmulateDrawingOneFrame(root); EXPECT_NE(root->transform_tree_index(), child->transform_tree_index()); @@ -576,66 +554,58 @@ TEST_F(DamageTrackerTest, TransformPropertyChangeNoSurface) { TEST_F(DamageTrackerTest, VerifyDamageForUpdateAndDamageRectsFromContributingContents) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - auto* child1 = - static_cast<TestLayerImpl*>(root->test_properties()->children[0]); - auto* child2 = - static_cast<TestLayerImpl*>(root->test_properties()->children[1]); - auto* grandchild1 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[0]); - - // CASE 1: Adding the layer1's damage rect and update rect should cause the + + // CASE 1: Adding child1_'s damage rect and update rect should cause the // corresponding damage to the surface. - child1->SetDrawsContent(true); + child1_->SetDrawsContent(true); ClearDamageForAllSurfaces(root); - child1->AddDamageRect(gfx::Rect(105, 106, 12, 15)); - child1->SetUpdateRect(gfx::Rect(115, 116, 12, 15)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + child1_->AddDamageRect(gfx::Rect(105, 106, 12, 15)); + child1_->SetUpdateRect(gfx::Rect(115, 116, 12, 15)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - // CASE 2: Adding the layer2's damage rect and update rect should cause the + // CASE 2: Adding child2_'s damage rect and update rect should cause the // corresponding damage to the surface. ClearDamageForAllSurfaces(root); - child2->AddDamageRect(gfx::Rect(11, 11, 12, 15)); - child2->SetUpdateRect(gfx::Rect(12, 12, 12, 15)); + child2_->AddDamageRect(gfx::Rect(11, 11, 12, 15)); + child2_->SetUpdateRect(gfx::Rect(12, 12, 12, 15)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child1) + EXPECT_FALSE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - // CASE 3: Adding the grandchild1's damage rect and update rect should cause + // CASE 3: Adding grand_child1_'s damage rect and update rect should cause // the corresponding damage to the surface. ClearDamageForAllSurfaces(root); - grandchild1->AddDamageRect(gfx::Rect(1, 0, 2, 5)); - grandchild1->SetUpdateRect(gfx::Rect(2, 1, 2, 5)); + grand_child1_->AddDamageRect(gfx::Rect(1, 0, 2, 5)); + grand_child1_->SetUpdateRect(gfx::Rect(2, 1, 2, 5)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageWhenSurfaceRemoved) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* surface = root->test_properties()->children[0]; - LayerImpl* child = surface->test_properties()->children[0]; + LayerImpl* surface = child1_; + LayerImpl* child = grand_child1_; child->SetDrawsContent(true); EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); - surface->test_properties()->force_render_surface = false; + SetRenderSurfaceReason(surface, RenderSurfaceReason::kNone); child->SetDrawsContent(false); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -652,18 +622,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { // transformed layer. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; - child->test_properties()->force_render_surface = true; + LayerImpl* child = child_layers_[0]; gfx::Transform rotation; rotation.Rotate(45.0); ClearDamageForAllSurfaces(root); - child->test_properties()->transform_origin = gfx::Point3F( - child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f); - child->test_properties()->position = gfx::PointF(85.f, 85.f); + auto& transform_node = CreateTransformNode(child); + transform_node.origin = gfx::Point3F(child->bounds().width() * 0.5f, + child->bounds().height() * 0.5f, 0.f); + transform_node.post_translation = gfx::Vector2dF(85.f, 85.f); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + child->NoteLayerPropertyChanged(); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Sanity check that the layer actually moved to (85, 85), damaging its old @@ -723,7 +695,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { // LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Transform transform; transform.Translate3d(550.0, 500.0, 0.0); @@ -732,23 +704,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { transform.Translate3d(-50.0, -50.0, 0.0); // Set up the child - child->test_properties()->position = gfx::PointF(0.f, 0.f); child->SetBounds(gfx::Size(100, 100)); - child->test_properties()->transform = transform; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateTransformNode(child).local = transform; + child->SetOffsetToTransformParent(gfx::Vector2dF()); EmulateDrawingOneFrame(root); // Sanity check that the child layer's bounds would actually get clipped by // w < 0, otherwise this test is not actually testing the intended scenario. - gfx::RectF test_rect(child->test_properties()->position, - gfx::SizeF(child->bounds())); + gfx::RectF test_rect(gfx::SizeF(child->bounds())); bool clipped = false; MathUtil::MapQuad(transform, gfx::QuadF(test_rect), &clipped); EXPECT_TRUE(clipped); // Damage the child without moving it. - child->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); root->layer_tree_impl()->SetOpacityMutated(child->element_id(), 0.5f); @@ -772,20 +741,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* surface = root->test_properties()->children[0]; - LayerImpl* child = surface->test_properties()->children[0]; + LayerImpl* surface = child1_; + LayerImpl* child = grand_child1_; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(5.f)); - // Setting the filter should not damage the conrresponding render surface. + // TODO(crbug.com/1001882): Setting the filter on an existing render surface + // should not damage the conrresponding render surface. ClearDamageForAllSurfaces(root); - surface->test_properties()->filters = filters; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetFilter(surface, filters); EmulateDrawingOneFrame(root); - EXPECT_FALSE(GetRenderSurface(root) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); EXPECT_FALSE(GetRenderSurface(surface) ->damage_tracker() ->has_damage_from_contributing_content()); @@ -794,7 +763,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { // surface, blurred based on the size of the blur filter. ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(1, 2, 3, 4)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of update_rect (1, 2) @@ -814,7 +782,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Rect root_damage_rect, child_damage_rect; // Allow us to set damage on child too. @@ -826,8 +794,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { 2, 2, BlurPaintFilter::TileMode::kClampToBlack_TileMode, nullptr))); // Setting the filter will damage the whole surface. - child->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateTransformNode(child).post_translation = + child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); @@ -896,7 +866,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Rect root_damage_rect, child_damage_rect; // Allow us to set damage on child too. @@ -911,9 +881,14 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { gfx::Transform transform; transform.RotateAboutYAxis(60); ClearDamageForAllSurfaces(root); - child->test_properties()->force_render_surface = true; - child->test_properties()->transform = transform; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + auto& transform_node = CreateTransformNode(child); + transform_node.local = transform; + transform_node.post_translation = child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + auto& effect_node = CreateEffectNode(child); + effect_node.render_surface_reason = RenderSurfaceReason::kFilter; + effect_node.has_potential_filter_animation = true; + EmulateDrawingOneFrame(root); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); EmulateDrawingOneFrame(root); @@ -955,21 +930,27 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Rect root_damage_rect, child_damage_rect; + ClearDamageForAllSurfaces(root); + int device_scale_factor = 2; + EmulateDrawingOneFrame(root, device_scale_factor); + // Allow us to set damage on child too. child->SetDrawsContent(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); - // Setting the filter will damage the whole surface. + // Setting the filter and creating a new render surface will damage the whole + // surface. + ClearDamageForAllSurfaces(root); + CreateTransformNode(child).post_translation = + child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; ClearDamageForAllSurfaces(root); - child->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - int device_scale_factor = 2; - EmulateDrawingOneFrame(root, device_scale_factor); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); EmulateDrawingOneFrame(root, device_scale_factor); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -979,14 +960,11 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { // Blur outset is 9px for a 3px blur, scaled up by DSF. int blur_outset = 9 * device_scale_factor; - gfx::Rect original_rect(100, 100, 100, 100); gfx::Rect expected_child_damage_rect(60, 60); expected_child_damage_rect.Inset(-blur_outset, -blur_outset); gfx::Rect expected_root_damage_rect(child_damage_rect); expected_root_damage_rect.Offset(200, 200); - gfx::Rect expected_total_damage_rect = expected_root_damage_rect; - expected_total_damage_rect.Union(original_rect); - EXPECT_EQ(expected_total_damage_rect, root_damage_rect); + EXPECT_EQ(expected_root_damage_rect, root_damage_rect); EXPECT_EQ(expected_child_damage_rect, child_damage_rect); // Setting the update rect should damage only the affected area (original, @@ -1006,36 +984,32 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - // Allow us to set damage on child1 too. - child1->SetDrawsContent(true); + // Allow us to set damage on child1_ too. + child1_->SetDrawsContent(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(2.f)); // Setting the filter will damage the whole surface. ClearDamageForAllSurfaces(root); - child1->test_properties()->backdrop_filters = filters; - child1->NoteLayerPropertyChanged(); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetBackdropFilter(child1_, filters); + child1_->NoteLayerPropertyChanged(); EmulateDrawingOneFrame(root); // CASE 1: Setting the update rect should cause the corresponding damage to // the surface, blurred based on the size of the child's backdrop - // blur filter. Note that child1's render surface has a size of - // 206x208 due to contributions from grand_child1 and grand_child2. + // blur filter. Note that child1_'s render surface has a size of + // 206x208 due to contributions from grand_child1_ and grand_child2_. ClearDamageForAllSurfaces(root); root->SetUpdateRect(gfx::Rect(297, 297, 2, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // Damage position on the surface should be a composition of the damage on - // the root and on child2. Damage on the root should be: position of + // the root and on child2_. Damage on the root should be: position of // update_rect (297, 297), but expanded by the blur outsets. gfx::Rect expected_damage_rect = gfx::Rect(297, 297, 2, 2); @@ -1049,13 +1023,12 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { // of the blurred layer, only the left/top should end up expanded. ClearDamageForAllSurfaces(root); root->SetUpdateRect(gfx::Rect(297, 297, 30, 30)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // Damage position on the surface should be a composition of the damage on - // the root and on child2. Damage on the root should be: position of + // the root and on child2_. Damage on the root should be: position of // update_rect (297, 297), but expanded on the left/top by the blur outsets. expected_damage_rect = gfx::Rect(297, 297, 30, 30); @@ -1064,10 +1037,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 3: Setting this update rect outside the blurred content_bounds of the - // blurred child1 will not cause it to be expanded. + // blurred child1_ will not cause it to be expanded. ClearDamageForAllSurfaces(root); root->SetUpdateRect(gfx::Rect(30, 30, 2, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1079,11 +1051,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 4: Setting this update rect inside the blurred content_bounds but - // outside the original content_bounds of the blurred child1 will + // outside the original content_bounds of the blurred child1_ will // cause it to be expanded. ClearDamageForAllSurfaces(root); root->SetUpdateRect(gfx::Rect(99, 99, 1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1096,37 +1067,35 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { expected_damage_rect = gfx::Rect(99, 99, 7, 7); EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); - // CASE 5: Setting the update rect on child2, which is above child1, will - // not get blurred by child1, so it does not need to get expanded. + // CASE 5: Setting the update rect on child2_, which is above child1_, will + // not get blurred by child1_, so it does not need to get expanded. ClearDamageForAllSurfaces(root); - child2->SetUpdateRect(gfx::Rect(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + child2_->SetUpdateRect(gfx::Rect(1, 1)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - // Damage on child2 should be: position of update_rect offset by the child's + // Damage on child2_ should be: position of update_rect offset by the child's // position (11, 11), and not expanded by anything. expected_damage_rect = gfx::Rect(11, 11, 1, 1); EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); - // CASE 6: Setting the update rect on child1 will also blur the damage, so + // CASE 6: Setting the update rect on child1_ will also blur the damage, so // that any pixels needed for the blur are redrawn in the current // frame. ClearDamageForAllSurfaces(root); - child1->SetUpdateRect(gfx::Rect(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + child1_->SetUpdateRect(gfx::Rect(1, 1)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - // Damage on child1 should be: position of update_rect offset by the child's + // Damage on child1_ should be: position of update_rect offset by the child's // position (100, 100), and expanded by the damage. - // Damage should be (0,0 1x1), offset by the 100,100 offset of child1 in + // Damage should be (0,0 1x1), offset by the 100,100 offset of child1_ in // root, and expanded 6px for the 2px blur (i.e., 94,94 13x13), but there - // should be no damage outside child1 (i.e. none above or to the left of + // should be no damage outside child1_ (i.e. none above or to the left of // 100,100. expected_damage_rect = gfx::Rect(100, 100, 7, 7); EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); @@ -1134,17 +1103,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { // CASE 7: No changes, so should not damage the surface. ClearDamageForAllSurfaces(root); // We want to make sure that the backdrop filter doesn't cause empty damage - // to get expanded. We position child1 so that an expansion of the empty rect - // would have non-empty intersection with child1 in its target space (root + // to get expanded. We position child1_ so that an expansion of the empty rect + // would have non-empty intersection with child1_ in its target space (root // space). - child1->test_properties()->position = gfx::PointF(); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetPostTranslation(child1_, gfx::Vector2dF()); + child1_->NoteLayerPropertyChanged(); + // The first call clears the damage caused by the movement. + EmulateDrawingOneFrame(root); + ClearDamageForAllSurfaces(root); EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); // Should not be expanded by the blur filter. @@ -1154,20 +1126,17 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child1 = root->test_properties()->children[0]; + LayerImpl* child1 = child_layers_[0]; // CASE 1: Adding a new layer should cause the appropriate damage. // ClearDamageForAllSurfaces(root); - { - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); - child2->test_properties()->position = gfx::PointF(400.f, 380.f); - child2->SetBounds(gfx::Size(6, 8)); - child2->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child2)); - } - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(6, 8)); + child2->SetDrawsContent(true); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(400.f, 380.f)); EmulateDrawingOneFrame(root); // Sanity check - all 3 layers should be on the same render surface; render @@ -1188,17 +1157,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { // Advance one frame without damage so that we know the damage rect is not // leftover from the previous case. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); - // Then, test removing child1. - root->test_properties()->RemoveChild(child1); - child1 = nullptr; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + // Then, test removing child1_. + { + OwnedLayerImplList layers = + host_impl()->active_tree()->DetachLayersKeepingRootLayerForTesting(); + ASSERT_EQ(3u, layers.size()); + ASSERT_EQ(child1, layers[1].get()); + host_impl()->active_tree()->AddLayer(std::move(layers[2])); + } EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1211,29 +1183,25 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { } TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { - // If child2 is added to the layer tree, but it doesn't have any explicit + // If child2_ is added to the layer tree, but it doesn't have any explicit // damage of its own, it should still indeed damage the target surface. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); ClearDamageForAllSurfaces(root); - { - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); - child2->test_properties()->position = gfx::PointF(400.f, 380.f); - child2->SetBounds(gfx::Size(6, 8)); - child2->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child2)); - root->layer_tree_impl()->BuildLayerListForTesting(); - host_impl_.active_tree()->ResetAllChangeTracking(); - LayerImpl* child2_ptr = host_impl_.active_tree()->LayerById(3); - // Sanity check the initial conditions of the test, if these asserts - // trigger, it means the test no longer actually covers the intended - // scenario. - ASSERT_FALSE(child2_ptr->LayerPropertyChanged()); - ASSERT_TRUE(child2_ptr->update_rect().IsEmpty()); - } - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(6, 8)); + child2->SetDrawsContent(true); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(400.f, 380.f)); + host_impl()->active_tree()->ResetAllChangeTracking(); + // Sanity check the initial conditions of the test, if these asserts + // trigger, it means the test no longer actually covers the intended + // scenario. + ASSERT_FALSE(child2->LayerPropertyChanged()); + ASSERT_TRUE(child2->update_rect().IsEmpty()); + EmulateDrawingOneFrame(root); // Sanity check - all 3 layers should be on the same render surface; render @@ -1251,30 +1219,24 @@ TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child1 = root->test_properties()->children[0]; + LayerImpl* child1 = child_layers_[0]; // In this test we don't want the above tree manipulation to be considered // part of the same frame. ClearDamageForAllSurfaces(root); - { - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); - child2->test_properties()->position = gfx::PointF(400.f, 380.f); - child2->SetBounds(gfx::Size(6, 8)); - child2->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child2)); - } - LayerImpl* child2 = root->test_properties()->children[1]; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(6, 8)); + child2->SetDrawsContent(true); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(400.f, 380.f)); EmulateDrawingOneFrame(root); // Damaging two layers simultaneously should cause combined damage. - // - child1 update rect in surface space: gfx::Rect(100, 100, 1, 2); - // - child2 update rect in surface space: gfx::Rect(400, 380, 3, 4); + // - child1_ update rect in surface space: gfx::Rect(100, 100, 1, 2); + // - child2_ update rect in surface space: gfx::Rect(400, 380, 3, 4); ClearDamageForAllSurfaces(root); child1->SetUpdateRect(gfx::Rect(1, 2)); child2->SetUpdateRect(gfx::Rect(3, 4)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1288,13 +1250,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - LayerImpl* grand_child1 = - root->test_properties()->children[0]->test_properties()->children[0]; - child2->test_properties()->force_render_surface = true; - grand_child1->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateEffectNode(child2_).render_surface_reason = RenderSurfaceReason::kTest; + CreateEffectNode(grand_child1_).render_surface_reason = + RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; @@ -1302,9 +1260,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { // CASE 1: Damage to a descendant surface should propagate properly to // ancestor surface. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(grand_child1->element_id(), 0.5f); + root->layer_tree_impl()->SetOpacityMutated(grand_child1_->element_id(), 0.5f); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1313,27 +1271,27 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child2) + EXPECT_FALSE(GetRenderSurface(child2_) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(grand_child1) + EXPECT_FALSE(GetRenderSurface(grand_child1_) ->damage_tracker() ->has_damage_from_contributing_content()); // CASE 2: Same as previous case, but with additional damage elsewhere that // should be properly unioned. - // - child1 surface damage in root surface space: + // - child1_ surface damage in root surface space: // gfx::Rect(300, 300, 6, 8); - // - child2 damage in root surface space: + // - child2_ damage in root surface space: // gfx::Rect(11, 11, 18, 18); ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(grand_child1->element_id(), 0.7f); - root->layer_tree_impl()->SetOpacityMutated(child2->element_id(), 0.7f); + root->layer_tree_impl()->SetOpacityMutated(grand_child1_->element_id(), 0.7f); + root->layer_tree_impl()->SetOpacityMutated(child2_->element_id(), 0.7f); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1343,13 +1301,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child2) + EXPECT_FALSE(GetRenderSurface(child2_) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(grand_child1) + EXPECT_FALSE(GetRenderSurface(grand_child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } @@ -1363,17 +1321,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { // entire surface should be marked dirty. LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* grand_child1 = - root->test_properties()->children[0]->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; ClearDamageForAllSurfaces(root); - grand_child1->test_properties()->position = gfx::PointF(195.f, 205.f); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + grand_child1_->SetOffsetToTransformParent(gfx::Vector2dF(195.f, 205.f)); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1383,7 +1337,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { EXPECT_EQ(gfx::Rect(190, 190, 11, 23).ToString(), child_damage_rect.ToString()); - // Damage to the root surface should be the union of child1's *entire* render + // Damage to the root surface should be the union of child1_'s *entire* render // surface (in target space), and its old exposed area (also in target // space). EXPECT_EQ(gfx::Rect(290, 290, 16, 23).ToString(), @@ -1392,7 +1346,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } @@ -1402,37 +1356,34 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantSurface) { // damaged with the old and new descendant surface regions. LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - child1->SetDrawsContent(true); + child1_->SetDrawsContent(true); EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; ClearDamageForAllSurfaces(root); - child1->test_properties()->position = gfx::PointF(105.f, 107.f); - child1->NoteLayerPropertyChanged(); - TransformNode* child1_transform = - root->layer_tree_impl()->property_trees()->transform_tree.Node( - child1->transform_tree_index()); - child1_transform->transform_changed = true; + SetPostTranslation(child1_, gfx::Vector2dF(105.f, 107.f)); + child1_->NoteLayerPropertyChanged(); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - // Damage to the root surface should be the union of child1's *entire* render + // Damage to the root surface should be the union of child1_'s *entire* render // surface (in target space), and its old exposed area (also in target // space). - EXPECT_EQ(gfx::Rect(100, 100, 206, 208).ToString(), + EXPECT_EQ(gfx::UnionRects(gfx::Rect(100, 100, 206, 208), + gfx::Rect(105, 107, 206, 208)) + .ToString(), root_damage_rect.ToString()); // The child surface should also be damaged. EXPECT_EQ(gfx::Rect(0, 0, 206, 208).ToString(), child_damage_rect.ToString()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } @@ -1441,26 +1392,25 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { // An ancestor/owning layer changes that affects the position/transform of // the render surface. Note that in this case, the layer_property_changed flag // already propagates to the subtree (tested in LayerImpltest), which damages - // the entire child1 surface, but the damage tracker still needs the correct + // the entire child1_ surface, but the damage tracker still needs the correct // logic to compute the exposed region on the root surface. // TODO(shawnsingh): the expectations of this test case should change when we // add support for a unique scissor_rect per RenderSurface. In that case, the - // child1 surface should be completely unchanged, since we are only + // child1_ surface should be completely unchanged, since we are only // transforming it, while the root surface would be damaged appropriately. LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; ClearDamageForAllSurfaces(root); gfx::Transform translation; translation.Translate(-50.f, -50.f); - root->layer_tree_impl()->SetTransformMutated(child1->element_id(), + root->layer_tree_impl()->SetTransformMutated(child1_->element_id(), translation); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1469,36 +1419,34 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), child_damage_rect.ToString()); - // The entire child1 surface and the old exposed child1 surface should damage - // the root surface. - // - old child1 surface in target space: gfx::Rect(290, 290, 16, 18) - // - new child1 surface in target space: gfx::Rect(240, 240, 16, 18) + // The entire child1_ surface and the old exposed child1_ surface should + // damage the root surface. + // - old child1_ surface in target space: gfx::Rect(290, 290, 16, 18) + // - new child1_ surface in target space: gfx::Rect(240, 240, 16, 18) EXPECT_EQ(gfx::Rect(240, 240, 66, 68).ToString(), root_damage_rect.ToString()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child1) + EXPECT_FALSE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; // CASE 1: If a descendant surface disappears, its entire old area becomes // exposed. ClearDamageForAllSurfaces(root); - child1->test_properties()->force_render_surface = false; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetRenderSurfaceReason(child1_, RenderSurfaceReason::kNone); EmulateDrawingOneFrame(root); // Sanity check that there is only one surface now. - ASSERT_EQ(GetRenderSurface(child1), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(child1_), GetRenderSurface(root)); ASSERT_EQ(4, GetRenderSurface(root)->num_contributors()); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1516,7 +1464,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { // Cycle one frame of no change, just to sanity check that the next rect is // not because of the old damage state. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1524,17 +1471,16 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { // Then change the tree so that the render surface is added back. ClearDamageForAllSurfaces(root); - child1->test_properties()->force_render_surface = true; + SetRenderSurfaceReason(child1_, RenderSurfaceReason::kTest); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Sanity check that there is a new surface now. - ASSERT_TRUE(GetRenderSurface(child1)); + ASSERT_TRUE(GetRenderSurface(child1_)); EXPECT_EQ(3, GetRenderSurface(root)->num_contributors()); - EXPECT_EQ(2, GetRenderSurface(child1)->num_contributors()); + EXPECT_EQ(2, GetRenderSurface(child1_)->num_contributors()); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1549,16 +1495,14 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; // CASE 1: If nothing changes, the damage rect should be empty. // ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1572,9 +1516,8 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { // empty. // ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1587,17 +1530,15 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; - // In our specific tree, the update rect of child1 should not cause any + // In our specific tree, the update rect of child1_ should not cause any // damage to any surface because it does not actually draw content. ClearDamageForAllSurfaces(root); - child1->SetUpdateRect(gfx::Rect(1, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + child1_->SetUpdateRect(gfx::Rect(1, 2)); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1610,55 +1551,57 @@ TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { TEST_F(DamageTrackerTest, VerifyDamageForMask) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // In the current implementation of the damage tracker, changes to mask // layers should damage the entire corresponding surface. ClearDamageForAllSurfaces(root); + CreateTransformNode(child).post_translation = + child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + // Set up the mask layer. - { - std::unique_ptr<LayerImpl> mask_layer = - LayerImpl::Create(host_impl_.active_tree(), 3); - mask_layer->test_properties()->position = - child->test_properties()->position; - mask_layer->SetBounds(child->bounds()); - child->test_properties()->SetMaskLayer(std::move(mask_layer)); - child->test_properties()->force_render_surface = true; - } - LayerImpl* mask_layer = child->test_properties()->mask_layer; + CreateEffectNode(child); + auto* mask_layer = AddLayer<FakePictureLayerImpl>(); + SetupMaskProperties(child, mask_layer); + Region empty_invalidation; + mask_layer->UpdateRasterSource( + FakeRasterSource::CreateFilled(child->bounds()), &empty_invalidation, + nullptr, nullptr); // Add opacity and a grand_child so that the render surface persists even // after we remove the mask. - { - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl_.active_tree(), 4); - grand_child->test_properties()->position = gfx::PointF(2.f, 2.f); - grand_child->SetBounds(gfx::Size(2, 2)); - grand_child->SetDrawsContent(true); - child->test_properties()->AddChild(std::move(grand_child)); - } - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + LayerImpl* grand_child = AddLayer<LayerImpl>(); + grand_child->SetBounds(gfx::Size(2, 2)); + grand_child->SetDrawsContent(true); + CopyProperties(child, grand_child); + grand_child->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); EmulateDrawingOneFrame(root); - // CASE 1: the update_rect on a mask layer should damage the entire target - // surface. + EXPECT_EQ(2, GetRenderSurface(root)->num_contributors()); + EXPECT_TRUE(root->contributes_to_drawn_render_surface()); + EXPECT_EQ(3, GetRenderSurface(child)->num_contributors()); + EXPECT_TRUE(child->contributes_to_drawn_render_surface()); + EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(mask_layer)); + EXPECT_TRUE(mask_layer->contributes_to_drawn_render_surface()); + + // CASE 1: the update_rect on a mask layer should damage the rect. ClearDamageForAllSurfaces(root); mask_layer->SetUpdateRect(gfx::Rect(1, 2, 3, 4)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(1, 2, 3, 4), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 2: a property change on the mask layer should damage the entire // target surface. @@ -1666,7 +1609,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // Advance one frame without damage so that we know the damage rect is not // leftover from the previous case. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); @@ -1676,18 +1618,17 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { ClearDamageForAllSurfaces(root); mask_layer->NoteLayerPropertyChanged(); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(30, 30), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 3: removing the mask also damages the entire target surface. // @@ -1695,7 +1636,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // Advance one frame without damage so that we know the damage rect is not // leftover from the previous case. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); @@ -1703,10 +1643,17 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // Then test mask removal. ClearDamageForAllSurfaces(root); - child->test_properties()->SetMaskLayer(nullptr); - child->NoteLayerPropertyChanged(); - ASSERT_TRUE(child->LayerPropertyChanged()); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + auto layers = + root->layer_tree_impl()->DetachLayersKeepingRootLayerForTesting(); + ASSERT_EQ(layers[1].get(), child); + root->layer_tree_impl()->AddLayer(std::move(layers[1])); + ASSERT_EQ(layers[2].get(), mask_layer); + ASSERT_EQ(layers[3].get(), grand_child); + root->layer_tree_impl()->AddLayer(std::move(layers[3])); + CopyProperties(root, child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child, grand_child); + EmulateDrawingOneFrame(root); // Sanity check that a render surface still exists. @@ -1714,7 +1661,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(30, 30), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() @@ -1723,7 +1670,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // Case 1: This test ensures that when the tracker is given damage, that // it is included with any other partial damage. @@ -1732,7 +1679,6 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); GetRenderSurface(root)->damage_tracker()->AddDamageNextUpdate( gfx::Rect(15, 16, 32, 33)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1750,7 +1696,6 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { ClearDamageForAllSurfaces(root); GetRenderSurface(root)->damage_tracker()->AddDamageNextUpdate( gfx::Rect(30, 31, 14, 15)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1761,34 +1706,33 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { } TEST_F(DamageTrackerTest, VerifyDamageWithNoContributingLayers) { - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_.active_tree(), 1); - root->test_properties()->force_render_surface = true; - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); - LayerImpl* root_ptr = host_impl_.active_tree()->root_layer_for_testing(); - root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; - EmulateDrawingOneFrame(root_ptr); - - DCHECK_EQ(GetRenderSurface(root_ptr), root_ptr->render_target()); - RenderSurfaceImpl* target_surface = GetRenderSurface(root_ptr); + LayerImpl* root = root_layer(); + ClearDamageForAllSurfaces(root); + + LayerImpl* empty_surface = AddLayer<LayerImpl>(); + CopyProperties(root, empty_surface); + CreateEffectNode(empty_surface).render_surface_reason = + RenderSurfaceReason::kTest; + EmulateDrawingOneFrame(root); + + DCHECK_EQ(GetRenderSurface(empty_surface), empty_surface->render_target()); + RenderSurfaceImpl* target_surface = GetRenderSurface(empty_surface); gfx::Rect damage_rect; EXPECT_TRUE( target_surface->damage_tracker()->GetDamageRectIfValid(&damage_rect)); EXPECT_TRUE(damage_rect.IsEmpty()); - EXPECT_FALSE(GetRenderSurface(root_ptr) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_FALSE( + target_surface->damage_tracker()->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // If damage is not cleared, it should accumulate. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Sanity check damage after the first frame; this isnt the actual test yet. @@ -1803,7 +1747,6 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // New damage, without having cleared the previous damage, should be unioned // to the previous one. child->SetUpdateRect(gfx::Rect(20, 25, 1, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1825,7 +1768,6 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // Damage should remain empty even after one frame, since there's yet no new // damage. - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1844,7 +1786,7 @@ TEST_F(DamageTrackerTest, HugeDamageRect) { for (int i = 0; i < kRange; ++i) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Transform transform; transform.Translate(-kBigNumber, -kBigNumber); @@ -1852,8 +1794,11 @@ TEST_F(DamageTrackerTest, HugeDamageRect) { // The child layer covers (0, 0, i, i) of the viewport, // but has a huge negative position. child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i)); - child->test_properties()->transform = transform; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + auto& transform_node = CreateTransformNode(child); + transform_node.local = transform; + transform_node.post_translation = child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + float device_scale_factor = 1.f; // Visible rects computed from combining clips in target space and root // space don't match because of the loss in floating point accuracy. So, we @@ -1876,20 +1821,19 @@ TEST_F(DamageTrackerTest, HugeDamageRect) { TEST_F(DamageTrackerTest, DamageRectTooBig) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(2); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; + LayerImpl* child1 = child_layers_[0]; + LayerImpl* child2 = child_layers_[1]; // Really far left. - child1->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::min() + 100, 0); + child1->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::min() + 100, 0)); child1->SetBounds(gfx::Size(1, 1)); // Really far right. - child2->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::max() - 100, 0); + child2->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::max() - 100, 0)); child2->SetBounds(gfx::Size(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; float device_scale_factor = 1.f; EmulateDrawingOneFrame(root, device_scale_factor); @@ -1907,25 +1851,24 @@ TEST_F(DamageTrackerTest, DamageRectTooBig) { TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(2); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; + LayerImpl* child1 = child_layers_[0]; + LayerImpl* child2 = child_layers_[1]; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(5.f)); root->SetDrawsContent(true); - root->test_properties()->backdrop_filters = filters; + SetBackdropFilter(root, filters); // Really far left. - child1->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::min() + 100, 0); + child1->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::min() + 100, 0)); child1->SetBounds(gfx::Size(1, 1)); // Really far right. - child2->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::max() - 100, 0); + child2->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::max() - 100, 0)); child2->SetBounds(gfx::Size(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; float device_scale_factor = 1.f; EmulateDrawingOneFrame(root, device_scale_factor); @@ -1943,190 +1886,168 @@ TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) { TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - auto* grandchild1 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[0]); - auto* grandchild2 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[1]); // Really far left. - grandchild1->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::min() + 500, 0); - grandchild1->SetBounds(gfx::Size(1, 1)); - grandchild1->SetDrawsContent(true); + grand_child1_->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::min() + 500, 0)); + grand_child1_->SetBounds(gfx::Size(1, 1)); + grand_child1_->SetDrawsContent(true); // Really far right. - grandchild2->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::max() - 500, 0); - grandchild2->SetBounds(gfx::Size(1, 1)); - grandchild2->SetDrawsContent(true); + grand_child2_->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::max() - 500, 0)); + grand_child2_->SetBounds(gfx::Size(1, 1)); + grand_child2_->SetDrawsContent(true); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - float device_scale_factor = 1.f; - RenderSurfaceList render_surface_list; - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); + UpdateDrawProperties(host_impl()->active_tree()); // Avoid the descendant-only property change path that skips unioning damage // from descendant layers. - GetRenderSurface(child1)->NoteAncestorPropertyChanged(); - DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), - render_surface_list); + GetRenderSurface(child1_)->NoteAncestorPropertyChanged(); + DamageTracker::UpdateDamageTracking(host_impl()->active_tree()); // The expected damage would be too large to store in a gfx::Rect, so we - // should damage everything on child1. + // should damage everything on child1_. gfx::Rect damage_rect; - EXPECT_FALSE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(GetRenderSurface(child1)->content_rect(), - GetRenderSurface(child1)->GetDamageRect()); + EXPECT_FALSE( + GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( + &damage_rect)); + EXPECT_EQ(GetRenderSurface(child1_)->content_rect(), + GetRenderSurface(child1_)->GetDamageRect()); - // However, the root should just use the child1 render surface's content rect + // However, the root should just use the child1_ render surface's content rect // as damage. ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + gfx::ToEnclosingRect(GetRenderSurface(child1_)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); // Add new damage, without changing properties, which goes down a different // path in the damage tracker. root->layer_tree_impl()->ResetAllChangeTracking(); - grandchild1->AddDamageRect(gfx::Rect(grandchild1->bounds())); - grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); + grand_child1_->AddDamageRect(gfx::Rect(grand_child1_->bounds())); + grand_child2_->AddDamageRect(gfx::Rect(grand_child1_->bounds())); // Recompute all damage / properties. - render_surface_list.clear(); - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); - DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), - render_surface_list); + UpdateDrawProperties(host_impl()->active_tree()); + DamageTracker::UpdateDamageTracking(host_impl()->active_tree()); // Child1 should still not have a valid rect, since the union of the damage of // its children is not representable by a single rect. - EXPECT_FALSE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(GetRenderSurface(child1)->content_rect(), - GetRenderSurface(child1)->GetDamageRect()); + EXPECT_FALSE( + GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( + &damage_rect)); + EXPECT_EQ(GetRenderSurface(child1_)->content_rect(), + GetRenderSurface(child1_)->GetDamageRect()); // Root should have valid damage and contain both its content rect and the - // drawable content rect of child1. + // drawable content rect of child1_. ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + gfx::ToEnclosingRect(GetRenderSurface(child1_)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - auto* grandchild1 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[0]); - auto* grandchild2 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[1]); // Set up a moving pixels filter on the child. FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(5.f)); - child1->SetDrawsContent(true); - child1->test_properties()->backdrop_filters = filters; + child1_->SetDrawsContent(true); + SetBackdropFilter(child1_, filters); // Really far left. - grandchild1->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::min() + 500, 0); - grandchild1->SetBounds(gfx::Size(1, 1)); - grandchild1->SetDrawsContent(true); + grand_child1_->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::min() + 500, 0)); + grand_child1_->SetBounds(gfx::Size(1, 1)); + grand_child1_->SetDrawsContent(true); // Really far right. - grandchild2->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::max() - 500, 0); - grandchild2->SetBounds(gfx::Size(1, 1)); - grandchild2->SetDrawsContent(true); + grand_child2_->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::max() - 500, 0)); + grand_child2_->SetBounds(gfx::Size(1, 1)); + grand_child2_->SetDrawsContent(true); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - float device_scale_factor = 1.f; - RenderSurfaceList render_surface_list; - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); + UpdateDrawProperties(host_impl()->active_tree()); // Avoid the descendant-only property change path that skips unioning damage // from descendant layers. - GetRenderSurface(child1)->NoteAncestorPropertyChanged(); - DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), - render_surface_list); + GetRenderSurface(child1_)->NoteAncestorPropertyChanged(); + DamageTracker::UpdateDamageTracking(host_impl()->active_tree()); // The expected damage would be too large to store in a gfx::Rect, so we - // should damage everything on child1. + // should damage everything on child1_. gfx::Rect damage_rect; - EXPECT_FALSE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(GetRenderSurface(child1)->content_rect(), - GetRenderSurface(child1)->GetDamageRect()); + EXPECT_FALSE( + GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( + &damage_rect)); + EXPECT_EQ(GetRenderSurface(child1_)->content_rect(), + GetRenderSurface(child1_)->GetDamageRect()); - // However, the root should just use the child1 render surface's content rect + // However, the root should just use the child1_ render surface's content rect // as damage. ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + gfx::ToEnclosingRect(GetRenderSurface(child1_)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); // Add new damage, without changing properties, which goes down a different // path in the damage tracker. root->layer_tree_impl()->ResetAllChangeTracking(); - grandchild1->AddDamageRect(gfx::Rect(grandchild1->bounds())); - grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); + grand_child1_->AddDamageRect(gfx::Rect(grand_child1_->bounds())); + grand_child2_->AddDamageRect(gfx::Rect(grand_child1_->bounds())); // Recompute all damage / properties. - render_surface_list.clear(); - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); - DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), - render_surface_list); + UpdateDrawProperties(host_impl()->active_tree()); + DamageTracker::UpdateDamageTracking(host_impl()->active_tree()); // Child1 should still not have a valid rect, since the union of the damage of // its children is not representable by a single rect. - EXPECT_FALSE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(GetRenderSurface(child1)->content_rect(), - GetRenderSurface(child1)->GetDamageRect()); + EXPECT_FALSE( + GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( + &damage_rect)); + EXPECT_EQ(GetRenderSurface(child1_)->content_rect(), + GetRenderSurface(child1_)->GetDamageRect()); // Root should have valid damage and contain both its content rect and the - // drawable content rect of child1. + // drawable content rect of child1_. ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + gfx::ToEnclosingRect(GetRenderSurface(child1_)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } diff --git a/chromium/cc/trees/debug_rect_history.cc b/chromium/cc/trees/debug_rect_history.cc index 07e6bd172b0..ca985285ffb 100644 --- a/chromium/cc/trees/debug_rect_history.cc +++ b/chromium/cc/trees/debug_rect_history.cc @@ -14,8 +14,8 @@ #include "cc/layers/render_surface_impl.h" #include "cc/trees/damage_tracker.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/scroll_node.h" #include "ui/gfx/geometry/rect_conversions.h" namespace cc { @@ -137,9 +137,8 @@ void DebugRectHistory::SaveScreenSpaceRects( } void DebugRectHistory::SaveTouchEventHandlerRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveTouchEventHandlerRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveTouchEventHandlerRectsCallback(layer); } void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) { @@ -167,19 +166,20 @@ void DebugRectHistory::SaveWheelEventHandlerRects(LayerTreeImpl* tree_impl) { // Since the wheel event handlers property is on the entire layer tree just // mark inner viewport if have listeners. - LayerImpl* inner_viewport = tree_impl->InnerViewportScrollLayer(); - if (!inner_viewport) + ScrollNode* inner_scroll = tree_impl->InnerViewportScrollNode(); + if (!inner_scroll) return; - debug_rects_.push_back(DebugRect( - WHEEL_EVENT_HANDLER_RECT_TYPE, - MathUtil::MapEnclosingClippedRect(inner_viewport->ScreenSpaceTransform(), - gfx::Rect(inner_viewport->bounds())))); + debug_rects_.push_back( + DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE, + MathUtil::MapEnclosingClippedRect( + tree_impl->property_trees()->transform_tree.ToScreen( + inner_scroll->transform_id), + gfx::Rect(inner_scroll->bounds)))); } void DebugRectHistory::SaveScrollEventHandlerRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveScrollEventHandlerRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveScrollEventHandlerRectsCallback(layer); } void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { @@ -193,9 +193,8 @@ void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { } void DebugRectHistory::SaveNonFastScrollableRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveNonFastScrollableRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveNonFastScrollableRectsCallback(layer); } void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) { diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/draw_properties_unittest.cc index 6a511ff0898..93acf2883ce 100644 --- a/chromium/cc/trees/layer_tree_host_common_unittest.cc +++ b/chromium/cc/trees/draw_properties_unittest.cc @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/trees/layer_tree_host_common.h" - #include <stddef.h> #include <algorithm> @@ -20,33 +18,22 @@ #include "cc/animation/single_keyframe_effect_animation.h" #include "cc/animation/transform_operations.h" #include "cc/base/math_util.h" -#include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/content_layer_client.h" #include "cc/layers/effect_tree_layer_list_iterator.h" #include "cc/layers/layer.h" #include "cc/layers/layer_client.h" #include "cc/layers/layer_impl.h" #include "cc/layers/render_surface_impl.h" -#include "cc/layers/texture_layer.h" -#include "cc/layers/texture_layer_client.h" #include "cc/test/animation_test_common.h" #include "cc/test/fake_content_layer_client.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_frame_sink.h" -#include "cc/test/fake_layer_tree_host.h" -#include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_picture_layer.h" #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" -#include "cc/test/test_task_graph_runner.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" -#include "cc/trees/property_tree_builder.h" #include "cc/trees/scroll_node.h" -#include "cc/trees/single_thread_proxy.h" -#include "cc/trees/task_runner_provider.h" #include "cc/trees/transform_node.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" @@ -64,12 +51,11 @@ bool LayerSubtreeHasCopyRequest(Layer* layer) { return GetEffectNode(layer)->subtree_has_copy_request; } -class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { +class DrawPropertiesTestBase : public LayerTreeImplTestBase { public: - LayerTreeHostCommonTestBase() - : LayerTestCommon::LayerImplTest(LayerListSettings()) {} - explicit LayerTreeHostCommonTestBase(const LayerTreeSettings& settings) - : LayerTestCommon::LayerImplTest(settings) {} + DrawPropertiesTestBase() = default; + explicit DrawPropertiesTestBase(const LayerTreeSettings& settings) + : LayerTreeImplTestBase(settings) {} static void SetScrollOffsetDelta(LayerImpl* layer_impl, const gfx::Vector2dF& delta) { @@ -97,40 +83,9 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { .starting_animation_scale; } - // Inherits the impl version from LayerImplTest. - using LayerImplTest::ExecuteCalculateDrawProperties; - - // This is the main version. - void ExecuteCalculateDrawProperties(Layer* root_layer, - float device_scale_factor = 1.0f, - float page_scale_factor = 1.0f, - Layer* page_scale_layer = nullptr) { - if (!host()->IsUsingLayerLists()) { - if (device_scale_factor != host()->device_scale_factor() || - page_scale_factor != host()->page_scale_factor()) { - host()->property_trees()->needs_rebuild = true; - } - } - - EXPECT_TRUE(page_scale_layer || (page_scale_factor == 1.f)); - gfx::Rect device_viewport_rect = - gfx::Rect(root_layer->bounds().width() * device_scale_factor, - root_layer->bounds().height() * device_scale_factor); - - root_layer->layer_tree_host()->SetViewportRectAndScale( - device_viewport_rect, device_scale_factor, - viz::LocalSurfaceIdAllocation()); - - // We are probably not testing what is intended if the root_layer bounds are - // empty. - DCHECK(!root_layer->bounds().IsEmpty()); - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - root_layer, device_viewport_rect); - inputs.device_scale_factor = device_scale_factor; - inputs.page_scale_factor = page_scale_factor; - inputs.page_scale_layer = page_scale_layer; - inputs.update_layer_list = &update_layer_list_; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + void UpdateMainDrawProperties(float device_scale_factor = 1.0f) { + SetDeviceScaleAndUpdateViewportRect(host(), device_scale_factor); + UpdateDrawProperties(host(), &update_layer_list_); } LayerImpl* ImplOf(const scoped_refptr<Layer>& layer) { @@ -146,11 +101,8 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { // Updates main thread draw properties, commits main thread tree to // impl-side pending tree, and updates pending tree draw properties. - void Commit(float device_scale_factor = 1.0f, - float page_scale_factor = 1.0f, - Layer* page_scale_layer = nullptr) { - ExecuteCalculateDrawProperties(host()->root_layer(), device_scale_factor, - page_scale_factor, page_scale_layer); + void Commit(float device_scale_factor = 1.0f) { + UpdateMainDrawProperties(device_scale_factor); if (!host_impl()->pending_tree()) host_impl()->CreatePendingTree(); host()->CommitAndCreatePendingTree(); @@ -158,22 +110,18 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { // FakeLayerTreeHost instead of manually pushing the properties from the // layer tree host to the pending tree. host()->PushLayerTreePropertiesTo(host_impl()->pending_tree()); - ExecuteCalculateDrawProperties( - host_impl()->pending_tree()->root_layer_for_testing(), - device_scale_factor, gfx::Transform(), page_scale_factor, - PendingImplOf(page_scale_layer)); + + UpdateDrawProperties(host_impl()->pending_tree()); } // Calls Commit(), then activates the pending tree, and updates active tree // draw properties. - void CommitAndActivate(float device_scale_factor = 1.0f, - float page_scale_factor = 1.0f, - Layer* page_scale_layer = nullptr) { - Commit(device_scale_factor, page_scale_factor, page_scale_layer); + void CommitAndActivate(float device_scale_factor = 1.0f) { + Commit(device_scale_factor); host_impl()->ActivateSyncTree(); - ExecuteCalculateDrawProperties(root_layer_for_testing(), - device_scale_factor, gfx::Transform(), - page_scale_factor, ImplOf(page_scale_layer)); + DCHECK_EQ(device_scale_factor, + host_impl()->active_tree()->device_scale_factor()); + UpdateActiveTreeDrawProperties(device_scale_factor); } bool UpdateLayerListContains(int id) const { @@ -186,36 +134,44 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { const LayerList& update_layer_list() const { return update_layer_list_; } + const RenderSurfaceList& GetRenderSurfaceList() { + return host_impl()->active_tree()->GetRenderSurfaceList(); + } + + void SetDeviceTransform(const gfx::Transform& device_transform) { + host_impl()->OnDraw(device_transform, host_impl()->external_viewport(), + false, false); + } + private: LayerList update_layer_list_; }; -class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase, - public testing::Test {}; +class DrawPropertiesTest : public DrawPropertiesTestBase, + public testing::Test {}; -class LayerTreeHostCommonTestWithLayerTree : public LayerTreeHostCommonTestBase, - public testing::Test { +class DrawPropertiesTestWithLayerTree : public DrawPropertiesTestBase, + public testing::Test { public: - LayerTreeHostCommonTestWithLayerTree() - : LayerTreeHostCommonTestBase(LayerTreeSettings()) {} + DrawPropertiesTestWithLayerTree() + : DrawPropertiesTestBase(LayerTreeSettings()) {} }; -class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest { +class DrawPropertiesDrawRectsTest : public DrawPropertiesTest { public: - LayerTreeHostCommonDrawRectsTest() : LayerTreeHostCommonTest() {} + DrawPropertiesDrawRectsTest() : DrawPropertiesTest() {} void SetUp() override { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetDrawsContent(true); root->SetBounds(gfx::Size(500, 500)); - SetupRootProperties(root); } LayerImpl* TestVisibleRectAndDrawableContentRect( const gfx::Rect& target_rect, const gfx::Transform& layer_transform, const gfx::Rect& layer_rect) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* target = AddLayer<LayerImpl>(); LayerImpl* drawing_layer = AddLayer<LayerImpl>(); @@ -238,7 +194,7 @@ class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest { gfx::PointF(layer_rect.origin()).OffsetFromOrigin(); drawing_layer_transform_node.flattens_inherited_transform = false; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); return drawing_layer; } @@ -248,18 +204,17 @@ class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest { // and with identity transforms, then the draw transform, // screen space transform, and the hierarchy passed on to children // layers should also be identity transforms. -TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { - LayerImpl* parent = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformsForNoOpLayer) { + LayerImpl* parent = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(100, 100)); - SetupRootProperties(parent); CopyProperties(parent, child); CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(parent); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), @@ -270,29 +225,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { grand_child->ScreenSpaceTransform()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, EffectTreeTransformIdTest) { - // Tests that effect tree node gets a valid transform id when a layer - // has opacity but doesn't create a render surface. - auto parent = Layer::Create(); - host()->SetRootLayer(parent); - auto child = Layer::Create(); - parent->AddChild(child); - child->SetIsDrawable(true); - - parent->SetBounds(gfx::Size(100, 100)); - child->SetPosition(gfx::PointF(10, 10)); - child->SetBounds(gfx::Size(100, 100)); - child->SetOpacity(0.f); - ExecuteCalculateDrawProperties(parent.get()); - EffectNode* node = GetEffectNode(child.get()); - const int transform_tree_size = - GetPropertyTrees(parent.get())->transform_tree.next_available_id(); - EXPECT_LT(node->transform_id, transform_tree_size); -} - -TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformsForSingleLayer) { + LayerImpl* root = root_layer(); LayerImpl* layer = AddLayer<LayerImpl>(); TransformTree& transform_tree = @@ -301,13 +235,12 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { host_impl()->active_tree()->property_trees()->effect_tree; root->SetBounds(gfx::Size(1, 2)); - SetupRootProperties(root); CopyProperties(root, layer); // Case 1: Setting the bounds of the layer should not affect either the draw // transform or the screenspace transform. layer->SetBounds(gfx::Size(10, 12)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( gfx::Transform(), draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -319,7 +252,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { // no effect on the transforms. CreateTransformNode(layer).origin = gfx::Point3F(2.5f, 3.0f, 0.f); layer->SetBounds(gfx::Size(10, 12)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( gfx::Transform(), draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -332,7 +265,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { gfx::Transform position_transform; position_transform.Translate(0.f, 1.2f); SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( position_transform, draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -348,7 +281,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { SetTransform(layer, layer_transform); SetTransformOrigin(layer, gfx::Point3F()); SetPostTranslation(layer, gfx::Vector2dF()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( layer_transform, draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -362,7 +295,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { gfx::Transform expected_result = translation_to_anchor * layer_transform * Inverse(translation_to_anchor); SetTransformOrigin(layer, gfx::Point3F(5.f, 0.f, 0.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_result, draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -376,7 +309,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { expected_result = position_transform * translation_to_anchor * layer_transform * Inverse(translation_to_anchor); SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_result, draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -385,7 +318,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { draw_property_utils::ScreenSpaceTransform(layer, transform_tree)); } -TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { +TEST_F(DrawPropertiesTest, TransformsAboutScrollOffset) { const gfx::ScrollOffset kScrollOffset(50, 100); const gfx::Vector2dF kScrollDelta(2.34f, 5.67f); const gfx::Vector2d kMaxScrollOffset(200, 200); @@ -406,16 +339,11 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(), scroll_layer->bounds().height() + kMaxScrollOffset.y())); - LayerImpl* page_scale_layer = AddLayer<LayerImpl>(); - page_scale_layer->SetBounds(gfx::Size(3, 4)); + LayerImpl* root = root_layer(); + root->SetBounds(gfx::Size(3, 4)); + SetupViewport(root, gfx::Size(3, 4), gfx::Size(500, 500)); - LayerImpl* root_layer = root_layer_for_testing(); - root_layer->SetBounds(gfx::Size(3, 4)); - - SetupRootProperties(root_layer); - CopyProperties(root_layer, page_scale_layer); - CreateTransformNode(page_scale_layer); - CopyProperties(page_scale_layer, scroll_layer); + CopyProperties(OuterViewportScrollLayer(), scroll_layer); CreateTransformNode(scroll_layer); CreateScrollNode(scroll_layer); CopyProperties(scroll_layer, sublayer); @@ -424,10 +352,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), kScrollOffset); SetScrollOffsetDelta(scroll_layer, kScrollDelta); + host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale); + UpdateActiveTreeDrawProperties(kDeviceScale); - const gfx::Transform kDeviceTransform; - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, - page_scale, page_scale_layer); gfx::Transform expected_transform; gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta; expected_transform.Translate( @@ -445,8 +372,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { const float kTranslateY = 20.6f; arbitrary_translate.Translate(kTranslateX, kTranslateY); SetTransform(scroll_layer, arbitrary_translate); - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, - page_scale, page_scale_layer); + UpdateActiveTreeDrawProperties(kDeviceScale); expected_transform.MakeIdentity(); expected_transform.Translate( std::round(kTranslateX * page_scale * kDeviceScale + @@ -461,13 +387,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { // Test that page scale is updated even when we don't rebuild property trees. page_scale = 1.888f; - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = page_scale_layer->id(); - root_layer->layer_tree_impl()->SetViewportLayersFromIds(viewport_ids); - root_layer->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale); - EXPECT_FALSE(root_layer->layer_tree_impl()->property_trees()->needs_rebuild); - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, - page_scale, page_scale_layer); + host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale); + EXPECT_FALSE(host_impl()->active_tree()->property_trees()->needs_rebuild); + UpdateActiveTreeDrawProperties(kDeviceScale); expected_transform.MakeIdentity(); expected_transform.Translate( @@ -481,8 +403,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { sublayer->DrawTransform()); } -TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformsForSimpleHierarchy) { + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -500,13 +422,12 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { child->SetBounds(gfx::Size(16, 18)); grand_child->SetBounds(gfx::Size(76, 78)); - SetupRootProperties(root); CopyProperties(root, parent); CreateTransformNode(parent).origin = gfx::Point3F(2.5f, 3.0f, 0.f); CopyProperties(parent, child); CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( gfx::Transform(), @@ -525,7 +446,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { gfx::Transform parent_position_transform; parent_position_transform.Translate(0.f, 1.2f); SetPostTranslation(parent, gfx::Vector2dF(0.f, 1.2f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( parent_position_transform, draw_property_utils::DrawTransform(child, transform_tree, effect_tree)); @@ -549,7 +470,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { Inverse(parent_translation_to_anchor); SetTransform(parent, parent_layer_transform); SetPostTranslation(parent, gfx::Vector2dF()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( parent_composite_transform, draw_property_utils::DrawTransform(child, transform_tree, effect_tree)); @@ -565,8 +486,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { draw_property_utils::ScreenSpaceTransform(grand_child, transform_tree)); } -TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformsForSingleRenderSurface) { + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -594,7 +515,6 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { grand_child->SetBounds(gfx::Size(8, 10)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, parent); auto& parent_transform_node = CreateTransformNode(parent); parent_transform_node.origin = gfx::Point3F(2.5f, 30.f, 0.f); @@ -603,7 +523,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Render surface should have been created now. ASSERT_TRUE(GetRenderSurface(child)); @@ -629,7 +549,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { child->render_target()->screen_space_transform()); } -TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { +TEST_F(DrawPropertiesTest, TransformsForRenderSurfaceHierarchy) { // This test creates a more complex tree and verifies it all at once. This // covers the following cases: // - layers that are described w.r.t. a render surface: should have draw @@ -641,7 +561,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { // - verifying that each layer has a reference to the correct render surface // and render target values. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); parent->SetDrawsContent(true); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); @@ -706,7 +626,6 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { grand_child_of_rs1->SetBounds(gfx::Size(10, 10)); grand_child_of_rs2->SetBounds(gfx::Size(10, 10)); - SetupRootProperties(root); CopyProperties(root, parent); auto& parent_transform_node = CreateTransformNode(parent); parent_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); @@ -755,7 +674,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { grand_child_of_rs2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); grand_child_of_rs2_transform_node.local = layer_transform; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Only layers that are associated with render surfaces should have an actual // RenderSurface() value. @@ -868,83 +787,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { 5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3)); } -// Needs layer tree mode: testing PropertyTreeBuilder (forcing flattening on -// surface). -TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformsForFlatteningLayer) { - // For layers that flatten their subtree, there should be an orthographic - // projection (for x and y values) in the middle of the transform sequence. - // Note that the way the code is currently implemented, it is not expected to - // use a canonical orthographic projection. - - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - child->SetIsDrawable(true); - auto grand_child = Layer::Create(); - child->AddChild(grand_child); - grand_child->SetIsDrawable(true); - auto great_grand_child = Layer::Create(); - grand_child->AddChild(great_grand_child); - great_grand_child->SetIsDrawable(true); - - gfx::Transform rotation_about_y_axis; - rotation_about_y_axis.RotateAboutYAxis(30.0); - - root->SetBounds(gfx::Size(100, 100)); - child->SetTransform(rotation_about_y_axis); - child->SetBounds(gfx::Size(10, 10)); - child->SetForceRenderSurfaceForTesting(true); - grand_child->SetTransform(rotation_about_y_axis); - grand_child->SetBounds(gfx::Size(10, 10)); - great_grand_child->SetBounds(gfx::Size(10, 10)); - - // No layers in this test should preserve 3d. - ASSERT_TRUE(root->should_flatten_transform()); - ASSERT_TRUE(child->should_flatten_transform()); - ASSERT_TRUE(grand_child->should_flatten_transform()); - ASSERT_TRUE(great_grand_child->should_flatten_transform()); - - gfx::Transform expected_child_draw_transform = rotation_about_y_axis; - gfx::Transform expected_child_screen_space_transform = rotation_about_y_axis; - gfx::Transform expected_grand_child_draw_transform = - rotation_about_y_axis; // draws onto child's render surface - gfx::Transform flattened_rotation_about_y = rotation_about_y_axis; - flattened_rotation_about_y.FlattenTo2d(); - gfx::Transform expected_grand_child_screen_space_transform = - flattened_rotation_about_y * rotation_about_y_axis; - gfx::Transform expected_great_grand_child_draw_transform = - flattened_rotation_about_y; - gfx::Transform expected_great_grand_child_screen_space_transform = - flattened_rotation_about_y * flattened_rotation_about_y; - - CommitAndActivate(); - - // The child's draw transform should have been taken by its surface. - ASSERT_TRUE(GetRenderSurfaceImpl(child)); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_child_draw_transform, - GetRenderSurfaceImpl(child)->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_child_screen_space_transform, - GetRenderSurfaceImpl(child)->screen_space_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - ImplOf(child)->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_screen_space_transform, - ImplOf(child)->ScreenSpaceTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform, - ImplOf(grand_child)->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform, - ImplOf(grand_child)->ScreenSpaceTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_draw_transform, - ImplOf(great_grand_child)->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_great_grand_child_screen_space_transform, - ImplOf(great_grand_child)->ScreenSpaceTransform()); -} - -TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LayerFullyContainedWithinClipInTargetSpace) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -960,7 +804,6 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = child_transform; CopyProperties(child, grand_child); @@ -968,7 +811,7 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { grand_child_transform_node.flattens_inherited_transform = false; grand_child_transform_node.local = grand_child_transform; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Mapping grand_child's bounds to screen space produces an empty rect, but // only because it is turned sideways. The entire rect is contained inside @@ -980,7 +823,7 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { grand_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { +TEST_F(DrawPropertiesTest, TransformsForDegenerateIntermediateLayer) { // A layer that is empty in one axis, but not the other, was accidentally // skipping a necessary translation. Without that translation, the coordinate // space of the layer's draw transform is incorrect. @@ -990,7 +833,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { // implicitly inherited by the rest of the subtree, which then is positioned // incorrectly as a result. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); grand_child->SetDrawsContent(true); @@ -1001,12 +844,11 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { child->SetBounds(gfx::Size(10, 0)); grand_child->SetBounds(gfx::Size(10, 10)); - SetupRootProperties(root); CopyProperties(root, child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(child)); // This is the real test, the rest are sanity checks. @@ -1017,8 +859,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { grand_child->DrawTransform()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceWithSublayerScale) { + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -1032,7 +874,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateTransformNode(render_surface).local = translate; CreateEffectNode(render_surface).render_surface_reason = @@ -1044,7 +885,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { // render_surface will have a sublayer scale because of device scale factor. float device_scale_factor = 2.0f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // Between grand_child and render_surface, we translate by (10, 10) and scale // by a factor of 2. @@ -1053,10 +894,10 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { expected_translation); } -TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { +TEST_F(DrawPropertiesTest, TransformAboveRootLayer) { // Transformations applied at the root of the tree should be forwarded // to child layers instead of applied to the root RenderSurface. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetDrawsContent(true); @@ -1065,7 +906,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { child->SetBounds(gfx::Size(100, 100)); child->SetMasksToBounds(true); - SetupRootProperties(root); CopyProperties(root, child); CreateClipNode(child); @@ -1073,7 +913,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform translate; translate.Translate(50, 50); { - ExecuteCalculateDrawProperties(root, device_scale_factor, translate); + SetDeviceTransform(translate); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( translate, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1087,7 +928,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform scale; scale.Scale(2, 2); { - ExecuteCalculateDrawProperties(root, device_scale_factor, scale); + SetDeviceTransform(scale); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( scale, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1101,7 +943,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform rotate; rotate.Rotate(2); { - ExecuteCalculateDrawProperties(root, device_scale_factor, rotate); + SetDeviceTransform(rotate); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( rotate, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1117,7 +960,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { composite.ConcatTransform(scale); composite.ConcatTransform(rotate); { - ExecuteCalculateDrawProperties(root, device_scale_factor, composite); + SetDeviceTransform(composite); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( composite, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1132,7 +976,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { device_scale_factor = 1.5f; { - ExecuteCalculateDrawProperties(root, device_scale_factor, translate); + SetDeviceTransform(translate); + UpdateActiveTreeDrawProperties(device_scale_factor); gfx::Transform device_scaled_translate = translate; device_scaled_translate.Scale(device_scale_factor, device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1149,216 +994,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { } } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceForNonAxisAlignedClipping) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto rotated_and_transparent = Layer::Create(); - root->AddChild(rotated_and_transparent); - auto clips_subtree = Layer::Create(); - rotated_and_transparent->AddChild(clips_subtree); - auto draws_content = Layer::Create(); - clips_subtree->AddChild(draws_content); - - root->SetBounds(gfx::Size(10, 10)); - rotated_and_transparent->SetBounds(gfx::Size(10, 10)); - rotated_and_transparent->SetOpacity(0.5f); - gfx::Transform rotate; - rotate.Rotate(2); - rotated_and_transparent->SetTransform(rotate); - clips_subtree->SetBounds(gfx::Size(10, 10)); - clips_subtree->SetMasksToBounds(true); - draws_content->SetBounds(gfx::Size(10, 10)); - draws_content->SetIsDrawable(true); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_TRUE(GetEffectNode(clips_subtree.get())->HasRenderSurface()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - EffectNodesForNonAxisAlignedClips) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto rotate_and_clip = Layer::Create(); - root->AddChild(rotate_and_clip); - auto only_clip = Layer::Create(); - rotate_and_clip->AddChild(only_clip); - auto rotate_and_clip2 = Layer::Create(); - only_clip->AddChild(rotate_and_clip2); - - gfx::Transform rotate; - rotate.Rotate(2); - root->SetBounds(gfx::Size(10, 10)); - rotate_and_clip->SetBounds(gfx::Size(10, 10)); - rotate_and_clip->SetTransform(rotate); - rotate_and_clip->SetMasksToBounds(true); - only_clip->SetBounds(gfx::Size(10, 10)); - only_clip->SetMasksToBounds(true); - rotate_and_clip2->SetBounds(gfx::Size(10, 10)); - rotate_and_clip2->SetTransform(rotate); - rotate_and_clip2->SetMasksToBounds(true); - - ExecuteCalculateDrawProperties(root.get()); - // non-axis aligned clip should create an effect node - EXPECT_NE(root->effect_tree_index(), rotate_and_clip->effect_tree_index()); - // Since only_clip's clip is in the same non-axis aligned space as - // rotate_and_clip's clip, no new effect node should be created. - EXPECT_EQ(rotate_and_clip->effect_tree_index(), - only_clip->effect_tree_index()); - // rotate_and_clip2's clip and only_clip's clip are in different non-axis - // aligned spaces. So, new effect node should be created. - EXPECT_NE(rotate_and_clip2->effect_tree_index(), - only_clip->effect_tree_index()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceListForRenderSurfaceWithClippedLayer) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto render_surface1 = Layer::Create(); - root->AddChild(render_surface1); - auto child = Layer::Create(); - render_surface1->AddChild(child); - - root->SetBounds(gfx::Size(10, 10)); - root->SetMasksToBounds(true); - render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->SetForceRenderSurfaceForTesting(true); - child->SetIsDrawable(true); - child->SetPosition(gfx::PointF(30.f, 30.f)); - child->SetBounds(gfx::Size(10, 10)); - - CommitAndActivate(); - - // The child layer's content is entirely outside the root's clip rect, so - // the intermediate render surface should not be listed here, even if it was - // forced to be created. Render surfaces without children or visible content - // are unexpected at draw time (e.g. we might try to create a content texture - // of size 0). - ASSERT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(1U, render_surface_list_impl()->size()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceListForTransparentChild) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto render_surface1 = Layer::Create(); - root->AddChild(render_surface1); - auto child = Layer::Create(); - render_surface1->AddChild(child); - - root->SetBounds(gfx::Size(10, 10)); - render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->SetForceRenderSurfaceForTesting(true); - render_surface1->SetOpacity(0.f); - child->SetBounds(gfx::Size(10, 10)); - child->SetIsDrawable(true); - - CommitAndActivate(); - - // Since the layer is transparent, render_surface1_impl->GetRenderSurface() - // should not have gotten added anywhere. Also, the drawable content rect - // should not have been extended by the children. - ASSERT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(0, GetRenderSurfaceImpl(root)->num_contributors()); - EXPECT_EQ(1U, render_surface_list_impl()->size()); - EXPECT_EQ(static_cast<viz::RenderPassId>(root->id()), - render_surface_list_impl()->at(0)->id()); - EXPECT_EQ(gfx::Rect(), ImplOf(root)->drawable_content_rect()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceListForTransparentChildWithBackdropFilter) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto render_surface1 = Layer::Create(); - root->AddChild(render_surface1); - auto child = Layer::Create(); - render_surface1->AddChild(child); - - root->SetBounds(gfx::Size(10, 10)); - render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->SetForceRenderSurfaceForTesting(true); - render_surface1->SetOpacity(0.f); - render_surface1->SetIsDrawable(true); - FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(1.5f)); - render_surface1->SetBackdropFilters(filters); - child->SetBounds(gfx::Size(10, 10)); - child->SetIsDrawable(true); - host()->SetElementIdsForTesting(); - - CommitAndActivate(); - EXPECT_EQ(2U, render_surface_list_impl()->size()); - - // The layer is fully transparent, but has a backdrop filter, so it - // shouldn't be skipped and should be drawn. - ASSERT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors()); - EXPECT_EQ(gfx::RectF(0, 0, 10, 10), - GetRenderSurfaceImpl(root)->DrawableContentRect()); - EXPECT_TRUE(GetEffectNode(ImplOf(render_surface1))->is_drawn); - - // When root is transparent, the layer should not be drawn. - host_impl()->active_tree()->SetOpacityMutated(root->element_id(), 0.f); - host_impl()->active_tree()->SetOpacityMutated(render_surface1->element_id(), - 1.f); - ImplOf(render_surface1)->set_visible_layer_rect(gfx::Rect()); - ExecuteCalculateDrawProperties(ImplOf(root)); - - EXPECT_FALSE(GetEffectNode(ImplOf(render_surface1))->is_drawn); - EXPECT_EQ(gfx::Rect(), ImplOf(render_surface1)->visible_layer_rect()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceListForFilter) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto parent = Layer::Create(); - root->AddChild(parent); - auto child1 = Layer::Create(); - parent->AddChild(child1); - auto child2 = Layer::Create(); - parent->AddChild(child2); - - gfx::Transform scale_matrix; - scale_matrix.Scale(2.0f, 2.0f); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetTransform(scale_matrix); - FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(10.0f)); - parent->SetFilters(filters); - parent->SetForceRenderSurfaceForTesting(true); - child1->SetBounds(gfx::Size(25, 25)); - child1->SetIsDrawable(true); - child1->SetForceRenderSurfaceForTesting(true); - child2->SetPosition(gfx::PointF(25, 25)); - child2->SetBounds(gfx::Size(25, 25)); - child2->SetIsDrawable(true); - child2->SetForceRenderSurfaceForTesting(true); - - CommitAndActivate(); - - ASSERT_TRUE(GetRenderSurfaceImpl(parent)); - EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); - EXPECT_EQ(4U, render_surface_list_impl()->size()); - - // The rectangle enclosing child1 and child2 (0,0 50x50), expanded for the - // blur (-30,-30 110x110), and then scaled by the scale matrix - // (-60,-60 220x220). - EXPECT_EQ(gfx::RectF(-60, -60, 220, 220), - GetRenderSurfaceImpl(parent)->DrawableContentRect()); -} - -TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, DrawableContentRectForReferenceFilter) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); @@ -1368,13 +1005,12 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { filters.Append(FilterOperation::CreateReferenceFilter( sk_make_sp<OffsetPaintFilter>(50, 50, nullptr))); - SetupRootProperties(root); CopyProperties(root, child); auto& child_effect_node = CreateEffectNode(child); child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; child_effect_node.filters = filters; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // The render surface's size should be unaffected by the offset image filter; // it need only have a drawable content rect large enough to contain the @@ -1384,10 +1020,10 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { GetRenderSurface(child)->DrawableContentRect()); } -TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { +TEST_F(DrawPropertiesTest, DrawableContentRectForReferenceFilterHighDpi) { const float device_scale_factor = 2.0f; - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); @@ -1398,13 +1034,12 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { filters.Append(FilterOperation::CreateReferenceFilter( sk_make_sp<OffsetPaintFilter>(50, 50, nullptr))); - SetupRootProperties(root); CopyProperties(root, child); auto& child_effect_node = CreateEffectNode(child); child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; child_effect_node.filters = filters; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // The render surface's size should be unaffected by the offset image filter; // it need only have a drawable content rect large enough to contain the @@ -1415,22 +1050,21 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { GetRenderSurface(child)->DrawableContentRect()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceForBlendMode) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(10, 10)); child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); auto& child_effect_node = CreateEffectNode(child); child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; child_effect_node.blend_mode = SkBlendMode::kMultiply; child_effect_node.opacity = 0.5f; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Since the child layer has a blend mode other than normal, it should get // its own render surface. @@ -1440,8 +1074,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { EXPECT_EQ(SkBlendMode::kMultiply, GetRenderSurface(child)->BlendMode()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceDrawOpacity) { + LayerImpl* root = root_layer(); LayerImpl* surface1 = AddLayer<LayerImpl>(); LayerImpl* not_surface = AddLayer<LayerImpl>(); LayerImpl* surface2 = AddLayer<LayerImpl>(); @@ -1453,7 +1087,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { surface2->SetBounds(gfx::Size(10, 10)); surface2->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, surface1); auto& surface1_effect_node = CreateEffectNode(surface1); surface1_effect_node.render_surface_reason = RenderSurfaceReason::kTest; @@ -1465,7 +1098,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { surface2_effect_node.render_surface_reason = RenderSurfaceReason::kTest; surface2_effect_node.opacity = 0.5f; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(surface1)); ASSERT_EQ(GetRenderSurface(not_surface), GetRenderSurface(surface1)); @@ -1476,88 +1109,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { EXPECT_EQ(0.25f, GetRenderSurface(surface2)->draw_opacity()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, ForceRenderSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto render_surface1 = Layer::Create(); - root->AddChild(render_surface1); - auto child = Layer::Create(); - render_surface1->AddChild(child); - - root->SetBounds(gfx::Size(10, 10)); - render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->SetForceRenderSurfaceForTesting(true); - child->SetBounds(gfx::Size(10, 10)); - child->SetIsDrawable(true); - - CommitAndActivate(); - - // The root layer always creates a render surface - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); - - render_surface1->SetForceRenderSurfaceForTesting(false); - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); -} - -// Needs layer tree mode: testing PropertyTreeBuilder (force flattening on -// surface). -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfacesFlattenScreenSpaceTransform) { - // Render surfaces act as a flattening point for their subtree, so should - // always flatten the target-to-screen space transform seen by descendants. - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto parent = Layer::Create(); - root->AddChild(parent); - auto child = Layer::Create(); - parent->AddChild(child); - auto grand_child = Layer::Create(); - child->AddChild(grand_child); - - gfx::Transform rotation_about_y_axis; - rotation_about_y_axis.RotateAboutYAxis(30.0); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetTransform(rotation_about_y_axis); - parent->SetBounds(gfx::Size(10, 10)); - parent->SetForceRenderSurfaceForTesting(true); - child->SetBounds(gfx::Size(10, 10)); - child->SetIsDrawable(true); - grand_child->SetBounds(gfx::Size(10, 10)); - grand_child->SetIsDrawable(true); - grand_child->SetShouldFlattenTransform(false); - - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(parent)); - EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(parent)); - EXPECT_EQ(GetRenderSurfaceImpl(grand_child), GetRenderSurfaceImpl(parent)); - - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - ImplOf(child)->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - ImplOf(grand_child)->DrawTransform()); - - // The screen-space transform inherited by |child| and |grand_child| - // should have been flattened at their render target. In particular, the fact - // that |grand_child| happens to preserve 3d shouldn't affect this - // flattening. - gfx::Transform flattened_rotation_about_y = rotation_about_y_axis; - flattened_rotation_about_y.FlattenTo2d(); - EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_y, - ImplOf(child)->ScreenSpaceTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_y, - ImplOf(grand_child)->ScreenSpaceTransform()); -} - -TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { +TEST_F(DrawPropertiesTest, ClipRectCullsRenderSurfaces) { // The entire subtree of layers that are outside the clip rect should be - // culled away, and should not affect the render_surface_list. + // culled away, and should not affect the GetRenderSurfaceList. // // The test tree is set up as follows: // - all layers except the leaf_nodes are forced to be a new render surface @@ -1571,13 +1125,14 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { // outside the clip rect, and they should never get scheduled on the list of // render surfaces. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); LayerImpl* great_grand_child = AddLayer<LayerImpl>(); - // leaf_node1 ensures that root and child are kept on the render_surface_list, - // even though grand_child and great_grand_child should be clipped. + // leaf_node1 ensures that root and child are kept on the + // GetRenderSurfaceList, even though grand_child and great_grand_child should + // be clipped. LayerImpl* leaf_node1 = AddLayer<LayerImpl>(); LayerImpl* leaf_node2 = AddLayer<LayerImpl>(); @@ -1591,7 +1146,6 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { leaf_node1->SetBounds(gfx::Size(20, 20)); leaf_node2->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateClipNode(child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; @@ -1605,16 +1159,16 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { leaf_node2->SetOffsetToTransformParent( great_grand_child->offset_to_transform_parent()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - ASSERT_EQ(2U, render_surface_list_impl()->size()); + ASSERT_EQ(2U, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); EXPECT_EQ(static_cast<uint64_t>(child->id()), - render_surface_list_impl()->at(1)->id()); + GetRenderSurfaceList().at(1)->id()); } -TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { +TEST_F(DrawPropertiesTest, ClipRectCullsSurfaceWithoutVisibleContent) { // When a render surface has a clip rect, it is used to clip the content rect // of the surface. @@ -1627,9 +1181,9 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { // In this configuration, grand_child should be outside the clipped // content rect of the child, making grand_child not appear in the - // render_surface_list. + // GetRenderSurfaceList. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); LayerImpl* leaf_node = AddLayer<LayerImpl>(); @@ -1641,7 +1195,6 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { leaf_node->SetBounds(gfx::Size(10, 10)); leaf_node->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; @@ -1653,15 +1206,15 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { leaf_node->SetOffsetToTransformParent( grand_child->offset_to_transform_parent()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - // We should cull child and grand_child from the render_surface_list. - ASSERT_EQ(1U, render_surface_list_impl()->size()); + // We should cull child and grand_child from the GetRenderSurfaceList. + ASSERT_EQ(1U, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); } -TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { +TEST_F(DrawPropertiesTest, IsClippedIsSetCorrectlyLayerImpl) { // Tests that LayerImpl's IsClipped() property is set to true when: // - the layer clips its subtree, e.g. masks to bounds, // - the layer is clipped by an ancestor that contributes to the same @@ -1675,7 +1228,7 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { // - but if the layer itself masks to bounds, it is considered clipped // and propagates the clip to the subtree. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); @@ -1697,7 +1250,6 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { leaf_node2->SetBounds(gfx::Size(100, 100)); leaf_node2->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, parent); CopyProperties(parent, child1); CopyProperties(child1, grand_child); @@ -1708,7 +1260,7 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { CopyProperties(child2, leaf_node2); // Case 1: nothing is clipped except the root render surface. - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(root)); ASSERT_TRUE(GetRenderSurface(child2)); @@ -1736,7 +1288,8 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { GetEffectNode(child2)->clip_id = parent->clip_tree_index(); leaf_node2->SetClipTreeIndex(parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + host_impl()->active_tree()->set_needs_update_draw_properties(); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(root)); ASSERT_TRUE(GetRenderSurface(child2)); @@ -1766,7 +1319,8 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { CreateClipNode(child2); leaf_node2->SetClipTreeIndex(child2->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + host_impl()->active_tree()->set_needs_update_draw_properties(); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(root)); ASSERT_TRUE(GetRenderSurface(child2)); @@ -1782,10 +1336,10 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { EXPECT_TRUE(leaf_node2->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { +TEST_F(DrawPropertiesTest, UpdateClipRectCorrectly) { // Tests that when as long as layer is clipped, it's clip rect is set to // correct value. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); @@ -1797,12 +1351,11 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { child->SetDrawsContent(true); child->SetMasksToBounds(true); - SetupRootProperties(root); CopyProperties(root, parent); CopyProperties(parent, child); CreateClipNode(child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(root->is_clipped()); EXPECT_FALSE(parent->is_clipped()); @@ -1815,7 +1368,8 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { child->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); GetClipNode(child)->clip += gfx::Vector2dF(100.f, 100.f); - ExecuteCalculateDrawProperties(root); + host_impl()->active_tree()->set_needs_update_draw_properties(); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(root->is_clipped()); EXPECT_TRUE(parent->is_clipped()); @@ -1823,7 +1377,7 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { EXPECT_EQ(gfx::Rect(), child->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { +TEST_F(DrawPropertiesTest, DrawableContentRectForLayers) { // Verify that layers get the appropriate DrawableContentRect when their // parent MasksToBounds is true. // @@ -1837,7 +1391,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { // grand_child4 - outside parent's clip rect; the DrawableContentRect should // be empty. - LayerImpl* parent = root_layer_for_testing(); + LayerImpl* parent = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child1 = AddLayer<LayerImpl>(); LayerImpl* grand_child2 = AddLayer<LayerImpl>(); @@ -1857,7 +1411,6 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { grand_child4->SetBounds(gfx::Size(10, 10)); grand_child4->SetDrawsContent(true); - SetupRootProperties(parent); CopyProperties(parent, child); CreateTransformNode(child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; @@ -1872,7 +1425,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { CopyProperties(child, grand_child4); grand_child4->SetOffsetToTransformParent(gfx::Vector2dF(45.f, 45.f)); - ExecuteCalculateDrawProperties(parent); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(5, 5, 10, 10), grand_child1->drawable_content_rect()); EXPECT_EQ(gfx::Rect(15, 15, 5, 5), grand_child3->drawable_content_rect()); @@ -1880,7 +1433,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { EXPECT_TRUE(grand_child4->drawable_content_rect().IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { +TEST_F(DrawPropertiesTest, ClipRectIsPropagatedCorrectlyToSurfaces) { // Verify that render surfaces (and their layers) get the appropriate // clip rects when their parent MasksToBounds is true. // @@ -1888,7 +1441,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { // clipping; instead the surface will enforce the clip for the entire subtree. // They may still have a clip rect of their own layer bounds, however, if // MasksToBounds was true. - LayerImpl* parent = root_layer_for_testing(); + LayerImpl* parent = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child1 = AddLayer<LayerImpl>(); LayerImpl* grand_child2 = AddLayer<LayerImpl>(); @@ -1919,7 +1472,6 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { leaf_node4->SetBounds(gfx::Size(10, 10)); leaf_node4->SetDrawsContent(true); - SetupRootProperties(parent); CopyProperties(parent, child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; CreateClipNode(child); @@ -1949,7 +1501,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { CreateClipNode(grand_child4); CopyProperties(grand_child4, leaf_node4); - ExecuteCalculateDrawProperties(parent); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(grand_child1)); ASSERT_TRUE(GetRenderSurface(grand_child2)); @@ -1965,8 +1517,8 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { GetRenderSurface(grand_child3)->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, AnimationsForRenderSurfaceHierarchy) { + LayerImpl* root = root_layer(); LayerImpl* top = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* child_of_rs1 = AddLayer<LayerImpl>(); @@ -2002,7 +1554,6 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { grand_child_of_rs1->SetBounds(gfx::Size(10, 10)); grand_child_of_rs2->SetBounds(gfx::Size(10, 10)); - SetupRootProperties(root); CopyProperties(root, top); CreateTransformNode(top).local = layer_transform; CopyProperties(top, render_surface1); @@ -2075,7 +1626,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { AddAnimatedTransformToElementWithAnimation(grand_child_of_rs2->element_id(), timeline_impl(), 10.0, 30, 0); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Only layers that are associated with render surfaces should have an actual // RenderSurface() value. @@ -2146,8 +1697,8 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { 5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3)); } -TEST_F(LayerTreeHostCommonTest, LargeTransforms) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LargeTransforms) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -2159,13 +1710,12 @@ TEST_F(LayerTreeHostCommonTest, LargeTransforms) { grand_child->SetBounds(gfx::Size(10, 10)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = large_transform; CopyProperties(child, grand_child); CreateTransformNode(grand_child).local = large_transform; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect()); } @@ -2182,9 +1732,9 @@ static bool HasPotentiallyRunningTransformAnimation(LayerImpl* layer) { layer->element_id(), layer->GetElementTypeForAnimation()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, ScreenSpaceTransformIsAnimatingWithDelayedAnimation) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); LayerImpl* great_grand_child = AddLayer<LayerImpl>(); @@ -2201,7 +1751,6 @@ TEST_F(LayerTreeHostCommonTest, SetElementIdsForTesting(); - SetupRootProperties(root); CopyProperties(root, child); CopyProperties(child, grand_child); CreateTransformNode(grand_child); // for animation. @@ -2216,7 +1765,7 @@ TEST_F(LayerTreeHostCommonTest, AddKeyframeModelToElementWithAnimation( grand_child->element_id(), timeline_impl(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(root->screen_space_transform_is_animating()); EXPECT_FALSE(child->screen_space_transform_is_animating()); @@ -2229,7 +1778,7 @@ TEST_F(LayerTreeHostCommonTest, // Test visible layer rect and drawable content rect are calculated correctly // for identity transforms. -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForIdentityTransform) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsForIdentityTransform) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Transform layer_to_surface_transform; @@ -2266,7 +1815,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForIdentityTransform) { // Test visible layer rect and drawable content rect are calculated correctly // for rotations about z-axis (i.e. 2D rotations). -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor2DRotations) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor2DRotations) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30); gfx::Transform layer_to_surface_transform; @@ -2330,7 +1879,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor2DRotations) { // Test visible layer rect and drawable content rect are calculated correctly // for 3d transforms. -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dOrthographicTransform) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dOrthographicTransform) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); gfx::Transform layer_to_surface_transform; @@ -2370,7 +1919,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dOrthographicTransform) { // Test visible layer rect and drawable content rect are calculated correctly // when the layer has a perspective projection onto the target surface. -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200); gfx::Transform layer_to_surface_transform; @@ -2424,7 +1973,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { // in our code (nor in the CSS spec to my knowledge). Therefore, layers that // are technically behind the surface in an orthographic world should not be // clipped when they are flattened to the surface. -TEST_F(LayerTreeHostCommonDrawRectsTest, +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dOrthographicIsNotClippedBehindSurface) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); @@ -2456,8 +2005,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, // coordinates before converting to cartesian coordinates. The drawable // content rect would be entire surface rect because layer is rotated at the // camera position. -TEST_F(LayerTreeHostCommonDrawRectsTest, - DrawRectsFor3dPerspectiveWhenClippedByW) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dPerspectiveWhenClippedByW) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 200, 200); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 2); gfx::Transform layer_to_surface_transform; @@ -2508,7 +2056,7 @@ static bool ProjectionClips(const gfx::Transform& map_transform, // transform was a perspective projection that was clipped, it returns a rect // that encloses the clipped bounds. Un-projecting this new rect may require // clipping again. -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsForPerspectiveUnprojection) { // This sequence of transforms causes one corner of the layer to protrude // across the w = 0 plane, and should be clipped. gfx::Rect target_surface_rect = gfx::Rect(0, 0, 150, 150); @@ -2540,8 +2088,8 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) { drawing_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForSimpleLayers) { + LayerImpl* root = root_layer(); LayerImpl* child1_layer = AddLayer<LayerImpl>(); LayerImpl* child2_layer = AddLayer<LayerImpl>(); LayerImpl* child3_layer = AddLayer<LayerImpl>(); @@ -2554,14 +2102,13 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { child3_layer->SetBounds(gfx::Size(50, 50)); child3_layer->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child1_layer); CopyProperties(root, child2_layer); child2_layer->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); CopyProperties(root, child3_layer); child3_layer->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::RectF(100.f, 100.f), GetRenderSurface(root)->DrawableContentRect()); @@ -2580,9 +2127,9 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForLayersClippedByLayer) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child1 = AddLayer<LayerImpl>(); LayerImpl* grand_child2 = AddLayer<LayerImpl>(); @@ -2598,7 +2145,6 @@ TEST_F(LayerTreeHostCommonTest, grand_child3->SetBounds(gfx::Size(50, 50)); grand_child3->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateClipNode(child); CopyProperties(child, grand_child1); @@ -2608,7 +2154,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(child, grand_child3); grand_child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::RectF(100.f, 100.f), GetRenderSurface(root)->DrawableContentRect()); @@ -2628,8 +2174,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_TRUE(grand_child3->drawable_content_rect().IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleContentRectWithClippingAndScaling) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -2644,147 +2190,25 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) { grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = child_scale_matrix; CreateClipNode(child); CopyProperties(child, grand_child); CreateTransformNode(grand_child).local = grand_child_scale_matrix; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // The visible rect is expanded to integer coordinates. EXPECT_EQ(gfx::Rect(41, 41), grand_child->visible_layer_rect()); } -// Needs layer tree mode: testing PropertyTreeBuilder (creating expanding clip -// node for pixel-moving filter). -TEST_F(LayerTreeHostCommonTestWithLayerTree, - VisibleRectWithClippingAndFilters) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto clip = Layer::Create(); - root->AddChild(clip); - auto filter = Layer::Create(); - clip->AddChild(filter); - auto filter_child = Layer::Create(); - filter->AddChild(filter_child); - - root->SetBounds(gfx::Size(100, 100)); - clip->SetBounds(gfx::Size(10, 10)); - filter->SetForceRenderSurfaceForTesting(true); - filter_child->SetBounds(gfx::Size(2000, 2000)); - filter_child->SetPosition(gfx::PointF(-50, -50)); - filter_child->SetIsDrawable(true); - - clip->SetMasksToBounds(true); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(50, 50, 10, 10), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurfaceImpl(filter)->content_rect()); - - FilterOperations blur_filter; - blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); - filter->SetFilters(blur_filter); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(38, 38, 34, 34), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(-12, -12, 34, 34), - GetRenderSurfaceImpl(filter)->content_rect()); - - gfx::Transform vertical_flip; - vertical_flip.Scale(1, -1); - sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>( - vertical_flip.matrix(), kLow_SkFilterQuality, nullptr); - FilterOperations reflection_filter; - reflection_filter.Append( - FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( - SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); - filter->SetFilters(reflection_filter); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(49, 39, 12, 21), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(-1, -11, 12, 21), - GetRenderSurfaceImpl(filter)->content_rect()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder (creating expanding clip -// node for pixel-moving filter). -TEST_F(LayerTreeHostCommonTestWithLayerTree, - VisibleRectWithScalingClippingAndFilters) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto scale = Layer::Create(); - root->AddChild(scale); - auto clip = Layer::Create(); - scale->AddChild(clip); - auto filter = Layer::Create(); - clip->AddChild(filter); - auto filter_child = Layer::Create(); - filter->AddChild(filter_child); - - root->SetBounds(gfx::Size(100, 100)); - clip->SetBounds(gfx::Size(10, 10)); - filter->SetForceRenderSurfaceForTesting(true); - filter_child->SetBounds(gfx::Size(2000, 2000)); - filter_child->SetPosition(gfx::PointF(-50, -50)); - filter_child->SetIsDrawable(true); - - clip->SetMasksToBounds(true); - - gfx::Transform scale_transform; - scale_transform.Scale(3, 3); - scale->SetTransform(scale_transform); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(50, 50, 10, 10), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(30, 30), GetRenderSurfaceImpl(filter)->content_rect()); - - FilterOperations blur_filter; - blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); - filter->SetFilters(blur_filter); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(38, 38, 34, 34), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(-36, -36, 102, 102), - GetRenderSurfaceImpl(filter)->content_rect()); - - gfx::Transform vertical_flip; - vertical_flip.Scale(1, -1); - sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>( - vertical_flip.matrix(), kLow_SkFilterQuality, nullptr); - FilterOperations reflection_filter; - reflection_filter.Append( - FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( - SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); - filter->SetFilters(reflection_filter); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(49, 39, 12, 21), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(-1, -31, 32, 61), - GetRenderSurfaceImpl(filter)->content_rect()); -} - -TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParent) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipRectWithClipParent) { + LayerImpl* root = root_layer(); LayerImpl* clip = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - SetupRootProperties(root); CreateClipNode(root); clip->SetBounds(gfx::Size(10, 10)); @@ -2800,7 +2224,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParent) { child2->SetDrawsContent(true); CopyProperties(clip, child2); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(child1->is_clipped()); EXPECT_TRUE(child2->is_clipped()); @@ -2808,8 +2232,8 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParent) { EXPECT_EQ(gfx::Rect(10, 10), child2->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipRectWithClippedDescendantOfFilter) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipRectWithClippedDescendantOfFilter) { + LayerImpl* root = root_layer(); LayerImpl* filter = AddLayer<LayerImpl>(); LayerImpl* clip = AddLayer<LayerImpl>(); LayerImpl* filter_grand_child = AddLayer<LayerImpl>(); @@ -2820,14 +2244,13 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClippedDescendantOfFilter) { filter_grand_child->SetBounds(gfx::Size(20, 20)); filter_grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, filter); CreateEffectNode(filter).render_surface_reason = RenderSurfaceReason::kTest; CopyProperties(filter, clip); CreateClipNode(clip); CopyProperties(clip, filter_grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(filter_grand_child->is_clipped()); EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect()); @@ -2835,15 +2258,15 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClippedDescendantOfFilter) { blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); SetFilter(filter, blur_filter); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(filter_grand_child->is_clipped()); EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); @@ -2858,7 +2281,6 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -2869,7 +2291,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface, child3); child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -2896,9 +2318,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, - VisibleContentRectsForClippedSurfaceWithEmptyClip) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleContentRectsForClippedSurfaceWithEmptyClip) { + LayerImpl* root = root_layer(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); LayerImpl* child3 = AddLayer<LayerImpl>(); @@ -2911,7 +2332,6 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child1); child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); CopyProperties(root, child2); @@ -2919,12 +2339,12 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(root, child3); child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - RenderSurfaceList render_surface_list_impl; // Now set the root render surface an empty clip. - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Rect(), &render_surface_list_impl); + // Not using UpdateActiveTreeDrawProperties() because we want a special + // device viewport rect. + host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect()); + UpdateDrawProperties(host_impl()->active_tree()); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); ASSERT_TRUE(GetRenderSurface(root)); EXPECT_FALSE(root->is_clipped()); @@ -2940,9 +2360,9 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(empty, child3->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); @@ -2953,11 +2373,10 @@ TEST_F(LayerTreeHostCommonTest, gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); ASSERT_FALSE(uninvertible_matrix.IsInvertible()); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = uninvertible_matrix; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); EXPECT_TRUE(child->drawable_content_rect().IsEmpty()); @@ -2969,7 +2388,7 @@ TEST_F(LayerTreeHostCommonTest, ASSERT_FALSE(uninvertible_matrix.IsInvertible()); SetTransform(child, uninvertible_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); EXPECT_TRUE(child->drawable_content_rect().IsEmpty()); @@ -2981,15 +2400,15 @@ TEST_F(LayerTreeHostCommonTest, ASSERT_FALSE(uninvertible_matrix.IsInvertible()); SetTransform(child, uninvertible_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); EXPECT_TRUE(child->drawable_content_rect().IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, VisibleContentRectForLayerWithUninvertibleDrawTransform) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -3005,7 +2424,6 @@ TEST_F(LayerTreeHostCommonTest, grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); auto& child_transform_node = CreateTransformNode(child); child_transform_node.flattens_inherited_transform = false; @@ -3018,7 +2436,7 @@ TEST_F(LayerTreeHostCommonTest, grand_child_transform_node.sorting_context_id = 1; grand_child_transform_node.local = rotation; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Though all layers have invertible transforms, matrix multiplication using // floating-point math makes the draw transform uninvertible. @@ -3030,7 +2448,7 @@ TEST_F(LayerTreeHostCommonTest, } // Needs layer tree mode: mask layer. -TEST_F(LayerTreeHostCommonTestWithLayerTree, OcclusionBySiblingOfTarget) { +TEST_F(DrawPropertiesTestWithLayerTree, OcclusionBySiblingOfTarget) { auto root = Layer::Create(); auto child = Layer::Create(); FakeContentLayerClient client; @@ -3069,7 +2487,6 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, OcclusionBySiblingOfTarget) { host()->SetRootLayer(root); CommitAndActivate(); - host_impl()->active_tree()->UpdateDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( GetRenderSurfaceImpl(surface)->draw_transform(), translate); @@ -3077,46 +2494,22 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, OcclusionBySiblingOfTarget) { // surface_child's contents. Occlusion actual_occlusion = GetRenderSurfaceImpl(surface_child)->occlusion_in_content_space(); - Occlusion expected_occlusion(translate, SimpleEnclosedRegion(gfx::Rect()), + Occlusion expected_occlusion(translate, SimpleEnclosedRegion(), SimpleEnclosedRegion(gfx::Rect(200, 200))); EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); - // Mask layer should have the same occlusion. + // Mask layer's occlusion is different because we create transform and render + // surface for it in layer tree mode. actual_occlusion = ImplOf(surface_child_mask)->draw_properties().occlusion_in_content_space; + expected_occlusion = Occlusion( + gfx::Transform(), SimpleEnclosedRegion(gfx::Rect(-20, -20, 200, 200)), + SimpleEnclosedRegion()); EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); } -// Needs layer tree mode: testing PropertyTreeBuilder (snapping transform for -// texture layer). -TEST_F(LayerTreeHostCommonTestWithLayerTree, TextureLayerSnapping) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = TextureLayer::CreateForMailbox(nullptr); - root->AddChild(child); - - root->SetBounds(gfx::Size(100, 100)); - child->SetBounds(gfx::Size(100, 100)); - child->SetIsDrawable(true); - gfx::Transform fractional_translate; - fractional_translate.Translate(10.5f, 20.3f); - child->SetTransform(fractional_translate); - - CommitAndActivate(); - - auto child_screen_space_transform = ImplOf(child)->ScreenSpaceTransform(); - EXPECT_NE(child_screen_space_transform, fractional_translate); - fractional_translate.RoundTranslationComponents(); - EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform, - fractional_translate); - gfx::RectF layer_bounds_in_screen_space = MathUtil::MapClippedRect( - child_screen_space_transform, gfx::RectF(gfx::SizeF(child->bounds()))); - EXPECT_EQ(layer_bounds_in_screen_space, gfx::RectF(11.f, 20.f, 100.f, 100.f)); -} - -TEST_F(LayerTreeHostCommonTest, - OcclusionForLayerWithUninvertibleDrawTransform) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, OcclusionForLayerWithUninvertibleDrawTransform) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); LayerImpl* occluding_child = AddLayer<LayerImpl>(); @@ -3137,7 +2530,6 @@ TEST_F(LayerTreeHostCommonTest, occluding_child->SetDrawsContent(true); occluding_child->SetContentsOpaque(true); - SetupRootProperties(root); CopyProperties(root, child); auto& child_transform_node = CreateTransformNode(child); child_transform_node.flattens_inherited_transform = false; @@ -3152,7 +2544,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(root, occluding_child); CreateTransformNode(occluding_child).flattens_inherited_transform = false; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Though all layers have invertible transforms, matrix multiplication using // floating-point math makes the draw transform uninvertible. @@ -3168,9 +2560,9 @@ TEST_F(LayerTreeHostCommonTest, .occlusion_in_content_space.GetUnoccludedContentRect(layer_bounds)); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); @@ -3186,7 +2578,6 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = @@ -3198,7 +2589,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface, child3); child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -3227,9 +2618,8 @@ TEST_F(LayerTreeHostCommonTest, } // Check that clipping does not propagate down surfaces. -TEST_F(LayerTreeHostCommonTest, - DrawableAndVisibleContentRectsForSurfaceHierarchy) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForSurfaceHierarchy) { + LayerImpl* root = root_layer(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* render_surface2 = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); @@ -3247,7 +2637,6 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface1); CreateEffectNode(render_surface1).render_surface_reason = @@ -3262,7 +2651,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface2, child3); child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface1)); ASSERT_TRUE(GetRenderSurface(render_surface2)); @@ -3298,9 +2687,9 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, VisibleRectsForClippedDescendantsOfUnclippedSurfaces) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); @@ -3318,7 +2707,6 @@ TEST_F(LayerTreeHostCommonTest, child1->SetMasksToBounds(true); child2->SetMasksToBounds(true); - SetupRootProperties(root); CopyProperties(root, render_surface1); CreateEffectNode(render_surface1).render_surface_reason = RenderSurfaceReason::kTest; @@ -3330,14 +2718,14 @@ TEST_F(LayerTreeHostCommonTest, CreateEffectNode(render_surface2).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(100, 100), child1->visible_layer_rect()); EXPECT_EQ(gfx::Rect(100, 100), render_surface2->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, VisibleRectsWhenClipChildIsBetweenTwoRenderSurfaces) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -3346,7 +2734,6 @@ TEST_F(LayerTreeHostCommonTest, root->SetBounds(gfx::Size(100, 100)); clip_parent->SetBounds(gfx::Size(50, 50)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); @@ -3368,14 +2755,14 @@ TEST_F(LayerTreeHostCommonTest, CreateEffectNode(render_surface2).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(20, 20), render_surface1->visible_layer_rect()); EXPECT_EQ(gfx::Rect(50, 50), clip_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(50, 50), render_surface2->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); @@ -3386,7 +2773,6 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { clip_parent->SetBounds(gfx::Size(50, 50)); clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(2, 2)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); @@ -3416,18 +2802,19 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { RenderSurfaceReason::kTest; float device_scale_factor = 1.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(render_surface2)->clip_rect()); device_scale_factor = 2.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); + EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(render_surface2)->clip_rect()); } // Test that only drawn layers contribute to render surface content rect. -TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceContentRectWhenLayerNotDrawn) { + LayerImpl* root = root_layer(); LayerImpl* surface = AddLayer<LayerImpl>(); LayerImpl* test_layer = AddLayer<LayerImpl>(); @@ -3436,16 +2823,15 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { surface->SetDrawsContent(true); test_layer->SetBounds(gfx::Size(150, 150)); - SetupRootProperties(root); CopyProperties(root, surface); CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; CopyProperties(surface, test_layer); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(surface)->content_rect()); test_layer->SetDrawsContent(true); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(150, 150), GetRenderSurface(surface)->content_rect()); } @@ -3453,8 +2839,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { // surface_with_unclipped_descendants->clipped_surface, checks that the bounds // of surface_with_unclipped_descendants doesn't propagate to the // clipped_surface below it. -TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleRectsMultipleSurfaces) { + LayerImpl* root = root_layer(); LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); @@ -3472,7 +2858,6 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { clipped_surface->SetBounds(gfx::Size(60, 60)); clipped_surface->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, unclipped_surface); CreateEffectNode(unclipped_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -3486,7 +2871,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { CreateEffectNode(clipped_surface).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), unclipped_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(20, 20), unclipped_desc_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(50, 50), clipped_surface->visible_layer_rect()); @@ -3495,8 +2880,8 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { // Tests visible rects computation when we have unclipped_surface-> // surface_with_unclipped_descendants->clipped_surface, checks that the bounds // of root propagate to the clipped_surface. -TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RootClipPropagationToClippedSurface) { + LayerImpl* root = root_layer(); LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); @@ -3512,9 +2897,7 @@ TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { clip_child->SetBounds(gfx::Size(100, 100)); clipped_surface->SetBounds(gfx::Size(50, 50)); clipped_surface->SetDrawsContent(true); - clipped_surface->test_properties()->force_render_surface = true; - SetupRootProperties(root); CopyProperties(root, unclipped_surface); CreateEffectNode(unclipped_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -3530,7 +2913,7 @@ TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { CreateEffectNode(clipped_surface).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(10, 10), unclipped_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(10, 10), unclipped_desc_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(10, 10), clipped_surface->visible_layer_rect()); @@ -3538,9 +2921,9 @@ TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { // Layers that have non-axis aligned bounds (due to transforms) have an // expanded, axis-aligned DrawableContentRect and visible content rect. -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); @@ -3552,7 +2935,6 @@ TEST_F(LayerTreeHostCommonTest, child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -3562,7 +2944,7 @@ TEST_F(LayerTreeHostCommonTest, child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f); child1_transform_node.local = child_rotation; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -3577,9 +2959,7 @@ TEST_F(LayerTreeHostCommonTest, // regions of the subtree. int diagonal_radius = ceil(sqrt(2.0) * 25.0); gfx::Rect expected_surface_drawable_content = - gfx::Rect(50 - diagonal_radius, - 50 - diagonal_radius, - diagonal_radius * 2, + gfx::Rect(50 - diagonal_radius, 50 - diagonal_radius, diagonal_radius * 2, diagonal_radius * 2); EXPECT_EQ(gfx::RectF(expected_surface_drawable_content), GetRenderSurface(render_surface)->DrawableContentRect()); @@ -3591,9 +2971,9 @@ TEST_F(LayerTreeHostCommonTest, // Layers that have non-axis aligned bounds (due to transforms) have an // expanded, axis-aligned DrawableContentRect and visible content rect. -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsWithTransformOnClippedSurface) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); @@ -3606,7 +2986,6 @@ TEST_F(LayerTreeHostCommonTest, child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = @@ -3617,17 +2996,16 @@ TEST_F(LayerTreeHostCommonTest, child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f); child1_transform_node.local = child_rotation; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface)); // The clipped surface clamps the DrawableContentRect that encloses the // rotated layer. int diagonal_radius = ceil(sqrt(2.0) * 25.0); - gfx::Rect unclipped_surface_content = gfx::Rect(50 - diagonal_radius, - 50 - diagonal_radius, - diagonal_radius * 2, - diagonal_radius * 2); + gfx::Rect unclipped_surface_content = + gfx::Rect(50 - diagonal_radius, 50 - diagonal_radius, diagonal_radius * 2, + diagonal_radius * 2); gfx::RectF expected_surface_drawable_content( gfx::IntersectRects(unclipped_surface_content, gfx::Rect(50, 50))); EXPECT_EQ(expected_surface_drawable_content, @@ -3642,8 +3020,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(unclipped_surface_content, child1->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsInHighDPI) { + LayerImpl* root = root_layer(); FakePictureLayerImpl* render_surface1 = AddLayer<FakePictureLayerImpl>(); FakePictureLayerImpl* render_surface2 = AddLayer<FakePictureLayerImpl>(); FakePictureLayerImpl* child1 = AddLayer<FakePictureLayerImpl>(); @@ -3663,7 +3041,6 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface1); CreateTransformNode(render_surface1).post_translation = @@ -3683,7 +3060,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); float device_scale_factor = 2.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); ASSERT_TRUE(GetRenderSurface(render_surface1)); ASSERT_TRUE(GetRenderSurface(render_surface2)); @@ -3716,375 +3093,11 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect()); } -// Verify the behavior of back-face culling when there are no preserve-3d -// layers. Note that 3d transforms still apply in this case, but they are -// "flattened" to each parent layer according to current W3C spec. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - BackFaceCullingWithoutPreserves3d) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto front_facing_child = Layer::Create(); - root->AddChild(front_facing_child); - auto back_facing_child = Layer::Create(); - root->AddChild(back_facing_child); - auto front_facing_surface = Layer::Create(); - root->AddChild(front_facing_surface); - auto back_facing_surface = Layer::Create(); - root->AddChild(back_facing_surface); - auto front_facing_child_of_front_facing_surface = Layer::Create(); - front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); - auto back_facing_child_of_front_facing_surface = Layer::Create(); - front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); - auto front_facing_child_of_back_facing_surface = Layer::Create(); - back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); - auto back_facing_child_of_back_facing_surface = Layer::Create(); - back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); - - // Nothing is double-sided - front_facing_child->SetDoubleSided(false); - back_facing_child->SetDoubleSided(false); - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); - front_facing_child_of_front_facing_surface->SetDoubleSided(false); - back_facing_child_of_front_facing_surface->SetDoubleSided(false); - front_facing_child_of_back_facing_surface->SetDoubleSided(false); - back_facing_child_of_back_facing_surface->SetDoubleSided(false); - - // Everything draws content. - front_facing_child->SetIsDrawable(true); - back_facing_child->SetIsDrawable(true); - front_facing_surface->SetIsDrawable(true); - back_facing_surface->SetIsDrawable(true); - front_facing_child_of_front_facing_surface->SetIsDrawable(true); - back_facing_child_of_front_facing_surface->SetIsDrawable(true); - front_facing_child_of_back_facing_surface->SetIsDrawable(true); - back_facing_child_of_back_facing_surface->SetIsDrawable(true); - - gfx::Transform backface_matrix; - backface_matrix.Translate(50.0, 50.0); - backface_matrix.RotateAboutYAxis(180.0); - backface_matrix.Translate(-50.0, -50.0); - - root->SetBounds(gfx::Size(100, 100)); - front_facing_child->SetBounds(gfx::Size(100, 100)); - back_facing_child->SetBounds(gfx::Size(100, 100)); - front_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - - front_facing_surface->SetForceRenderSurfaceForTesting(true); - back_facing_surface->SetForceRenderSurfaceForTesting(true); - - back_facing_child->SetTransform(backface_matrix); - back_facing_surface->SetTransform(backface_matrix); - back_facing_child_of_front_facing_surface->SetTransform(backface_matrix); - back_facing_child_of_back_facing_surface->SetTransform(backface_matrix); - - // Note: No layers preserve 3d. According to current W3C CSS gfx::Transforms - // spec, these layers should blindly use their own local transforms to - // determine back-face culling. - CommitAndActivate(); - - // Verify which render surfaces were created. - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child), - GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface), - GetRenderSurfaceImpl(back_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), - GetRenderSurfaceImpl(back_facing_surface)); - - EXPECT_EQ(3u, update_layer_impl_list().size()); - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerImplListContains( - front_facing_child_of_front_facing_surface->id())); -} - -// Verify the behavior of back-face culling when preserves-3d transform style -// is used. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, BackFaceCullingWithPreserves3d) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto front_facing_child = Layer::Create(); - root->AddChild(front_facing_child); - auto back_facing_child = Layer::Create(); - root->AddChild(back_facing_child); - auto front_facing_surface = Layer::Create(); - root->AddChild(front_facing_surface); - auto back_facing_surface = Layer::Create(); - root->AddChild(back_facing_surface); - auto front_facing_child_of_front_facing_surface = Layer::Create(); - front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); - auto back_facing_child_of_front_facing_surface = Layer::Create(); - front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); - auto front_facing_child_of_back_facing_surface = Layer::Create(); - back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); - auto back_facing_child_of_back_facing_surface = Layer::Create(); - back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); - // Opacity will not force creation of render surfaces in this case because of - // the preserve-3d transform style. Instead, an example of when a surface - // would be created with preserve-3d is when there is a mask layer. - FakeContentLayerClient client; - auto dummy_mask_layer1 = PictureLayer::Create(&client); - front_facing_surface->SetMaskLayer(dummy_mask_layer1); - auto dummy_mask_layer2 = PictureLayer::Create(&client); - back_facing_surface->SetMaskLayer(dummy_mask_layer2); - - // Nothing is double-sided - front_facing_child->SetDoubleSided(false); - back_facing_child->SetDoubleSided(false); - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); - front_facing_child_of_front_facing_surface->SetDoubleSided(false); - back_facing_child_of_front_facing_surface->SetDoubleSided(false); - front_facing_child_of_back_facing_surface->SetDoubleSided(false); - back_facing_child_of_back_facing_surface->SetDoubleSided(false); - - // Everything draws content. - front_facing_child->SetIsDrawable(true); - back_facing_child->SetIsDrawable(true); - front_facing_surface->SetIsDrawable(true); - back_facing_surface->SetIsDrawable(true); - front_facing_child_of_front_facing_surface->SetIsDrawable(true); - back_facing_child_of_front_facing_surface->SetIsDrawable(true); - front_facing_child_of_back_facing_surface->SetIsDrawable(true); - back_facing_child_of_back_facing_surface->SetIsDrawable(true); - dummy_mask_layer1->SetIsDrawable(true); - dummy_mask_layer2->SetIsDrawable(true); - - gfx::Transform backface_matrix; - backface_matrix.Translate(50.0, 50.0); - backface_matrix.RotateAboutYAxis(180.0); - backface_matrix.Translate(-50.0, -50.0); - - root->SetBounds(gfx::Size(100, 100)); - front_facing_child->SetBounds(gfx::Size(100, 100)); - back_facing_child->SetBounds(gfx::Size(100, 100)); - front_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - dummy_mask_layer1->SetBounds(gfx::Size(100, 100)); - dummy_mask_layer2->SetBounds(gfx::Size(100, 100)); - - back_facing_child->SetTransform(backface_matrix); - back_facing_surface->SetTransform(backface_matrix); - back_facing_child_of_front_facing_surface->SetTransform(backface_matrix); - back_facing_child_of_back_facing_surface->SetTransform(backface_matrix); - - // Each surface creates its own new 3d rendering context (as defined by W3C - // spec). According to current W3C CSS gfx::Transforms spec, layers in a 3d - // rendering context should use the transform with respect to that context. - // This 3d rendering context occurs when (a) parent's transform style is flat - // and (b) the layer's transform style is preserve-3d. - front_facing_surface->SetShouldFlattenTransform(false); - front_facing_surface->Set3dSortingContextId(1); - back_facing_surface->SetShouldFlattenTransform(false); - back_facing_surface->Set3dSortingContextId(1); - front_facing_child_of_front_facing_surface->Set3dSortingContextId(1); - back_facing_child_of_front_facing_surface->Set3dSortingContextId(1); - front_facing_child_of_back_facing_surface->Set3dSortingContextId(1); - back_facing_child_of_back_facing_surface->Set3dSortingContextId(1); - - CommitAndActivate(); - - // Verify which render surfaces were created and used. - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child), - GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface), - GetRenderSurfaceImpl(root)); - // We expect that a render surface was created but not used. - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface), - GetRenderSurfaceImpl(back_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), - GetRenderSurfaceImpl(back_facing_surface)); - - EXPECT_EQ(3u, update_layer_impl_list().size()); - - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerImplListContains( - front_facing_child_of_front_facing_surface->id())); -} - -// Verify that layers are appropriately culled when their back face is showing -// and they are not double sided, while animations are going on. -// Even layers that are animating get culled if their back face is showing and -// they are not double sided. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - BackFaceCullingWithAnimatingTransforms) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto animating_surface = Layer::Create(); - root->AddChild(animating_surface); - auto child_of_animating_surface = Layer::Create(); - animating_surface->AddChild(child_of_animating_surface); - auto animating_child = Layer::Create(); - root->AddChild(animating_child); - auto child2 = Layer::Create(); - root->AddChild(child2); - - // Nothing is double-sided - child->SetDoubleSided(false); - child2->SetDoubleSided(false); - animating_surface->SetDoubleSided(false); - child_of_animating_surface->SetDoubleSided(false); - animating_child->SetDoubleSided(false); - - // Everything draws content. - child->SetIsDrawable(true); - child2->SetIsDrawable(true); - animating_surface->SetIsDrawable(true); - child_of_animating_surface->SetIsDrawable(true); - animating_child->SetIsDrawable(true); - - gfx::Transform backface_matrix; - backface_matrix.Translate(50.0, 50.0); - backface_matrix.RotateAboutYAxis(180.0); - backface_matrix.Translate(-50.0, -50.0); - - host()->SetElementIdsForTesting(); - - // Animate the transform on the render surface. - AddAnimatedTransformToElementWithAnimation(animating_surface->element_id(), - timeline(), 10.0, 30, 0); - // This is just an animating layer, not a surface. - AddAnimatedTransformToElementWithAnimation(animating_child->element_id(), - timeline(), 10.0, 30, 0); - - root->SetBounds(gfx::Size(100, 100)); - child->SetBounds(gfx::Size(100, 100)); - child->SetTransform(backface_matrix); - animating_surface->SetBounds(gfx::Size(100, 100)); - animating_surface->SetTransform(backface_matrix); - animating_surface->SetForceRenderSurfaceForTesting(true); - child_of_animating_surface->SetBounds(gfx::Size(100, 100)); - child_of_animating_surface->SetTransform(backface_matrix); - animating_child->SetBounds(gfx::Size(100, 100)); - animating_child->SetTransform(backface_matrix); - child2->SetBounds(gfx::Size(100, 100)); - - CommitAndActivate(); - - EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); - EXPECT_TRUE(GetRenderSurfaceImpl(animating_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(child_of_animating_surface), - GetRenderSurfaceImpl(animating_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(animating_child), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root)); - - EXPECT_EQ(1u, update_layer_impl_list().size()); - - // The back facing layers are culled from the layer list, and have an empty - // visible rect. - EXPECT_TRUE(UpdateLayerImplListContains(child2->id())); - EXPECT_TRUE(ImplOf(child)->visible_layer_rect().IsEmpty()); - EXPECT_TRUE(ImplOf(animating_surface)->visible_layer_rect().IsEmpty()); - EXPECT_TRUE( - ImplOf(child_of_animating_surface)->visible_layer_rect().IsEmpty()); - EXPECT_TRUE(ImplOf(animating_child)->visible_layer_rect().IsEmpty()); - - EXPECT_EQ(gfx::Rect(100, 100), ImplOf(child2)->visible_layer_rect()); -} - -// Verify the behavior of back-face culling for a render surface that is -// created when it flattens its subtree, and its parent has preserves-3d. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - BackFaceCullingWithPreserves3dForFlatteningSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto front_facing_surface = Layer::Create(); - root->AddChild(front_facing_surface); - auto back_facing_surface = Layer::Create(); - root->AddChild(back_facing_surface); - auto child1 = Layer::Create(); - front_facing_surface->AddChild(child1); - auto child2 = Layer::Create(); - back_facing_surface->AddChild(child2); - - // RenderSurfaces are not double-sided - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); - - // Everything draws content. - front_facing_surface->SetIsDrawable(true); - back_facing_surface->SetIsDrawable(true); - child1->SetIsDrawable(true); - child2->SetIsDrawable(true); - - gfx::Transform backface_matrix; - backface_matrix.Translate(50.0, 50.0); - backface_matrix.RotateAboutYAxis(180.0); - backface_matrix.Translate(-50.0, -50.0); - - root->SetBounds(gfx::Size(100, 100)); - front_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_surface->SetForceRenderSurfaceForTesting(true); - back_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_surface->SetTransform(backface_matrix); - back_facing_surface->SetForceRenderSurfaceForTesting(true); - child1->SetBounds(gfx::Size(100, 100)); - child2->SetBounds(gfx::Size(100, 100)); - - front_facing_surface->Set3dSortingContextId(1); - back_facing_surface->Set3dSortingContextId(1); - - CommitAndActivate(); - - // Verify which render surfaces were created and used. - EXPECT_TRUE(GetRenderSurfaceImpl(front_facing_surface)); - - // We expect the render surface to have been created, but remain unused. - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(child1), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(child2), - GetRenderSurfaceImpl(back_facing_surface)); - - EXPECT_EQ(2u, update_layer_impl_list().size()); - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerImplListContains(child1->id())); -} - -using LayerTreeHostCommonScalingTest = LayerTreeHostCommonTest; +using DrawPropertiesScalingTest = DrawPropertiesTest; // Verify draw and screen space transforms of layers not in a surface. -TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesScalingTest, LayerTransformsInHighDPI) { + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); @@ -4098,19 +3111,18 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { float device_scale_factor = 2.5f; - SetupRootProperties(root); CopyProperties(root, child); child->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); CopyProperties(root, child2); child2->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_FLOAT_EQ(device_scale_factor, root->GetIdealContentsScale()); EXPECT_FLOAT_EQ(device_scale_factor, child->GetIdealContentsScale()); EXPECT_FLOAT_EQ(device_scale_factor, child2->GetIdealContentsScale()); - EXPECT_EQ(1u, render_surface_list_impl()->size()); + EXPECT_EQ(1u, GetRenderSurfaceList().size()); // Verify root transforms gfx::Transform expected_root_transform; @@ -4171,7 +3183,7 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { } // Verify draw and screen space transforms of layers in a surface. -TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { +TEST_F(DrawPropertiesScalingTest, SurfaceLayerTransformsInHighDPI) { gfx::Transform perspective_matrix; perspective_matrix.ApplyPerspectiveDepth(2.0); gfx::Vector2dF perspective_surface_offset(2.f, 2.f); @@ -4179,11 +3191,9 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { gfx::Transform scale_small_matrix; scale_small_matrix.Scale(SK_MScalar1 / 10.f, SK_MScalar1 / 12.f); - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - - LayerImpl* page_scale = AddLayer<LayerImpl>(); - page_scale->SetBounds(gfx::Size(100, 100)); + SetupViewport(root, gfx::Size(100, 100), gfx::Size(100, 100)); LayerImpl* parent = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(100, 100)); @@ -4197,11 +3207,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { scale_surface->SetBounds(gfx::Size(10, 10)); scale_surface->SetDrawsContent(true); - SetupRootProperties(root); - CopyProperties(root, page_scale); - auto& page_scale_transform_node = CreateTransformNode(page_scale); - page_scale_transform_node.in_subtree_of_page_scale_layer = true; - CopyProperties(page_scale, parent); + CopyProperties(OuterViewportScrollLayer(), parent); CopyProperties(parent, perspective_surface); auto& perspective_surface_transform = CreateTransformNode(perspective_surface); @@ -4218,15 +3224,9 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { float device_scale_factor = 2.5f; float page_scale_factor = 3.f; - const gfx::Transform kDeviceTransform; - - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = page_scale->id(); - root->layer_tree_impl()->SetViewportLayersFromIds(viewport_ids); - root->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale_factor); + host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - ExecuteCalculateDrawProperties(root, device_scale_factor, kDeviceTransform, - page_scale_factor, page_scale); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor, parent->GetIdealContentsScale()); @@ -4248,11 +3248,10 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { gfx::Vector2dF target_space_transform_scales = MathUtil::ComputeTransform2dScaleComponents( scale_surface->draw_properties().target_space_transform, 0.f); - EXPECT_FLOAT_EQ(max_2d_scale, - std::max(target_space_transform_scales.x(), - target_space_transform_scales.y())); + EXPECT_FLOAT_EQ(max_2d_scale, std::max(target_space_transform_scales.x(), + target_space_transform_scales.y())); - EXPECT_EQ(3u, render_surface_list_impl()->size()); + EXPECT_EQ(3u, GetRenderSurfaceList().size()); gfx::Transform expected_parent_draw_transform; expected_parent_draw_transform.Scale(device_scale_factor * page_scale_factor, @@ -4282,7 +3281,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { perspective_surface->DrawTransform()); } -TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { +TEST_F(DrawPropertiesScalingTest, SmallIdealScale) { gfx::Transform parent_scale_matrix; SkMScalar initial_parent_scale = 1.75; parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); @@ -4291,7 +3290,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { SkMScalar initial_child_scale = 0.25; child_scale_matrix.Scale(initial_child_scale, initial_child_scale); - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); LayerImpl* page_scale = AddLayer<LayerImpl>(); @@ -4307,9 +3306,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { float device_scale_factor = 2.5f; float page_scale_factor = 0.01f; - const gfx::Transform kDeviceTransform; - SetupRootProperties(root); CopyProperties(root, page_scale); CreateTransformNode(page_scale).in_subtree_of_page_scale_layer = true; CopyProperties(page_scale, parent); @@ -4317,8 +3314,13 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { CopyProperties(parent, child_scale); CreateTransformNode(child_scale).local = child_scale_matrix; - ExecuteCalculateDrawProperties(root, device_scale_factor, kDeviceTransform, - page_scale_factor, page_scale); + LayerTreeImpl::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.page_scale_transform = + page_scale->transform_tree_index(); + host_impl()->active_tree()->SetViewportPropertyIds(viewport_property_ids); + + host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // The ideal scale is able to go below 1. float expected_ideal_scale = @@ -4332,7 +3334,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { EXPECT_FLOAT_EQ(expected_ideal_scale, child_scale->GetIdealContentsScale()); } -TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { +TEST_F(DrawPropertiesScalingTest, IdealScaleForAnimatingLayer) { gfx::Transform parent_scale_matrix; SkMScalar initial_parent_scale = 1.75; parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); @@ -4341,7 +3343,7 @@ TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { SkMScalar initial_child_scale = 1.25; child_scale_matrix.Scale(initial_child_scale, initial_child_scale); - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); LayerImpl* parent = AddLayer<LayerImpl>(); @@ -4352,13 +3354,12 @@ TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { child_scale->SetBounds(gfx::Size(10, 10)); child_scale->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, parent); CreateTransformNode(parent).local = parent_scale_matrix; CopyProperties(parent, child_scale); CreateTransformNode(child_scale).local = child_scale_matrix; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FLOAT_EQ(initial_parent_scale, parent->GetIdealContentsScale()); // Animating layers compute ideal scale in the same way as when @@ -4367,8 +3368,8 @@ TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { child_scale->GetIdealContentsScale()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { - LayerImpl* parent = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceTransformsInHighDPI) { + LayerImpl* parent = root_layer(); parent->SetBounds(gfx::Size(30, 30)); parent->SetDrawsContent(true); @@ -4385,7 +3386,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { float device_scale_factor = 1.5f; gfx::Vector2dF child_offset(2.f, 2.f); - SetupRootProperties(parent); CopyProperties(parent, child); CreateTransformNode(child).post_translation = child_offset; CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; @@ -4393,11 +3393,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { duplicate_child_non_owner->SetOffsetToTransformParent( child->offset_to_transform_parent()); - ExecuteCalculateDrawProperties(parent, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // We should have two render surfaces. The root's render surface and child's // render surface (it needs one because of force_render_surface). - EXPECT_EQ(2u, render_surface_list_impl()->size()); + EXPECT_EQ(2u, GetRenderSurfaceList().size()); gfx::Transform expected_parent_transform; expected_parent_transform.Scale(device_scale_factor, device_scale_factor); @@ -4450,9 +3450,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { GetRenderSurface(child)->screen_space_transform()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) { - LayerImpl* parent = root_layer_for_testing(); + LayerImpl* parent = root_layer(); parent->SetBounds(gfx::Size(33, 31)); parent->SetDrawsContent(true); @@ -4462,15 +3462,14 @@ TEST_F(LayerTreeHostCommonTest, float device_scale_factor = 1.7f; - SetupRootProperties(parent); CopyProperties(parent, child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(parent, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // We should have two render surfaces. The root's render surface and child's // render surface (it needs one because of force_render_surface). - EXPECT_EQ(2u, render_surface_list_impl()->size()); + EXPECT_EQ(2u, GetRenderSurfaceList().size()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), GetRenderSurface(child)->draw_transform()); @@ -4481,7 +3480,7 @@ TEST_F(LayerTreeHostCommonTest, } // Needs layer tree mode: mask layer. Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, LayerSearch) { +TEST_F(DrawPropertiesTestWithLayerTree, LayerSearch) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> child = Layer::Create(); scoped_refptr<Layer> grand_child = Layer::Create(); @@ -4502,8 +3501,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, LayerSearch) { EXPECT_FALSE(host()->LayerById(nonexistent_id)); } -TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransparentChildRenderSurfaceCreation) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -4512,16 +3511,15 @@ TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { grand_child->SetBounds(gfx::Size(10, 10)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateEffectNode(child).opacity = 0.5f; CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(root)); } -TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { +TEST_F(DrawPropertiesTest, OpacityAnimatingOnPendingTree) { host_impl()->CreatePendingTree(); LayerImpl* root = EnsureRootLayerInPendingTree(); root->SetBounds(gfx::Size(100, 100)); @@ -4532,7 +3530,6 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { child->SetDrawsContent(true); host_impl()->pending_tree()->SetElementIdsForTesting(); - SetupRootProperties(root); CopyProperties(root, child); CreateEffectNode(child).opacity = 0.0f; @@ -4540,17 +3537,17 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { AddOpacityTransitionToElementWithAnimation( child->element_id(), timeline_impl(), 10.0, 0.0f, 1.0f, false); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); // We should have one render surface and two layers. The child // layer should be included even though it is transparent. - ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(1u, host_impl()->pending_tree()->GetRenderSurfaceList().size()); ASSERT_EQ(2, GetRenderSurface(root)->num_contributors()); // If the root itself is hidden, the child should not be drawn even if it has // an animating opacity. SetOpacity(root, 0.0f); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); EXPECT_FALSE(GetEffectNode(child)->is_drawn); @@ -4558,7 +3555,7 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { // it has animating opacity even if it has opacity 0. SetOpacity(root, 1.0f); SetOpacity(child, 0.0f); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); EXPECT_TRUE(GetEffectNode(child)->is_drawn); EXPECT_TRUE(GetPropertyTrees(root)->effect_tree.ContributesToDrawnSurface( @@ -4568,13 +3565,12 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { // be drawn. host_impl()->ActivateSyncTree(); LayerTreeImpl* active_tree = host_impl()->active_tree(); - LayerImpl* active_root = active_tree->LayerById(root->id()); LayerImpl* active_child = active_tree->LayerById(child->id()); EffectTree& active_effect_tree = active_tree->property_trees()->effect_tree; EXPECT_TRUE(active_effect_tree.needs_update()); - ExecuteCalculateDrawProperties(active_root); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(GetEffectNode(active_child)->is_drawn); EXPECT_FALSE(active_effect_tree.ContributesToDrawnSurface( @@ -4582,10 +3578,10 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { } using LCDTextTestParam = std::tuple<bool, bool>; -class LCDTextTest : public LayerTreeHostCommonTestBase, +class LCDTextTest : public DrawPropertiesTestBase, public testing::TestWithParam<LCDTextTestParam> { public: - LCDTextTest() : LayerTreeHostCommonTestBase(LCDTextTestLayerTreeSettings()) {} + LCDTextTest() : DrawPropertiesTestBase(LCDTextTestLayerTreeSettings()) {} protected: LayerTreeSettings LCDTextTestLayerTreeSettings() { @@ -4599,7 +3595,7 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, } void SetUp() override { - root_ = root_layer_for_testing(); + root_ = root_layer(); child_ = AddLayer<LayerImpl>(); grand_child_ = AddLayer<LayerImpl>(); SetElementIdsForTesting(); @@ -4616,7 +3612,6 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, child_->SetBounds(gfx::Size(1, 1)); grand_child_->SetBounds(gfx::Size(1, 1)); - SetupRootProperties(root_); CopyProperties(root_, child_); CreateTransformNode(child_); CreateEffectNode(child_).render_surface_reason = RenderSurfaceReason::kTest; @@ -4636,7 +3631,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Case 1: Identity transform. - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4646,7 +3641,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { integral_translation.Translate(1.0, 2.0); SetTransform(child_, integral_translation); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4655,7 +3650,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { gfx::Transform non_integral_translation; non_integral_translation.Translate(1.5, 2.5); SetTransform(child_, non_integral_translation); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4664,7 +3659,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { gfx::Transform rotation; rotation.Rotate(10.0); SetTransform(child_, rotation); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4673,7 +3668,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { gfx::Transform scale; scale.Scale(2.0, 2.0); SetTransform(child_, scale); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4682,7 +3677,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { gfx::Transform skew; skew.Skew(10.0, 0.0); SetTransform(child_, skew); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4690,7 +3685,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 7: Translucent. SetTransform(child_, gfx::Transform()); SetOpacity(child_, 0.5f); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4698,28 +3693,28 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 8: Sanity check: restore transform and opacity. SetTransform(child_, gfx::Transform()); SetOpacity(child_, 1.f); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 9: Non-opaque content. child_->SetContentsOpaque(false); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 10: Sanity check: restore content opaqueness. child_->SetContentsOpaque(true); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 11: will-change: transform child_->SetHasWillChangeTransformHint(true); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4730,7 +3725,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Sanity check: Make sure can_use_lcd_text_ is set on each node. - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4739,7 +3734,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { SetOpacity(child_, 0.9f); AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); // Text LCD should be adjusted while animation is active. EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); @@ -4751,7 +3746,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Sanity check: Make sure can_use_lcd_text_ is set on each node. - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4760,19 +3755,19 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) { child_->SetContentsOpaque(false); AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); // LCD text should be disabled for non-opaque layers even during animations. EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); } -INSTANTIATE_TEST_SUITE_P(LayerTreeHostCommonTest, +INSTANTIATE_TEST_SUITE_P(DrawPropertiesTest, LCDTextTest, testing::Combine(testing::Bool(), testing::Bool())); // Needs layer tree mode: hide_layer_and_subtree. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); root->SetIsDrawable(true); @@ -4796,7 +3791,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { // We should have one render surface and two layers. The grand child has // hidden itself. - ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface()); @@ -4804,7 +3799,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { } // Needs layer tree mode: hide_layer_and_subtree. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); root->SetIsDrawable(true); @@ -4826,7 +3821,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { // We should have one render surface and one layer. The child has // hidden itself and the grand child. - ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors()); EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); @@ -4834,7 +3829,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { } // Needs layer tree mode: mask layer, hide_layer_and_subtree and copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHiddenWithCopyRequest) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHiddenWithCopyRequest) { auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); root->SetIsDrawable(true); @@ -4900,15 +3895,15 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHiddenWithCopyRequest) { // We should have four render surfaces, one for the root, one for the grand // parent since it has opacity and two drawing descendants, one for the parent // since it owns a surface, and one for the copy_layer. - ASSERT_EQ(4u, render_surface_list_impl()->size()); + ASSERT_EQ(4u, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); EXPECT_EQ(static_cast<uint64_t>(copy_grand_parent->id()), - render_surface_list_impl()->at(1)->id()); + GetRenderSurfaceList().at(1)->id()); EXPECT_EQ(static_cast<uint64_t>(copy_parent->id()), - render_surface_list_impl()->at(2)->id()); + GetRenderSurfaceList().at(2)->id()); EXPECT_EQ(static_cast<uint64_t>(copy_layer->id()), - render_surface_list_impl()->at(3)->id()); + GetRenderSurfaceList().at(3)->id()); // The root render surface should have 2 contributing layers. EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); @@ -4948,7 +3943,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHiddenWithCopyRequest) { } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, ClippedOutCopyRequest) { +TEST_F(DrawPropertiesTestWithLayerTree, ClippedOutCopyRequest) { auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); root->SetIsDrawable(true); @@ -4978,9 +3973,9 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, ClippedOutCopyRequest) { CommitAndActivate(); // We should have two render surface, as the others are clipped out. - ASSERT_EQ(2u, render_surface_list_impl()->size()); + ASSERT_EQ(2u, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); // The root render surface should have only 2 contributing layer, since the // other layers are clipped away. @@ -4989,7 +3984,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, ClippedOutCopyRequest) { } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SingularTransformAndCopyRequests) { +TEST_F(DrawPropertiesTestWithLayerTree, SingularTransformAndCopyRequests) { auto root = Layer::Create(); host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); @@ -5040,7 +4035,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SingularTransformAndCopyRequests) { } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, VisibleRectInNonRootCopyRequest) { +TEST_F(DrawPropertiesTestWithLayerTree, VisibleRectInNonRootCopyRequest) { auto root = Layer::Create(); host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); @@ -5105,12 +4100,12 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, VisibleRectInNonRootCopyRequest) { EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect()); // Case 3: When there is device scale factor. - float device_scale_factor = 2.f; + SetDeviceScaleAndUpdateViewportRect(host(), 2.f); copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); ASSERT_TRUE(copy_layer->HasCopyRequest()); - CommitAndActivate(device_scale_factor); + CommitAndActivate(); ASSERT_FALSE(copy_layer->HasCopyRequest()); EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect()); @@ -5120,7 +4115,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, VisibleRectInNonRootCopyRequest) { EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { +TEST_F(DrawPropertiesTest, TransformedClipParent) { // Ensure that a transform between the layer and its render surface is not a // problem. Constructs the following layer tree. // @@ -5133,12 +4128,11 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { // // The render surface should be resized correctly and the clip child should // inherit the right clip rect. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(50, 50)); LayerImpl* render_surface = AddLayer<LayerImpl>(); render_surface->SetBounds(gfx::Size(10, 10)); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -5166,7 +4160,7 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { CopyProperties(intervening, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(root)); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -5190,7 +4184,7 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { GetRenderSurface(render_surface)->content_rect())); } -TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { +TEST_F(DrawPropertiesTest, ClipParentWithInterveningRenderSurface) { // Ensure that intervening render surfaces are not a problem in the basic // case. In the following tree, both render surfaces should be resized to // accomodate for the clip child, despite an intervening clip. @@ -5203,7 +4197,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { // + render_surface2 (also sets opacity) // + clip_child (clipped by clip_parent) // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* intervening = AddLayer<LayerImpl>(); @@ -5214,7 +4208,6 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { clip_parent->SetBounds(gfx::Size(40, 40)); clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(1, 1)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); @@ -5243,7 +4236,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { CopyProperties(render_surface2, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetRenderSurface(root)); EXPECT_TRUE(GetRenderSurface(render_surface1)); @@ -5285,7 +4278,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { EXPECT_FALSE(clip_child->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { +TEST_F(DrawPropertiesTest, ClipParentScrolledInterveningLayer) { // Ensure that intervening render surfaces are not a problem, even if there // is a scroll involved. Note, we do _not_ have to consider any other sort // of transform. @@ -5298,7 +4291,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { // + render_surface2 (also has render surface) // + clip_child (clipped by clip_parent) // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* intervening = AddLayer<LayerImpl>(); @@ -5308,7 +4301,6 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { root->SetBounds(gfx::Size(50, 50)); clip_parent->SetBounds(gfx::Size(40, 40)); - SetupRootProperties(root); CopyProperties(root, clip_parent); auto& clip_parent_transform = CreateTransformNode(clip_parent); clip_parent_transform.local.Translate(2, 2); @@ -5343,7 +4335,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); SetScrollOffset(intervening, gfx::ScrollOffset(3, 3)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetRenderSurface(root)); EXPECT_TRUE(GetRenderSurface(render_surface1)); @@ -5384,7 +4376,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { EXPECT_FALSE(clip_child->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { +TEST_F(DrawPropertiesTest, DescendantsOfClipChildren) { // Ensures that descendants of the clip child inherit the correct clip. // // Virtual layer tree: @@ -5394,7 +4386,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { // + clip_child (clipped by clip_parent, skipping intervening) // + child // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* intervening = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -5403,7 +4395,6 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { root->SetBounds(gfx::Size(50, 50)); clip_parent->SetBounds(gfx::Size(40, 40)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); @@ -5420,7 +4411,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { child->SetBounds(gfx::Size(60, 60)); CopyProperties(clip_child, child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetRenderSurface(root)); @@ -5432,7 +4423,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { EXPECT_TRUE(child->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, SurfacesShouldBeUnaffectedByNonDescendantClipChildren) { // Ensures that non-descendant clip children in the tree do not affect // render surfaces. @@ -5446,7 +4437,7 @@ TEST_F(LayerTreeHostCommonTest, // + non_clip_child (in normal clip hierarchy) // // In this example render_surface2 should be unaffected by clip_child. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); @@ -5467,7 +4458,6 @@ TEST_F(LayerTreeHostCommonTest, non_clip_child->SetDrawsContent(true); non_clip_child->SetBounds(gfx::Size(5, 5)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); CopyProperties(clip_parent, clip_layer); @@ -5484,7 +4474,7 @@ TEST_F(LayerTreeHostCommonTest, clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); CopyProperties(render_surface2, non_clip_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetRenderSurface(root)); EXPECT_TRUE(GetRenderSurface(render_surface1)); @@ -5515,171 +4505,8 @@ TEST_F(LayerTreeHostCommonTest, GetRenderSurface(render_surface2)->content_rect()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - CreateRenderSurfaceWhenFlattenInsideRenderingContext) { - // Verifies that Render Surfaces are created at the edge of rendering context. - - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child1 = Layer::Create(); - root->AddChild(child1); - auto child2 = Layer::Create(); - child1->AddChild(child2); - auto child3 = Layer::Create(); - child2->AddChild(child3); - root->SetIsDrawable(true); - - gfx::Size bounds(100, 100); - - root->SetBounds(bounds); - child1->SetBounds(bounds); - child1->SetIsDrawable(true); - child1->SetShouldFlattenTransform(false); - child1->Set3dSortingContextId(1); - child2->SetBounds(bounds); - child2->SetIsDrawable(true); - child2->Set3dSortingContextId(1); - child3->SetBounds(bounds); - child3->SetIsDrawable(true); - child3->Set3dSortingContextId(1); - - CommitAndActivate(); - - // Verify which render surfaces were created. - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(child1), GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(child3), GetRenderSurfaceImpl(child2)); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - DoNotIncludeBackfaceInvisibleSurfaces) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto back_facing = Layer::Create(); - root->AddChild(back_facing); - - auto render_surface1 = Layer::Create(); - back_facing->AddChild(render_surface1); - auto child1 = Layer::Create(); - render_surface1->AddChild(child1); - - auto flattener = Layer::Create(); - back_facing->AddChild(flattener); - auto render_surface2 = Layer::Create(); - flattener->AddChild(render_surface2); - auto child2 = Layer::Create(); - render_surface2->AddChild(child2); - - child1->SetIsDrawable(true); - child2->SetIsDrawable(true); - - root->SetBounds(gfx::Size(50, 50)); - back_facing->SetBounds(gfx::Size(50, 50)); - back_facing->SetShouldFlattenTransform(false); - - render_surface1->SetBounds(gfx::Size(30, 30)); - render_surface1->SetShouldFlattenTransform(false); - render_surface1->SetForceRenderSurfaceForTesting(true); - render_surface1->SetDoubleSided(false); - child1->SetBounds(gfx::Size(20, 20)); - - flattener->SetBounds(gfx::Size(30, 30)); - render_surface2->SetBounds(gfx::Size(30, 30)); - render_surface2->SetShouldFlattenTransform(false); - render_surface2->SetForceRenderSurfaceForTesting(true); - render_surface2->SetDoubleSided(false); - child2->SetBounds(gfx::Size(20, 20)); - - CommitAndActivate(); - - EXPECT_EQ(3u, render_surface_list_impl()->size()); - EXPECT_EQ(2, render_surface_list_impl()->at(0)->num_contributors()); - EXPECT_EQ(1, render_surface_list_impl()->at(1)->num_contributors()); - - gfx::Transform rotation_transform; - rotation_transform.RotateAboutXAxis(180.0); - back_facing->SetTransform(rotation_transform); - - CommitAndActivate(); - - // render_surface1 is in the same 3d rendering context as back_facing and is - // not double sided, so it should not be in RSLL. render_surface2 is also not - // double-sided, but will still be in RSLL as it's in a different 3d rendering - // context. - EXPECT_EQ(2u, render_surface_list_impl()->size()); - EXPECT_EQ(1, render_surface_list_impl()->at(0)->num_contributors()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - DoNotIncludeBackfaceInvisibleLayers) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto grand_child = Layer::Create(); - child->AddChild(grand_child); - - root->SetBounds(gfx::Size(50, 50)); - root->SetShouldFlattenTransform(false); - child->SetBounds(gfx::Size(30, 30)); - child->SetDoubleSided(false); - child->SetShouldFlattenTransform(false); - grand_child->SetBounds(gfx::Size(20, 20)); - grand_child->SetIsDrawable(true); - grand_child->SetUseParentBackfaceVisibility(true); - grand_child->SetShouldFlattenTransform(false); - - CommitAndActivate(); - - EXPECT_EQ(1u, render_surface_list_impl()->size()); - EXPECT_TRUE(ImplOf(grand_child)->contributes_to_drawn_render_surface()); - - // A ll layers with invisible backfgaces should be checked. - EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); - - gfx::Transform rotation_transform; - rotation_transform.RotateAboutXAxis(180.0); - - child->SetTransform(rotation_transform); - child->Set3dSortingContextId(1); - grand_child->Set3dSortingContextId(1); - - CommitAndActivate(); - - EXPECT_EQ(1u, render_surface_list_impl()->size()); - EXPECT_EQ(0, render_surface_list_impl()->at(0)->num_contributors()); - - // We should check for backface visibilty of child as it has a rotation - // transform. We should also check for grand_child as it uses the backface - // visibility of its parent. - EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); - - grand_child->SetUseParentBackfaceVisibility(false); - grand_child->SetDoubleSided(false); - - CommitAndActivate(); - - EXPECT_EQ(1u, render_surface_list_impl()->size()); - EXPECT_EQ(0, render_surface_list_impl()->at(0)->num_contributors()); - - // We should check the backface visibility of child as it has a rotation - // transform and for grand_child as it is in a 3d rendering context and not - // the root of it. - EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); -} - -TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformAnimationUpdatesBackfaceVisibility) { + LayerImpl* root = root_layer(); LayerImpl* back_facing = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* render_surface2 = AddLayer<LayerImpl>(); @@ -5693,7 +4520,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { render_surface2->SetBounds(gfx::Size(30, 30)); SetElementIdsForTesting(); - SetupRootProperties(root); CopyProperties(root, back_facing); auto& back_facing_transform_node = CreateTransformNode(back_facing); back_facing_transform_node.flattens_inherited_transform = false; @@ -5716,7 +4542,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { RenderSurfaceReason::kTest; render_surface2_effect_node.double_sided = false; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); @@ -5725,21 +4551,21 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { gfx::Transform()); root->layer_tree_impl()->SetTransformMutated(render_surface2->element_id(), rotate_about_y); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); root->layer_tree_impl()->SetTransformMutated(render_surface1->element_id(), rotate_about_y); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); } -TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { +TEST_F(DrawPropertiesTest, ScrollChildAndScrollParentDifferentTargets) { // Tests the computation of draw transform for the scroll child when its // render surface is different from its scroll parent's render surface. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* scroll_child_target = AddLayer<LayerImpl>(); LayerImpl* scroll_child = AddLayer<LayerImpl>(); LayerImpl* scroll_parent_target = AddLayer<LayerImpl>(); @@ -5753,7 +4579,6 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { scroll_child->SetBounds(gfx::Size(50, 50)); scroll_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, scroll_child_target); auto& child_target_effect_node = CreateEffectNode(scroll_child_target); child_target_effect_node.render_surface_reason = RenderSurfaceReason::kTest; @@ -5772,19 +4597,18 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { scroll_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10)); float device_scale_factor = 1.5f; - ExecuteCalculateDrawProperties(root, device_scale_factor); - + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_EQ(scroll_child->effect_tree_index(), scroll_child_target->effect_tree_index()); EXPECT_EQ(scroll_child->visible_layer_rect(), gfx::Rect(10, 10, 40, 40)); EXPECT_EQ(scroll_child->clip_rect(), gfx::Rect(15, 15, 75, 75)); gfx::Transform scale; - scale.Scale(1.5f, 1.5f); + scale.Scale(device_scale_factor, device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ(scroll_child->DrawTransform(), scale); } -TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, SingularTransformSubtreesDoNotDraw) { + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); @@ -5795,7 +4619,6 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { child->SetBounds(gfx::Size(20, 20)); child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, parent); CreateTransformNode(parent).sorting_context_id = 1; CreateEffectNode(parent).render_surface_reason = RenderSurfaceReason::kTest; @@ -5803,29 +4626,29 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { CreateTransformNode(child).sorting_context_id = 1; CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - EXPECT_EQ(3u, render_surface_list_impl()->size()); + EXPECT_EQ(3u, GetRenderSurfaceList().size()); gfx::Transform singular_transform; - singular_transform.Scale3d( - SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0)); + singular_transform.Scale3d(SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), + SkDoubleToMScalar(0.0)); SetTransform(child, singular_transform); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - EXPECT_EQ(2u, render_surface_list_impl()->size()); + EXPECT_EQ(2u, GetRenderSurfaceList().size()); // Ensure that the entire subtree under a layer with singular transform does // not get rendered. SetTransform(parent, singular_transform); SetTransform(child, gfx::Transform()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - EXPECT_EQ(1u, render_surface_list_impl()->size()); + EXPECT_EQ(1u, GetRenderSurfaceList().size()); } -TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { +TEST_F(DrawPropertiesTest, ScrollSnapping) { // This test verifies that a scrolling layer gets scroll offset snapped to // integer coordinates. // @@ -5834,7 +4657,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { // + container // + scroller // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* container = AddLayer<LayerImpl>(); LayerImpl* scroller = AddLayer<LayerImpl>(); @@ -5842,7 +4665,6 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { container->SetBounds(gfx::Size(40, 40)); container->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, container); gfx::Vector2dF container_offset(10, 20); @@ -5859,7 +4681,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { { gfx::Vector2dF scroll_delta(3.0, 5.0); SetScrollOffsetDelta(scroller, scroll_delta); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR_EQ( scroller->draw_properties().screen_space_transform.To2dTranslation(), @@ -5870,7 +4692,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { { gfx::Vector2dF scroll_delta(4.1f, 8.1f); SetScrollOffsetDelta(scroller, scroll_delta); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); gfx::Vector2dF rounded_scroll_delta(4.f, 8.f); EXPECT_VECTOR_EQ( @@ -5879,8 +4701,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { } } -TEST_F(LayerTreeHostCommonTest, - ScrollSnappingWithAnimatedScreenSpaceTransform) { +TEST_F(DrawPropertiesTest, ScrollSnappingWithAnimatedScreenSpaceTransform) { // This test verifies that a scrolling layer whose screen space transform is // animating doesn't get snapped to integer coordinates. // @@ -5891,7 +4712,7 @@ TEST_F(LayerTreeHostCommonTest, // + container // + scroller // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* animated_layer = AddLayer<FakePictureLayerImpl>(); LayerImpl* surface = AddLayer<LayerImpl>(); LayerImpl* container = AddLayer<LayerImpl>(); @@ -5904,7 +4725,6 @@ TEST_F(LayerTreeHostCommonTest, start_scale.Scale(1.5f, 1.5f); animated_layer->SetBounds(gfx::Size(50, 50)); - SetupRootProperties(root); CopyProperties(root, animated_layer); CreateTransformNode(animated_layer).local = start_scale; @@ -5936,14 +4756,14 @@ TEST_F(LayerTreeHostCommonTest, gfx::Vector2dF scroll_delta(5.f, 9.f); SetScrollOffsetDelta(scroller, scroll_delta); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); gfx::Vector2dF expected_draw_transform_translation(-7.5f, -13.5f); EXPECT_VECTOR2DF_EQ(expected_draw_transform_translation, scroller->DrawTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { +TEST_F(DrawPropertiesTest, ScrollSnappingWithScrollChild) { // This test verifies that a scrolling child of a scrolling layer doesn't get // snapped to integer coordinates. // @@ -5953,7 +4773,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { // + scroller // + scroll_child (transform parent is scroller) // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* container = AddLayer<LayerImpl>(); LayerImpl* scroller = AddLayer<LayerImpl>(); LayerImpl* scroll_child = AddLayer<LayerImpl>(); @@ -5962,7 +4782,6 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { root->SetBounds(gfx::Size(50, 50)); container->SetBounds(gfx::Size(50, 50)); - SetupRootProperties(root); CopyProperties(root, container); gfx::Vector2dF container_offset(10.3f, 10.3f); @@ -5981,7 +4800,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { gfx::Vector2dF scroll_delta(5.f, 9.f); SetScrollOffsetDelta(scroller, scroll_delta); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); gfx::Vector2dF expected_scroller_screen_space_transform_translation(5.f, 1.f); EXPECT_VECTOR2DF_EQ(expected_scroller_screen_space_transform_translation, @@ -5994,7 +4813,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { scroll_child->ScreenSpaceTransform()); } -class LayerTreeHostCommonStickyPositionTest : public LayerTreeHostCommonTest { +class DrawPropertiesStickyPositionTest : public DrawPropertiesTest { protected: // Setup layers and property trees. // Virtual layer hierarchy: @@ -6041,11 +4860,11 @@ class LayerTreeHostCommonStickyPositionTest : public LayerTreeHostCommonTest { } void CommitAndUpdateImplPointers() { - ExecuteCalculateDrawProperties(root_.get()); - host()->host_impl()->CreatePendingTree(); + UpdateMainDrawProperties(); + host_impl()->CreatePendingTree(); host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + host_impl()->ActivateSyncTree(); + LayerTreeImpl* layer_tree_impl = host_impl()->active_tree(); root_impl_ = layer_tree_impl->LayerById(root_->id()); scroller_impl_ = layer_tree_impl->LayerById(scroller_->id()); sticky_pos_impl_ = layer_tree_impl->LayerById(sticky_pos_->id()); @@ -6065,7 +4884,7 @@ class LayerTreeHostCommonStickyPositionTest : public LayerTreeHostCommonTest { LayerImpl* sticky_pos_impl_; }; -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionTop) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionTop) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20)); @@ -6087,19 +4906,19 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionTop) { // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(5.f, 15.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6107,13 +4926,13 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionTop) { // Scroll past the end of the sticky container (note: this element does not // have its own layer as it does not need to be composited). SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, -10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionSubpixelScroll) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionSubpixelScroll) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 200)); @@ -6130,13 +4949,13 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionSubpixelScroll) { SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.8f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionBottom) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionBottom) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 150)); @@ -6157,7 +4976,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionBottom) { sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 95.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6165,25 +4984,25 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionBottom) { // Once we get past the top of the container it moves to be aligned 10px // up from the the bottom of the scroller. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Once we scroll past its initial location, it sticks there. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 150.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionBottomOuterViewportDelta) { CreateTree(); @@ -6214,7 +5033,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, GetPropertyTrees(scroller_impl_) ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -10.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 70.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6222,7 +5041,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, // On hiding more of the toolbar the sticky element starts to stick. GetPropertyTrees(scroller_impl_) ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -20.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); // On hiding more the sticky element stops moving as it has reached its // limit. @@ -6232,14 +5051,14 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, GetPropertyTrees(scroller_impl_) ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 60.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionLeftRight) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(145, 0)); @@ -6258,12 +5077,12 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { // Initially the sticky element is moved the leftmost side of the container. - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(100.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(95.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6271,12 +5090,12 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { // Once we get past the left side of the container it moves to be aligned 10px // up from the the right of the scroller. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(25.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(80.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(30.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(80.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6284,36 +5103,36 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { // When we get to the sticky element's original position we stop sticking // to the right. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(95.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(50.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(105.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(40.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // The element starts sticking to the left once we scroll far enough. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(150.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(10.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(155.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(10.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Finally it stops sticking when it hits the right side of the container. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(190.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(195.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6322,7 +5141,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { // This test ensures that the compositor sticky position code correctly accounts // for the element having been given a position from the main thread sticky // position code. -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionMainThreadUpdates) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20)); @@ -6344,14 +5163,14 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(5.f, 15.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6369,14 +5188,14 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { // (0, 0) because we have synced a scroll offset of (15, 15) from the main // thread. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And if we scroll a little further it remains there. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6385,8 +5204,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { // This tests the main thread updates with a composited sticky container. In // this case the position received from main is relative to the container but // the constraint rects are relative to the ancestor scroller. -TEST_F(LayerTreeHostCommonStickyPositionTest, - StickyPositionCompositedContainer) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionCompositedContainer) { CreateRootAndScroller(); scoped_refptr<Layer> sticky_container = Layer::Create(); @@ -6416,14 +5234,14 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 25.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6440,28 +5258,28 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, // (0, 0) because we have synced a scroll offset of (0, 25) from the main // thread. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And if we scroll a little further it remains there. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And hits the bottom of the container. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 5.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } // A transform on a sticky element should not affect its sticky position. -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionScaledStickyBox) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 20)); @@ -6487,7 +5305,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 5.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6495,19 +5313,19 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { // Scroll past the sticking point, the box is positioned at the scroller // edge. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the end of the sticky container. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, -10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6515,7 +5333,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { // Tests that a transform does not affect the sticking points. The sticky // element will however move relative to the viewport due to its transform. -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledContainer) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionScaledContainer) { CreateRootAndScroller(); scoped_refptr<Layer> sticky_container = Layer::Create(); @@ -6543,7 +5361,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledContainer) { // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 25.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6551,25 +5369,25 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledContainer) { // Scroll past the sticking point, the box is positioned at the scroller // edge but is also scaled by its container so it begins to move down. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 25.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 30.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the end of the sticky container. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 30.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionNested) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 50)); @@ -6609,7 +5427,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { // Scroll less than the sticking point. Both sticky elements should move with // scroll as we haven't gotten to the sticky item locations yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 45.f), outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); @@ -6620,7 +5438,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { // Scroll such that the inner sticky should stick, but the outer one should // keep going as it hasn't reached its position yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 20.f), outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); @@ -6630,7 +5448,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { // Keep going, both should stick. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 100.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 10.f), outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); @@ -6658,8 +5476,8 @@ class AnimationScaleFactorTrackingLayerImpl : public LayerImpl { } }; -TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, MaximumAnimationScaleFactor) { + LayerImpl* root = root_layer(); auto* grand_parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); auto* parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); auto* child = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); @@ -6672,7 +5490,6 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { child->SetBounds(gfx::Size(1, 2)); grand_child->SetBounds(gfx::Size(1, 2)); - SetupRootProperties(root); CopyProperties(root, grand_parent); CreateTransformNode(grand_parent); CopyProperties(grand_parent, parent); @@ -6682,7 +5499,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { CopyProperties(child, grand_child); CreateTransformNode(grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // No layers have animations. EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); @@ -6741,7 +5558,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(child_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Only |child| has a scale-affecting animation. EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); @@ -6756,7 +5573,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(grand_parent_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |grand_parent| and |child| have scale-affecting animations. EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent)); @@ -6773,7 +5590,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(parent_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |grand_parent|, |parent|, and |child| have scale-affecting animations. EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent)); @@ -6798,7 +5615,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(child_animation.get(), 1.0, TransformOperations(), perspective); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |child| has a scale-affecting animation but computing the maximum of this // animation is not supported. @@ -6822,7 +5639,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(parent_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |grand_parent| and |parent| each have scale 2.f. |parent| has a scale // animation with maximum scale 5.f. @@ -6839,7 +5656,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { gfx::Transform perspective_matrix; perspective_matrix.ApplyPerspectiveDepth(2.f); SetTransform(child, perspective_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |child| has a transform that's neither a translation nor a scale. EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); @@ -6853,7 +5670,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); SetTransform(parent, perspective_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |parent| and |child| have transforms that are neither translations nor // scales. @@ -6871,7 +5688,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { SetTransform(child, gfx::Transform()); SetTransform(grand_parent, perspective_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |grand_parent| has a transform that's neither a translation nor a scale. EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); @@ -6894,14 +5711,11 @@ static void GatherDrawnLayers(LayerTreeImpl* tree_impl, if (it.state() != EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) continue; - - if (it.current_render_surface()->MaskLayer()) - drawn_layers->insert(it.current_render_surface()->MaskLayer()); } } // Needs layer tree mode: mask layer. -TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceLayerListMembership) { +TEST_F(DrawPropertiesTestWithLayerTree, RenderSurfaceLayerListMembership) { auto root = Layer::Create(); auto grand_parent = Layer::Create(); auto parent = Layer::Create(); @@ -7043,11 +5857,13 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceLayerListMembership) { EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); - EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); + // Mask layer has its own render surface in layer tree mode. + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); + expected.insert(ImplOf(mask)); actual.clear(); GatherDrawnLayers(host_impl()->active_tree(), &actual); EXPECT_EQ(expected, actual); @@ -7102,9 +5918,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceLayerListMembership) { } // Needs layer tree mode: mask layer. -TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { +TEST_F(DrawPropertiesTestWithLayerTree, DrawPropertyDeviceScale) { auto root = Layer::Create(); - auto page_scale = Layer::Create(); auto child1 = Layer::Create(); auto child2 = Layer::Create(); @@ -7123,14 +5938,11 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { mask->SetBounds(child1->bounds()); child1->SetMaskLayer(mask); - page_scale->AddChild(child1); - page_scale->AddChild(child2); - root->AddChild(page_scale); + root->AddChild(child1); + root->AddChild(child2); host()->SetRootLayer(root); host()->SetElementIdsForTesting(); - CommitAndActivate(); - TransformOperations scale; scale.AppendScale(5.f, 8.f, 3.f); @@ -7143,12 +5955,80 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { CommitAndActivate(); EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(3.f, ImplOf(mask)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); + EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2))); + + // Changing device-scale would affect ideal_contents_scale and + // maximum_animation_contents_scale. + + float device_scale_factor = 4.0f; + CommitAndActivate(device_scale_factor); + + EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(12.f, ImplOf(child1)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(12.f, ImplOf(mask)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(20.f, ImplOf(child2)->GetIdealContentsScale()); + + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); + EXPECT_FLOAT_EQ(32.f, GetMaximumAnimationScale(ImplOf(child2))); +} + +TEST_F(DrawPropertiesTest, DrawPropertyScales) { + auto root = Layer::Create(); + auto page_scale = Layer::Create(); + auto child1 = Layer::Create(); + auto child2 = Layer::Create(); + + gfx::Transform scale_transform_child1, scale_transform_child2; + scale_transform_child1.Scale(2, 3); + scale_transform_child2.Scale(4, 5); + + root->SetBounds(gfx::Size(1, 1)); + root->SetIsDrawable(true); + child1->SetBounds(gfx::Size(1, 1)); + child1->SetIsDrawable(true); + child2->SetBounds(gfx::Size(1, 1)); + child2->SetIsDrawable(true); + + root->AddChild(child1); + root->AddChild(child2); + root->AddChild(page_scale); + host()->SetRootLayer(root); + host()->SetElementIdsForTesting(); + + SetupRootProperties(root.get()); + CopyProperties(root.get(), page_scale.get()); + CreateTransformNode(page_scale.get()); + CopyProperties(page_scale.get(), child1.get()); + CreateTransformNode(child1.get()).local = scale_transform_child1; + CopyProperties(page_scale.get(), child2.get()); + CreateTransformNode(child2.get()).local = scale_transform_child2; + + LayerTreeHost::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.page_scale_transform = + page_scale->transform_tree_index(); + host()->RegisterViewportPropertyIds(viewport_property_ids); + + TransformOperations scale; + scale.AppendScale(5.f, 8.f, 3.f); + + AddAnimatedTransformToElementWithAnimation(child2->element_id(), timeline(), + 1.0, TransformOperations(), scale); + + CommitAndActivate(); + + EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale()); + + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale))); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2))); @@ -7157,13 +6037,12 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { // maximum_animation_contents_scale. float device_scale_factor = 1.0f; - float page_scale_factor = 3.f; - CommitAndActivate(device_scale_factor, page_scale_factor, page_scale.get()); + host()->SetPageScaleFactorAndLimits(3.f, 3.f, 3.f); + CommitAndActivate(); EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(3.f, ImplOf(page_scale)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(9.f, ImplOf(child1)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(9.f, ImplOf(mask)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(15.f, ImplOf(child2)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); @@ -7175,12 +6054,11 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { // maximum_animation_contents_scale. device_scale_factor = 4.0f; - CommitAndActivate(device_scale_factor, page_scale_factor, page_scale.get()); + CommitAndActivate(device_scale_factor); EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(12.f, ImplOf(page_scale)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(36.f, ImplOf(child1)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(36.f, ImplOf(mask)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(60.f, ImplOf(child2)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); @@ -7189,10 +6067,10 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { EXPECT_FLOAT_EQ(96.f, GetMaximumAnimationScale(ImplOf(child2))); } -TEST_F(LayerTreeHostCommonTest, AnimationScales) { - LayerImpl* root = root_layer_for_testing(); - auto* child1 = AddChildToRoot<LayerImpl>(); - auto* child2 = AddChildToRoot<LayerImpl>(); +TEST_F(DrawPropertiesTest, AnimationScales) { + LayerImpl* root = root_layer(); + auto* child1 = AddLayer<LayerImpl>(); + auto* child2 = AddLayer<LayerImpl>(); SetElementIdsForTesting(); gfx::Transform scale_transform_child1, scale_transform_child2; @@ -7203,7 +6081,6 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) { child1->SetBounds(gfx::Size(1, 1)); child2->SetBounds(gfx::Size(1, 1)); - SetupRootProperties(root); CopyProperties(root, child1); CreateTransformNode(child1).local = scale_transform_child1; CopyProperties(child1, child2); @@ -7214,7 +6091,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) { AddAnimatedTransformToElementWithAnimation( child2->element_id(), timeline_impl(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root)); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1)); @@ -7228,7 +6105,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) { SetTransform(child1, gfx::Transform()); root->layer_tree_impl()->SetTransformMutated(child1->element_id(), gfx::Transform()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(child2)); EXPECT_FLOAT_EQ(1.f, GetStartingAnimationScale(child2)); @@ -7239,8 +6116,8 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) { EXPECT_FLOAT_EQ(100.f, GetStartingAnimationScale(child2)); } -TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleContentRectInChildRenderSurface) { + LayerImpl* root = root_layer(); LayerImpl* clip = AddLayer<LayerImpl>(); LayerImpl* content = AddLayer<LayerImpl>(); @@ -7251,74 +6128,64 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { content->SetBounds(gfx::Size(768 / 2, 10000)); content->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip); CreateClipNode(clip); CopyProperties(clip, content); CreateEffectNode(content).render_surface_reason = RenderSurfaceReason::kTest; - gfx::Rect device_viewport_rect(768, 582); - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_rect, gfx::Transform(), &render_surface_list_impl); - inputs.device_scale_factor = 2.f; - inputs.page_scale_factor = 1.f; - inputs.page_scale_layer = nullptr; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + // Not calling UpdateActiveTreeDrawProperties() because we want to set a + // special device viewport rect. + host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(768, 582)); + float device_scale_factor = 2.f; + host_impl()->active_tree()->SetDeviceScaleFactor(device_scale_factor); + UpdateDrawProperties(host_impl()->active_tree()); // Layers in the root render surface have their visible content rect clipped // by the viewport. - EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), root->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(768 / device_scale_factor, 582 / device_scale_factor), + root->visible_layer_rect()); // Layers drawing to a child render surface should still have their visible // content rect clipped by the viewport. - EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), content->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(768 / device_scale_factor, 582 / device_scale_factor), + content->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, ViewportBoundsDeltaAffectVisibleContentRect) { - // Set two layers: the root layer clips it's child, - // the child draws its content. - - gfx::Size root_size = gfx::Size(300, 500); - - // Sublayer should be bigger than the root enlarged by bounds_delta. - gfx::Size sublayer_size = gfx::Size(300, 1000); +TEST_F(DrawPropertiesTest, ViewportBoundsDeltaAffectVisibleContentRect) { + gfx::Size container_size = gfx::Size(300, 500); + gfx::Size scroll_size = gfx::Size(300, 1000); // Device viewport accomidated the root and the browser controls. gfx::Rect device_viewport_rect = gfx::Rect(300, 600); - host_impl()->active_tree()->SetDeviceViewportRect(device_viewport_rect); - - LayerImpl* root = root_layer_for_testing(); - root->SetBounds(root_size); - root->SetMasksToBounds(true); - - // Make root the inner viewport scroll layer. This ensures the later call to - // |SetViewportBoundsDelta| will be on a viewport layer. - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.inner_viewport_scroll = root->id(); - host_impl()->active_tree()->SetViewportLayersFromIds(viewport_ids); + LayerTreeImpl* active_tree = host_impl()->active_tree(); + active_tree->SetDeviceViewportRect(device_viewport_rect); + active_tree->set_browser_controls_shrink_blink_size(true); + active_tree->SetTopControlsHeight(50); + active_tree->PushPageScaleFromMainThread(1.0f, 1.0f, 1.0f); - LayerImpl* sublayer = AddLayer<LayerImpl>(); - sublayer->SetBounds(sublayer_size); - sublayer->SetDrawsContent(true); + LayerImpl* root = root_layer(); + root->SetBounds(device_viewport_rect.size()); + SetupViewport(root, container_size, scroll_size); - SetupRootProperties(root); - CreateClipNode(root); - CopyProperties(root, sublayer); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); + scroll_layer->SetDrawsContent(true); - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect()); + active_tree->SetCurrentBrowserControlsShownRatio(1.0f); + active_tree->UpdateViewportContainerSizes(); + UpdateActiveTreeDrawProperties(); + EXPECT_EQ(gfx::Rect(container_size), scroll_layer->visible_layer_rect()); - root->SetViewportBoundsDelta(gfx::Vector2dF(0.0, 50.0)); - ExecuteCalculateDrawProperties(root); + active_tree->SetCurrentBrowserControlsShownRatio(0.0f); + active_tree->UpdateViewportContainerSizes(); + UpdateActiveTreeDrawProperties(); - gfx::Rect affected_by_delta(0, 0, root_size.width(), - root_size.height() + 50); - EXPECT_EQ(affected_by_delta, sublayer->visible_layer_rect()); + gfx::Rect affected_by_delta(container_size.width(), + container_size.height() + 50); + EXPECT_EQ(affected_by_delta, scroll_layer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) { +TEST_F(DrawPropertiesTest, VisibleContentRectForAnimatedLayer) { host_impl()->CreatePendingTree(); LayerImpl* root = EnsureRootLayerInPendingTree(); LayerImpl* animated = AddLayerInPendingTree<LayerImpl>(); @@ -7329,18 +6196,17 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) { root->SetBounds(gfx::Size(100, 100)); animated->SetBounds(gfx::Size(20, 20)); - SetupRootProperties(root); CopyProperties(root, animated); CreateEffectNode(animated).opacity = 0.f; AddOpacityTransitionToElementWithAnimation( animated->element_id(), timeline_impl(), 10.0, 0.f, 1.f, false); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); EXPECT_FALSE(animated->visible_layer_rect().IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, VisibleContentRectForAnimatedLayerWithSingularTransform) { host_impl()->CreatePendingTree(); LayerImpl* root = EnsureRootLayerInPendingTree(); @@ -7365,7 +6231,6 @@ TEST_F(LayerTreeHostCommonTest, surface->SetBounds(gfx::Size(100, 100)); descendant_of_keyframe_model->SetBounds(gfx::Size(200, 200)); - SetupRootProperties(root); CopyProperties(root, clip); CreateClipNode(clip); CopyProperties(clip, animated); @@ -7382,7 +6247,7 @@ TEST_F(LayerTreeHostCommonTest, AddAnimatedTransformToElementWithAnimation( animated->element_id(), timeline_impl(), 10.0, start_transform_operations, end_transform_operations); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); // Since animated has singular transform, it is not be part of render // surface layer list but should be rastered. EXPECT_FALSE(animated->contributes_to_drawn_render_surface()); @@ -7402,7 +6267,7 @@ TEST_F(LayerTreeHostCommonTest, zero_matrix.Scale3d(0.f, 0.f, 0.f); root->layer_tree_impl()->SetTransformMutated(animated->element_id(), zero_matrix); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); // The animated layer will be treated as fully visible when we combine clips // in screen space. @@ -7417,7 +6282,7 @@ TEST_F(LayerTreeHostCommonTest, host_impl()->ActivateSyncTree(); LayerImpl* active_root = host_impl()->active_tree()->LayerById(root->id()); - ExecuteCalculateDrawProperties(active_root); + UpdateActiveTreeDrawProperties(); // Since the animated has singular transform, it is not be part of render // surface layer list. @@ -7432,159 +6297,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(120, 120), active_animated->visible_layer_rect()); } -// Verify that having animated opacity but current opacity 1 still creates -// a render surface. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - AnimatedOpacityCreatesRenderSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto grandchild = Layer::Create(); - child->AddChild(grandchild); - - root->SetBounds(gfx::Size(50, 50)); - child->SetBounds(gfx::Size(50, 50)); - child->SetIsDrawable(true); - grandchild->SetBounds(gfx::Size(50, 50)); - grandchild->SetIsDrawable(true); - - host()->SetElementIdsForTesting(); - AddOpacityTransitionToElementWithAnimation(child->element_id(), timeline(), - 10.0, 1.f, 0.2f, false); - CommitAndActivate(); - - EXPECT_EQ(1.f, ImplOf(child)->Opacity()); - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); -} - -static bool FilterIsAnimating(LayerImpl* layer) { - MutatorHost* host = layer->layer_tree_impl()->mutator_host(); - return host->IsAnimatingFilterProperty(layer->element_id(), - layer->GetElementTypeForAnimation()); -} - -// Verify that having an animated filter (but no current filter, as these -// are mutually exclusive) correctly creates a render surface. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - AnimatedFilterCreatesRenderSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto grandchild = Layer::Create(); - child->AddChild(grandchild); - - root->SetBounds(gfx::Size(50, 50)); - child->SetBounds(gfx::Size(50, 50)); - grandchild->SetBounds(gfx::Size(50, 50)); - - host()->SetElementIdsForTesting(); - AddAnimatedFilterToElementWithAnimation(child->element_id(), timeline(), 10.0, - 0.1f, 0.2f); - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); - EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); - - EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); - EXPECT_TRUE(FilterIsAnimating(ImplOf(child))); - EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); -} - -bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) { - MutatorHost* host = layer.layer_tree_impl()->mutator_host(); - return host->HasPotentiallyRunningFilterAnimation( - layer.element_id(), layer.GetElementTypeForAnimation()); -} - -// Verify that having a filter animation with a delayed start time creates a -// render surface. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - DelayedFilterAnimationCreatesRenderSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto grandchild = Layer::Create(); - child->AddChild(grandchild); - - root->SetBounds(gfx::Size(50, 50)); - child->SetBounds(gfx::Size(50, 50)); - grandchild->SetBounds(gfx::Size(50, 50)); - - host()->SetElementIdsForTesting(); - - std::unique_ptr<KeyframedFilterAnimationCurve> curve( - KeyframedFilterAnimationCurve::Create()); - FilterOperations start_filters; - start_filters.Append(FilterOperation::CreateBrightnessFilter(0.1f)); - FilterOperations end_filters; - end_filters.Append(FilterOperation::CreateBrightnessFilter(0.3f)); - curve->AddKeyframe( - FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr)); - curve->AddKeyframe(FilterKeyframe::Create( - base::TimeDelta::FromMilliseconds(100), end_filters, nullptr)); - std::unique_ptr<KeyframeModel> keyframe_model = - KeyframeModel::Create(std::move(curve), 0, 1, TargetProperty::FILTER); - keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE); - keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); - - AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(), - std::move(keyframe_model)); - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); - EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); - - EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); - EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(root))); - EXPECT_FALSE(FilterIsAnimating(ImplOf(child))); - EXPECT_TRUE(HasPotentiallyRunningFilterAnimation(*ImplOf(child))); - EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); - EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(grandchild))); -} - -// Needs layer tree mode: needs_rebuild flag. Not using impl-side -// PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - ChangingAxisAlignmentTriggersRebuild) { - gfx::Transform translate; - gfx::Transform rotate; - - translate.Translate(10, 10); - rotate.Rotate(45); - - scoped_refptr<Layer> root = Layer::Create(); - root->SetBounds(gfx::Size(800, 800)); - - host()->SetRootLayer(root); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_FALSE(host()->property_trees()->needs_rebuild); - - root->SetTransform(translate); - EXPECT_FALSE(host()->property_trees()->needs_rebuild); - - root->SetTransform(rotate); - EXPECT_TRUE(host()->property_trees()->needs_rebuild); -} - -TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ChangeTransformOrigin) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); gfx::Transform scale_matrix; @@ -7595,21 +6309,20 @@ TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) { child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = scale_matrix; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); SetTransformOrigin(child, gfx::Point3F(10.f, 10.f, 10.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(5, 5, 5, 5), child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, UpdateScrollChildPosition) { + LayerImpl* root = root_layer(); LayerImpl* scroll_parent = AddLayer<LayerImpl>(); LayerImpl* scroll_child = AddLayer<LayerImpl>(); @@ -7624,27 +6337,26 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { scroll_child->SetBounds(gfx::Size(40, 40)); scroll_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, scroll_parent); CreateTransformNode(scroll_parent); CreateScrollNode(scroll_parent); CopyProperties(scroll_parent, scroll_child); CreateTransformNode(scroll_child).local.Scale(2.f, 2.f); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect()); SetScrollOffset(scroll_parent, gfx::ScrollOffset(0.f, 10.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect()); SetPostTranslation(scroll_child, gfx::Vector2dF(0, -10.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(0, 10, 25, 25), scroll_child->visible_layer_rect()); } // Needs layer tree mode: copy request. Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, HasCopyRequestsInTargetSubtree) { +TEST_F(DrawPropertiesTestWithLayerTree, HasCopyRequestsInTargetSubtree) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> child1 = Layer::Create(); scoped_refptr<Layer> child2 = Layer::Create(); @@ -7662,7 +6374,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, HasCopyRequestsInTargetSubtree) { greatgrandchild->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); child2->SetOpacity(0.f); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(LayerSubtreeHasCopyRequest(root.get())); EXPECT_TRUE(LayerSubtreeHasCopyRequest(child1.get())); @@ -7673,7 +6385,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, HasCopyRequestsInTargetSubtree) { // Needs layer tree mode: hide_layer_and_subtree, etc. // Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { +TEST_F(DrawPropertiesTestWithLayerTree, SkippingSubtreeMain) { FakeContentLayerClient client; scoped_refptr<Layer> root = Layer::Create(); @@ -7697,7 +6409,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { host()->SetElementIdsForTesting(); // Check the non-skipped case. - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); // Now we will reset the visible rect from property trees for the grandchild, @@ -7708,12 +6420,12 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { singular.matrix().set(0, 0, 0); child->SetTransform(singular); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); child->SetTransform(gfx::Transform()); child->SetHideLayerAndSubtree(true); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); child->SetHideLayerAndSubtree(false); @@ -7731,14 +6443,14 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); RemoveKeyframeModelFromElementWithExistingKeyframeEffect( child->element_id(), timeline(), keyframe_model_id); child->SetTransform(gfx::Transform()); child->SetOpacity(0.f); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); // Now, even though child has zero opacity, we will configure |grandchild| and @@ -7746,7 +6458,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { // processed anyhow. grandchild->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); // Add an opacity animation with a start delay. @@ -7758,12 +6470,12 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddKeyframeModelToElementWithExistingKeyframeEffect( child->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); } // Needs layer tree mode: hide_layer_and_subtree, etc. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayerImpl) { +TEST_F(DrawPropertiesTestWithLayerTree, SkippingLayerImpl) { auto root = Layer::Create(); host()->SetRootLayer(root); auto parent = Layer::Create(); @@ -7892,7 +6604,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayerImpl) { // we can ignore the size of all its children. We need to make sure that // we don't do this if an animation can replace this transform in the // compositor without recomputing the trees. -TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { +TEST_F(DrawPropertiesTest, LayerSkippingInSubtreeOfSingularTransform) { // Set up a transform animation std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); @@ -7914,7 +6626,7 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { animation->AddKeyframeModel(std::move(transform_animation)); // Set up some layers to have a tree. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -7939,12 +6651,11 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child); CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect()); ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); @@ -7952,7 +6663,7 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { SetTransform(child, singular); grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(), child->visible_layer_rect()); @@ -7961,7 +6672,7 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect()); ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); @@ -7973,14 +6684,14 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { SetTransform(child, singular); grand_child->set_visible_layer_rect(gfx::Rect(1, 1)); child->set_visible_layer_rect(gfx::Rect(1, 1)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); } // This tests that we skip computing the visible areas for the subtree // rooted at nodes with constant zero opacity. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingPendingLayerImpl) { +TEST_F(DrawPropertiesTestWithLayerTree, SkippingPendingLayerImpl) { auto root = Layer::Create(); auto child = Layer::Create(); auto grandchild = Layer::Create(); @@ -8035,7 +6746,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingPendingLayerImpl) { } // Needs layer tree mode: hide_layer_and_subtree. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayer) { +TEST_F(DrawPropertiesTestWithLayerTree, SkippingLayer) { auto root = Layer::Create(); host()->SetRootLayer(root); auto child = Layer::Create(); @@ -8074,86 +6785,11 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayer) { EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -// Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, ResetPropertyTreeIndices) { - scoped_refptr<Layer> root = Layer::Create(); - root->SetBounds(gfx::Size(800, 800)); - - gfx::Transform translate_z; - translate_z.Translate3d(0, 0, 10); - - scoped_refptr<Layer> child = Layer::Create(); - child->SetTransform(translate_z); - child->SetBounds(gfx::Size(100, 100)); - - root->AddChild(child); - - host()->SetRootLayer(root); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_NE(-1, child->transform_tree_index()); - - child->RemoveFromParent(); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_EQ(-1, child->transform_tree_index()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceClipsSubtree) { - // Ensure that a Clip Node is added when a render surface applies clip. - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto significant_transform = Layer::Create(); - root->AddChild(significant_transform); - auto layer_clips_subtree = Layer::Create(); - significant_transform->AddChild(layer_clips_subtree); - auto render_surface = Layer::Create(); - layer_clips_subtree->AddChild(render_surface); - auto test_layer = Layer::Create(); - render_surface->AddChild(test_layer); - - // This transform should be a significant one so that a transform node is - // formed for it. - gfx::Transform transform1; - transform1.RotateAboutYAxis(45); - transform1.RotateAboutXAxis(30); - // This transform should be a 3d transform as we want the render surface - // to flatten the transform - gfx::Transform transform2; - transform2.Translate3d(10, 10, 10); - - root->SetBounds(gfx::Size(30, 30)); - significant_transform->SetTransform(transform1); - significant_transform->SetBounds(gfx::Size(30, 30)); - layer_clips_subtree->SetBounds(gfx::Size(30, 30)); - layer_clips_subtree->SetMasksToBounds(true); - layer_clips_subtree->SetForceRenderSurfaceForTesting(true); - render_surface->SetTransform(transform2); - render_surface->SetBounds(gfx::Size(30, 30)); - render_surface->SetForceRenderSurfaceForTesting(true); - test_layer->SetBounds(gfx::Size(30, 30)); - test_layer->SetIsDrawable(true); - - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(significant_transform), - GetRenderSurfaceImpl(root)); - EXPECT_TRUE(GetRenderSurfaceImpl(layer_clips_subtree)); - EXPECT_NE(GetRenderSurfaceImpl(render_surface), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(test_layer), - GetRenderSurfaceImpl(render_surface)); - - EXPECT_EQ(gfx::Rect(30, 20), ImplOf(test_layer)->visible_layer_rect()); -} - -TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { +TEST_F(DrawPropertiesTest, TransformOfParentClipNodeAncestorOfTarget) { // Ensure that when parent clip node's transform is an ancestor of current // clip node's target, clip is 'projected' from parent space to current // target space and visible rects are calculated correctly. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* target_layer = AddLayer<LayerImpl>(); LayerImpl* test_layer = AddLayer<LayerImpl>(); @@ -8169,7 +6805,6 @@ TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { test_layer->SetBounds(gfx::Size(30, 30)); test_layer->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_layer); CreateTransformNode(clip_layer).local = transform; CreateClipNode(clip_layer); @@ -8178,16 +6813,15 @@ TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { CreateClipNode(target_layer); CopyProperties(target_layer, test_layer); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), test_layer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, - RenderSurfaceWithUnclippedDescendantsClipsSubtree) { +TEST_F(DrawPropertiesTest, RenderSurfaceWithUnclippedDescendantsClipsSubtree) { // Ensure clip rect is calculated correctly when render surface has unclipped // descendants. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* between_clip_parent_and_child = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); @@ -8200,7 +6834,6 @@ TEST_F(LayerTreeHostCommonTest, test_layer->SetBounds(gfx::Size(30, 30)); test_layer->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateTransformNode(clip_parent).local.Translate(2, 2); CreateClipNode(clip_parent); @@ -8214,7 +6847,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface, test_layer); test_layer->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(test_layer->is_clipped()); EXPECT_FALSE(test_layer->render_target()->is_clipped()); @@ -8222,12 +6855,12 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(28, 28), test_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, RenderSurfaceWithUnclippedDescendantsButDoesntApplyOwnClip) { // Ensure that the visible layer rect of a descendant of a surface with // unclipped descendants is computed correctly, when the surface doesn't apply // a clip. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -8241,7 +6874,6 @@ TEST_F(LayerTreeHostCommonTest, child->SetBounds(gfx::Size(40, 40)); child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_parent); CopyProperties(clip_parent, render_surface); CreateEffectNode(render_surface).render_surface_reason = @@ -8250,13 +6882,13 @@ TEST_F(LayerTreeHostCommonTest, clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); CopyProperties(clip_child, child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 10), child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, RenderSurfaceClipsSubtreeAndHasUnclippedDescendants) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* test_layer1 = AddLayer<LayerImpl>(); @@ -8274,7 +6906,6 @@ TEST_F(LayerTreeHostCommonTest, test_layer2->SetBounds(gfx::Size(50, 50)); test_layer2->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, clip_parent); CopyProperties(clip_parent, render_surface); @@ -8286,15 +6917,15 @@ TEST_F(LayerTreeHostCommonTest, clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); CopyProperties(clip_child, test_layer2); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), render_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(30, 30), test_layer1->visible_layer_rect()); EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(30, 30), test_layer2->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, UnclippedClipParent) { + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -8307,7 +6938,6 @@ TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { clip_child->SetBounds(gfx::Size(50, 50)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_parent); CopyProperties(clip_parent, render_surface); CreateEffectNode(render_surface).render_surface_reason = @@ -8316,7 +6946,7 @@ TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { CopyProperties(render_surface, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // The clip child should inherit its clip parent's clipping state, not its // tree parent's clipping state. @@ -8325,11 +6955,11 @@ TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { EXPECT_FALSE(clip_child->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { +TEST_F(DrawPropertiesTest, RenderSurfaceContentRectWithMultipleSurfaces) { // Tests the value of render surface content rect when we have multiple types // of surfaces : unclipped surfaces, surfaces with unclipped surfaces and // clipped surfaces. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); @@ -8352,7 +6982,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { clipped_surface->SetBounds(gfx::Size(70, 70)); clipped_surface->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, unclipped_surface); CreateEffectNode(unclipped_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -8373,7 +7002,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { CreateEffectNode(clipped_surface).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(unclipped_surface)->content_rect()); EXPECT_EQ(gfx::Rect(50, 50), @@ -8384,10 +7013,10 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { GetRenderSurface(clipped_surface)->content_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { +TEST_F(DrawPropertiesTest, ClipBetweenClipChildTargetAndClipParentTarget) { // Tests the value of render surface content rect when we have a layer that // clips between the clip parent's target and clip child's target. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* surface = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); @@ -8403,7 +7032,6 @@ TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, surface); CreateTransformNode(surface).local.RotateAboutXAxis(10); CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -8418,14 +7046,14 @@ TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { CopyProperties(unclipped_desc_surface, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurface(unclipped_desc_surface)->content_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleRectForDescendantOfScaledSurface) { + LayerImpl* root = root_layer(); LayerImpl* surface = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); @@ -8441,7 +7069,6 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, surface); CreateTransformNode(surface).local.Scale(2, 2); CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -8455,13 +7082,13 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { CopyProperties(unclipped_desc_surface, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(20, 20), clip_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LayerWithInputHandlerAndZeroOpacity) { + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* test_layer = AddLayer<LayerImpl>(); @@ -8478,7 +7105,6 @@ TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 20, 20)); test_layer->SetTouchActionRegion(std::move(touch_action_region)); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -8487,13 +7113,13 @@ TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { CreateTransformNode(test_layer).local = translation; CreateEffectNode(test_layer).opacity = 0.f; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ(translation, test_layer->ScreenSpaceTransform()); } -TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipParentDrawsIntoScaledRootSurface) { + LayerImpl* root = root_layer(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* clip_parent_child = AddLayer<LayerImpl>(); @@ -8509,7 +7135,6 @@ TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) { clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_layer); CreateClipNode(clip_layer); CopyProperties(clip_layer, clip_parent); @@ -8523,18 +7148,18 @@ TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) { clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); float device_scale_factor = 1.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_EQ(gfx::Rect(-10, -10, 20, 20), clip_child->clip_rect()); EXPECT_EQ(gfx::Rect(10, 10), clip_child->visible_layer_rect()); device_scale_factor = 2.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_EQ(gfx::Rect(-20, -20, 40, 40), clip_child->clip_rect()); EXPECT_EQ(gfx::Rect(10, 10), clip_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipChildVisibleRect) { + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -8546,7 +7171,6 @@ TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { clip_child->SetBounds(gfx::Size(50, 50)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); CopyProperties(clip_parent, render_surface); @@ -8556,13 +7180,12 @@ TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { CopyProperties(render_surface, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, - LayerClipRectLargerThanClippingRenderSurfaceRect) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LayerClipRectLargerThanClippingRenderSurfaceRect) { + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* test_layer = AddLayer<LayerImpl>(); @@ -8574,7 +7197,6 @@ TEST_F(LayerTreeHostCommonTest, test_layer->SetBounds(gfx::Size(50, 50)); test_layer->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface); CreateTransformNode(render_surface); @@ -8584,7 +7206,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface, test_layer); CreateClipNode(test_layer); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), root->clip_rect()); EXPECT_EQ(gfx::Rect(50, 50), render_surface->clip_rect()); @@ -8592,7 +7214,7 @@ TEST_F(LayerTreeHostCommonTest, } // Needs layer tree mode: hide_layer_and_subtree. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeIsHiddenTest) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeIsHiddenTest) { // Tests that subtree is hidden is updated. auto root = Layer::Create(); host()->SetRootLayer(root); @@ -8621,8 +7243,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeIsHiddenTest) { GetRenderSurfaceImpl(test)->OwningEffectNode()->screen_space_opacity); } -TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TwoUnclippedRenderSurfaces) { + LayerImpl* root = root_layer(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* render_surface2 = AddLayer<LayerImpl>(); @@ -8637,7 +7259,6 @@ TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { clip_child->SetBounds(gfx::Size(30, 30)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, clip_layer); CreateClipNode(clip_layer); @@ -8652,13 +7273,13 @@ TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { CopyProperties(render_surface2, clip_child); clip_child->SetClipTreeIndex(root->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(-10, -10, 30, 30), render_surface2->clip_rect()); } // Needs layer tree mode: mask layer. -TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { +TEST_F(DrawPropertiesTestWithLayerTree, MaskLayerDrawProperties) { // Tests that a mask layer's draw properties are computed correctly. auto root = Layer::Create(); host()->SetRootLayer(root); @@ -8675,7 +7296,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { root->SetIsDrawable(true); child->SetTransform(transform); child->SetBounds(gfx::Size(30, 30)); - child->SetIsDrawable(false); + child->SetIsDrawable(true); + child->SetOpacity(0.f); mask->SetBounds(gfx::Size(30, 30)); CommitAndActivate(); @@ -8684,13 +7306,14 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { // mask doesn't contribute to a drawn render surface. This means it has an // empty visible rect, but its screen space transform can still be computed // correctly on-demand. + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_EQ(gfx::Rect(), ImplOf(mask)->visible_layer_rect()); EXPECT_TRANSFORMATION_MATRIX_EQ(transform, ImplOf(mask)->ScreenSpaceTransform()); // Make the child's render surface have contributing content. - child->SetIsDrawable(true); + child->SetOpacity(1.f); CommitAndActivate(); EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_EQ(gfx::Rect(30, 30), ImplOf(mask)->visible_layer_rect()); @@ -8703,11 +7326,21 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { EXPECT_TRANSFORMATION_MATRIX_EQ(transform, ImplOf(mask)->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(20, 20), ImplOf(mask)->visible_layer_rect()); + + // For now SetIsDrawable of masked layer doesn't affect draw properties of + // the mask layer because it doesn't affect property trees. + child->SetIsDrawable(false); + CommitAndActivate(); + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); + + // SetIsDrawable of mask layer itself affects its draw properties. + mask->SetIsDrawable(false); + CommitAndActivate(); + EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); } -TEST_F(LayerTreeHostCommonTest, - SublayerScaleWithTransformNodeBetweenTwoTargets) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, SublayerScaleWithTransformNodeBetweenTwoTargets) { + LayerImpl* root = root_layer(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* between_targets = AddLayer<LayerImpl>(); LayerImpl* render_surface2 = AddLayer<LayerImpl>(); @@ -8726,7 +7359,6 @@ TEST_F(LayerTreeHostCommonTest, // We want layer between the two targets to create a clip node and effect // node but it shouldn't create a render surface. between_targets->SetMasksToBounds(true); - SetupRootProperties(root); CopyProperties(root, render_surface1); CreateTransformNode(render_surface1).local = scale; CreateEffectNode(render_surface1).render_surface_reason = @@ -8739,7 +7371,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceReason::kTest; CopyProperties(render_surface2, test_layer); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), GetEffectNode(render_surface1)->surface_contents_scale); @@ -8751,8 +7383,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(15, 15), test_layer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, NoisyTransform) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, NoisyTransform) { + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); @@ -8770,7 +7402,6 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { transform.matrix().setDouble(2, 2, 6.12323e-17); transform.matrix().setDouble(2, 0, -1); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateTransformNode(render_surface).local = transform; CreateEffectNode(render_surface).render_surface_reason = @@ -8779,7 +7410,7 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { CopyProperties(parent, child); CreateTransformNode(child).local = transform; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); gfx::Transform expected; expected.matrix().setDouble(0, 0, 3.749395e-33); @@ -8789,8 +7420,8 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { EXPECT_TRANSFORMATION_MATRIX_EQ(expected, child->ScreenSpaceTransform()); } -TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LargeTransformTest) { + LayerImpl* root = root_layer(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); @@ -8813,7 +7444,6 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { // what exactly happens here. child->SetBounds(gfx::Size(30, 30)); - SetupRootProperties(root); CopyProperties(root, render_surface1); CreateEffectNode(render_surface1).render_surface_reason = RenderSurfaceReason::kTest; @@ -8821,7 +7451,7 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { CreateTransformNode(child).local = large_transform; CreateClipNode(child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::RectF(), GetRenderSurface(render_surface1)->DrawableContentRect()); @@ -8835,54 +7465,11 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { EXPECT_TRUE(is_inf_or_nan); // The root layer should be in the RenderSurfaceList. - const auto* rsl = render_surface_list_impl(); - EXPECT_TRUE(base::Contains(*rsl, GetRenderSurface(root))); -} - -// Needs layer tree mode: testing needs_rebuild flag. -// Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - PropertyTreesRebuildWithOpacityChanges) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> child = Layer::Create(); - child->SetIsDrawable(true); - root->AddChild(child); - host()->SetRootLayer(root); - - root->SetBounds(gfx::Size(100, 100)); - child->SetBounds(gfx::Size(20, 20)); - ExecuteCalculateDrawProperties(root.get()); - - // Changing the opacity from 1 to non-1 value should trigger rebuild of - // property trees as a new effect node will be created. - child->SetOpacity(0.5f); - PropertyTrees* property_trees = host()->property_trees(); - EXPECT_TRUE(property_trees->needs_rebuild); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); - - // child already has an effect node. Changing its opacity shouldn't trigger - // a property trees rebuild. - child->SetOpacity(0.8f); - property_trees = host()->property_trees(); - EXPECT_FALSE(property_trees->needs_rebuild); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); - - // Changing the opacity from non-1 value to 1 should trigger a rebuild of - // property trees as the effect node may no longer be needed. - child->SetOpacity(1.f); - property_trees = host()->property_trees(); - EXPECT_TRUE(property_trees->needs_rebuild); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_EQ(child->effect_tree_index(), root->effect_tree_index()); + EXPECT_TRUE(base::Contains(GetRenderSurfaceList(), GetRenderSurface(root))); } // In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, OpacityAnimationsTrackingTest) { +TEST_F(DrawPropertiesTestWithLayerTree, OpacityAnimationsTrackingTest) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> animated = Layer::Create(); animated->SetIsDrawable(true); @@ -8912,7 +7499,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, OpacityAnimationsTrackingTest) { AddKeyframeModelToElementWithExistingKeyframeEffect( animated->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EffectNode* node = GetEffectNode(animated.get()); EXPECT_FALSE(node->is_currently_animating_opacity); @@ -8932,7 +7519,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, OpacityAnimationsTrackingTest) { } // In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformAnimationsTrackingTest) { +TEST_F(DrawPropertiesTestWithLayerTree, TransformAnimationsTrackingTest) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> animated = Layer::Create(); animated->SetIsDrawable(true); @@ -8970,7 +7557,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformAnimationsTrackingTest) { AddKeyframeModelToElementWithExistingKeyframeEffect( animated->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); TransformNode* node = GetTransformNode(animated.get()); EXPECT_FALSE(node->is_currently_animating); @@ -8990,7 +7577,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformAnimationsTrackingTest) { } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, CopyRequestScalingTest) { +TEST_F(DrawPropertiesTestWithLayerTree, CopyRequestScalingTest) { auto root = Layer::Create(); host()->SetRootLayer(root); auto scale_layer = Layer::Create(); @@ -9044,8 +7631,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, CopyRequestScalingTest) { } // Needs layer tree mode: hide_layer_and_subtree, etc. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - SubtreeHiddenWithCacheRenderSurface) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHiddenWithCacheRenderSurface) { auto root = Layer::Create(); host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); @@ -9101,15 +7687,15 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, // We should have four render surfaces, one for the root, one for the grand // parent since it has opacity and two drawing descendants, one for the parent // since it owns a surface, and one for the cache. - ASSERT_EQ(4u, render_surface_list_impl()->size()); + ASSERT_EQ(4u, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); EXPECT_EQ(static_cast<uint64_t>(cache_grand_parent->id()), - render_surface_list_impl()->at(1)->id()); + GetRenderSurfaceList().at(1)->id()); EXPECT_EQ(static_cast<uint64_t>(cache_parent->id()), - render_surface_list_impl()->at(2)->id()); + GetRenderSurfaceList().at(2)->id()); EXPECT_EQ(static_cast<uint64_t>(cache_render_surface->id()), - render_surface_list_impl()->at(3)->id()); + GetRenderSurfaceList().at(3)->id()); // The root render surface should have 2 contributing layers. EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); @@ -9152,7 +7738,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, +TEST_F(DrawPropertiesTestWithLayerTree, VisibleRectInNonRootCacheRenderSurface) { auto root = Layer::Create(); host()->SetRootLayer(root); @@ -9260,1132 +7846,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, EXPECT_EQ(gfx::Rect(20, 20), ImplOf(cache_surface)->visible_layer_rect()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceListForTrilinearFiltering) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto parent = Layer::Create(); - root->AddChild(parent); - auto child1 = Layer::Create(); - parent->AddChild(child1); - auto child2 = Layer::Create(); - parent->AddChild(child2); - - gfx::Transform scale_matrix; - scale_matrix.Scale(.25f, .25f); - - root->SetBounds(gfx::Size(200, 200)); - parent->SetTransform(scale_matrix); - parent->SetTrilinearFiltering(true); - child1->SetBounds(gfx::Size(50, 50)); - child1->SetIsDrawable(true); - child1->SetForceRenderSurfaceForTesting(true); - child2->SetPosition(gfx::PointF(50, 50)); - child2->SetBounds(gfx::Size(50, 50)); - child2->SetIsDrawable(true); - child2->SetForceRenderSurfaceForTesting(true); - - CommitAndActivate(); - - ASSERT_TRUE(GetRenderSurfaceImpl(parent)); - EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); - EXPECT_EQ(4U, render_surface_list_impl()->size()); - - // The rectangle enclosing child1 and child2 (0,0 100x100), scaled by the - // scale matrix to (0,0 25x25). - EXPECT_EQ(gfx::RectF(0, 0, 25, 25), - GetRenderSurfaceImpl(parent)->DrawableContentRect()); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, RoundedCornerBounds) { - // Layer Tree: - // +root - // +--render surface - // +----rounded corner layer 1 [should trigger render surface] - // +----layer 1 - // +--rounded corner layer 2 [should trigger render surface] - // +----layer 2 - // +------rounded corner layer 3 [should trigger render surface] - // +--------rounded corner layer 4 [should trigger render surface] - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - constexpr int kRoundedCorner3Radius = 1; - constexpr int kRoundedCorner4Radius = 1; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(15.f, 15.f, 20.f, 20.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f); - constexpr gfx::RectF kRoundedCornerLayer3Bound(0.f, 15.f, 5.f, 5.f); - constexpr gfx::RectF kRoundedCornerLayer4Bound(1.f, 1.f, 3.f, 3.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> render_surface = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); - scoped_refptr<Layer> layer_2 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create(); - - // Set up layer tree - root->AddChild(render_surface); - root->AddChild(rounded_corner_layer_2); - - render_surface->AddChild(rounded_corner_layer_1); - render_surface->AddChild(layer_1); - - rounded_corner_layer_2->AddChild(layer_2); - - layer_2->AddChild(rounded_corner_layer_3); - - rounded_corner_layer_3->AddChild(rounded_corner_layer_4); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - render_surface->SetPosition(gfx::PointF(0, 0)); - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - layer_1->SetPosition(gfx::PointF(10.f, 10.f)); - rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); - layer_2->SetPosition(gfx::PointF(30.f, 30.f)); - rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin()); - rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - render_surface->SetBounds(gfx::Size(50, 50)); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - layer_1->SetBounds(gfx::Size(10, 10)); - rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - layer_2->SetBounds(gfx::Size(25, 25)); - rounded_corner_layer_3->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); - rounded_corner_layer_4->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); - - // Add Layer transforms. - gfx::Transform layer_2_transform; - constexpr gfx::Vector2dF kLayer2Translation(10.f, 10.f); - layer_2_transform.Translate(kLayer2Translation); - layer_2->SetTransform(layer_2_transform); - - gfx::Transform rounded_corner_layer_3_transform; - constexpr float kRoundedCorner3Scale = 2.f; - rounded_corner_layer_3_transform.Scale(kRoundedCorner3Scale, - kRoundedCorner3Scale); - rounded_corner_layer_3->SetTransform(rounded_corner_layer_3_transform); - - // Set the layer properties - render_surface->SetForceRenderSurfaceForTesting(true); - - root->SetIsDrawable(true); - render_surface->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - layer_1->SetIsDrawable(true); - rounded_corner_layer_2->SetIsDrawable(true); - layer_2->SetIsDrawable(true); - rounded_corner_layer_3->SetIsDrawable(true); - rounded_corner_layer_4->SetIsDrawable(true); - - // Set Rounded corners - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - rounded_corner_layer_3->SetRoundedCorner( - {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, - kRoundedCorner3Radius}); - rounded_corner_layer_4->SetRoundedCorner( - {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, - kRoundedCorner4Radius}); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this effect node has no descendants that draw and no descendant that - // has a rounded corner, it does not need a render surface. - const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this node has descendants with roudned corners, it needs a render - // surface. It also has 2 descendants that draw. - effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - // Since this node has a descendant that has a rounded corner, it will trigger - // the creation of a render surface. - effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), - kRoundedCorner3Radius); - EXPECT_EQ(rounded_corner_bounds_3.rect(), - gfx::RectF(kRoundedCornerLayer3Bound.size())); - - // Since this node has no descendants that draw nor any descendant that has a - // rounded corner, it does not need a render surface. - effect_node = GetEffectNode(rounded_corner_layer_4.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), - kRoundedCorner4Radius); - EXPECT_EQ(rounded_corner_bounds_4.rect(), - gfx::RectF(kRoundedCornerLayer4Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* rounded_corner_layer_1_impl = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_2_impl = - layer_tree_impl->LayerById(rounded_corner_layer_2->id()); - LayerImpl* rounded_corner_layer_3_impl = - layer_tree_impl->LayerById(rounded_corner_layer_3->id()); - LayerImpl* rounded_corner_layer_4_impl = - layer_tree_impl->LayerById(rounded_corner_layer_4->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Rounded corner layer 1 - // The render target for this layer is |render_surface|, hence its target - // bounds are relative to |render_surface|. - // The offset from the origin of the render target is [15, 15] and the device - // scale factor is 1.6 thus giving the target space origin of [24, 24]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Rounded corner layer 2 - // The render target for this layer is |root|. - // The offset from the origin of the render target is [40, 40] and the device - // scale factor is 1.6 thus giving the target space origin of [64, 64]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_2 = - rounded_corner_layer_2_impl->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); - - // Rounded corner layer 3 - // The render target for this layer is |rounded_corner_2|. - // The net offset from the origin of the render target is [40, 55] and the - // device scale factor is 1.6 thus giving the target space origin of [64, 88]. - // The corner radius is also scaled by a factor of 1.6 * transform scale. - const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_3_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer3Bound; - bounds_in_target_space += - layer_2->position().OffsetFromOrigin() + kLayer2Translation; - bounds_in_target_space.Scale(kDeviceScale); - gfx::SizeF transformed_size = bounds_in_target_space.size(); - transformed_size.Scale(kRoundedCorner3Scale); - bounds_in_target_space.set_size(transformed_size); - - const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_3_impl->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), - kRoundedCorner3Radius * kDeviceScale * kRoundedCorner3Scale); - - // Rounded corner layer 4 - // The render target for this layer is |rounded_corner_3|. - // The net offset from the origin of the render target is [1, 1] and the - // net scale is 1.6 * transform scale = 3.2 thus giving the target space o - // rigin of [3.2, 3.2]. - // The corner radius is also scaled by a factor of 3.2. - const gfx::RRectF actual_rrect_4 = - rounded_corner_layer_4_impl->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer4Bound; - bounds_in_target_space.Scale(kDeviceScale * kRoundedCorner3Scale); - EXPECT_EQ(actual_rrect_4.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_4.GetSimpleRadius(), - kRoundedCorner4Radius * kDeviceScale * kRoundedCorner3Scale); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RoundedCornerBoundsInterveningRenderTarget) { - // Layer Tree: - // +root - // +--rounded corner layer 1 [should not trigger render surface] - // +----render surface [Does not draw] - // +------rounded corner layer 2 [should not trigger render surface] - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(60.f, 0.f, 40.f, 30.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 30.f, 20.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> render_surface = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); - - // Set up layer tree - root->AddChild(rounded_corner_layer_1); - rounded_corner_layer_1->AddChild(render_surface); - render_surface->AddChild(rounded_corner_layer_2); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - render_surface->SetPosition(gfx::PointF(0, 0)); - rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - render_surface->SetBounds(gfx::Size(30, 30)); - rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - - // Set the layer properties - render_surface->SetForceRenderSurfaceForTesting(true); - - root->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - rounded_corner_layer_2->SetIsDrawable(true); - - // Set Rounded corners - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this effect node has only 1 descendant that draws and no descendant - // that has a rounded corner before the render surface, it does not need a - // render surface. - const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this effect node has no descendants that draw and no descendant that - // has a rounded corner, it does not need a render surface. - effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* rounded_corner_layer_1_impl = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_2_impl = - layer_tree_impl->LayerById(rounded_corner_layer_2->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Rounded corner layer 1 - // The render target for this layer is |root|, hence its target - // bounds are relative to |root|. - // The offset from the origin of the render target is [60, 0] and the device - // scale factor is 1.6 thus giving the target space origin of [96, 0]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Rounded corner layer 2 - // The render target for this layer is |render_surface|. - // The offset from the origin of the render target is [0, 0]. - const gfx::RRectF actual_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RoundedCornerBoundsSiblingRenderTarget) { - // Layer Tree: - // +root - // +--rounded corner layer 1 [should trigger render surface] - // +----render surface [Does not draw] - // +----rounded corner layer 2 [should not trigger render surface] - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 60.f, 30.f, 40.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 20.f, 30.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> render_surface = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); - - // Set up layer tree - root->AddChild(rounded_corner_layer_1); - rounded_corner_layer_1->AddChild(render_surface); - rounded_corner_layer_1->AddChild(rounded_corner_layer_2); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - render_surface->SetPosition(gfx::PointF(0, 0)); - rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - render_surface->SetBounds(gfx::Size(30, 30)); - rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - - // Set the layer properties - render_surface->SetForceRenderSurfaceForTesting(true); - - root->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - rounded_corner_layer_2->SetIsDrawable(true); - - // Set Rounded corners - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this effect node has 1 descendant with a rounded corner without a - // render surface along the chain, it need a render surface. - const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this effect node has no descendants that draw and no descendant that - // has a rounded corner, it does not need a render surface. - effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* rounded_corner_layer_1_impl = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_2_impl = - layer_tree_impl->LayerById(rounded_corner_layer_2->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Rounded corner layer 1 - // The render target for this layer is |root|, hence its target - // bounds are relative to |root|. - // The offset from the origin of the render target is [0, 60] and the device - // scale factor is 1.6 thus giving the target space origin of [0, 96]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); - - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_1 = - rounded_corner_layer_1_impl->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Rounded corner layer 2 - // The render target for this layer is |render_surface|. - // The offset from the origin of the render target is [0, 0]. - const gfx::RRectF actual_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - FastRoundedCornerDoesNotTriggerRenderSurface) { - // Layer Tree: - // +root - // +--fast rounded corner layer [should not trigger render surface] - // +----layer 1 - // +----layer 2 - // +--rounded corner layer [should trigger render surface] - // +----layer 3 - // +----layer 4 - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 0.f, 50.f, 50.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> fast_rounded_corner_layer = Layer::Create(); - scoped_refptr<Layer> layer_1 = Layer::Create(); - scoped_refptr<Layer> layer_2 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer = Layer::Create(); - scoped_refptr<Layer> layer_3 = Layer::Create(); - scoped_refptr<Layer> layer_4 = Layer::Create(); - - // Set up layer tree - root->AddChild(fast_rounded_corner_layer); - root->AddChild(rounded_corner_layer); - - fast_rounded_corner_layer->AddChild(layer_1); - fast_rounded_corner_layer->AddChild(layer_2); - - rounded_corner_layer->AddChild(layer_3); - rounded_corner_layer->AddChild(layer_4); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - fast_rounded_corner_layer->SetPosition(kRoundedCornerLayer1Bound.origin()); - layer_1->SetPosition(gfx::PointF(0.f, 0.f)); - layer_2->SetPosition(gfx::PointF(25.f, 0.f)); - rounded_corner_layer->SetPosition(kRoundedCornerLayer2Bound.origin()); - layer_3->SetPosition(gfx::PointF(0.f, 0.f)); - layer_4->SetPosition(gfx::PointF(30.f, 0.f)); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - fast_rounded_corner_layer->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - layer_1->SetBounds(gfx::Size(25, 25)); - layer_2->SetBounds(gfx::Size(25, 25)); - rounded_corner_layer->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - layer_3->SetBounds(gfx::Size(30, 60)); - layer_4->SetBounds(gfx::Size(30, 60)); - - root->SetIsDrawable(true); - fast_rounded_corner_layer->SetIsDrawable(true); - layer_1->SetIsDrawable(true); - layer_2->SetIsDrawable(true); - rounded_corner_layer->SetIsDrawable(true); - layer_3->SetIsDrawable(true); - layer_4->SetIsDrawable(true); - - // Set Rounded corners - fast_rounded_corner_layer->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - - fast_rounded_corner_layer->SetIsFastRoundedCorner(true); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this layer has a fast rounded corner, it should not have a render - // surface even though it has 2 layers in the subtree that draws content. - const EffectNode* effect_node = - GetEffectNode(fast_rounded_corner_layer.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this node has 2 descendants that draw, it will have a rounded corner. - effect_node = GetEffectNode(rounded_corner_layer.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* fast_rounded_corner_layer_impl = - layer_tree_impl->LayerById(fast_rounded_corner_layer->id()); - LayerImpl* layer_1_impl = layer_tree_impl->LayerById(layer_1->id()); - LayerImpl* layer_2_impl = layer_tree_impl->LayerById(layer_2->id()); - LayerImpl* rounded_corner_layer_impl = - layer_tree_impl->LayerById(rounded_corner_layer->id()); - LayerImpl* layer_3_impl = layer_tree_impl->LayerById(layer_3->id()); - LayerImpl* layer_4_impl = layer_tree_impl->LayerById(layer_4->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Fast rounded corner layer. - // The render target for this layer is |root|, hence its target bounds are - // relative to |root|. - // The offset from the origin of the render target is [0, 0] and the device - // scale factor is 1.6. - const gfx::RRectF actual_rrect_1 = - fast_rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Layer 1 and layer 2 rounded corner bounds - // This should have the same rounded corner boudns as fast rounded corner - // layer. - const gfx::RRectF layer_1_rrect = - layer_1_impl->draw_properties().rounded_corner_bounds; - const gfx::RRectF layer_2_rrect = - layer_2_impl->draw_properties().rounded_corner_bounds; - EXPECT_EQ(actual_rrect_1, layer_1_rrect); - EXPECT_EQ(actual_rrect_1, layer_2_rrect); - - // Rounded corner layer - // The render target for this layer is |root|. - // The offset from the origin of the render target is [40, 40] and the device - // scale factor is 1.6 thus giving the target space origin of [64, 64]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_2 = - rounded_corner_layer_impl->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); - - // Layer 3 and layer 4 should have no rounded corner bounds set as their - // parent is a render surface. - const gfx::RRectF layer_3_rrect = - layer_3_impl->draw_properties().rounded_corner_bounds; - const gfx::RRectF layer_4_rrect = - layer_4_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(layer_3_rrect.IsEmpty()); - EXPECT_TRUE(layer_4_rrect.IsEmpty()); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - FastRoundedCornerTriggersRenderSurfaceInAncestor) { - // Layer Tree: - // +root - // +--rounded corner layer [1] [should trigger render surface] - // +----fast rounded corner layer [2] [should not trigger render surface] - // +--rounded corner layer [3] [should trigger render surface] - // +----rounded corner layer [4] [should not trigger render surface] - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - constexpr int kRoundedCorner3Radius = 1; - constexpr int kRoundedCorner4Radius = 3; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(5.f, 5.f, 50.f, 50.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 25.f, 25.f); - constexpr gfx::RectF kRoundedCornerLayer3Bound(40.f, 40.f, 60.f, 60.f); - constexpr gfx::RectF kRoundedCornerLayer4Bound(30.f, 0.f, 30.f, 60.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> fast_rounded_corner_layer_2 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create(); - - // Set up layer tree - root->AddChild(rounded_corner_layer_1); - root->AddChild(rounded_corner_layer_3); - - rounded_corner_layer_1->AddChild(fast_rounded_corner_layer_2); - - rounded_corner_layer_3->AddChild(rounded_corner_layer_4); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - fast_rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); - rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin()); - rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - fast_rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - rounded_corner_layer_3->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); - rounded_corner_layer_4->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); - - root->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - fast_rounded_corner_layer_2->SetIsDrawable(true); - rounded_corner_layer_3->SetIsDrawable(true); - rounded_corner_layer_4->SetIsDrawable(true); - - // Set Rounded corners - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - fast_rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - rounded_corner_layer_3->SetRoundedCorner( - {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, - kRoundedCorner3Radius}); - rounded_corner_layer_4->SetRoundedCorner( - {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, - kRoundedCorner4Radius}); - - fast_rounded_corner_layer_2->SetIsFastRoundedCorner(true); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this layer has a descendant that has rounded corner, this node will - // require a render surface. - const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this layer has no descendant with rounded corner or drawable, it will - // not have a render surface. - effect_node = GetEffectNode(fast_rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - // Since this layer has 1 descendant with a rounded corner, it should have a - // render surface. - effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), - kRoundedCorner3Radius); - EXPECT_EQ(rounded_corner_bounds_3.rect(), - gfx::RectF(kRoundedCornerLayer3Bound.size())); - - // Since this layer no descendants, it would no thave a render pass. - effect_node = GetEffectNode(rounded_corner_layer_4.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), - kRoundedCorner4Radius); - EXPECT_EQ(rounded_corner_bounds_4.rect(), - gfx::RectF(kRoundedCornerLayer4Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* rounded_corner_layer_impl_1 = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* fast_rounded_corner_layer_impl_2 = - layer_tree_impl->LayerById(fast_rounded_corner_layer_2->id()); - LayerImpl* rounded_corner_layer_impl_3 = - layer_tree_impl->LayerById(rounded_corner_layer_3->id()); - LayerImpl* rounded_corner_layer_impl_4 = - layer_tree_impl->LayerById(rounded_corner_layer_4->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Rounded corner layer 1. - // The render target for this layer is |root|, hence its target bounds are - // relative to |root|. - // The offset from the origin of the render target is [5, 5] and the device - // scale factor is 1.6 giving a total offset of [8, 8]. - const gfx::RRectF actual_self_rrect_1 = - rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); - - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_1 = - rounded_corner_layer_impl_1->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Fast rounded corner layer 2 - // The render target for this layer is |rounded_corner_layer_1|. - // The offset from the origin of the render target is [0, 0] and the device - // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_2 = - fast_rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); - - // Rounded corner layer 3 - // The render target for this layer is |root|. - // The offset from the origin of the render target is [40, 40] and the device - // scale factor is 1.6 thus giving the target space origin of [64, 64]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer3Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_impl_3->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), - kRoundedCorner3Radius * kDeviceScale); - - // Rounded corner layer 4 - // The render target for this layer is |rounded_corner_layer_3|. - // The offset from the origin of the render target is [30, 0] and the device - // scale factor is 1.6 thus giving the target space origin of [48, 0]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_4 = - rounded_corner_layer_impl_4->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer4Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(), - kRoundedCorner4Radius * kDeviceScale); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - FastRoundedCornerDoesNotTriggerRenderSurfaceFromSubtree) { - // Layer Tree: - // +root - // +--fast rounded corner layer 1 [should trigger render surface] - // +----rounded corner layer 1 [should not trigger render surface] - // +--rounded corner layer 2 [should trigger render surface] - // +----rounded corner layer 3 [should not trigger render surface] - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - constexpr int kRoundedCorner3Radius = 4; - constexpr int kRoundedCorner4Radius = 5; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(10.f, 5.f, 45.f, 50.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(5.f, 5.f, 20.f, 20.f); - constexpr gfx::RectF kRoundedCornerLayer3Bound(60.f, 5.f, 40.f, 25.f); - constexpr gfx::RectF kRoundedCornerLayer4Bound(0.f, 10.f, 10.f, 20.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> fast_rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); - - // Set up layer tree - root->AddChild(fast_rounded_corner_layer_1); - root->AddChild(rounded_corner_layer_2); - - fast_rounded_corner_layer_1->AddChild(rounded_corner_layer_1); - rounded_corner_layer_2->AddChild(rounded_corner_layer_3); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - fast_rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer2Bound.origin()); - rounded_corner_layer_2->SetPosition(kRoundedCornerLayer3Bound.origin()); - rounded_corner_layer_3->SetPosition(kRoundedCornerLayer4Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - fast_rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); - rounded_corner_layer_3->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); - - root->SetIsDrawable(true); - fast_rounded_corner_layer_1->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - rounded_corner_layer_2->SetIsDrawable(true); - rounded_corner_layer_3->SetIsDrawable(true); - - // Set Rounded corners - fast_rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, - kRoundedCorner3Radius}); - rounded_corner_layer_3->SetRoundedCorner( - {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, - kRoundedCorner4Radius}); - - fast_rounded_corner_layer_1->SetIsFastRoundedCorner(true); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this layer has a descendant with rounded corner, it needs a render - // surface. - const EffectNode* effect_node = - GetEffectNode(fast_rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this layer has no descendant with rounded corner or drawable, it will - // not have a render surface. - effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - // Since this layer has a descendant with rounded corner, it should have a - // render surface. - effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), - kRoundedCorner3Radius); - EXPECT_EQ(rounded_corner_bounds_3.rect(), - gfx::RectF(kRoundedCornerLayer3Bound.size())); - - // Since this layer has no descendant, it does not need a render surface. - effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), - kRoundedCorner4Radius); - EXPECT_EQ(rounded_corner_bounds_4.rect(), - gfx::RectF(kRoundedCornerLayer4Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* fast_rounded_corner_layer_impl_1 = - layer_tree_impl->LayerById(fast_rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_impl_1 = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_impl_2 = - layer_tree_impl->LayerById(rounded_corner_layer_2->id()); - LayerImpl* rounded_corner_layer_impl_3 = - layer_tree_impl->LayerById(rounded_corner_layer_3->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Fast rounded corner layer 1. - // The render target for this layer is |root|, hence its target bounds are - // relative to |root|. - // The offset from the origin of the render target is [5, 5] and the device - // scale factor is 1.6. - const gfx::RRectF actual_self_rrect_1 = - fast_rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); - - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_1 = - fast_rounded_corner_layer_impl_1->render_target() - ->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Rounded corner layer 1 - // The render target for this layer is |fast_rounded_corner_layer_1|. - // The offset from the origin of the render target is [0, 0] and the device - // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); - - // Rounded corner layer 3 - // The render target for this layer is |root|. - // The offset from the origin of the render target is [5, 5] and the device - // scale factor is 1.6 thus giving the target space origin of [8, 8]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer3Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_impl_2->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), - kRoundedCorner3Radius * kDeviceScale); - - // Rounded corner layer 4 - // The render target for this layer is |rounded_corner_layer_2|. - // The offset from the origin of the render target is [0, 5] and the device - // scale factor is 1.6 thus giving the target space origin of [0, 8]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_4 = - rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer4Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(), - kRoundedCorner4Radius * kDeviceScale); -} - // In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { +TEST_F(DrawPropertiesTestWithLayerTree, CustomLayerClipBounds) { // The custom clip API should have the same effect as if an intermediate // clip layer has been added to the layer tree. To check this the test creates // 2 subtree for a root layer. One of the subtree uses the clip API to clip @@ -10453,24 +7915,17 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { parent->SetClipRect(kClipBounds); clip_layer->SetMasksToBounds(true); - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); + UpdateMainDrawProperties(kDeviceScale); EXPECT_EQ(GetClipNode(parent.get())->clip, gfx::RectF(kClipBounds)); EXPECT_TRUE(!parent->clip_rect().IsEmpty()); EXPECT_EQ(GetClipNode(child.get())->clip, gfx::RectF(kClipBounds)); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); + CommitAndActivate(kDeviceScale); LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id()); LayerImpl* child_impl = layer_tree_impl->LayerById(child->id()); LayerImpl* expected_parent_impl = @@ -10478,7 +7933,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { LayerImpl* expected_child_impl = layer_tree_impl->LayerById(expected_child->id()); - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); EXPECT_TRUE(parent_impl->is_clipped()); EXPECT_TRUE(child_impl->is_clipped()); @@ -10490,8 +7945,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { } // In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - CustomLayerClipBoundsWithMaskToBounds) { +TEST_F(DrawPropertiesTestWithLayerTree, CustomLayerClipBoundsWithMaskToBounds) { // The custom clip API should have the same effect as if an intermediate // clip layer has been added to the layer tree. To check this the test creates // 2 subtree for a root layer. One of the subtree uses the clip API to clip @@ -10563,7 +8017,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, clip_layer->SetMasksToBounds(true); expected_parent->SetMasksToBounds(true); - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); + UpdateMainDrawProperties(kDeviceScale); const gfx::RectF expected_clip_bounds = gfx::IntersectRects( gfx::RectF(kClipBounds), gfx::RectF(kParentLayerBounds)); @@ -10572,17 +8026,10 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, EXPECT_EQ(GetClipNode(child.get())->clip, expected_clip_bounds); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); + CommitAndActivate(kDeviceScale); LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id()); LayerImpl* child_impl = layer_tree_impl->LayerById(child->id()); LayerImpl* expected_parent_impl = @@ -10590,7 +8037,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, LayerImpl* expected_child_impl = layer_tree_impl->LayerById(expected_child->id()); - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); EXPECT_TRUE(parent_impl->is_clipped()); EXPECT_TRUE(child_impl->is_clipped()); @@ -10601,5 +8048,74 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect()); } +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(DrawPropertiesTestWithLayerTree, RoundedCornerOnRenderSurface) { + // -Root + // - Parent 1 + // - [Render Surface] Child 1 with rounded corner + // - [Render Surface] Parent 2 with rounded corner + // - [Render Surface] Child 2 + // - Parent 3 with rounded corner + // - [Render Surface] Child 3 + + scoped_refptr<Layer> root = Layer::Create(); + host()->SetRootLayer(root); + root->SetBounds(gfx::Size(250, 250)); + root->SetIsDrawable(true); + + scoped_refptr<Layer> parent_1 = Layer::Create(); + root->AddChild(parent_1); + parent_1->SetBounds(gfx::Size(80, 80)); + parent_1->SetPosition(gfx::PointF(0, 0)); + parent_1->SetIsDrawable(true); + + scoped_refptr<Layer> parent_2 = Layer::Create(); + root->AddChild(parent_2); + parent_2->SetBounds(gfx::Size(80, 80)); + parent_1->SetPosition(gfx::PointF(80, 80)); + parent_2->SetIsDrawable(true); + parent_2->SetForceRenderSurfaceForTesting(true); + parent_2->SetRoundedCorner(gfx::RoundedCornersF(10.f)); + parent_2->SetIsFastRoundedCorner(true); + + scoped_refptr<Layer> parent_3 = Layer::Create(); + root->AddChild(parent_3); + parent_3->SetBounds(gfx::Size(80, 80)); + parent_1->SetPosition(gfx::PointF(160, 160)); + parent_3->SetIsDrawable(true); + parent_3->SetRoundedCorner(gfx::RoundedCornersF(10.f)); + parent_3->SetIsFastRoundedCorner(true); + + scoped_refptr<Layer> child_1 = Layer::Create(); + parent_1->AddChild(child_1); + child_1->SetBounds(gfx::Size(80, 80)); + child_1->SetIsDrawable(true); + child_1->SetForceRenderSurfaceForTesting(true); + child_1->SetRoundedCorner(gfx::RoundedCornersF(10.f)); + child_1->SetIsFastRoundedCorner(true); + + scoped_refptr<Layer> child_2 = Layer::Create(); + parent_2->AddChild(child_2); + child_2->SetBounds(gfx::Size(80, 80)); + child_2->SetIsDrawable(true); + child_2->SetForceRenderSurfaceForTesting(true); + + scoped_refptr<Layer> child_3 = Layer::Create(); + parent_3->AddChild(child_3); + child_3->SetBounds(gfx::Size(80, 80)); + child_3->SetIsDrawable(true); + child_3->SetForceRenderSurfaceForTesting(true); + + UpdateMainDrawProperties(); + CommitAndActivate(); + + EXPECT_FALSE( + GetRenderSurfaceImpl(child_1)->rounded_corner_bounds().IsEmpty()); + EXPECT_FALSE( + GetRenderSurfaceImpl(child_2)->rounded_corner_bounds().IsEmpty()); + EXPECT_FALSE( + GetRenderSurfaceImpl(child_3)->rounded_corner_bounds().IsEmpty()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index 57241bad713..ad08ae82627 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -8,6 +8,7 @@ #include <vector> +#include "base/containers/adapters.h" #include "base/containers/stack.h" #include "cc/base/math_util.h" #include "cc/layers/draw_properties.h" @@ -30,21 +31,21 @@ namespace draw_property_utils { namespace { -static gfx::Rect ToEnclosingClipRect(const gfx::RectF& clip_rect) { +gfx::Rect ToEnclosingClipRect(const gfx::RectF& clip_rect) { constexpr float kClipError = 0.00001f; return gfx::ToEnclosingRectIgnoringError(clip_rect, kClipError); } -static bool IsRootLayer(const Layer* layer) { +bool IsRootLayer(const Layer* layer) { return !layer->parent(); } -static bool IsRootLayer(const LayerImpl* layer) { +bool IsRootLayer(const LayerImpl* layer) { return layer->layer_tree_impl()->IsRootLayer(layer); } -static void PostConcatSurfaceContentsScale(const EffectNode* effect_node, - gfx::Transform* transform) { +void PostConcatSurfaceContentsScale(const EffectNode* effect_node, + gfx::Transform* transform) { if (!effect_node) { // This can happen when PaintArtifactCompositor builds property trees as it // doesn't set effect ids on clip nodes. @@ -55,11 +56,11 @@ static void PostConcatSurfaceContentsScale(const EffectNode* effect_node, effect_node->surface_contents_scale.y(), 1.f); } -static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, - int source_effect_id, - int dest_effect_id, - gfx::RectF clip_in_source_space, - gfx::RectF* clip_in_dest_space) { +bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, + int source_effect_id, + int dest_effect_id, + gfx::RectF clip_in_source_space, + gfx::RectF* clip_in_dest_space) { const EffectNode* source_effect_node = property_trees->effect_tree.Node(source_effect_id); int source_transform_id = source_effect_node->transform_id; @@ -89,7 +90,7 @@ static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, return true; } -static ConditionalClip ComputeTargetRectInLocalSpace( +ConditionalClip ComputeTargetRectInLocalSpace( gfx::RectF rect, const PropertyTrees* property_trees, int target_transform_id, @@ -110,7 +111,7 @@ static ConditionalClip ComputeTargetRectInLocalSpace( MathUtil::ProjectClippedRect(target_to_local, rect)}; } -static ConditionalClip ComputeLocalRectInTargetSpace( +ConditionalClip ComputeLocalRectInTargetSpace( gfx::RectF rect, const PropertyTrees* property_trees, int current_transform_id, @@ -131,10 +132,10 @@ static ConditionalClip ComputeLocalRectInTargetSpace( MathUtil::ProjectClippedRect(current_to_target, rect)}; } -static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, - const PropertyTrees* property_trees, - int target_transform_id, - int target_effect_id) { +ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, + const PropertyTrees* property_trees, + int target_transform_id, + int target_effect_id) { if (clip_node->transform_id != target_transform_id) { return ComputeLocalRectInTargetSpace(clip_node->clip, property_trees, clip_node->transform_id, @@ -152,12 +153,12 @@ static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, return ConditionalClip{true /* is_clipped */, current_clip}; } -static bool ApplyClipNodeToAccumulatedClip(const PropertyTrees* property_trees, - bool include_expanding_clips, - int target_id, - int target_transform_id, - const ClipNode* clip_node, - gfx::RectF* accumulated_clip) { +bool ApplyClipNodeToAccumulatedClip(const PropertyTrees* property_trees, + bool include_expanding_clips, + int target_id, + int target_transform_id, + const ClipNode* clip_node, + gfx::RectF* accumulated_clip) { switch (clip_node->clip_type) { case ClipNode::ClipType::APPLIES_LOCAL_CLIP: { ConditionalClip current_clip = ComputeCurrentClip( @@ -207,10 +208,10 @@ static bool ApplyClipNodeToAccumulatedClip(const PropertyTrees* property_trees, return true; } -static ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, - bool include_expanding_clips, - int local_clip_id, - int target_id) { +ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, + bool include_expanding_clips, + int local_clip_id, + int target_id) { ClipRectData* cached_data = property_trees->FetchClipRectFromCache(local_clip_id, target_id); if (cached_data->target_id != EffectTree::kInvalidNodeId) { @@ -325,15 +326,14 @@ static ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, return clip; } -static bool HasSingularTransform(int transform_tree_index, - const TransformTree& tree) { +bool HasSingularTransform(int transform_tree_index, const TransformTree& tree) { const TransformNode* node = tree.Node(transform_tree_index); return !node->is_invertible || !node->ancestors_are_invertible; } -static int LowestCommonAncestor(int clip_id_1, - int clip_id_2, - const ClipTree* clip_tree) { +int LowestCommonAncestor(int clip_id_1, + int clip_id_2, + const ClipTree* clip_tree) { const ClipNode* clip_node_1 = clip_tree->Node(clip_id_1); const ClipNode* clip_node_2 = clip_tree->Node(clip_id_2); while (clip_node_1->id != clip_node_2->id) { @@ -345,9 +345,9 @@ static int LowestCommonAncestor(int clip_id_1, return clip_node_1->id; } -static void SetHasContributingLayerThatEscapesClip(int lca_clip_id, - int target_effect_id, - EffectTree* effect_tree) { +void SetHasContributingLayerThatEscapesClip(int lca_clip_id, + int target_effect_id, + EffectTree* effect_tree) { const EffectNode* effect_node = effect_tree->Node(target_effect_id); // Find all ancestor targets starting from effect_node who are clipped by // a descendant of lowest ancestor clip and set their @@ -362,14 +362,14 @@ static void SetHasContributingLayerThatEscapesClip(int lca_clip_id, } template <typename LayerType> -static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, - const TransformTree& tree) { +int TransformTreeIndexForBackfaceVisibility(LayerType* layer, + const TransformTree& tree) { if (!layer->use_parent_backface_visibility() || !layer->has_transform_node()) return layer->transform_tree_index(); return tree.Node(layer->transform_tree_index())->parent_id; } -static bool IsTargetSpaceTransformBackFaceVisible( +bool IsTargetSpaceTransformBackFaceVisible( Layer* layer, int transform_tree_index, const PropertyTrees* property_trees) { @@ -378,7 +378,7 @@ static bool IsTargetSpaceTransformBackFaceVisible( return false; } -static bool IsTargetSpaceTransformBackFaceVisible( +bool IsTargetSpaceTransformBackFaceVisible( LayerImpl* layer, int transform_tree_index, const PropertyTrees* property_trees) { @@ -390,30 +390,30 @@ static bool IsTargetSpaceTransformBackFaceVisible( } template <typename LayerType> -static bool IsLayerBackFaceVisible(LayerType* layer, - int transform_tree_index, - const PropertyTrees* property_trees) { +bool IsLayerBackFaceVisible(LayerType* layer, + int transform_tree_index, + const PropertyTrees* property_trees) { return IsTargetSpaceTransformBackFaceVisible(layer, transform_tree_index, property_trees); } -static inline bool TransformToScreenIsKnown(Layer* layer, - int transform_tree_index, - const TransformTree& tree) { +inline bool TransformToScreenIsKnown(Layer* layer, + int transform_tree_index, + const TransformTree& tree) { const TransformNode* node = tree.Node(transform_tree_index); return !node->to_screen_is_potentially_animated; } -static inline bool TransformToScreenIsKnown(LayerImpl* layer, - int transform_tree_index, - const TransformTree& tree) { +inline bool TransformToScreenIsKnown(LayerImpl* layer, + int transform_tree_index, + const TransformTree& tree) { return true; } template <typename LayerType> -static bool LayerNeedsUpdateInternal(LayerType* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees) { +bool LayerNeedsUpdate(LayerType* layer, + bool layer_is_drawn, + const PropertyTrees* property_trees) { // Layers can be skipped if any of these conditions are met. // - is not drawn due to it or one of its ancestors being hidden (or having // no copy requests). @@ -454,7 +454,7 @@ static bool LayerNeedsUpdateInternal(LayerType* layer, } template <typename LayerType> -static inline bool LayerShouldBeSkippedInternal( +inline bool LayerShouldBeSkippedForDrawPropertiesComputation( LayerType* layer, const TransformTree& transform_tree, const EffectTree& effect_tree) { @@ -470,7 +470,7 @@ static inline bool LayerShouldBeSkippedInternal( effect_node->hidden_by_backface_visibility || !effect_node->is_drawn; } -static gfx::Rect LayerDrawableContentRect( +gfx::Rect LayerDrawableContentRect( const LayerImpl* layer, const gfx::Rect& layer_bounds_in_target_space, const gfx::Rect& clip_rect) { @@ -480,8 +480,8 @@ static gfx::Rect LayerDrawableContentRect( return layer_bounds_in_target_space; } -static void SetSurfaceIsClipped(const ClipTree& clip_tree, - RenderSurfaceImpl* render_surface) { +void SetSurfaceIsClipped(const ClipTree& clip_tree, + RenderSurfaceImpl* render_surface) { bool is_clipped; if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { // Root render surface is always clipped. @@ -504,8 +504,8 @@ static void SetSurfaceIsClipped(const ClipTree& clip_tree, render_surface->SetIsClipped(is_clipped); } -static void SetSurfaceDrawOpacity(const EffectTree& tree, - RenderSurfaceImpl* render_surface) { +void SetSurfaceDrawOpacity(const EffectTree& tree, + RenderSurfaceImpl* render_surface) { // Draw opacity of a surface is the product of opacities between the surface // (included) and its target surface (excluded). const EffectNode* node = tree.Node(render_surface->EffectTreeIndex()); @@ -517,7 +517,7 @@ static void SetSurfaceDrawOpacity(const EffectTree& tree, render_surface->SetDrawOpacity(draw_opacity); } -static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { +float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { if (!layer->render_target()) return 0.f; @@ -536,20 +536,18 @@ static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { } template <typename LayerType> -static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, - const TransformTree& tree) { +gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, + const TransformTree& tree) { gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), layer->offset_to_transform_parent().y()); gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); xform.ConcatTransform(ssxform); - if (layer->should_flatten_screen_space_transform_from_property_tree()) - xform.FlattenTo2d(); return xform; } -static void SetSurfaceClipRect(const ClipNode* parent_clip_node, - PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface) { +void SetSurfaceClipRect(const ClipNode* parent_clip_node, + PropertyTrees* property_trees, + RenderSurfaceImpl* render_surface) { if (!render_surface->is_clipped()) { render_surface->SetClipRect(gfx::Rect()); return; @@ -573,8 +571,8 @@ static void SetSurfaceClipRect(const ClipNode* parent_clip_node, } } -static void SetSurfaceDrawTransform(const PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface) { +void SetSurfaceDrawTransform(const PropertyTrees* property_trees, + RenderSurfaceImpl* render_surface) { const TransformTree& transform_tree = property_trees->transform_tree; const EffectTree& effect_tree = property_trees->effect_tree; const TransformNode* transform_node = @@ -597,8 +595,7 @@ static void SetSurfaceDrawTransform(const PropertyTrees* property_trees, render_surface->SetDrawTransform(render_surface_transform); } -static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, - LayerImpl* layer) { +gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, LayerImpl* layer) { const EffectNode* effect_node = property_trees->effect_tree.Node(layer->effect_tree_index()); int effect_ancestor_with_cache_render_surface = @@ -655,8 +652,7 @@ static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, return visible_rect; } -static ConditionalClip LayerClipRect(PropertyTrees* property_trees, - LayerImpl* layer) { +ConditionalClip LayerClipRect(PropertyTrees* property_trees, LayerImpl* layer) { const EffectTree* effect_tree = &property_trees->effect_tree; const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); const EffectNode* target_node = @@ -668,7 +664,7 @@ static ConditionalClip LayerClipRect(PropertyTrees* property_trees, layer->clip_tree_index(), target_node->id); } -static std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( +std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( const PropertyTrees* property_trees, int effect_tree_index, bool for_render_surface) { @@ -693,9 +689,16 @@ static std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( break; } - // Simply break if we reached a node that has a render surface or is the - // render target. - if (node->HasRenderSurface() || node->id == target_id) + // If the iteration has reached a node in the parent chain that has a render + // surface, then break. If this iteration is for a render surface to begin + // with, then ensure |node| is a parent of |effect_node|. + if (node->HasRenderSurface() && + (!for_render_surface || effect_node != node)) { + break; + } + + // Simply break if we reached a node that is the render target. + if (node->id == target_id) break; node = effect_tree->parent(node); @@ -710,17 +713,16 @@ static std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( if (!property_trees->GetToTarget(node->transform_id, target_id, &to_target)) return kEmptyRoundedCornerInfo; - DCHECK(to_target.Preserves2dAxisAlignment()); + auto result = + std::make_pair(node->rounded_corner_bounds, node->is_fast_rounded_corner); - SkRRect result; - if (!SkRRect(node->rounded_corner_bounds) - .transform(to_target.matrix(), &result)) { + if (!to_target.TransformRRectF(&result.first)) return kEmptyRoundedCornerInfo; - } - return std::make_pair(gfx::RRectF(result), node->is_fast_rounded_corner); + + return result; } -static void UpdateRenderTarget(EffectTree* effect_tree) { +void UpdateRenderTarget(EffectTree* effect_tree) { for (int i = EffectTree::kContentsRootNodeId; i < static_cast<int>(effect_tree->size()); ++i) { EffectNode* node = effect_tree->Node(i); @@ -735,7 +737,7 @@ static void UpdateRenderTarget(EffectTree* effect_tree) { } } -static void ComputeClips(PropertyTrees* property_trees) { +void ComputeClips(PropertyTrees* property_trees) { DCHECK(!property_trees->transform_tree.needs_update()); ClipTree* clip_tree = &property_trees->clip_tree; if (!clip_tree->needs_update()) @@ -765,6 +767,352 @@ static void ComputeClips(PropertyTrees* property_trees) { clip_tree->set_needs_update(false); } +void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, + RenderSurfaceImpl* render_surface) { + SetSurfaceIsClipped(property_trees->clip_tree, render_surface); + SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); + SetSurfaceDrawTransform(property_trees, render_surface); + + render_surface->SetRoundedCornerRRect( + GetRoundedCornerRRect(property_trees, render_surface->EffectTreeIndex(), + /*for_render_surface*/ true) + .first); + render_surface->SetScreenSpaceTransform( + property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( + render_surface->TransformTreeIndex(), + render_surface->EffectTreeIndex())); + + const ClipNode* clip_node = + property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); + SetSurfaceClipRect(clip_node, property_trees, render_surface); +} + +void AddSurfaceToRenderSurfaceList(RenderSurfaceImpl* render_surface, + RenderSurfaceList* render_surface_list, + PropertyTrees* property_trees) { + // |render_surface| must appear after its target, so first make sure its + // target is in the list. + RenderSurfaceImpl* target = render_surface->render_target(); + bool is_root = + render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; + if (!is_root && !target->is_render_surface_list_member()) { + AddSurfaceToRenderSurfaceList(target, render_surface_list, property_trees); + } + render_surface->ClearAccumulatedContentRect(); + render_surface_list->push_back(render_surface); + render_surface->set_is_render_surface_list_member(true); + if (is_root) { + // The root surface does not contribute to any other surface, it has no + // target. + render_surface->set_contributes_to_drawn_surface(false); + } else { + bool contributes_to_drawn_surface = + property_trees->effect_tree.ContributesToDrawnSurface( + render_surface->EffectTreeIndex()); + render_surface->set_contributes_to_drawn_surface( + contributes_to_drawn_surface); + } + + ComputeSurfaceDrawProperties(property_trees, render_surface); + + // Ignore occlusion from outside the surface when surface contents need to be + // fully drawn. Layers with copy-request need to be complete. We could be + // smarter about layers with filters that move pixels and exclude regions + // where both layers and the filters are occluded, but this seems like + // overkill. + // TODO(senorblanco): make this smarter for the SkImageFilter case (check for + // pixel-moving filters) + const FilterOperations& filters = render_surface->Filters(); + bool is_occlusion_immune = render_surface->HasCopyRequest() || + render_surface->ShouldCacheRenderSurface() || + filters.HasReferenceFilter() || + filters.HasFilterThatMovesPixels(); + if (is_occlusion_immune) { + render_surface->SetNearestOcclusionImmuneAncestor(render_surface); + } else if (is_root) { + render_surface->SetNearestOcclusionImmuneAncestor(nullptr); + } else { + render_surface->SetNearestOcclusionImmuneAncestor( + render_surface->render_target()->nearest_occlusion_immune_ancestor()); + } +} + +bool SkipForInvertibility(const LayerImpl* layer, + PropertyTrees* property_trees) { + const TransformNode* transform_node = + property_trees->transform_tree.Node(layer->transform_tree_index()); + const EffectNode* effect_node = + property_trees->effect_tree.Node(layer->effect_tree_index()); + bool non_root_copy_request = + effect_node->closest_ancestor_with_copy_request_id > + EffectTree::kContentsRootNodeId; + gfx::Transform from_target; + // If there is a copy request, we check the invertibility of the transform + // between the node corresponding to the layer and the node corresponding to + // the copy request. Otherwise, we are interested in the invertibility of + // screen space transform which is already cached on the transform node. + return non_root_copy_request + ? !property_trees->GetFromTarget( + layer->transform_tree_index(), + effect_node->closest_ancestor_with_copy_request_id, + &from_target) + : !transform_node->ancestors_are_invertible; +} + +void ComputeInitialRenderSurfaceList(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + RenderSurfaceList* render_surface_list) { + EffectTree& effect_tree = property_trees->effect_tree; + for (int i = EffectTree::kContentsRootNodeId; + i < static_cast<int>(effect_tree.size()); ++i) { + if (RenderSurfaceImpl* render_surface = effect_tree.GetRenderSurface(i)) { + render_surface->set_is_render_surface_list_member(false); + render_surface->reset_num_contributors(); + } + } + + RenderSurfaceImpl* root_surface = + effect_tree.GetRenderSurface(EffectTree::kContentsRootNodeId); + // The root surface always gets added to the render surface list. + AddSurfaceToRenderSurfaceList(root_surface, render_surface_list, + property_trees); + // For all non-skipped layers, add their target to the render surface list if + // it's not already been added, and add their content rect to the target + // surface's accumulated content rect. + for (LayerImpl* layer : *layer_tree_impl) { + DCHECK(layer); + layer->EnsureValidPropertyTreeIndices(); + + layer->set_contributes_to_drawn_render_surface(false); + layer->set_raster_even_if_not_drawn(false); + + bool is_root = layer_tree_impl->IsRootLayer(layer); + + bool skip_draw_properties_computation = + LayerShouldBeSkippedForDrawPropertiesComputation( + layer, property_trees->transform_tree, property_trees->effect_tree); + + bool skip_for_invertibility = SkipForInvertibility(layer, property_trees); + + bool skip_layer = !is_root && (skip_draw_properties_computation || + skip_for_invertibility); + + layer->set_raster_even_if_not_drawn(skip_for_invertibility && + !skip_draw_properties_computation); + if (skip_layer) + continue; + + bool layer_is_drawn = + property_trees->effect_tree.Node(layer->effect_tree_index())->is_drawn; + bool layer_should_be_drawn = + LayerNeedsUpdate(layer, layer_is_drawn, property_trees); + if (!layer_should_be_drawn) + continue; + + RenderSurfaceImpl* render_target = layer->render_target(); + if (!render_target->is_render_surface_list_member()) { + AddSurfaceToRenderSurfaceList(render_target, render_surface_list, + property_trees); + } + + layer->set_contributes_to_drawn_render_surface(true); + + // The layer contributes its drawable content rect to its render target. + render_target->AccumulateContentRectFromContributingLayer(layer); + render_target->increment_num_contributors(); + } +} + +void ComputeSurfaceContentRects(PropertyTrees* property_trees, + RenderSurfaceList* render_surface_list, + int max_texture_size) { + // Walk the list backwards, accumulating each surface's content rect into its + // target's content rect. + for (RenderSurfaceImpl* render_surface : + base::Reversed(*render_surface_list)) { + if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { + // The root surface's content rect is always the entire viewport. + render_surface->SetContentRectToViewport(); + continue; + } + + // Now all contributing drawable content rect has been accumulated to this + // render surface, calculate the content rect. + render_surface->CalculateContentRectFromAccumulatedContentRect( + max_texture_size); + + // Now the render surface's content rect is calculated correctly, it could + // contribute to its render target. + RenderSurfaceImpl* render_target = render_surface->render_target(); + DCHECK(render_target->is_render_surface_list_member()); + render_target->AccumulateContentRectFromContributingRenderSurface( + render_surface); + render_target->increment_num_contributors(); + } +} + +void ComputeListOfNonEmptySurfaces(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + RenderSurfaceList* initial_surface_list, + RenderSurfaceList* final_surface_list) { + // Walk the initial surface list forwards. The root surface and each + // surface with a non-empty content rect go into the final render surface + // layer list. Surfaces with empty content rects or whose target isn't in + // the final list do not get added to the final list. + bool removed_surface = false; + for (RenderSurfaceImpl* surface : *initial_surface_list) { + bool is_root = + surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; + RenderSurfaceImpl* target_surface = surface->render_target(); + if (!is_root && (surface->content_rect().IsEmpty() || + !target_surface->is_render_surface_list_member())) { + surface->set_is_render_surface_list_member(false); + removed_surface = true; + target_surface->decrement_num_contributors(); + continue; + } + final_surface_list->push_back(surface); + } + if (removed_surface) { + for (LayerImpl* layer : *layer_tree_impl) { + if (layer->contributes_to_drawn_render_surface()) { + RenderSurfaceImpl* render_target = layer->render_target(); + if (!render_target->is_render_surface_list_member()) { + layer->set_contributes_to_drawn_render_surface(false); + render_target->decrement_num_contributors(); + } + } + } + } +} + +void CalculateRenderSurfaceLayerList(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + RenderSurfaceList* render_surface_list, + const int max_texture_size) { + RenderSurfaceList initial_render_surface_list; + + // First compute a list that might include surfaces that later turn out to + // have an empty content rect. After surface content rects are computed, + // produce a final list that omits empty surfaces. + ComputeInitialRenderSurfaceList(layer_tree_impl, property_trees, + &initial_render_surface_list); + ComputeSurfaceContentRects(property_trees, &initial_render_surface_list, + max_texture_size); + ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, + &initial_render_surface_list, + render_surface_list); +} + +void RecordRenderSurfaceReasonsForTracing( + const PropertyTrees* property_trees, + const RenderSurfaceList* render_surface_list) { + static const auto* tracing_enabled = + TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("cc"); + if (!*tracing_enabled || + // Don't output single root render surface. + render_surface_list->size() <= 1) + return; + + TRACE_EVENT_INSTANT1("cc", "RenderSurfaceReasonCount", + TRACE_EVENT_SCOPE_THREAD, "total", + render_surface_list->size()); + + // kTest is the last value which is not included for tracing. + constexpr auto kNumReasons = static_cast<size_t>(RenderSurfaceReason::kTest); + int reason_counts[kNumReasons] = {0}; + for (const auto* render_surface : *render_surface_list) { + const auto* effect_node = + property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); + reason_counts[static_cast<size_t>(effect_node->render_surface_reason)]++; + } + for (size_t i = 0; i < kNumReasons; i++) { + if (!reason_counts[i]) + continue; + TRACE_EVENT_INSTANT1( + "cc", "RenderSurfaceReasonCount", TRACE_EVENT_SCOPE_THREAD, + RenderSurfaceReasonToString(static_cast<RenderSurfaceReason>(i)), + reason_counts[i]); + } +} + +void UpdateElasticOverscroll( + PropertyTrees* property_trees, + TransformNode* overscroll_elasticity_transform_node, + const gfx::Vector2dF& elastic_overscroll) { + if (!overscroll_elasticity_transform_node) { + DCHECK(elastic_overscroll.IsZero()); + return; + } + + if (overscroll_elasticity_transform_node->scroll_offset == + gfx::ScrollOffset(elastic_overscroll)) + return; + + overscroll_elasticity_transform_node->scroll_offset = + gfx::ScrollOffset(elastic_overscroll); + overscroll_elasticity_transform_node->needs_local_transform_update = true; + property_trees->transform_tree.set_needs_update(true); +} + +void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, + PropertyTrees* property_trees) { + // Compute transforms + for (LayerImpl* layer : *layer_list) { + const TransformNode* transform_node = + property_trees->transform_tree.Node(layer->transform_tree_index()); + + layer->draw_properties().screen_space_transform = + ScreenSpaceTransformInternal(layer, property_trees->transform_tree); + layer->draw_properties().target_space_transform = DrawTransform( + layer, property_trees->transform_tree, property_trees->effect_tree); + layer->draw_properties().screen_space_transform_is_animating = + transform_node->to_screen_is_potentially_animated; + auto rounded_corner_info = + GetRoundedCornerRRect(property_trees, layer->effect_tree_index(), + /*from_render_surface*/ false); + layer->draw_properties().rounded_corner_bounds = rounded_corner_info.first; + layer->draw_properties().is_fast_rounded_corner = + rounded_corner_info.second; + } + + // Compute effects and determine if render surfaces have contributing layers + // that escape clip. + for (LayerImpl* layer : *layer_list) { + layer->draw_properties().opacity = + LayerDrawOpacity(layer, property_trees->effect_tree); + RenderSurfaceImpl* render_target = layer->render_target(); + int lca_clip_id = LowestCommonAncestor(layer->clip_tree_index(), + render_target->ClipTreeIndex(), + &property_trees->clip_tree); + if (lca_clip_id != render_target->ClipTreeIndex()) { + SetHasContributingLayerThatEscapesClip(lca_clip_id, + render_target->EffectTreeIndex(), + &property_trees->effect_tree); + } + } + + // Compute clips and visible rects + for (LayerImpl* layer : *layer_list) { + ConditionalClip clip = LayerClipRect(property_trees, layer); + // is_clipped should be set before visible rect computation as it is used + // there. + layer->draw_properties().is_clipped = clip.is_clipped; + layer->draw_properties().clip_rect = ToEnclosingClipRect(clip.clip_rect); + layer->draw_properties().visible_layer_rect = + LayerVisibleRect(property_trees, layer); + } + + // Compute drawable content rects + for (LayerImpl* layer : *layer_list) { + gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( + layer->draw_properties().target_space_transform, + gfx::Rect(layer->bounds())); + layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( + layer, bounds_in_target_space, layer->draw_properties().clip_rect); + } +} + } // namespace void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, @@ -776,23 +1124,9 @@ void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, 1.0 / effect_node->surface_contents_scale.y()); } -bool LayerShouldBeSkippedForDrawPropertiesComputation( - LayerImpl* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree) { - return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); -} - -bool LayerShouldBeSkippedForDrawPropertiesComputation( - Layer* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree) { - return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); -} - void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, - const PropertyTrees* property_trees, LayerList* update_layer_list) { + const PropertyTrees* property_trees = layer_tree_host->property_trees(); const TransformTree& transform_tree = property_trees->transform_tree; const EffectTree& effect_tree = property_trees->effect_tree; for (auto* layer : *layer_tree_host) { @@ -806,20 +1140,12 @@ void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, if (LayerNeedsUpdate(layer, layer_is_drawn, property_trees)) { update_layer_list->push_back(layer); } - - // Append mask layers to the update layer list. They don't have valid - // visible rects, so need to get added after the above calculation. - if (PictureLayer* mask_layer = layer->mask_layer()) { - // Layers with empty bounds should never be painted, including masks. - if (!mask_layer->bounds().IsEmpty()) - update_layer_list->push_back(mask_layer); - } } } void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, - const PropertyTrees* property_trees, std::vector<LayerImpl*>* visible_layer_list) { + const PropertyTrees* property_trees = layer_tree_impl->property_trees(); const TransformTree& transform_tree = property_trees->transform_tree; const EffectTree& effect_tree = property_trees->effect_tree; @@ -868,11 +1194,10 @@ void ComputeEffects(EffectTree* effect_tree) { effect_tree->set_needs_update(false); } -void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, - PropertyTrees* property_trees) { +void UpdatePropertyTrees(LayerTreeHost* layer_tree_host) { DCHECK(layer_tree_host); + auto* property_trees = layer_tree_host->property_trees(); DCHECK(property_trees); - DCHECK_EQ(layer_tree_host->property_trees(), property_trees); if (property_trees->transform_tree.needs_update()) { property_trees->clip_tree.set_needs_update(true); property_trees->effect_tree.set_needs_update(true); @@ -899,18 +1224,6 @@ void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, ComputeClips(property_trees); } -bool LayerNeedsUpdate(Layer* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees) { - return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); -} - -bool LayerNeedsUpdate(LayerImpl* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees) { - return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); -} - gfx::Transform DrawTransform(const LayerImpl* layer, const TransformTree& transform_tree, const EffectTree& effect_tree) { @@ -921,8 +1234,6 @@ gfx::Transform DrawTransform(const LayerImpl* layer, transform_tree.property_trees()->GetToTarget( layer->transform_tree_index(), layer->render_target_effect_tree_index(), &xform); - if (layer->should_flatten_screen_space_transform_from_property_tree()) - xform.FlattenTo2d(); xform.Translate(layer->offset_to_transform_parent().x(), layer->offset_to_transform_parent().y()); return xform; @@ -938,110 +1249,6 @@ gfx::Transform ScreenSpaceTransform(const LayerImpl* layer, return ScreenSpaceTransformInternal(layer, tree); } -void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, - PropertyTrees* property_trees) { - // Compute transforms - for (LayerImpl* layer : *layer_list) { - const TransformNode* transform_node = - property_trees->transform_tree.Node(layer->transform_tree_index()); - - layer->draw_properties().screen_space_transform = - ScreenSpaceTransformInternal(layer, property_trees->transform_tree); - layer->draw_properties().target_space_transform = DrawTransform( - layer, property_trees->transform_tree, property_trees->effect_tree); - layer->draw_properties().screen_space_transform_is_animating = - transform_node->to_screen_is_potentially_animated; - auto rounded_corner_info = - GetRoundedCornerRRect(property_trees, layer->effect_tree_index(), - /*from_render_surface*/ false); - layer->draw_properties().rounded_corner_bounds = rounded_corner_info.first; - layer->draw_properties().is_fast_rounded_corner = - rounded_corner_info.second; - } - - // Compute effects and determine if render surfaces have contributing layers - // that escape clip. - for (LayerImpl* layer : *layer_list) { - layer->draw_properties().opacity = - LayerDrawOpacity(layer, property_trees->effect_tree); - RenderSurfaceImpl* render_target = layer->render_target(); - int lca_clip_id = LowestCommonAncestor(layer->clip_tree_index(), - render_target->ClipTreeIndex(), - &property_trees->clip_tree); - if (lca_clip_id != render_target->ClipTreeIndex()) { - SetHasContributingLayerThatEscapesClip(lca_clip_id, - render_target->EffectTreeIndex(), - &property_trees->effect_tree); - } - } - - // Compute clips and visible rects - for (LayerImpl* layer : *layer_list) { - ConditionalClip clip = LayerClipRect(property_trees, layer); - // is_clipped should be set before visible rect computation as it is used - // there. - layer->draw_properties().is_clipped = clip.is_clipped; - layer->draw_properties().clip_rect = ToEnclosingClipRect(clip.clip_rect); - layer->draw_properties().visible_layer_rect = - LayerVisibleRect(property_trees, layer); - } - - // Compute drawable content rects - for (LayerImpl* layer : *layer_list) { - gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( - layer->draw_properties().target_space_transform, - gfx::Rect(layer->bounds())); - layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( - layer, bounds_in_target_space, layer->draw_properties().clip_rect); - } -} - -void ComputeMaskDrawProperties(LayerImpl* mask_layer, - PropertyTrees* property_trees) { - // Mask draw properties are used only for rastering, so most of the draw - // properties computed for other layers are not needed. - // Draw transform of a mask layer has to be a 2d scale. - // TODO(sunxd): the draw transform of a mask layer misses the "scale to fit" - // factor from mask layer to its parent. So does the screen space transform. - // It does not cause a problem because currently we only have 1:1 mask layer. - mask_layer->draw_properties().target_space_transform = DrawTransform( - mask_layer, property_trees->transform_tree, property_trees->effect_tree); - mask_layer->draw_properties().screen_space_transform = - ScreenSpaceTransformInternal(mask_layer, - property_trees->transform_tree); - - ConditionalClip clip = LayerClipRect(property_trees, mask_layer); - // is_clipped should be set before visible rect computation as it is used - // there. - mask_layer->draw_properties().is_clipped = clip.is_clipped; - mask_layer->draw_properties().clip_rect = ToEnclosingClipRect(clip.clip_rect); - // Calculate actual visible layer rect for mask layers, since we could have - // tiled mask layers and the tile manager would need this info for rastering. - mask_layer->draw_properties().visible_layer_rect = - LayerVisibleRect(property_trees, mask_layer); - mask_layer->draw_properties().opacity = 1; -} - -void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface) { - SetSurfaceIsClipped(property_trees->clip_tree, render_surface); - SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); - SetSurfaceDrawTransform(property_trees, render_surface); - - render_surface->SetRoundedCornerRRect( - GetRoundedCornerRRect(property_trees, render_surface->EffectTreeIndex(), - /*for_render_surface*/ true) - .first); - render_surface->SetScreenSpaceTransform( - property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( - render_surface->TransformTreeIndex(), - render_surface->EffectTreeIndex())); - - const ClipNode* clip_node = - property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); - SetSurfaceClipRect(clip_node, property_trees, render_surface); -} - void UpdatePageScaleFactor(PropertyTrees* property_trees, TransformNode* page_scale_node, float page_scale_factor) { @@ -1061,24 +1268,77 @@ void UpdatePageScaleFactor(PropertyTrees* property_trees, property_trees->transform_tree.set_needs_update(true); } -void UpdateElasticOverscroll(PropertyTrees* property_trees, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll) { - if (!overscroll_elasticity_element_id) { - DCHECK(elastic_overscroll.IsZero()); - return; +void CalculateDrawProperties( + LayerTreeImpl* layer_tree_impl, + RenderSurfaceList* output_render_surface_list, + LayerImplList* output_update_layer_list_for_testing) { + output_render_surface_list->clear(); + + LayerImplList visible_layer_list; + // Since page scale and elastic overscroll are SyncedProperties, changes + // on the active tree immediately affect the pending tree, so instead of + // trying to update property trees whenever these values change, we + // update property trees before using them. + + // We should never be setting a non-unit page scale factor on an oopif + // subframe ... if we attempt this log it and fail. + // TODO(wjmaclean): Remove as part of conditions for closing the bug. + // https://crbug.com/845097 + PropertyTrees* property_trees = layer_tree_impl->property_trees(); + if (layer_tree_impl->current_page_scale_factor() != + property_trees->transform_tree.page_scale_factor() && + !layer_tree_impl->PageScaleTransformNode()) { + LOG(ERROR) << "Setting PageScale on subframe: new psf = " + << layer_tree_impl->page_scale_factor() << ", old psf = " + << property_trees->transform_tree.page_scale_factor() + << ", in_oopif = " + << layer_tree_impl->settings().is_layer_tree_for_subframe; + NOTREACHED(); } - TransformNode* node = property_trees->transform_tree.FindNodeFromElementId( - overscroll_elasticity_element_id); - DCHECK(node); + UpdatePageScaleFactor(property_trees, + layer_tree_impl->PageScaleTransformNode(), + layer_tree_impl->current_page_scale_factor()); + UpdateElasticOverscroll(property_trees, + layer_tree_impl->OverscrollElasticityTransformNode(), + layer_tree_impl->current_elastic_overscroll()); + // Similarly, the device viewport and device transform are shared + // by both trees. + property_trees->clip_tree.SetViewportClip( + gfx::RectF(layer_tree_impl->GetDeviceViewport())); + property_trees->transform_tree.SetRootScaleAndTransform( + layer_tree_impl->device_scale_factor(), layer_tree_impl->DrawTransform()); + UpdatePropertyTreesAndRenderSurfaces(layer_tree_impl->root_layer(), + property_trees); + + { + TRACE_EVENT0("cc", "draw_property_utils::FindLayersThatNeedUpdates"); + FindLayersThatNeedUpdates(layer_tree_impl, &visible_layer_list); + } - if (node->scroll_offset == gfx::ScrollOffset(elastic_overscroll)) - return; + { + TRACE_EVENT1("cc", + "draw_property_utils::ComputeDrawPropertiesOfVisibleLayers", + "visible_layers", visible_layer_list.size()); + ComputeDrawPropertiesOfVisibleLayers(&visible_layer_list, property_trees); + } - node->scroll_offset = gfx::ScrollOffset(elastic_overscroll); - node->needs_local_transform_update = true; - property_trees->transform_tree.set_needs_update(true); + { + TRACE_EVENT0("cc", "CalculateRenderSurfaceLayerList"); + CalculateRenderSurfaceLayerList(layer_tree_impl, property_trees, + output_render_surface_list, + layer_tree_impl->max_texture_size()); + } + RecordRenderSurfaceReasonsForTracing(property_trees, + output_render_surface_list); + + // A root layer render_surface should always exist after + // CalculateDrawProperties. + DCHECK(property_trees->effect_tree.GetRenderSurface( + EffectTree::kContentsRootNodeId)); + + if (output_update_layer_list_for_testing) + *output_update_layer_list_for_testing = std::move(visible_layer_list); } } // namespace draw_property_utils diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h index 54c7a458d33..2f286c2550d 100644 --- a/chromium/cc/trees/draw_property_utils.h +++ b/chromium/cc/trees/draw_property_utils.h @@ -10,7 +10,6 @@ namespace gfx { class Transform; -class Vector2dF; } // namespace gfx namespace cc { @@ -19,13 +18,11 @@ class Layer; class LayerImpl; class LayerTreeHost; class LayerTreeImpl; -class RenderSurfaceImpl; class EffectTree; class TransformTree; class PropertyTrees; struct EffectNode; struct TransformNode; -struct ElementId; namespace draw_property_utils { @@ -39,52 +36,25 @@ void CC_EXPORT ComputeTransforms(TransformTree* transform_tree); // Computes screen space opacity for every node in the opacity tree. void CC_EXPORT ComputeEffects(EffectTree* effect_tree); -void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host, - PropertyTrees* property_trees); +void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host); void CC_EXPORT UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, PropertyTrees* property_trees); void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, - const PropertyTrees* property_trees, LayerList* update_layer_list); void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, - const PropertyTrees* property_trees, std::vector<LayerImpl*>* visible_layer_list); -void CC_EXPORT -ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, - PropertyTrees* property_trees); - -void CC_EXPORT ComputeMaskDrawProperties(LayerImpl* mask_layer, - PropertyTrees* property_trees); - -void CC_EXPORT ComputeSurfaceDrawProperties(PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface); - -bool CC_EXPORT LayerShouldBeSkippedForDrawPropertiesComputation( - LayerImpl* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree); - -bool CC_EXPORT LayerNeedsUpdate(Layer* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees); - -bool CC_EXPORT LayerNeedsUpdate(LayerImpl* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees); - gfx::Transform CC_EXPORT DrawTransform(const LayerImpl* layer, const TransformTree& transform_tree, const EffectTree& effect_tree); gfx::Transform CC_EXPORT ScreenSpaceTransform(const Layer* layer, const TransformTree& tree); - gfx::Transform CC_EXPORT ScreenSpaceTransform(const LayerImpl* layer, const TransformTree& tree); @@ -92,10 +62,10 @@ void CC_EXPORT UpdatePageScaleFactor(PropertyTrees* property_trees, TransformNode* page_scale_node, float page_scale_factor); -void CC_EXPORT -UpdateElasticOverscroll(PropertyTrees* property_trees, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll); +void CC_EXPORT CalculateDrawProperties( + LayerTreeImpl* layer_tree_impl, + RenderSurfaceList* output_render_surface_list, + LayerImplList* output_update_layer_list_for_testing = nullptr); } // namespace draw_property_utils } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/draw_property_utils_perftest.cc index 14283d082f6..3facfbd838f 100644 --- a/chromium/cc/trees/layer_tree_host_common_perftest.cc +++ b/chromium/cc/trees/draw_property_utils_perftest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/trees/draw_property_utils.h" + #include <stddef.h> #include <memory> @@ -19,11 +21,10 @@ #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/layer_tree_json_parser.h" #include "cc/test/layer_tree_test.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/transform_node.h" #include "components/viz/test/paths.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -32,9 +33,9 @@ static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; -class LayerTreeHostCommonPerfTest : public LayerTreeTest { +class DrawPropertyUtilsPerfTest : public LayerTreeTest { public: - LayerTreeHostCommonPerfTest() + DrawPropertyUtilsPerfTest() : timer_(kWarmupRuns, base::TimeDelta::FromMilliseconds(kTimeLimitMillis), kTimeCheckInterval) {} @@ -58,22 +59,25 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest { content_layer_client_.set_bounds(viewport); } - void SetTestName(const std::string& name) { test_name_ = name; } + void SetUpReporter(const std::string& story_name) { + reporter_ = std::make_unique<perf_test::PerfResultReporter>( + "calc_draw_props_time", story_name); + reporter_->RegisterImportantMetric("", "us"); + } void AfterTest() override { - CHECK(!test_name_.empty()) << "Must SetTestName() before TearDown()."; - perf_test::PrintResult("calc_draw_props_time", "", test_name_, - timer_.TimePerLap().InMicrosecondsF(), "us", true); + CHECK(reporter_) << "Must SetUpReporter() before TearDown()."; + reporter_->AddResult("", timer_.TimePerLap().InMicrosecondsF()); } protected: FakeContentLayerClient content_layer_client_; base::LapTimer timer_; - std::string test_name_; std::string json_; + std::unique_ptr<perf_test::PerfResultReporter> reporter_; }; -class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { +class CalcDrawPropsTest : public DrawPropertyUtilsPerfTest { public: void RunCalcDrawProps() { RunTest(CompositorMode::SINGLE_THREADED); } @@ -81,59 +85,38 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { timer_.Reset(); - LayerTreeImpl* active_tree = host_impl->active_tree(); do { - int max_texture_size = 8096; - DoCalcDrawPropertiesImpl(max_texture_size, active_tree, host_impl); - + RenderSurfaceList render_surface_list; + draw_property_utils::CalculateDrawProperties(host_impl->active_tree(), + &render_surface_list); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); EndTest(); } - - void DoCalcDrawPropertiesImpl(int max_texture_size, - LayerTreeImpl* active_tree, - LayerTreeHostImpl* host_impl) { - RenderSurfaceList update_list; - LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - active_tree->root_layer_for_testing(), active_tree->GetDeviceViewport(), - host_impl->DrawTransform(), active_tree->device_scale_factor(), - active_tree->current_page_scale_factor(), - active_tree->InnerViewportContainerLayer(), - active_tree->InnerViewportScrollLayer(), - active_tree->OuterViewportScrollLayer(), - active_tree->elastic_overscroll()->Current(active_tree->IsActiveTree()), - active_tree->OverscrollElasticityElementId(), max_texture_size, - &update_list, active_tree->property_trees(), - active_tree->property_trees()->transform_tree.Node( - active_tree->InnerViewportContainerLayer() - ->transform_tree_index())); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); - } }; TEST_F(CalcDrawPropsTest, TenTen) { - SetTestName("10_10"); + SetUpReporter("10_10"); ReadTestFile("10_10_layer_tree"); RunCalcDrawProps(); } TEST_F(CalcDrawPropsTest, HeavyPage) { - SetTestName("heavy_page"); + SetUpReporter("heavy_page"); ReadTestFile("heavy_layer_tree"); RunCalcDrawProps(); } TEST_F(CalcDrawPropsTest, TouchRegionLight) { - SetTestName("touch_region_light"); + SetUpReporter("touch_region_light"); ReadTestFile("touch_region_light"); RunCalcDrawProps(); } TEST_F(CalcDrawPropsTest, TouchRegionHeavy) { - SetTestName("touch_region_heavy"); + SetUpReporter("touch_region_heavy"); ReadTestFile("touch_region_heavy"); RunCalcDrawProps(); } diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc index 339be0b576b..b84952f357e 100644 --- a/chromium/cc/trees/effect_node.cc +++ b/chromium/cc/trees/effect_node.cc @@ -31,7 +31,6 @@ EffectNode::EffectNode() is_currently_animating_backdrop_filter(false), is_currently_animating_opacity(false), has_masking_child(false), - is_masked(false), effect_changed(false), subtree_has_copy_request(false), is_fast_rounded_corner(false), @@ -39,7 +38,6 @@ EffectNode::EffectNode() transform_id(0), clip_id(0), target_id(1), - mask_layer_id(Layer::INVALID_ID), closest_ancestor_with_cached_render_surface_id(-1), closest_ancestor_with_copy_request_id(-1) {} @@ -66,7 +64,6 @@ bool EffectNode::operator==(const EffectNode& other) const { HasRenderSurface() == other.HasRenderSurface() && blend_mode == other.blend_mode && surface_contents_scale == other.surface_contents_scale && - unscaled_mask_target_size == other.unscaled_mask_target_size && hidden_by_backface_visibility == other.hidden_by_backface_visibility && double_sided == other.double_sided && trilinear_filtering == other.trilinear_filtering && @@ -83,11 +80,10 @@ bool EffectNode::operator==(const EffectNode& other) const { is_currently_animating_opacity == other.is_currently_animating_opacity && has_masking_child == other.has_masking_child && - is_masked == other.is_masked && effect_changed == other.effect_changed && subtree_has_copy_request == other.subtree_has_copy_request && transform_id == other.transform_id && clip_id == other.clip_id && - target_id == other.target_id && mask_layer_id == other.mask_layer_id && + target_id == other.target_id && closest_ancestor_with_cached_render_surface_id == other.closest_ancestor_with_cached_render_surface_id && closest_ancestor_with_copy_request_id == @@ -126,8 +122,6 @@ const char* RenderSurfaceReasonToString(RenderSurfaceReason reason) { return "clip axis alignment"; case RenderSurfaceReason::kMask: return "mask"; - case RenderSurfaceReason::kRootOrIsolatedGroup: - return "root or isolated group"; case RenderSurfaceReason::kTrilinearFiltering: return "trilinear filtering"; case RenderSurfaceReason::kCache: @@ -144,7 +138,7 @@ const char* RenderSurfaceReasonToString(RenderSurfaceReason reason) { void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("backdrop_mask_element_id", - backdrop_mask_element_id.GetInternalValue()); + backdrop_mask_element_id.GetStableId()); value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); value->SetInteger("stable_id", stable_id); @@ -171,7 +165,6 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetBoolean("has_potential_opacity_animation", has_potential_opacity_animation); value->SetBoolean("has_masking_child", has_masking_child); - value->SetBoolean("is_masked", is_masked); value->SetBoolean("effect_changed", effect_changed); value->SetBoolean("subtree_has_copy_request", subtree_has_copy_request); value->SetString("render_surface_reason", @@ -179,7 +172,6 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("transform_id", transform_id); value->SetInteger("clip_id", clip_id); value->SetInteger("target_id", target_id); - value->SetInteger("mask_layer_id", mask_layer_id); value->SetInteger("closest_ancestor_with_cached_render_surface_id", closest_ancestor_with_cached_render_surface_id); value->SetInteger("closest_ancestor_with_copy_request_id", diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h index 0f9d220d218..50a8d725dec 100644 --- a/chromium/cc/trees/effect_node.h +++ b/chromium/cc/trees/effect_node.h @@ -37,7 +37,6 @@ enum class RenderSurfaceReason : uint8_t { kClipPath, kClipAxisAlignment, kMask, - kRootOrIsolatedGroup, kTrilinearFiltering, kCache, kCopyRequest, @@ -88,8 +87,6 @@ struct CC_EXPORT EffectNode { gfx::Vector2dF surface_contents_scale; - gfx::Size unscaled_mask_target_size; - bool cache_render_surface : 1; bool has_copy_request : 1; bool hidden_by_backface_visibility : 1; @@ -118,8 +115,6 @@ struct CC_EXPORT EffectNode { bool is_currently_animating_opacity : 1; // Whether this node has a child node with kDstIn blend mode. bool has_masking_child : 1; - // Whether this node has a mask. This bit is not used when using layer lists. - bool is_masked : 1; // Whether this node's effect has been changed since the last // frame. Needed in order to compute damage rect. bool effect_changed : 1; @@ -140,9 +135,6 @@ struct CC_EXPORT EffectNode { // This is the id of the ancestor effect node that induces a // RenderSurfaceImpl. int target_id; - // The layer id of the mask layer, if any, to apply to this effect - // node's content when rendering to a surface. - int mask_layer_id; int closest_ancestor_with_cached_render_surface_id; int closest_ancestor_with_copy_request_id; diff --git a/chromium/cc/trees/latency_info_swap_promise_monitor.cc b/chromium/cc/trees/latency_info_swap_promise_monitor.cc index 5da4b6895b3..a69055c986d 100644 --- a/chromium/cc/trees/latency_info_swap_promise_monitor.cc +++ b/chromium/cc/trees/latency_info_swap_promise_monitor.cc @@ -25,16 +25,6 @@ bool AddRenderingScheduledComponent(ui::LatencyInfo* latency_info, return true; } -bool AddForwardingScrollUpdateToMainComponent(ui::LatencyInfo* latency_info) { - if (latency_info->FindLatency( - ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT, - nullptr)) - return false; - latency_info->AddLatencyNumber( - ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT); - return true; -} - } // namespace namespace cc { @@ -67,20 +57,4 @@ void LatencyInfoSwapPromiseMonitor::OnSetNeedsRedrawOnImpl() { } } -void LatencyInfoSwapPromiseMonitor::OnForwardScrollUpdateToMainThreadOnImpl() { - if (AddForwardingScrollUpdateToMainComponent(latency_)) { - ui::LatencyInfo new_latency; - new_latency.CopyLatencyFrom( - *latency_, - ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT); - new_latency.AddLatencyNumberWithTraceName( - ui::LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT, - "ScrollUpdate"); - std::unique_ptr<SwapPromise> swap_promise( - new LatencyInfoSwapPromise(new_latency)); - host_impl_->QueueSwapPromiseForMainThreadScrollUpdate( - std::move(swap_promise)); - } -} - } // namespace cc diff --git a/chromium/cc/trees/latency_info_swap_promise_monitor.h b/chromium/cc/trees/latency_info_swap_promise_monitor.h index c127b966018..eb1d8f4a635 100644 --- a/chromium/cc/trees/latency_info_swap_promise_monitor.h +++ b/chromium/cc/trees/latency_info_swap_promise_monitor.h @@ -26,7 +26,6 @@ class CC_EXPORT LatencyInfoSwapPromiseMonitor : public SwapPromiseMonitor { void OnSetNeedsCommitOnMain() override; void OnSetNeedsRedrawOnImpl() override; - void OnForwardScrollUpdateToMainThreadOnImpl() override; private: ui::LatencyInfo* latency_; diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h index 50848593309..e56d9c563cd 100644 --- a/chromium/cc/trees/layer_tree_frame_sink_client.h +++ b/chromium/cc/trees/layer_tree_frame_sink_client.h @@ -15,12 +15,12 @@ #include "ui/gfx/geometry/rect.h" namespace gfx { -struct PresentationFeedback; class Transform; } namespace viz { class BeginFrameSource; +struct FrameTimingDetails; struct HitTestRegionList; } @@ -57,11 +57,10 @@ class CC_EXPORT LayerTreeFrameSinkClient { // so that frames are submitted only at the rate it can handle them. virtual void DidReceiveCompositorFrameAck() = 0; - // See ui/gfx/presentation_feedback.h for details on args. |time| is always - // non-zero. + // See components/viz/common/frame_timing_details.h for details on args. virtual void DidPresentCompositorFrame( - uint32_t presentation_token, - const gfx::PresentationFeedback& feedback) = 0; + uint32_t frame_token, + const viz::FrameTimingDetails& details) = 0; // The LayerTreeFrameSink is lost when the viz::ContextProviders held by it // encounter an error. In this case the LayerTreeFrameSink (and the diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc index 1fab49e82ec..09cd244629c 100644 --- a/chromium/cc/trees/layer_tree_host.cc +++ b/chromium/cc/trees/layer_tree_host.cc @@ -48,12 +48,13 @@ #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_host_client.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" +#include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/property_tree_builder.h" #include "cc/trees/proxy_main.h" #include "cc/trees/render_frame_metadata_observer.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/swap_promise_manager.h" @@ -126,6 +127,7 @@ LayerTreeHost::LayerTreeHost(InitParams params, CompositorMode mode) compositor_mode_(mode), ui_resource_manager_(std::make_unique<UIResourceManager>()), client_(params.client), + scheduling_client_(params.scheduling_client), rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()), settings_(*params.settings), debug_state_(settings_.initial_debug_state), @@ -199,9 +201,6 @@ LayerTreeHost::~LayerTreeHost() { // Clear any references into the LayerTreeHost. mutator_host_->SetMutatorHostClient(nullptr); - // We must clear any pointers into the layer tree prior to destroying it. - RegisterViewportLayers(ViewportLayers()); - if (root_layer_) { root_layer_->SetLayerTreeHost(nullptr); @@ -289,8 +288,12 @@ const LayerTreeDebugState& LayerTreeHost::GetDebugState() const { return debug_state_; } -void LayerTreeHost::RequestMainFrameUpdate() { +void LayerTreeHost::RequestMainFrameUpdate(bool report_cc_metrics) { client_->UpdateLayerTreeHost(); + if (report_cc_metrics) + begin_main_frame_metrics_ = client_->GetBeginMainFrameMetrics(); + else + begin_main_frame_metrics_.reset(); } // This function commits the LayerTreeHost to an impl tree. When modifying @@ -368,6 +371,7 @@ void LayerTreeHost::FinishCommitOnImplThread( TRACE_EVENT0("cc", "LayerTreeHost::AnimationHost::PushProperties"); DCHECK(host_impl->mutator_host()); mutator_host_->PushPropertiesTo(host_impl->mutator_host()); + MoveChangeTrackingToLayers(sync_tree); // Updating elements affects whether animations are in effect based on their // properties so run after pushing updated animation properties. @@ -402,6 +406,27 @@ void LayerTreeHost::FinishCommitOnImplThread( } } +void LayerTreeHost::MoveChangeTrackingToLayers(LayerTreeImpl* tree_impl) { + // This is only true for single-thread compositing (i.e. not via Blink). + bool property_trees_changed_on_active_tree = + tree_impl->IsActiveTree() && tree_impl->property_trees()->changed; + + if (property_trees_changed_on_active_tree) { + // Property trees may store damage status. We preserve the sync tree damage + // status by pushing the damage status from sync tree property trees to main + // thread property trees or by moving it onto the layers. + if (root_layer_) { + if (property_trees_.sequence_number == + tree_impl->property_trees()->sequence_number) + tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_); + else + tree_impl->MoveChangeTrackingToLayers(); + } + } else { + tree_impl->MoveChangeTrackingToLayers(); + } +} + void LayerTreeHost::ImageDecodesFinished( const std::vector<std::pair<int, bool>>& results) { // Issue stored callbacks and remove them from the pending list. @@ -442,8 +467,8 @@ void LayerTreeHost::WillCommit() { // PushPropertiesTo() propagates layer debug info to the impl side -- // otherwise this won't happen for the layers that remain unchanged since // tracing started. - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsPushProperties(); }); + for (auto* layer : *this) + layer->SetNeedsPushProperties(); } for (Layer* layer : LayersThatShouldPushProperties()) @@ -454,8 +479,7 @@ void LayerTreeHost::WillCommit() { void LayerTreeHost::UpdateDeferMainFrameUpdateInternal() { proxy_->SetDeferMainFrameUpdate( defer_main_frame_update_count_ > 0 || - (settings_.enable_surface_synchronization && - !local_surface_id_allocation_from_parent_.IsValid())); + !local_surface_id_allocation_from_parent_.IsValid()); } bool LayerTreeHost::IsUsingLayerLists() const { @@ -526,13 +550,13 @@ LayerTreeHost::CreateLayerTreeHostImpl( std::unique_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( settings_, client, task_runner_provider_.get(), rendering_stats_instrumentation_.get(), task_graph_runner_, - std::move(mutator_host_impl), id_, std::move(image_worker_task_runner_)); + std::move(mutator_host_impl), id_, std::move(image_worker_task_runner_), + scheduling_client_); if (ukm_recorder_factory_) { host_impl->InitializeUkm(ukm_recorder_factory_->CreateRecorder()); ukm_recorder_factory_.reset(); } - host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); host_impl->SetContentHasSlowPaths(content_has_slow_paths_); host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_); task_graph_runner_ = nullptr; @@ -653,16 +677,6 @@ void LayerTreeHost::SetDebugState( SetNeedsCommit(); } -void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) { - if (has_trigger == has_gpu_rasterization_trigger_) - return; - - has_gpu_rasterization_trigger_ = has_trigger; - TRACE_EVENT_INSTANT1("cc", "LayerTreeHost::SetHasGpuRasterizationTrigger", - TRACE_EVENT_SCOPE_THREAD, "has_trigger", - has_gpu_rasterization_trigger_); -} - void LayerTreeHost::ApplyPageScaleDeltaFromImplSide( float page_scale_delta) { DCHECK(CommitRequested()); @@ -687,7 +701,7 @@ void LayerTreeHost::LayoutAndUpdateLayers() { DCHECK(IsSingleThreaded()); // This function is only valid when not using the scheduler. DCHECK(!settings_.single_thread_proxy_scheduler); - RequestMainFrameUpdate(); + RequestMainFrameUpdate(false); UpdateLayers(); } @@ -702,6 +716,7 @@ void LayerTreeHost::Composite(base::TimeTicks frame_begin_time, bool raster) { bool LayerTreeHost::UpdateLayers() { if (!root_layer()) { property_trees_.clear(); + viewport_property_ids_ = ViewportPropertyIds(); return false; } @@ -713,8 +728,11 @@ bool LayerTreeHost::UpdateLayers() { client_->DidUpdateLayers(); micro_benchmark_controller_.DidUpdateLayers(); + base::TimeDelta elapsed_delta = timer.Elapsed(); + if (begin_main_frame_metrics_) + begin_main_frame_metrics_->update_layers = elapsed_delta; if (const char* client_name = GetClientNameForMetrics()) { - auto elapsed = timer.Elapsed().InMicroseconds(); + auto elapsed = elapsed_delta.InMicroseconds(); std::string histogram_name = base::StringPrintf("Compositing.%s.LayersUpdateTime", client_name); @@ -761,8 +779,6 @@ void LayerTreeHost::RecordGpuRasterizationHistogram( UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled", gpu_rasterization_enabled); if (gpu_rasterization_enabled) { - UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered", - has_gpu_rasterization_trigger_); UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent", !content_has_slow_paths_); UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSlowPathsWithNonAAPaint", @@ -801,13 +817,7 @@ bool LayerTreeHost::DoUpdateLayers() { // need to be built here. if (!IsUsingLayerLists()) { TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees"); - Layer* page_scale_layer = viewport_layers_.page_scale.get(); - gfx::Transform identity_transform; - PropertyTreeBuilder::BuildPropertyTrees( - root_layer_.get(), page_scale_layer, inner_viewport_scroll_layer(), - outer_viewport_scroll_layer(), overscroll_elasticity_element_id(), - elastic_overscroll_, page_scale_factor_, device_scale_factor_, - device_viewport_rect_, identity_transform, &property_trees_); + PropertyTreeBuilder::BuildPropertyTrees(this); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "LayerTreeHost::UpdateLayers_BuiltPropertyTrees", TRACE_EVENT_SCOPE_THREAD, "property_trees", @@ -848,11 +858,10 @@ bool LayerTreeHost::DoUpdateLayers() { CHECK(property_trees_.effect_tree.Node(root_layer_->effect_tree_index())); #endif - draw_property_utils::UpdatePropertyTrees(this, &property_trees_); + draw_property_utils::UpdatePropertyTrees(this); LayerList update_layer_list; - draw_property_utils::FindLayersThatNeedUpdates(this, &property_trees_, - &update_layer_list); + draw_property_utils::FindLayersThatNeedUpdates(this, &update_layer_list); bool painted_content_has_slow_paths = false; bool painted_content_has_non_aa_paint = false; @@ -898,10 +907,13 @@ void LayerTreeHost::ApplyViewportChanges(const ScrollAndScaleSet& info) { // Preemptively apply the scroll offset and scale delta here before sending // it to the client. If the client comes back and sets it to the same // value, then the layer can early out without needing a full commit. - if (viewport_layers_.inner_viewport_scroll) { - viewport_layers_.inner_viewport_scroll->SetScrollOffsetFromImplSide( - viewport_layers_.inner_viewport_scroll->CurrentScrollOffset() + - inner_viewport_scroll_delta); + if (auto* inner_scroll = property_trees()->scroll_tree.Node( + viewport_property_ids_.inner_scroll)) { + if (auto* inner_scroll_layer = LayerByElementId(inner_scroll->element_id)) { + inner_scroll_layer->SetScrollOffsetFromImplSide( + inner_scroll_layer->CurrentScrollOffset() + + inner_viewport_scroll_delta); + } } ApplyPageScaleDeltaFromImplSide(info.page_scale_delta); @@ -1100,36 +1112,26 @@ void LayerTreeHost::SetNonBlinkManagedRootLayer( force_use_property_tree_builder_ = true; } -void LayerTreeHost::RegisterViewportLayers(const ViewportLayers& layers) { - DCHECK(!layers.inner_viewport_scroll || - layers.inner_viewport_scroll != layers.outer_viewport_scroll); - // The page scale layer only affects the innter viewport scroll layer. The - // page scale layer should be sandwiched between the inner viewport scroll and - // inner viewport container layers: - // inner viewport container - // overscroll elasticity (optional) - // page scale - // inner viewport scroll - DCHECK(IsUsingLayerLists() || !layers.page_scale || - layers.inner_viewport_scroll->parent() == layers.page_scale); - DCHECK(IsUsingLayerLists() || !layers.page_scale || - layers.page_scale->parent()->element_id() == - layers.overscroll_elasticity_element_id || - layers.page_scale->parent() == layers.inner_viewport_container); - viewport_layers_.overscroll_elasticity_element_id = - layers.overscroll_elasticity_element_id; - viewport_layers_.page_scale = layers.page_scale; - viewport_layers_.inner_viewport_container = layers.inner_viewport_container; - viewport_layers_.outer_viewport_container = layers.outer_viewport_container; - viewport_layers_.inner_viewport_scroll = layers.inner_viewport_scroll; - viewport_layers_.outer_viewport_scroll = layers.outer_viewport_scroll; -} - void LayerTreeHost::RegisterViewportPropertyIds( const ViewportPropertyIds& ids) { - DCHECK(!viewport_layers_.inner_viewport_scroll); DCHECK(IsUsingLayerLists()); viewport_property_ids_ = ids; + // Outer viewport properties exist only if inner viewport property exists. + DCHECK(ids.inner_scroll != ScrollTree::kInvalidNodeId || + (ids.outer_scroll == ScrollTree::kInvalidNodeId && + ids.outer_clip == ClipTree::kInvalidNodeId)); +} + +Layer* LayerTreeHost::InnerViewportScrollLayerForTesting() const { + auto* scroll_node = + property_trees()->scroll_tree.Node(viewport_property_ids_.inner_scroll); + return scroll_node ? LayerByElementId(scroll_node->element_id) : nullptr; +} + +Layer* LayerTreeHost::OuterViewportScrollLayerForTesting() const { + auto* scroll_node = + property_trees()->scroll_tree.Node(viewport_property_ids_.outer_scroll); + return scroll_node ? LayerByElementId(scroll_node->element_id) : nullptr; } void LayerTreeHost::RegisterSelection(const LayerSelection& selection) { @@ -1172,8 +1174,8 @@ void LayerTreeHost::SetEventListenerProperties( old_properties == EventListenerProperties::kBlockingAndPassive; if (old_property_is_blocking != new_property_is_blocking) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsPushProperties(); }); + for (auto* layer : *this) + layer->SetNeedsPushProperties(); } } @@ -1321,8 +1323,8 @@ void LayerTreeHost::SetRasterColorSpace( return; raster_color_space_id_ = gfx::ColorSpace::GetNextId(); raster_color_space_ = raster_color_space; - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsDisplay(); }); + for (auto* layer : *this) + layer->SetNeedsDisplay(); } void LayerTreeHost::SetExternalPageScaleFactor( @@ -1396,11 +1398,8 @@ void LayerTreeHost::SetLocalSurfaceIdAllocationFromParent( } void LayerTreeHost::RequestNewLocalSurfaceId() { - // If surface synchronization is enabled, then we can still request a new - // viz::LocalSurfaceId but that request will be deferred until we have a valid - // viz::LocalSurfaceId from the parent. - DCHECK(settings_.enable_surface_synchronization || - local_surface_id_allocation_from_parent_.IsValid()); + // We can still request a new viz::LocalSurfaceId but that request will be + // deferred until we have a valid viz::LocalSurfaceId from the parent. if (new_local_surface_id_request_) return; new_local_surface_id_request_ = true; @@ -1554,32 +1553,7 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) { EventListenerClass::kTouchEndOrCancel, event_listener_properties(EventListenerClass::kTouchEndOrCancel)); - if (viewport_layers_.inner_viewport_scroll) { - LayerTreeImpl::ViewportLayerIds ids; - if (viewport_layers_.overscroll_elasticity_element_id) { - ids.overscroll_elasticity_element_id = - viewport_layers_.overscroll_elasticity_element_id; - } - if (viewport_layers_.page_scale) { - ids.page_scale = viewport_layers_.page_scale->id(); - } - if (viewport_layers_.inner_viewport_container) { - ids.inner_viewport_container = - viewport_layers_.inner_viewport_container->id(); - } - if (viewport_layers_.outer_viewport_container) { - ids.outer_viewport_container = - viewport_layers_.outer_viewport_container->id(); - } - ids.inner_viewport_scroll = viewport_layers_.inner_viewport_scroll->id(); - if (viewport_layers_.outer_viewport_scroll) - ids.outer_viewport_scroll = viewport_layers_.outer_viewport_scroll->id(); - tree_impl->SetViewportLayersFromIds(ids); - } else { - tree_impl->ClearViewportLayers(); - } - - tree_impl->set_viewport_property_ids(viewport_property_ids_); + tree_impl->SetViewportPropertyIds(viewport_property_ids_); tree_impl->RegisterSelection(selection_); @@ -1641,7 +1615,6 @@ void LayerTreeHost::PushSurfaceRangesTo(LayerTreeImpl* tree_impl) { void LayerTreeHost::PushLayerTreeHostPropertiesTo( LayerTreeHostImpl* host_impl) { - host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); host_impl->SetContentHasSlowPaths(content_has_slow_paths_); host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_); host_impl->set_external_pinch_gesture_active( @@ -1684,21 +1657,13 @@ void LayerTreeHost::UpdateActiveElements() { mutator_host_->UpdateRegisteredElementIds(ElementListType::ACTIVE); } -static void SetElementIdForTesting(Layer* layer) { - layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); -} - void LayerTreeHost::SetElementIdsForTesting() { - LayerTreeHostCommon::CallFunctionForEveryLayer(this, SetElementIdForTesting); + for (auto* layer : *this) + layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); } void LayerTreeHost::BuildPropertyTreesForTesting() { - gfx::Transform identity_transform; - PropertyTreeBuilder::BuildPropertyTrees( - root_layer(), page_scale_layer(), inner_viewport_scroll_layer(), - outer_viewport_scroll_layer(), overscroll_elasticity_element_id(), - elastic_overscroll(), page_scale_factor(), device_scale_factor(), - device_viewport_rect(), identity_transform, property_trees()); + PropertyTreeBuilder::BuildPropertyTrees(this); } bool LayerTreeHost::IsElementInPropertyTrees(ElementId element_id, @@ -1846,20 +1811,20 @@ void LayerTreeHost::QueueImageDecode(const PaintImage& image, SetNeedsCommit(); } -LayerListIterator<Layer> LayerTreeHost::begin() const { - return LayerListIterator<Layer>(root_layer_.get()); +LayerListIterator LayerTreeHost::begin() const { + return LayerListIterator(root_layer_.get()); } -LayerListIterator<Layer> LayerTreeHost::end() const { - return LayerListIterator<Layer>(nullptr); +LayerListIterator LayerTreeHost::end() const { + return LayerListIterator(nullptr); } -LayerListReverseIterator<Layer> LayerTreeHost::rbegin() { - return LayerListReverseIterator<Layer>(root_layer_.get()); +LayerListReverseIterator LayerTreeHost::rbegin() { + return LayerListReverseIterator(root_layer_.get()); } -LayerListReverseIterator<Layer> LayerTreeHost::rend() { - return LayerListReverseIterator<Layer>(nullptr); +LayerListReverseIterator LayerTreeHost::rend() { + return LayerListReverseIterator(nullptr); } void LayerTreeHost::SetPropertyTreesForTesting( diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index 0c3405f8cb7..104cc541e97 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -33,6 +33,7 @@ #include "cc/input/scrollbar.h" #include "cc/layers/layer_collections.h" #include "cc/layers/layer_list_iterator.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "cc/paint/node_id.h" #include "cc/trees/compositor_mode.h" #include "cc/trees/layer_tree_frame_sink.h" @@ -57,7 +58,6 @@ namespace cc { class HeadsUpDisplayLayer; class Layer; -class LayerTreeHostClient; class LayerTreeHostImpl; class LayerTreeHostImplClient; class LayerTreeHostSingleThreadClient; @@ -96,6 +96,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { InitParams& operator=(InitParams&&); LayerTreeHostClient* client = nullptr; + LayerTreeHostSchedulingClient* scheduling_client = nullptr; TaskGraphRunner* task_graph_runner = nullptr; LayerTreeSettings const* settings = nullptr; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner; @@ -172,14 +173,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // when a main frame is requested. SwapPromiseManager* GetSwapPromiseManager(); - // Sets or gets whether the content is suitable to use Gpu Rasterization. This - // flag is used to enable gpu rasterization, and can be modified at any time - // to change the setting based on content. - void SetHasGpuRasterizationTrigger(bool has_trigger); - bool has_gpu_rasterization_trigger() const { - return has_gpu_rasterization_trigger_; - } - // Visibility and LayerTreeFrameSink ------------------------------- // Sets or gets if the LayerTreeHost is visible. When not visible it will: @@ -280,8 +273,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // Input Handling --------------------------------------------- - // Sets the state of the browser controls. (Used for URL bar animations on - // android). + // Sets the state of the browser controls. (Used for URL bar animations). void UpdateBrowserControlsState(BrowserControlsState constraints, BrowserControlsState current, bool animate); @@ -332,37 +324,24 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // caller inform blink about the layer and remove the function. void SetNonBlinkManagedRootLayer(scoped_refptr<Layer> root_layer); - // Sets or gets the collection of viewport Layers, defined to allow pinch-zoom - // transformations on the compositor thread. - void RegisterViewportLayers(const ViewportLayers& viewport_layers); - ElementId overscroll_elasticity_element_id() const { - return viewport_layers_.overscroll_elasticity_element_id; - } - Layer* page_scale_layer() const { return viewport_layers_.page_scale.get(); } - Layer* inner_viewport_container_layer() const { - return viewport_layers_.inner_viewport_container.get(); - } - Layer* outer_viewport_container_layer() const { - return viewport_layers_.outer_viewport_container.get(); - } - Layer* inner_viewport_scroll_layer() const { - return viewport_layers_.inner_viewport_scroll.get(); - } - Layer* outer_viewport_scroll_layer() const { - return viewport_layers_.outer_viewport_scroll.get(); - } - - // Counterpart of ViewportLayers for CompositeAfterPaint which doesn't create - // viewport layers. struct ViewportPropertyIds { + int overscroll_elasticity_transform = TransformTree::kInvalidNodeId; int page_scale_transform = TransformTree::kInvalidNodeId; int inner_scroll = ScrollTree::kInvalidNodeId; - // TODO(crbug.com/909750): Switch other usages of viewport layers to - // property ids for CompositeAfterPaint. + int outer_clip = ClipTree::kInvalidNodeId; + int outer_scroll = ScrollTree::kInvalidNodeId; }; + // Sets the collection of viewport property ids, defined to allow viewport + // pinch-zoom etc. on the compositor thread. void RegisterViewportPropertyIds(const ViewportPropertyIds&); + LayerTreeHost::ViewportPropertyIds ViewportPropertyIdsForTesting() const { + return viewport_property_ids_; + } + Layer* InnerViewportScrollLayerForTesting() const; + Layer* OuterViewportScrollLayerForTesting() const; + // Sets or gets the position of touch handles for a text selection. These are // submitted to the display compositor along with the Layer tree's contents // allowing it to present the selection handles. This is done because the @@ -546,6 +525,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl); void PushSurfaceRangesTo(LayerTreeImpl* tree_impl); void PushLayerTreeHostPropertiesTo(LayerTreeHostImpl* host_impl); + void MoveChangeTrackingToLayers(LayerTreeImpl* tree_impl); MutatorHost* mutator_host() const { return mutator_host_; } @@ -564,10 +544,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void BuildPropertyTreesForTesting(); // Layer iterators. - LayerListIterator<Layer> begin() const; - LayerListIterator<Layer> end() const; - LayerListReverseIterator<Layer> rbegin(); - LayerListReverseIterator<Layer> rend(); + LayerListIterator begin() const; + LayerListIterator end() const; + LayerListReverseIterator rbegin(); + LayerListReverseIterator rend(); // LayerTreeHost interface to Proxy. void WillBeginMainFrame(); @@ -576,7 +556,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void BeginMainFrameNotExpectedSoon(); void BeginMainFrameNotExpectedUntil(base::TimeTicks time); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); - void RequestMainFrameUpdate(); + void RequestMainFrameUpdate(bool report_cc_metrics); void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); void WillCommit(); void CommitComplete(); @@ -602,6 +582,9 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time); LayerTreeHostClient* client() { return client_; } + LayerTreeHostSchedulingClient* scheduling_client() { + return scheduling_client_; + } bool gpu_rasterization_histogram_recorded() const { return gpu_rasterization_histogram_recorded_; @@ -744,6 +727,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { std::unique_ptr<UIResourceManager> ui_resource_manager_; LayerTreeHostClient* client_; + LayerTreeHostSchedulingClient* scheduling_client_; std::unique_ptr<Proxy> proxy_; std::unique_ptr<TaskRunnerProvider> task_runner_provider_; @@ -766,7 +750,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { bool visible_ = false; - bool has_gpu_rasterization_trigger_ = false; bool content_has_slow_paths_ = false; bool content_has_non_aa_paint_ = false; bool gpu_rasterization_histogram_recorded_ = false; @@ -788,8 +771,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { scoped_refptr<Layer> root_layer_; - ViewportLayers viewport_layers_; - // For CompositeAfterPaint. ViewportPropertyIds viewport_property_ids_; float top_controls_height_ = 0.f; @@ -886,6 +867,12 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // added here. std::vector<PresentationTimeCallback> pending_presentation_time_callbacks_; + // Latency information for work done in ProxyMain::BeginMainFrame. The + // unique_ptr is allocated in RequestMainFrameUpdate, and passed to Blink's + // LocalFrameView that fills in the fields. This object adds the timing for + // UpdateLayers. CC reads the data during commit, and clears the unique_ptr. + std::unique_ptr<BeginMainFrameMetrics> begin_main_frame_metrics_; + // Used to vend weak pointers to LayerTreeHost to ScopedDeferMainFrameUpdate // objects. base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_{ diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h index 7f424be64e6..8cf1a5682a0 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -22,6 +22,7 @@ struct BeginFrameArgs; } namespace cc { +struct BeginMainFrameMetrics; struct ElementId; struct ApplyViewportChangesArgs { @@ -149,11 +150,29 @@ class LayerTreeHostClient { // the time from the start of BeginMainFrame to the Commit, or early out. virtual void RecordStartOfFrameMetrics() = 0; virtual void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) = 0; + // Return metrics information for the stages of BeginMainFrame. This is + // ultimately implemented by Blink's LocalFrameUKMAggregator. It must be a + // distinct call from the FrameMetrics above because the BeginMainFrameMetrics + // for compositor latency must be gathered before the layer tree is + // committed to the compositor, which is before the call to + // RecordEndOfFrameMetrics. + virtual std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() = 0; protected: virtual ~LayerTreeHostClient() {} }; +// LayerTreeHost->WebThreadScheduler callback interface. Instances of this class +// must be safe to use on both the compositor and main threads. +class LayerTreeHostSchedulingClient { + public: + // Indicates that the compositor thread scheduled a BeginMainFrame to run on + // the main thread. + virtual void DidScheduleBeginMainFrame() = 0; + // Called unconditionally when BeginMainFrame runs on the main thread. + virtual void DidRunBeginMainFrame() = 0; +}; + } // namespace cc #endif // CC_TREES_LAYER_TREE_HOST_CLIENT_H_ diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc deleted file mode 100644 index e91bd95593a..00000000000 --- a/chromium/cc/trees/layer_tree_host_common.cc +++ /dev/null @@ -1,687 +0,0 @@ -// Copyright 2011 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 "cc/trees/layer_tree_host_common.h" - -#include <stddef.h> - -#include <algorithm> - -#include "base/containers/adapters.h" -#include "base/trace_event/trace_event.h" -#include "cc/base/math_util.h" -#include "cc/layers/heads_up_display_layer_impl.h" -#include "cc/layers/layer.h" -#include "cc/layers/layer_impl.h" -#include "cc/trees/draw_property_utils.h" -#include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_impl.h" -#include "cc/trees/property_tree_builder.h" -#include "cc/trees/scroll_node.h" -#include "cc/trees/transform_node.h" -#include "ui/gfx/geometry/rect_conversions.h" -#include "ui/gfx/geometry/vector2d_conversions.h" -#include "ui/gfx/transform.h" -#include "ui/gfx/transform_util.h" - -namespace cc { - -LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - float page_scale_factor, - const Layer* page_scale_layer, - const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer) - : root_layer(root_layer), - device_viewport_rect(device_viewport_rect), - device_transform(device_transform), - device_scale_factor(device_scale_factor), - page_scale_factor(page_scale_factor), - page_scale_layer(page_scale_layer), - inner_viewport_scroll_layer(inner_viewport_scroll_layer), - outer_viewport_scroll_layer(outer_viewport_scroll_layer) {} - -LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform) - : CalcDrawPropsMainInputsForTesting(root_layer, - device_viewport_rect, - device_transform, - 1.f, - 1.f, - nullptr, - nullptr, - nullptr) {} - -LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect) - : CalcDrawPropsMainInputsForTesting(root_layer, - device_viewport_rect, - gfx::Transform()) {} - -LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( - LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - float page_scale_factor, - const LayerImpl* page_scale_layer, - const LayerImpl* inner_viewport_scroll_layer, - const LayerImpl* outer_viewport_scroll_layer, - const gfx::Vector2dF& elastic_overscroll, - const ElementId elastic_overscroll_element_id, - int max_texture_size, - RenderSurfaceList* render_surface_list, - PropertyTrees* property_trees, - TransformNode* page_scale_transform_node) - : root_layer(root_layer), - device_viewport_rect(device_viewport_rect), - device_transform(device_transform), - device_scale_factor(device_scale_factor), - page_scale_factor(page_scale_factor), - page_scale_layer(page_scale_layer), - inner_viewport_scroll_layer(inner_viewport_scroll_layer), - outer_viewport_scroll_layer(outer_viewport_scroll_layer), - elastic_overscroll(elastic_overscroll), - elastic_overscroll_element_id(elastic_overscroll_element_id), - max_texture_size(max_texture_size), - render_surface_list(render_surface_list), - property_trees(property_trees), - page_scale_transform_node(page_scale_transform_node) {} - -LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - RenderSurfaceList* render_surface_list) - : CalcDrawPropsImplInputs(root_layer, - device_viewport_rect, - device_transform, - device_scale_factor, - 1.f, - nullptr, - nullptr, - nullptr, - gfx::Vector2dF(), - ElementId(), - std::numeric_limits<int>::max() / 2, - render_surface_list, - GetPropertyTrees(root_layer), - nullptr) { - DCHECK(root_layer); - DCHECK(render_surface_list); -} - -LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - RenderSurfaceList* render_surface_list) - : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_rect, - device_transform, - 1.f, - render_surface_list) {} - -LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - RenderSurfaceList* render_surface_list) - : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_rect, - gfx::Transform(), - 1.f, - render_surface_list) {} - -LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - float device_scale_factor, - RenderSurfaceList* render_surface_list) - : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_rect, - gfx::Transform(), - device_scale_factor, - render_surface_list) {} - -bool LayerTreeHostCommon::ScrollUpdateInfo::operator==( - const LayerTreeHostCommon::ScrollUpdateInfo& other) const { - return element_id == other.element_id && scroll_delta == other.scroll_delta; -} - -LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo() - : element_id(), hidden(true) {} - -LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo(ElementId id, - bool hidden) - : element_id(id), hidden(hidden) {} - -bool LayerTreeHostCommon::ScrollbarsUpdateInfo::operator==( - const LayerTreeHostCommon::ScrollbarsUpdateInfo& other) const { - return element_id == other.element_id && hidden == other.hidden; -} - -ScrollAndScaleSet::ScrollAndScaleSet() - : page_scale_delta(1.f), - is_pinch_gesture_active(false), - top_controls_delta(0.f), - browser_controls_constraint(BrowserControlsState::kBoth), - browser_controls_constraint_changed(false), - scroll_gesture_did_end(false), - manipulation_info(kManipulationInfoNone) {} - -ScrollAndScaleSet::~ScrollAndScaleSet() = default; - -static inline void SetMaskLayersContributeToDrawnRenderSurface( - RenderSurfaceImpl* surface, - PropertyTrees* property_trees) { - LayerImpl* mask_layer = surface->MaskLayer(); - if (mask_layer) { - mask_layer->set_contributes_to_drawn_render_surface(true); - draw_property_utils::ComputeMaskDrawProperties(mask_layer, property_trees); - } -} - -static inline void ClearMaskLayersContributeToDrawnRenderSurface( - RenderSurfaceImpl* surface) { - LayerImpl* mask_layer = surface->MaskLayer(); - if (mask_layer) - mask_layer->set_contributes_to_drawn_render_surface(false); -} - -static float TranslationFromActiveTreeLayerScreenSpaceTransform( - LayerImpl* pending_tree_layer) { - LayerTreeImpl* layer_tree_impl = pending_tree_layer->layer_tree_impl(); - if (layer_tree_impl) { - LayerImpl* active_tree_layer = - layer_tree_impl->FindActiveTreeLayerById(pending_tree_layer->id()); - if (active_tree_layer) { - gfx::Transform active_tree_screen_space_transform = - active_tree_layer->draw_properties().screen_space_transform; - if (active_tree_screen_space_transform.IsIdentity()) - return 0.f; - if (active_tree_screen_space_transform.ApproximatelyEqual( - pending_tree_layer->draw_properties().screen_space_transform)) - return 0.f; - return (active_tree_layer->draw_properties() - .screen_space_transform.To2dTranslation() - - pending_tree_layer->draw_properties() - .screen_space_transform.To2dTranslation()) - .Length(); - } - } - return 0.f; -} - -// A layer jitters if its screen space transform is same on two successive -// commits, but has changed in between the commits. CalculateLayerJitter -// computes the jitter for the layer. -int LayerTreeHostCommon::CalculateLayerJitter(LayerImpl* layer) { - float jitter = 0.f; - layer->performance_properties().translation_from_last_frame = 0.f; - layer->performance_properties().last_commit_screen_space_transform = - layer->draw_properties().screen_space_transform; - - if (!layer->visible_layer_rect().IsEmpty()) { - if (layer->draw_properties().screen_space_transform.ApproximatelyEqual( - layer->performance_properties() - .last_commit_screen_space_transform)) { - float translation_from_last_commit = - TranslationFromActiveTreeLayerScreenSpaceTransform(layer); - if (translation_from_last_commit > 0.f) { - layer->performance_properties().num_fixed_point_hits++; - layer->performance_properties().translation_from_last_frame = - translation_from_last_commit; - if (layer->performance_properties().num_fixed_point_hits > - layer->layer_tree_impl()->kFixedPointHitsThreshold) { - // Jitter = Translation from fixed point * sqrt(Area of the layer). - // The square root of the area is used instead of the area to match - // the dimensions of both terms on the rhs. - jitter += translation_from_last_commit * - sqrt(layer->visible_layer_rect().size().GetArea()); - } - } else { - layer->performance_properties().num_fixed_point_hits = 0; - } - } - } - return jitter; -} - -enum PropertyTreeOption { BUILD_PROPERTY_TREES, DONT_BUILD_PROPERTY_TREES }; - -static void AddSurfaceToRenderSurfaceList( - RenderSurfaceImpl* render_surface, - RenderSurfaceList* render_surface_list, - PropertyTrees* property_trees) { - // |render_surface| must appear after its target, so first make sure its - // target is in the list. - RenderSurfaceImpl* target = render_surface->render_target(); - bool is_root = - render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; - if (!is_root && !target->is_render_surface_list_member()) { - AddSurfaceToRenderSurfaceList(target, render_surface_list, property_trees); - } - render_surface->ClearAccumulatedContentRect(); - render_surface_list->push_back(render_surface); - render_surface->set_is_render_surface_list_member(true); - if (is_root) { - // The root surface does not contribute to any other surface, it has no - // target. - render_surface->set_contributes_to_drawn_surface(false); - } else { - bool contributes_to_drawn_surface = - property_trees->effect_tree.ContributesToDrawnSurface( - render_surface->EffectTreeIndex()); - render_surface->set_contributes_to_drawn_surface( - contributes_to_drawn_surface); - } - - draw_property_utils::ComputeSurfaceDrawProperties(property_trees, - render_surface); - - // Ignore occlusion from outside the surface when surface contents need to be - // fully drawn. Layers with copy-request need to be complete. We could be - // smarter about layers with filters that move pixels and exclude regions - // where both layers and the filters are occluded, but this seems like - // overkill. - // TODO(senorblanco): make this smarter for the SkImageFilter case (check for - // pixel-moving filters) - const FilterOperations& filters = render_surface->Filters(); - bool is_occlusion_immune = render_surface->HasCopyRequest() || - render_surface->ShouldCacheRenderSurface() || - filters.HasReferenceFilter() || - filters.HasFilterThatMovesPixels(); - if (is_occlusion_immune) { - render_surface->SetNearestOcclusionImmuneAncestor(render_surface); - } else if (is_root) { - render_surface->SetNearestOcclusionImmuneAncestor(nullptr); - } else { - render_surface->SetNearestOcclusionImmuneAncestor( - render_surface->render_target()->nearest_occlusion_immune_ancestor()); - } -} - -static bool SkipForInvertibility(const LayerImpl* layer, - PropertyTrees* property_trees) { - const TransformNode* transform_node = - property_trees->transform_tree.Node(layer->transform_tree_index()); - const EffectNode* effect_node = - property_trees->effect_tree.Node(layer->effect_tree_index()); - bool non_root_copy_request = - effect_node->closest_ancestor_with_copy_request_id > - EffectTree::kContentsRootNodeId; - gfx::Transform from_target; - // If there is a copy request, we check the invertibility of the transform - // between the node corresponding to the layer and the node corresponding to - // the copy request. Otherwise, we are interested in the invertibility of - // screen space transform which is already cached on the transform node. - return non_root_copy_request - ? !property_trees->GetFromTarget( - layer->transform_tree_index(), - effect_node->closest_ancestor_with_copy_request_id, - &from_target) - : !transform_node->ancestors_are_invertible; -} - -static void ComputeInitialRenderSurfaceList( - LayerTreeImpl* layer_tree_impl, - PropertyTrees* property_trees, - RenderSurfaceList* render_surface_list) { - EffectTree& effect_tree = property_trees->effect_tree; - for (int i = EffectTree::kContentsRootNodeId; - i < static_cast<int>(effect_tree.size()); ++i) { - if (RenderSurfaceImpl* render_surface = effect_tree.GetRenderSurface(i)) { - render_surface->set_is_render_surface_list_member(false); - render_surface->reset_num_contributors(); - ClearMaskLayersContributeToDrawnRenderSurface(render_surface); - } - } - - RenderSurfaceImpl* root_surface = - effect_tree.GetRenderSurface(EffectTree::kContentsRootNodeId); - // The root surface always gets added to the render surface list. - AddSurfaceToRenderSurfaceList(root_surface, render_surface_list, - property_trees); - // For all non-skipped layers, add their target to the render surface list if - // it's not already been added, and add their content rect to the target - // surface's accumulated content rect. - for (LayerImpl* layer : *layer_tree_impl) { - DCHECK(layer); - layer->EnsureValidPropertyTreeIndices(); - - layer->set_contributes_to_drawn_render_surface(false); - layer->set_raster_even_if_not_drawn(false); - - bool is_root = layer_tree_impl->IsRootLayer(layer); - - bool skip_draw_properties_computation = - draw_property_utils::LayerShouldBeSkippedForDrawPropertiesComputation( - layer, property_trees->transform_tree, property_trees->effect_tree); - - bool skip_for_invertibility = SkipForInvertibility(layer, property_trees); - - bool skip_layer = !is_root && (skip_draw_properties_computation || - skip_for_invertibility); - - layer->set_raster_even_if_not_drawn(skip_for_invertibility && - !skip_draw_properties_computation); - if (skip_layer) - continue; - - bool layer_is_drawn = - property_trees->effect_tree.Node(layer->effect_tree_index())->is_drawn; - bool layer_should_be_drawn = draw_property_utils::LayerNeedsUpdate( - layer, layer_is_drawn, property_trees); - if (!layer_should_be_drawn) - continue; - - RenderSurfaceImpl* render_target = layer->render_target(); - if (!render_target->is_render_surface_list_member()) { - AddSurfaceToRenderSurfaceList(render_target, render_surface_list, - property_trees); - } - - layer->set_contributes_to_drawn_render_surface(true); - - // The layer contributes its drawable content rect to its render target. - render_target->AccumulateContentRectFromContributingLayer(layer); - render_target->increment_num_contributors(); - } -} - -static void ComputeSurfaceContentRects(PropertyTrees* property_trees, - RenderSurfaceList* render_surface_list, - int max_texture_size) { - // Walk the list backwards, accumulating each surface's content rect into its - // target's content rect. - for (RenderSurfaceImpl* render_surface : - base::Reversed(*render_surface_list)) { - if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { - // The root surface's content rect is always the entire viewport. - render_surface->SetContentRectToViewport(); - continue; - } - - // Now all contributing drawable content rect has been accumulated to this - // render surface, calculate the content rect. - render_surface->CalculateContentRectFromAccumulatedContentRect( - max_texture_size); - - // Now the render surface's content rect is calculated correctly, it could - // contribute to its render target. - RenderSurfaceImpl* render_target = render_surface->render_target(); - DCHECK(render_target->is_render_surface_list_member()); - render_target->AccumulateContentRectFromContributingRenderSurface( - render_surface); - render_target->increment_num_contributors(); - } -} - -static void ComputeListOfNonEmptySurfaces( - LayerTreeImpl* layer_tree_impl, - PropertyTrees* property_trees, - RenderSurfaceList* initial_surface_list, - RenderSurfaceList* final_surface_list) { - // Walk the initial surface list forwards. The root surface and each - // surface with a non-empty content rect go into the final render surface - // layer list. Surfaces with empty content rects or whose target isn't in - // the final list do not get added to the final list. - bool removed_surface = false; - for (RenderSurfaceImpl* surface : *initial_surface_list) { - bool is_root = - surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; - RenderSurfaceImpl* target_surface = surface->render_target(); - if (!is_root && (surface->content_rect().IsEmpty() || - !target_surface->is_render_surface_list_member())) { - surface->set_is_render_surface_list_member(false); - removed_surface = true; - target_surface->decrement_num_contributors(); - continue; - } - SetMaskLayersContributeToDrawnRenderSurface(surface, property_trees); - final_surface_list->push_back(surface); - } - if (removed_surface) { - for (LayerImpl* layer : *layer_tree_impl) { - if (layer->contributes_to_drawn_render_surface()) { - RenderSurfaceImpl* render_target = layer->render_target(); - if (!render_target->is_render_surface_list_member()) { - layer->set_contributes_to_drawn_render_surface(false); - render_target->decrement_num_contributors(); - } - } - } - } -} - -static void CalculateRenderSurfaceLayerList( - LayerTreeImpl* layer_tree_impl, - PropertyTrees* property_trees, - RenderSurfaceList* render_surface_list, - const int max_texture_size) { - RenderSurfaceList initial_render_surface_list; - - // First compute a list that might include surfaces that later turn out to - // have an empty content rect. After surface content rects are computed, - // produce a final list that omits empty surfaces. - ComputeInitialRenderSurfaceList(layer_tree_impl, property_trees, - &initial_render_surface_list); - ComputeSurfaceContentRects(property_trees, &initial_render_surface_list, - max_texture_size); - ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, - &initial_render_surface_list, - render_surface_list); -} - -static void RecordRenderSurfaceReasonsForTracing( - const PropertyTrees* property_trees, - const RenderSurfaceList* render_surface_list) { - static const auto* tracing_enabled = - TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("cc"); - if (!*tracing_enabled || - // Don't output single root render surface. - render_surface_list->size() <= 1) - return; - - TRACE_EVENT_INSTANT1("cc", "RenderSurfaceReasonCount", - TRACE_EVENT_SCOPE_THREAD, "total", - render_surface_list->size()); - - // kTest is the last value which is not included for tracing. - constexpr auto kNumReasons = static_cast<size_t>(RenderSurfaceReason::kTest); - int reason_counts[kNumReasons] = {0}; - for (const auto* render_surface : *render_surface_list) { - const auto* effect_node = - property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); - reason_counts[static_cast<size_t>(effect_node->render_surface_reason)]++; - } - for (size_t i = 0; i < kNumReasons; i++) { - if (!reason_counts[i]) - continue; - TRACE_EVENT_INSTANT1( - "cc", "RenderSurfaceReasonCount", TRACE_EVENT_SCOPE_THREAD, - RenderSurfaceReasonToString(static_cast<RenderSurfaceReason>(i)), - reason_counts[i]); - } -} - -static void CalculateDrawPropertiesInternal( - LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs, - PropertyTreeOption property_tree_option, - LayerImplList* output_update_layer_list) { - inputs->render_surface_list->clear(); - - LayerImplList visible_layer_list; - switch (property_tree_option) { - case BUILD_PROPERTY_TREES: { - // The translation from layer to property trees is an intermediate - // state. We will eventually get these data passed directly to the - // compositor. - PropertyTreeBuilder::BuildPropertyTrees( - inputs->root_layer, inputs->page_scale_layer, - inputs->inner_viewport_scroll_layer, - inputs->outer_viewport_scroll_layer, - inputs->elastic_overscroll_element_id, inputs->elastic_overscroll, - inputs->page_scale_factor, inputs->device_scale_factor, - inputs->device_viewport_rect, inputs->device_transform, - inputs->property_trees); - draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( - inputs->root_layer, inputs->property_trees); - break; - } - case DONT_BUILD_PROPERTY_TREES: { - // Since page scale and elastic overscroll are SyncedProperties, changes - // on the active tree immediately affect the pending tree, so instead of - // trying to update property trees whenever these values change, we - // update property trees before using them. - - // We should never be setting a non-unit page scale factor on an oopif - // subframe ... if we attempt this log it and fail. - // TODO(wjmaclean): Remove as part of conditions for closing the bug. - // https://crbug.com/845097 - if (inputs->page_scale_factor != - inputs->property_trees->transform_tree.page_scale_factor() && - !inputs->page_scale_transform_node) { - LOG(ERROR) << "Setting PageScale on subframe: new psf = " - << inputs->page_scale_factor << ", old psf = " - << inputs->property_trees->transform_tree.page_scale_factor() - << ", in_oopif = " - << inputs->root_layer->layer_tree_impl() - ->settings() - .is_layer_tree_for_subframe; - NOTREACHED(); - } - - DCHECK_NE(inputs->page_scale_layer, inputs->root_layer); - draw_property_utils::UpdatePageScaleFactor( - inputs->property_trees, inputs->page_scale_transform_node, - inputs->page_scale_factor); - draw_property_utils::UpdateElasticOverscroll( - inputs->property_trees, inputs->elastic_overscroll_element_id, - inputs->elastic_overscroll); - // Similarly, the device viewport and device transform are shared - // by both trees. - PropertyTrees* property_trees = inputs->property_trees; - property_trees->clip_tree.SetViewportClip( - gfx::RectF(inputs->device_viewport_rect)); - property_trees->transform_tree.SetRootScaleAndTransform( - inputs->device_scale_factor, inputs->device_transform); - draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( - inputs->root_layer, inputs->property_trees); - break; - } - } - - { - TRACE_EVENT0("cc", "draw_property_utils::FindLayersThatNeedUpdates"); - draw_property_utils::FindLayersThatNeedUpdates( - inputs->root_layer->layer_tree_impl(), inputs->property_trees, - &visible_layer_list); - } - - { - TRACE_EVENT1("cc", - "draw_property_utils::ComputeDrawPropertiesOfVisibleLayers", - "visible_layers", visible_layer_list.size()); - draw_property_utils::ComputeDrawPropertiesOfVisibleLayers( - &visible_layer_list, inputs->property_trees); - } - - { - TRACE_EVENT0("cc", "CalculateRenderSurfaceLayerList"); - CalculateRenderSurfaceLayerList( - inputs->root_layer->layer_tree_impl(), inputs->property_trees, - inputs->render_surface_list, inputs->max_texture_size); - } - RecordRenderSurfaceReasonsForTracing(inputs->property_trees, - inputs->render_surface_list); - - // A root layer render_surface should always exist after - // CalculateDrawProperties. - DCHECK(inputs->property_trees->effect_tree.GetRenderSurface( - EffectTree::kContentsRootNodeId)); - - if (output_update_layer_list) - *output_update_layer_list = std::move(visible_layer_list); -} - -void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( - CalcDrawPropsMainInputsForTesting* inputs) { - LayerList update_layer_list; - PropertyTrees* property_trees = - inputs->root_layer->layer_tree_host()->property_trees(); - if (inputs->root_layer->layer_tree_host()->IsUsingLayerLists()) { - // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all - // unnecessary setting of the flag in layer list mode. - property_trees->needs_rebuild = false; - } else { - gfx::Vector2dF elastic_overscroll; - PropertyTreeBuilder::BuildPropertyTrees( - inputs->root_layer, inputs->page_scale_layer, - inputs->inner_viewport_scroll_layer, - inputs->outer_viewport_scroll_layer, ElementId(), elastic_overscroll, - inputs->page_scale_factor, inputs->device_scale_factor, - inputs->device_viewport_rect, inputs->device_transform, property_trees); - } - draw_property_utils::UpdatePropertyTrees( - inputs->root_layer->layer_tree_host(), property_trees); - draw_property_utils::FindLayersThatNeedUpdates( - inputs->root_layer->layer_tree_host(), property_trees, - &update_layer_list); - - if (inputs->update_layer_list) - *inputs->update_layer_list = std::move(update_layer_list); -} - -void LayerTreeHostCommon::CalculateDrawProperties( - CalcDrawPropsImplInputs* inputs) { - CalculateDrawPropertiesInternal(inputs, DONT_BUILD_PROPERTY_TREES, nullptr); -} - -void LayerTreeHostCommon::PrepareForUpdateDrawPropertiesForTesting( - LayerTreeImpl* layer_tree_impl) { - if (layer_tree_impl->settings().use_layer_lists) { - // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all - // unnecessary setting of the flag in layer list mode. - auto* property_trees = layer_tree_impl->property_trees(); - property_trees->needs_rebuild = false; - // The following are needed for tests that modify impl-side property trees. - // In production code impl-side property trees are pushed from the main - // thread and the following are done in other ways. - std::vector<std::unique_ptr<RenderSurfaceImpl>> old_render_surfaces; - property_trees->effect_tree.TakeRenderSurfaces(&old_render_surfaces); - property_trees->effect_tree.CreateOrReuseRenderSurfaces( - &old_render_surfaces, layer_tree_impl); - property_trees->ResetCachedData(); - } -} - -void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( - CalcDrawPropsImplInputsForTesting* inputs) { - PrepareForUpdateDrawPropertiesForTesting( - inputs->root_layer->layer_tree_impl()); - CalculateDrawPropertiesInternal(inputs, - inputs->property_trees->needs_rebuild - ? BUILD_PROPERTY_TREES - : DONT_BUILD_PROPERTY_TREES, - inputs->update_layer_list); -} - -PropertyTrees* GetPropertyTrees(const Layer* layer) { - return layer->layer_tree_host()->property_trees(); -} - -PropertyTrees* GetPropertyTrees(const LayerImpl* layer) { - return layer->layer_tree_impl()->property_trees(); -} - -} // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h deleted file mode 100644 index 6c9dfd5f065..00000000000 --- a/chromium/cc/trees/layer_tree_host_common.h +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2011 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. - -#ifndef CC_TREES_LAYER_TREE_HOST_COMMON_H_ -#define CC_TREES_LAYER_TREE_HOST_COMMON_H_ - -#include <stddef.h> - -#include <limits> -#include <vector> - -#include "base/bind.h" -#include "base/memory/ref_counted.h" -#include "cc/cc_export.h" -#include "cc/input/browser_controls_state.h" -#include "cc/layers/layer.h" -#include "cc/layers/layer_collections.h" -#include "cc/layers/layer_impl.h" -#include "cc/layers/picture_layer.h" -#include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_impl.h" -#include "cc/trees/property_tree.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/vector2d.h" -#include "ui/gfx/transform.h" - -namespace cc { - -class LayerImpl; -class Layer; -class SwapPromise; -class PropertyTrees; - -class CC_EXPORT LayerTreeHostCommon { - public: - struct CC_EXPORT CalcDrawPropsMainInputsForTesting { - public: - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - float page_scale_factor, - const Layer* page_scale_layer, - const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer); - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform); - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect); - Layer* root_layer; - gfx::Rect device_viewport_rect; - gfx::Transform device_transform; - float device_scale_factor; - float page_scale_factor; - const Layer* page_scale_layer; - const Layer* inner_viewport_scroll_layer; - const Layer* outer_viewport_scroll_layer; - // If not null, accepts layers output from FindLayersThatNeedUpdates(). - LayerList* update_layer_list = nullptr; - }; - - struct CC_EXPORT CalcDrawPropsImplInputs { - public: - CalcDrawPropsImplInputs(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - float page_scale_factor, - const LayerImpl* page_scale_layer, - const LayerImpl* inner_viewport_scroll_layer, - const LayerImpl* outer_viewport_scroll_layer, - const gfx::Vector2dF& elastic_overscroll, - const ElementId elastic_overscroll_element_id, - int max_texture_size, - RenderSurfaceList* render_surface_list, - PropertyTrees* property_trees, - TransformNode* page_scale_transform_node); - - LayerImpl* root_layer; - gfx::Rect device_viewport_rect; - gfx::Transform device_transform; - float device_scale_factor; - float page_scale_factor; - const LayerImpl* page_scale_layer; - const LayerImpl* inner_viewport_scroll_layer; - const LayerImpl* outer_viewport_scroll_layer; - gfx::Vector2dF elastic_overscroll; - const ElementId elastic_overscroll_element_id; - int max_texture_size; - RenderSurfaceList* render_surface_list; - PropertyTrees* property_trees; - TransformNode* page_scale_transform_node; - }; - - struct CC_EXPORT CalcDrawPropsImplInputsForTesting - : public CalcDrawPropsImplInputs { - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - RenderSurfaceList* render_surface_list); - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - RenderSurfaceList* render_surface_list); - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - RenderSurfaceList* render_surface_list); - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - float device_scale_factor, - RenderSurfaceList* render_surface_list); - - // If not null, accepts layers output from FindLayersThatNeedUpdates(). - LayerImplList* update_layer_list = nullptr; - }; - - static int CalculateLayerJitter(LayerImpl* scrolling_layer); - static void CalculateDrawPropertiesForTesting( - CalcDrawPropsMainInputsForTesting* inputs); - - static void CalculateDrawProperties(CalcDrawPropsImplInputs* inputs); - - // TODO(wangxianzhu): Move these functions into testing classes. - static void PrepareForUpdateDrawPropertiesForTesting(LayerTreeImpl*); - static void CalculateDrawPropertiesForTesting( - CalcDrawPropsImplInputsForTesting* inputs); - - template <typename Function> - static void CallFunctionForEveryLayer(LayerTreeHost* host, - const Function& function); - - template <typename Function> - static void CallFunctionForEveryLayer(LayerTreeImpl* layer, - const Function& function); - - struct CC_EXPORT ScrollUpdateInfo { - ElementId element_id; - gfx::ScrollOffset scroll_delta; - - bool operator==(const ScrollUpdateInfo& other) const; - }; - - // Used to communicate scrollbar visibility from Impl thread to Blink. - // Scrollbar input is handled by Blink but the compositor thread animates - // opacity on scrollbars to fade them out when they're overlay. Blink needs - // to be told when they're faded out so it can stop handling input for - // invisible scrollbars. - struct CC_EXPORT ScrollbarsUpdateInfo { - ElementId element_id; - bool hidden; - - ScrollbarsUpdateInfo(); - ScrollbarsUpdateInfo(ElementId element_id, bool hidden); - - bool operator==(const ScrollbarsUpdateInfo& other) const; - }; -}; - -struct CC_EXPORT ScrollAndScaleSet { - ScrollAndScaleSet(); - ScrollAndScaleSet(const ScrollAndScaleSet&) = delete; - ~ScrollAndScaleSet(); - - ScrollAndScaleSet& operator=(const ScrollAndScaleSet&) = delete; - - // The inner viewport scroll delta is kept separate since it's special. - // Because the inner (visual) viewport's maximum offset depends on the - // current page scale, the two must be committed at the same time to prevent - // clamping. - LayerTreeHostCommon::ScrollUpdateInfo inner_viewport_scroll; - - std::vector<LayerTreeHostCommon::ScrollUpdateInfo> scrolls; - float page_scale_delta; - bool is_pinch_gesture_active; - - // Elastic overscroll effect offset delta. This is used only on Mac and shows - // the pixels that the page is rubber-banned/stretched by. - gfx::Vector2dF elastic_overscroll_delta; - - // Unconsumed scroll delta used to send overscroll events to the latched - // element on the main thread; - gfx::Vector2dF overscroll_delta; - - // The element id of the node to which scrolling is latched. This is used to - // send overscroll/scrollend DOM events to proper targets whenever needed. - ElementId scroll_latched_element_id; - - float top_controls_delta; - std::vector<LayerTreeHostCommon::ScrollbarsUpdateInfo> scrollbars; - std::vector<std::unique_ptr<SwapPromise>> swap_promises; - BrowserControlsState browser_controls_constraint; - bool browser_controls_constraint_changed; - - // Set to true when a scroll gesture being handled on the compositor has - // ended. - bool scroll_gesture_did_end; - - // Tracks different methods of scrolling (e.g. wheel, touch, precision - // touchpad, etc.). - ManipulationInfo manipulation_info; -}; - -template <typename Function> -void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeHost* host, - const Function& function) { - for (auto* layer : *host) { - function(layer); - if (PictureLayer* mask_layer = layer->mask_layer()) - function(mask_layer); - } -} - -template <typename Function> -void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeImpl* tree_impl, - const Function& function) { - for (auto* layer : *tree_impl) - function(layer); - - for (int id : tree_impl->property_trees()->effect_tree.mask_layer_ids()) { - function(tree_impl->LayerById(id)); - } -} - -CC_EXPORT PropertyTrees* GetPropertyTrees(const Layer* layer); -CC_EXPORT PropertyTrees* GetPropertyTrees(const LayerImpl* layer); - -} // namespace cc - -#endif // CC_TREES_LAYER_TREE_HOST_COMMON_H_ diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index 49112276c53..0dd3041f319 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -79,12 +79,12 @@ #include "cc/trees/image_animation_controller.h" #include "cc/trees/latency_info_swap_promise_monitor.h" #include "cc/trees/layer_tree_frame_sink.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/presentation_time_callback_buffer.h" #include "cc/trees/render_frame_metadata.h" #include "cc/trees/render_frame_metadata_observer.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" @@ -92,6 +92,7 @@ #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/delay_based_time_source.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/hit_test/hit_test_region_list.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/quads/compositor_frame_metadata.h" @@ -117,7 +118,6 @@ #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/vector2d_conversions.h" -#include "ui/gfx/presentation_feedback.h" #include "ui/gfx/skia_util.h" namespace cc { @@ -202,25 +202,6 @@ void RecordCompositorSlowScrollMetric(InputHandler::ScrollInputType type, } } -ui::FrameMetricsSettings LTHI_FrameMetricsSettings( - const LayerTreeSettings& settings) { - ui::FrameMetricsSource source = - settings.commit_to_active_tree - ? ui::FrameMetricsSource::UiCompositor - : ui::FrameMetricsSource::RendererCompositor; - ui::FrameMetricsSourceThread source_thread = - settings.commit_to_active_tree - ? ui::FrameMetricsSourceThread::UiCompositor - : ui::FrameMetricsSourceThread::RendererCompositor; - ui::FrameMetricsCompileTarget compile_target = - settings.using_synchronous_renderer_compositor - ? ui::FrameMetricsCompileTarget::SynchronousCompositor - : settings.wait_for_all_pipeline_stages_before_draw - ? ui::FrameMetricsCompileTarget::Headless - : ui::FrameMetricsCompileTarget::Chromium; - return ui::FrameMetricsSettings(source, source_thread, compile_target); -} - class ScopedPostAnimationEventsToMainThread { public: ScopedPostAnimationEventsToMainThread(MutatorHost* animation_host, @@ -263,11 +244,12 @@ std::unique_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( TaskGraphRunner* task_graph_runner, std::unique_ptr<MutatorHost> mutator_host, int id, - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner) { + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, + LayerTreeHostSchedulingClient* scheduling_client) { return base::WrapUnique(new LayerTreeHostImpl( settings, client, task_runner_provider, rendering_stats_instrumentation, task_graph_runner, std::move(mutator_host), id, - std::move(image_worker_task_runner))); + std::move(image_worker_task_runner), scheduling_client)); } LayerTreeHostImpl::LayerTreeHostImpl( @@ -278,8 +260,10 @@ LayerTreeHostImpl::LayerTreeHostImpl( TaskGraphRunner* task_graph_runner, std::unique_ptr<MutatorHost> mutator_host, int id, - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner) + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, + LayerTreeHostSchedulingClient* scheduling_client) : client_(client), + scheduling_client_(scheduling_client), task_runner_provider_(task_runner_provider), current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), compositor_frame_reporting_controller_( @@ -314,12 +298,11 @@ LayerTreeHostImpl::LayerTreeHostImpl( image_animation_controller_(GetTaskRunner(), this, settings_.enable_image_animation_resync), - frame_metrics_(LTHI_FrameMetricsSettings(settings_)), - skipped_frame_tracker_(&frame_metrics_), is_animating_for_snap_(false), paint_image_generator_client_id_(PaintImage::GetNextGeneratorClientId()), scrollbar_controller_(std::make_unique<ScrollbarController>(this)), - frame_trackers_(compositor_frame_reporting_controller_.get()), + frame_trackers_(settings.single_thread_proxy_scheduler, + compositor_frame_reporting_controller_.get()), scroll_gesture_did_end_(false) { DCHECK(mutator_host_); mutator_host_->SetMutatorHostClient(this); @@ -388,6 +371,11 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { mutator_host_->SetMutatorHostClient(nullptr); } +void LayerTreeHostImpl::WillSendBeginMainFrame() { + if (scheduling_client_) + scheduling_client_->DidScheduleBeginMainFrame(); +} + void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) { if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) begin_main_frame_sent_during_impl_ = true; @@ -756,8 +744,8 @@ void LayerTreeHostImpl::AnimateInternal() { did_animate |= AnimateScrollbars(monotonic_time); did_animate |= AnimateBrowserControls(monotonic_time); - // Animating stuff can change the root scroll offset, so inform the - // synchronous input handler. + // Animating stuff can change the root scroll offset, so inform the + // synchronous input handler. UpdateRootLayerStateForSynchronousInputHandler(); if (did_animate) { // If the tree changed, then we want to draw at the end of the current @@ -766,7 +754,6 @@ void LayerTreeHostImpl::AnimateInternal() { } } - bool LayerTreeHostImpl::PrepareTiles() { if (!tile_priorities_dirty_) return false; @@ -802,8 +789,8 @@ void LayerTreeHostImpl::StartPageScaleAnimation( gfx::ScrollOffset scroll_total = active_tree_->TotalScrollOffset(); gfx::SizeF scrollable_size = active_tree_->ScrollableSize(); - gfx::SizeF viewport_size = - gfx::SizeF(active_tree_->InnerViewportContainerLayer()->bounds()); + gfx::SizeF viewport_size( + active_tree_->InnerViewportScrollNode()->container_bounds); // TODO(miletus) : Pass in ScrollOffset. page_scale_animation_ = @@ -836,9 +823,7 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingViewport() const { auto* node = CurrentlyScrollingNode(); if (!node) return false; - if (!viewport()->MainScrollLayer()) - return false; - return node->id == viewport()->MainScrollLayer()->scroll_tree_index(); + return node == viewport()->MainScrollNode(); } bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt( @@ -1028,11 +1013,13 @@ void LayerTreeHostImpl::FrameData::AsValueInto( base::trace_event::TracedValue* value) const { value->SetBoolean("has_no_damage", has_no_damage); - // Quad data can be quite large, so only dump render passes if we select - // viz.quads. - bool quads_enabled; - TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("viz.quads"), - &quads_enabled); + // Quad data can be quite large, so only dump render passes if we are + // logging verbosely or viz.quads tracing category is enabled. + bool quads_enabled = VLOG_IS_ON(3); + if (!quads_enabled) { + TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("viz.quads"), + &quads_enabled); + } if (quads_enabled) { value->BeginArray("render_passes"); for (size_t i = 0; i < render_passes.size(); ++i) { @@ -1044,6 +1031,18 @@ void LayerTreeHostImpl::FrameData::AsValueInto( } } +std::string LayerTreeHostImpl::FrameData::ToString() const { + base::trace_event::TracedValue value; + AsValueInto(&value); + std::string str; + base::JSONWriter::WriteWithOptions( + *value.ToBaseValue(), + base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION | + base::JSONWriter::OPTIONS_PRETTY_PRINT, + &str); + return str; +} + DrawMode LayerTreeHostImpl::GetDrawMode() const { if (resourceless_software_draw_) { return DRAW_MODE_RESOURCELESS_SOFTWARE; @@ -1150,8 +1149,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { // must compute all damage tracking before drawing anything, so that we know // the root damage rect. The root damage rect is then used to scissor each // surface. - DamageTracker::UpdateDamageTracking(active_tree_.get(), - active_tree_->GetRenderSurfaceList()); + DamageTracker::UpdateDamageTracking(active_tree_.get()); if (HasDamage()) { consecutive_frame_with_damage_count_++; @@ -1469,7 +1467,6 @@ void LayerTreeHostImpl::InvalidateLayerTreeFrameSink(bool needs_redraw) { DCHECK(layer_tree_frame_sink()); layer_tree_frame_sink()->Invalidate(needs_redraw); - skipped_frame_tracker_.DidProduceFrame(); } DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { @@ -1588,6 +1585,15 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { } DrawResult draw_result = CalculateRenderPasses(frame); + + // Dump render passes and draw quads if run with: + // --vmodule=layer_tree_host_impl=3 + if (VLOG_IS_ON(3)) { + VLOG(3) << "Prepare to draw (" + << (client_name ? client_name : "<unknown client>") << ")\n" + << frame->ToString(); + } + if (draw_result != DRAW_SUCCESS) { DCHECK(!resourceless_software_draw_); return draw_result; @@ -1696,6 +1702,7 @@ void LayerTreeHostImpl::ResetTreesForTesting() { active_tree()->top_controls_shown_ratio(), active_tree()->elastic_overscroll()); active_tree_->property_trees()->is_active = true; + active_tree_->property_trees()->clear(); if (pending_tree_) pending_tree_->DetachLayers(); pending_tree_ = nullptr; @@ -1995,25 +2002,19 @@ void LayerTreeHostImpl::DidReceiveCompositorFrameAck() { void LayerTreeHostImpl::DidPresentCompositorFrame( uint32_t frame_token, - const gfx::PresentationFeedback& feedback) { - frame_trackers_.NotifyFramePresented(frame_token, feedback); + const viz::FrameTimingDetails& details) { + frame_trackers_.NotifyFramePresented(frame_token, + details.presentation_feedback); PresentationTimeCallbackBuffer::PendingCallbacks activated = presentation_time_callbacks_.PopPendingCallbacks(frame_token); - // Update compositor frame latency and smoothness stats only for frames - // that caused on-screen damage. - if (!activated.frame_time.is_null()) { - frame_metrics_.AddFrameDisplayed(activated.frame_time, feedback.timestamp); - } - // Send all the main-thread callbacks to the client in one batch. The client // is in charge of posting them to the main thread. client_->DidPresentCompositorFrameOnImplThread( - frame_token, std::move(activated.main_thread_callbacks), feedback); + frame_token, std::move(activated.main_thread_callbacks), details); } void LayerTreeHostImpl::DidNotNeedBeginFrame() { - skipped_frame_tracker_.WillNotProduceFrame(); frame_trackers_.NotifyPauseFrameProduction(); } @@ -2233,7 +2234,6 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { DCHECK(CanDraw()); DCHECK_EQ(frame->has_no_damage, frame->render_passes.empty()); ResetRequiresHighResToDraw(); - skipped_frame_tracker_.DidProduceFrame(); if (frame->has_no_damage) { DCHECK(!resourceless_software_draw_); @@ -2314,11 +2314,11 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( TRACE_EVENT_IS_NEW_TRACE(&is_new_trace); if (is_new_trace) { if (pending_tree_) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - pending_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }); + for (auto* layer : *pending_tree_) + layer->DidBeginTracing(); } - LayerTreeHostCommon::CallFunctionForEveryLayer( - active_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }); + for (auto* layer : *active_tree_) + layer->DidBeginTracing(); } { @@ -2362,15 +2362,7 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( active_tree()->TakeForceSendMetadataRequest()); } - metadata.latency_info.emplace_back(ui::SourceEventType::FRAME); - ui::LatencyInfo& new_latency_info = metadata.latency_info.back(); - if (CommitToActiveTree()) { - new_latency_info.AddLatencyNumberWithTimestamp( - ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, frame_time); - } else { - new_latency_info.AddLatencyNumberWithTimestamp( - ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, frame_time); - + if (!CommitToActiveTree()) { base::TimeTicks draw_time = base::TimeTicks::Now(); for (auto& latency : metadata.latency_info) { latency.AddLatencyNumberWithTimestamp( @@ -2399,20 +2391,18 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( resources, &compositor_frame.resource_list, layer_tree_frame_sink_->context_provider()); compositor_frame.render_pass_list = std::move(frame->render_passes); - // TODO(fsamuel): Once all clients get their viz::LocalSurfaceId from their - // parent, the viz::LocalSurfaceId should hang off CompositorFrameMetadata. - if (settings_.enable_surface_synchronization) { - // If surface synchronization is on, we should always have a valid - // LocalSurfaceId in LayerTreeImpl unless we don't have a scheduler because - // without a scheduler commits are not deferred and LayerTrees without valid - // LocalSurfaceId might slip through, but single-thread-without-scheduler - // mode is only used in tests so it doesn't matter. - CHECK(!settings_.single_thread_proxy_scheduler || - active_tree()->local_surface_id_allocation_from_parent().IsValid()); - layer_tree_frame_sink_->SetLocalSurfaceId( - child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation() - .local_surface_id()); - } + + // We should always have a valid LocalSurfaceId in LayerTreeImpl unless we + // don't have a scheduler because without a scheduler commits are not deferred + // and LayerTrees without valid LocalSurfaceId might slip through, but + // single-thread-without-scheduler mode is only used in tests so it doesn't + // matter. + CHECK(!settings_.single_thread_proxy_scheduler || + active_tree()->local_surface_id_allocation_from_parent().IsValid()); + layer_tree_frame_sink_->SetLocalSurfaceId( + child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation() + .local_surface_id()); + last_draw_local_surface_id_allocation_ = child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation(); return compositor_frame; @@ -2440,13 +2430,6 @@ int LayerTreeHostImpl::RequestedMSAASampleCount() const { return settings_.gpu_rasterization_msaa_sample_count; } -void LayerTreeHostImpl::SetHasGpuRasterizationTrigger(bool flag) { - if (has_gpu_rasterization_trigger_ != flag) { - has_gpu_rasterization_trigger_ = flag; - need_update_gpu_rasterization_status_ = true; - } -} - void LayerTreeHostImpl::SetContentHasSlowPaths(bool flag) { if (content_has_slow_paths_ != flag) { content_has_slow_paths_ = flag; @@ -2471,9 +2454,15 @@ void LayerTreeHostImpl::GetGpuRasterizationCapabilities( *max_msaa_samples = 0; *supports_disable_msaa = false; + if (settings_.gpu_rasterization_disabled) { + DCHECK(!settings_.gpu_rasterization_forced); + return; + } + if (!(layer_tree_frame_sink_ && layer_tree_frame_sink_->context_provider() && - layer_tree_frame_sink_->worker_context_provider())) + layer_tree_frame_sink_->worker_context_provider())) { return; + } viz::RasterContextProvider* context_provider = layer_tree_frame_sink_->worker_context_provider(); @@ -2559,8 +2548,6 @@ bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() { } } else if (!gpu_rasterization_enabled) { gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE; - } else if (!has_gpu_rasterization_trigger_) { - gpu_rasterization_status_ = GpuRasterizationStatus::OFF_VIEWPORT; } else if (content_has_slow_paths_ && using_msaa_for_slow_paths) { use_gpu = use_msaa = true; gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT; @@ -2612,6 +2599,15 @@ void LayerTreeHostImpl::UpdateTreeResourcesForGpuRasterizationIfNeeded() { SetRequiresHighResToDraw(); } +void LayerTreeHostImpl::RegisterCompositorPresentationTimeCallback( + uint32_t frame_token, + LayerTreeHost::PresentationTimeCallback callback) { + std::vector<LayerTreeHost::PresentationTimeCallback> as_vector; + as_vector.emplace_back(std::move(callback)); + presentation_time_callbacks_.RegisterCompositorPresentationCallbacks( + frame_token, std::move(as_vector)); +} + bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) { impl_thread_phase_ = ImplThreadPhase::INSIDE_IMPL_FRAME; current_begin_frame_tracker_.Start(args); @@ -2639,8 +2635,6 @@ bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) { for (auto* it : video_frame_controllers_) it->OnBeginFrame(args); - skipped_frame_tracker_.BeginFrame(args.frame_time, args.interval); - bool recent_frame_had_no_damage = consecutive_frame_with_damage_count_ < settings_.damaged_frame_limit; // Check damage early if the setting is enabled and a recent frame had no @@ -2650,8 +2644,7 @@ bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) { CanDraw()) { bool ok = active_tree()->UpdateDrawProperties(); DCHECK(ok); - DamageTracker::UpdateDamageTracking(active_tree_.get(), - active_tree_->GetRenderSurfaceList()); + DamageTracker::UpdateDamageTracking(active_tree_.get()); bool has_damage = HasDamage(); // Animations are updated after we attempt to draw. If the frame is aborted, // update animations now. @@ -2676,7 +2669,6 @@ void LayerTreeHostImpl::DidFinishImplFrame() { frame_trackers_.NotifyMainFrameCausedNoDamage( current_begin_frame_tracker_.Current()); } - skipped_frame_tracker_.FinishFrame(); impl_thread_phase_ = ImplThreadPhase::IDLE; current_begin_frame_tracker_.Finish(); } @@ -2859,26 +2851,10 @@ void LayerTreeHostImpl::SetNeedsCommit() { client_->SetNeedsCommitOnImplThread(); } -LayerImpl* LayerTreeHostImpl::InnerViewportContainerLayer() const { - return active_tree_->InnerViewportContainerLayer(); -} - -LayerImpl* LayerTreeHostImpl::InnerViewportScrollLayer() const { - return active_tree_->InnerViewportScrollLayer(); -} - ScrollNode* LayerTreeHostImpl::InnerViewportScrollNode() const { return active_tree_->InnerViewportScrollNode(); } -LayerImpl* LayerTreeHostImpl::OuterViewportContainerLayer() const { - return active_tree_->OuterViewportContainerLayer(); -} - -LayerImpl* LayerTreeHostImpl::OuterViewportScrollLayer() const { - return active_tree_->OuterViewportScrollLayer(); -} - ScrollNode* LayerTreeHostImpl::OuterViewportScrollNode() const { return active_tree_->OuterViewportScrollNode(); } @@ -3155,8 +3131,6 @@ void LayerTreeHostImpl::SetNeedsOneBeginImplFrame() { void LayerTreeHostImpl::SetNeedsRedraw() { NotifySwapPromiseMonitorsOfSetNeedsRedraw(); client_->SetNeedsRedrawOnImplThread(); - if (CurrentlyScrollingNode()) - skipped_frame_tracker_.WillProduceFrame(); } ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const { @@ -3306,16 +3280,8 @@ void LayerTreeHostImpl::SetPaintWorkletLayerPainter( paint_worklet_painter_ = std::move(painter); } -LayerImpl* LayerTreeHostImpl::ViewportMainScrollLayer() { - return viewport()->MainScrollLayer(); -} - ScrollNode* LayerTreeHostImpl::ViewportMainScrollNode() { - if (!ViewportMainScrollLayer()) - return nullptr; - - return active_tree_->property_trees()->scroll_tree.Node( - ViewportMainScrollLayer()->scroll_tree_index()); + return viewport()->MainScrollNode(); } void LayerTreeHostImpl::QueueImageDecode(int request_id, @@ -3482,6 +3448,8 @@ bool LayerTreeHostImpl::InitializeFrameSink( has_valid_layer_tree_frame_sink_ = true; auto* context_provider = layer_tree_frame_sink_->context_provider(); + frame_trackers_.StartSequence(FrameSequenceTrackerType::kUniversal); + if (context_provider) { max_texture_size_ = context_provider->ContextCapabilities().max_texture_size; @@ -3940,7 +3908,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( ElementId current_native_scrolling_element = scroll_state->data()->current_native_scrolling_element(); - if (current_native_scrolling_element.GetInternalValue() != 0) { + if (current_native_scrolling_element.GetStableId() != 0) { auto& scroll_tree = active_tree_->property_trees()->scroll_tree; scrolling_node = scroll_tree.FindNodeFromElementId(current_native_scrolling_element); @@ -4240,8 +4208,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( } bool scrolls_main_viewport_scroll_layer = - viewport()->MainScrollLayer() && - viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node->id; + scroll_node == viewport()->MainScrollNode(); if (scrolls_main_viewport_scroll_layer) { // Flash the overlay scrollbar even if the scroll dalta is 0. if (settings_.scrollbar_flash_after_any_scroll_update) { @@ -4728,11 +4695,6 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( if (did_scroll_content) { ShowScrollbarsForImplScroll(current_scrolling_node->element_id); - // If we are scrolling with an active scroll handler, forward latency - // tracking information to the main thread so the delay introduced by the - // handler is accounted for. - if (scroll_affects_scroll_handler()) - NotifySwapPromiseMonitorsOfForwardingToMainThread(); client_->SetNeedsCommitOnImplThread(); SetNeedsRedraw(); client_->RenewTreePriority(); @@ -4830,7 +4792,7 @@ void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset( if (!changed) return; - ShowScrollbarsForImplScroll(OuterViewportScrollLayer()->element_id()); + ShowScrollbarsForImplScroll(OuterViewportScrollNode()->element_id); client_->SetNeedsCommitOnImplThread(); // After applying the synchronous input handler's scroll offset, tell it what // we ended up with. @@ -4859,6 +4821,8 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() { ScrollOffsetToVector2dF(snap_position - current_position); bool scrolls_main_viewport_scroll_layer = scroll_node == ViewportMainScrollNode(); + + bool did_animate = false; if (scrolls_main_viewport_scroll_layer) { // Flash the overlay scrollbar even if the scroll dalta is 0. if (settings_.scrollbar_flash_after_any_scroll_update) { @@ -4871,27 +4835,23 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() { } gfx::Vector2dF scaled_delta(delta); scaled_delta.Scale(active_tree()->page_scale_factor_for_scroll()); - viewport()->ScrollAnimated(scaled_delta, base::TimeDelta()); + gfx::Vector2dF consumed_delta = + viewport()->ScrollAnimated(scaled_delta, base::TimeDelta()); + did_animate = !consumed_delta.IsZero(); } else { - ScrollAnimationCreate(scroll_node, delta, base::TimeDelta()); + did_animate = ScrollAnimationCreate(scroll_node, delta, base::TimeDelta()); } DCHECK(!is_animating_for_snap_); - is_animating_for_snap_ = true; - return true; + is_animating_for_snap_ = did_animate; + return did_animate; } gfx::ScrollOffset LayerTreeHostImpl::GetVisualScrollOffset( const ScrollNode& scroll_node) const { - const ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree; - - bool scrolls_main_viewport_scroll_layer = - viewport()->MainScrollLayer() && - viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node.id; - - if (scrolls_main_viewport_scroll_layer) + if (&scroll_node == viewport()->MainScrollNode()) return viewport()->TotalScrollOffset(); - else - return scroll_tree.current_scroll_offset(scroll_node.element_id); + return active_tree()->property_trees()->scroll_tree.current_scroll_offset( + scroll_node.element_id); } bool LayerTreeHostImpl::GetSnapFlingInfo( @@ -4968,7 +4928,8 @@ void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state, bool should_snap) { } InputHandlerPointerResult LayerTreeHostImpl::MouseDown( - const gfx::PointF& viewport_point) { + const gfx::PointF& viewport_point, + bool shift_modifier) { ScrollbarAnimationController* animation_controller = ScrollbarAnimationControllerForElementId( scroll_element_id_mouse_currently_over_); @@ -4979,8 +4940,10 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseDown( } InputHandlerPointerResult result; - if (settings().compositor_threaded_scrollbar_scrolling) - result = scrollbar_controller_->HandlePointerDown(viewport_point); + if (settings().compositor_threaded_scrollbar_scrolling) { + result = scrollbar_controller_->HandlePointerDown(viewport_point, + shift_modifier); + } return result; } @@ -5008,9 +4971,10 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseUp( InputHandlerPointerResult LayerTreeHostImpl::MouseMoveAt( const gfx::Point& viewport_point) { InputHandlerPointerResult result; - if (settings().compositor_threaded_scrollbar_scrolling) + if (settings().compositor_threaded_scrollbar_scrolling) { result = - scrollbar_controller_->HandleMouseMove(gfx::PointF(viewport_point)); + scrollbar_controller_->HandlePointerMove(gfx::PointF(viewport_point)); + } // Early out if there are no animation controllers and avoid the hit test. // This happens on platforms without animated scrollbars. @@ -5039,9 +5003,9 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseMoveAt( scroll_element_id = scroll_node->element_id; // Scrollbars for the viewport are registered with the outer viewport layer. - if (InnerViewportScrollNode() && OuterViewportScrollLayer() && + if (InnerViewportScrollNode() && OuterViewportScrollNode() && scroll_element_id == InnerViewportScrollNode()->element_id) - scroll_element_id = OuterViewportScrollLayer()->element_id(); + scroll_element_id = OuterViewportScrollNode()->element_id; } ScrollbarAnimationController* new_animation_controller = @@ -5139,8 +5103,8 @@ void LayerTreeHostImpl::CollectScrollbarUpdates( ScrollAndScaleSet* scroll_info) const { scroll_info->scrollbars.reserve(scrollbar_animation_controllers_.size()); for (auto& pair : scrollbar_animation_controllers_) { - scroll_info->scrollbars.push_back(LayerTreeHostCommon::ScrollbarsUpdateInfo( - pair.first, pair.second->ScrollbarsHidden())); + scroll_info->scrollbars.push_back( + {pair.first, pair.second->ScrollbarsHidden()}); } } @@ -5367,16 +5331,16 @@ LayerTreeHostImpl::ScrollbarAnimationControllerForElementId( // The viewport layers have only one set of scrollbars. On Android, these are // registered with the inner viewport, otherwise they're registered with the // outer viewport. If a controller for one exists, the other shouldn't. - if (InnerViewportScrollNode() && OuterViewportScrollLayer()) { + if (InnerViewportScrollNode() && OuterViewportScrollNode()) { if (scroll_element_id == InnerViewportScrollNode()->element_id || - scroll_element_id == OuterViewportScrollLayer()->element_id()) { + scroll_element_id == OuterViewportScrollNode()->element_id) { auto itr = scrollbar_animation_controllers_.find( InnerViewportScrollNode()->element_id); if (itr != scrollbar_animation_controllers_.end()) return itr->second.get(); itr = scrollbar_animation_controllers_.find( - OuterViewportScrollLayer()->element_id()); + OuterViewportScrollNode()->element_id); if (itr != scrollbar_animation_controllers_.end()) return itr->second.get(); @@ -5872,12 +5836,6 @@ void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfSetNeedsRedraw() { (*it)->OnSetNeedsRedrawOnImpl(); } -void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfForwardingToMainThread() { - auto it = swap_promise_monitor_.begin(); - for (; it != swap_promise_monitor_.end(); it++) - (*it)->OnForwardScrollUpdateToMainThreadOnImpl(); -} - void LayerTreeHostImpl::UpdateRootLayerStateForSynchronousInputHandler() { if (!input_handler_client_) return; diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index 395419652fc..4242cd1e415 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -60,7 +60,6 @@ #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/common/surfaces/surface_range.h" #include "ui/gfx/geometry/rect.h" -#include "ui/latency/frame_metrics.h" namespace gfx { class ScrollOffset; @@ -69,7 +68,8 @@ class ScrollOffset; namespace viz { class CompositorFrame; class CompositorFrameMetadata; -} +struct FrameTimingDetails; +} // namespace viz namespace cc { @@ -106,7 +106,6 @@ enum class GpuRasterizationStatus { ON, ON_FORCED, OFF_DEVICE, - OFF_VIEWPORT, MSAA_CONTENT, }; @@ -160,7 +159,7 @@ class LayerTreeHostImplClient { virtual void DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) = 0; + const viz::FrameTimingDetails& details) = 0; // Returns whether the main-thread is expected to receive a BeginMainFrame. virtual bool IsBeginMainFrameExpected() = 0; @@ -198,6 +197,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, FrameData& operator=(const FrameData&) = delete; void AsValueInto(base::trace_event::TracedValue* value) const; + std::string ToString() const; // frame_token is populated by the LayerTreeHostImpl when submitted. uint32_t frame_token = 0; @@ -251,7 +251,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, TaskGraphRunner* task_graph_runner, std::unique_ptr<MutatorHost> mutator_host, int id, - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner); + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, + LayerTreeHostSchedulingClient* scheduling_client); LayerTreeHostImpl(const LayerTreeHostImpl&) = delete; ~LayerTreeHostImpl() override; @@ -277,8 +278,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, const gfx::ScrollOffset& root_content_offset) override; void ScrollEnd(ScrollState* scroll_state, bool should_snap = false) override; - InputHandlerPointerResult MouseDown( - const gfx::PointF& viewport_point) override; + InputHandlerPointerResult MouseDown(const gfx::PointF& viewport_point, + bool shift_modifier) override; InputHandlerPointerResult MouseUp(const gfx::PointF& viewport_point) override; InputHandlerPointerResult MouseMoveAt( const gfx::Point& viewport_point) override; @@ -336,7 +337,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, return viewport_damage_rect_; } - virtual void WillSendBeginMainFrame() {} + virtual void WillSendBeginMainFrame(); virtual void DidSendBeginMainFrame(const viz::BeginFrameArgs& args); virtual void BeginMainFrameAborted( CommitEarlyOutReason reason, @@ -494,7 +495,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, void DidReceiveCompositorFrameAck() override; void DidPresentCompositorFrame( uint32_t frame_token, - const gfx::PresentationFeedback& feedback) override; + const viz::FrameTimingDetails& details) override; void ReclaimResources( const std::vector<viz::ReturnedResource>& resources) override; void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override; @@ -521,7 +522,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, virtual bool InitializeFrameSink(LayerTreeFrameSink* layer_tree_frame_sink); TileManager* tile_manager() { return &tile_manager_; } - void SetHasGpuRasterizationTrigger(bool flag); void SetContentHasSlowPaths(bool flag); void SetContentHasNonAAPaint(bool flag); void GetGpuRasterizationCapabilities(bool* gpu_rasterization_enabled, @@ -547,6 +547,14 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, uint32_t next_frame_token() const { return *next_frame_token_; } + // Buffers |callback| until a relevant frame swap ocurrs, at which point the + // callback will be run on the compositor thread. A frame swap is considered + // relevant if the swapped frame's token is greater than or equal to + // |frame_token|. + void RegisterCompositorPresentationTimeCallback( + uint32_t frame_token, + LayerTreeHost::PresentationTimeCallback callback); + virtual bool WillBeginImplFrame(const viz::BeginFrameArgs& args); virtual void DidFinishImplFrame(); void DidNotProduceFrame(const viz::BeginFrameAck& ack); @@ -566,11 +574,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, virtual void ActivateSyncTree(); // Shortcuts to layers/nodes on the active tree. - LayerImpl* InnerViewportContainerLayer() const; - LayerImpl* InnerViewportScrollLayer() const; ScrollNode* InnerViewportScrollNode() const; - LayerImpl* OuterViewportContainerLayer() const; - LayerImpl* OuterViewportScrollLayer() const; ScrollNode* OuterViewportScrollNode() const; ScrollNode* CurrentlyScrollingNode(); const ScrollNode* CurrentlyScrollingNode() const; @@ -764,7 +768,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, // of these -- we call that the "main" scroll node. When scrolling it, we // scroll using the Viewport class which knows how to distribute scroll // between the two. - LayerImpl* ViewportMainScrollLayer(); ScrollNode* ViewportMainScrollNode(); void QueueImageDecode(int request_id, const PaintImage& image); @@ -810,7 +813,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, TaskGraphRunner* task_graph_runner, std::unique_ptr<MutatorHost> mutator_host, int id, - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner); + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, + LayerTreeHostSchedulingClient* scheduling_client); // Virtual for testing. virtual bool AnimateLayers(base::TimeTicks monotonic_time, @@ -824,6 +828,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, static void RemoveRenderPasses(FrameData* frame); LayerTreeHostImplClient* const client_; + LayerTreeHostSchedulingClient* const scheduling_client_; TaskRunnerProvider* const task_runner_provider_; BeginFrameTracker current_begin_frame_tracker_; @@ -944,7 +949,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, bool lost); void NotifySwapPromiseMonitorsOfSetNeedsRedraw(); - void NotifySwapPromiseMonitorsOfForwardingToMainThread(); void UpdateRootLayerStateForSynchronousInputHandler(); @@ -1034,7 +1038,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, bool need_update_gpu_rasterization_status_ = false; bool content_has_slow_paths_ = false; bool content_has_non_aa_paint_ = false; - bool has_gpu_rasterization_trigger_ = false; bool use_gpu_rasterization_ = false; bool use_oop_rasterization_ = false; bool use_msaa_ = false; @@ -1237,8 +1240,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; PresentationTimeCallbackBuffer presentation_time_callbacks_; - ui::FrameMetrics frame_metrics_; - ui::SkippedFrameTracker skipped_frame_tracker_; bool is_animating_for_snap_; const PaintImage::GeneratorClientId paint_image_generator_client_id_; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index f695646918f..986eca85577 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -44,6 +44,7 @@ #include "cc/resources/ui_resource_bitmap.h" #include "cc/resources/ui_resource_manager.h" #include "cc/test/animation_test_common.h" +#include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_mask_layer_impl.h" @@ -62,11 +63,11 @@ #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" #include "cc/trees/latency_info_swap_promise.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/render_frame_metadata.h" #include "cc/trees/render_frame_metadata_observer.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" @@ -107,6 +108,10 @@ using ::testing::AtLeast; using ::testing::_; using media::VideoFrame; +namespace viz { +struct FrameTimingDetails; +} + namespace cc { namespace { @@ -145,12 +150,19 @@ class LayerTreeHostImplTest : public testing::Test, } LayerTreeSettings DefaultSettings() { - LayerTreeSettings settings; - settings.enable_surface_synchronization = true; + LayerListSettings settings; settings.minimum_occlusion_tracking_size = gfx::Size(); return settings; } + // Settings with GPU rasterization disabled. New tests should test with GPU + // rasterization enabled by default. + LayerTreeSettings LegacySWSettings() { + LayerTreeSettings settings = DefaultSettings(); + settings.gpu_rasterization_disabled = true; + return settings; + } + void SetUp() override { CreateHostImpl(DefaultSettings(), CreateLayerTreeFrameSink()); } @@ -237,7 +249,7 @@ class LayerTreeHostImplTest : public testing::Test, void DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) override {} + const viz::FrameTimingDetails& details) override {} void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state, ElementListType tree_type) override {} void NotifyPaintWorkletStateChange( @@ -247,30 +259,22 @@ class LayerTreeHostImplTest : public testing::Test, reduce_memory_result_ = reduce_memory_result; } - virtual bool CreateHostImpl( - const LayerTreeSettings& settings, - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) { - return CreateHostImplWithTaskRunnerProvider( - settings, std::move(layer_tree_frame_sink), &task_runner_provider_); - } - AnimationHost* GetImplAnimationHost() const { return static_cast<AnimationHost*>(host_impl_->mutator_host()); } - virtual bool CreateHostImplWithTaskRunnerProvider( + virtual bool CreateHostImpl( const LayerTreeSettings& settings, - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink, - TaskRunnerProvider* task_runner_provider) { + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) { if (host_impl_) host_impl_->ReleaseLayerTreeFrameSink(); host_impl_.reset(); InitializeImageWorker(settings); host_impl_ = LayerTreeHostImpl::Create( - settings, this, task_runner_provider, &stats_instrumentation_, + settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, - image_worker_ ? image_worker_->task_runner() : nullptr); + image_worker_ ? image_worker_->task_runner() : nullptr, nullptr); layer_tree_frame_sink_ = std::move(layer_tree_frame_sink); host_impl_->SetVisible(true); bool init = host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get()); @@ -293,13 +297,32 @@ class LayerTreeHostImplTest : public testing::Test, return init; } - void SetupRootLayerImpl(std::unique_ptr<LayerImpl> root) { - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); + template <typename T, typename... Args> + T* SetupRootLayer(LayerTreeImpl* layer_tree_impl, + const gfx::Size& viewport_size, + Args&&... args) { + const int kRootLayerId = 1; + DCHECK(!layer_tree_impl->root_layer()); + DCHECK(!layer_tree_impl->LayerById(kRootLayerId)); + layer_tree_impl->SetRootLayerForTesting( + T::Create(layer_tree_impl, kRootLayerId, std::forward<Args>(args)...)); + auto* root = layer_tree_impl->root_layer(); + root->SetBounds(viewport_size); + layer_tree_impl->SetDeviceViewportRect( + gfx::Rect(DipSizeToPixelSize(viewport_size))); + SetupRootProperties(root); + return static_cast<T*>(root); + } + + LayerImpl* SetupDefaultRootLayer(const gfx::Size& viewport_size) { + return SetupRootLayer<LayerImpl>(host_impl_->active_tree(), viewport_size); + } + + LayerImpl* root_layer() { return host_impl_->active_tree()->root_layer(); } + + gfx::Size DipSizeToPixelSize(const gfx::Size& size) { + return gfx::ScaleToRoundedSize( + size, host_impl_->active_tree()->device_scale_factor()); } static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) { @@ -359,138 +382,98 @@ class LayerTreeHostImplTest : public testing::Test, ASSERT_EQ(0, times_encountered); } - LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl, - const gfx::Size& content_size) { - // Clear any existing viewport layers that were setup so this function can - // be called multiple times. - layer_tree_impl->ClearViewportLayers(); - - // Create both an inner viewport scroll layer and an outer viewport scroll - // layer. The MaxScrollOffset of the outer viewport scroll layer will be - // 0x0, so the scrolls will be applied directly to the inner viewport. - const int kOuterViewportClipLayerId = 116; - const int kOuterViewportScrollLayerId = 117; - const int kContentLayerId = 118; - const int kInnerViewportScrollLayerId = 2; - const int kInnerViewportClipLayerId = 4; - const int kPageScaleLayerId = 5; - - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(content_size); - root->test_properties()->position = gfx::PointF(); - root->test_properties()->force_render_surface = true; - - std::unique_ptr<LayerImpl> inner_scroll = - LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); - inner_scroll->test_properties()->is_container_for_fixed_position_layers = - true; - inner_scroll->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - inner_scroll->element_id(), gfx::ScrollOffset()); - - std::unique_ptr<LayerImpl> inner_clip = - LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); - gfx::Size viewport_scroll_bounds = - gfx::Size(content_size.width() / 2, content_size.height() / 2); - inner_clip->SetBounds(viewport_scroll_bounds); - - std::unique_ptr<LayerImpl> page_scale = - LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); - - inner_scroll->SetScrollable(viewport_scroll_bounds); - inner_scroll->SetHitTestable(true); - inner_scroll->SetElementId( - LayerIdToElementIdForTesting(inner_scroll->id())); - inner_scroll->SetBounds(content_size); - inner_scroll->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> outer_clip = - LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId); - outer_clip->SetBounds(content_size); - outer_clip->test_properties()->is_container_for_fixed_position_layers = - true; - - std::unique_ptr<LayerImpl> outer_scroll = - LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); - outer_scroll->SetScrollable(content_size); - outer_scroll->SetHitTestable(true); - outer_scroll->SetElementId( - LayerIdToElementIdForTesting(outer_scroll->id())); - outer_scroll->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - outer_scroll->element_id(), gfx::ScrollOffset()); - outer_scroll->SetBounds(content_size); - outer_scroll->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> contents = - LayerImpl::Create(layer_tree_impl, kContentLayerId); - contents->SetDrawsContent(true); - contents->SetBounds(content_size); - contents->test_properties()->position = gfx::PointF(); - - outer_scroll->test_properties()->AddChild(std::move(contents)); - outer_clip->test_properties()->AddChild(std::move(outer_scroll)); - inner_scroll->test_properties()->AddChild(std::move(outer_clip)); - page_scale->test_properties()->AddChild(std::move(inner_scroll)); - inner_clip->test_properties()->AddChild(std::move(page_scale)); - root->test_properties()->AddChild(std::move(inner_clip)); - - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = kPageScaleLayerId; - viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; - viewport_ids.outer_viewport_container = kOuterViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; - viewport_ids.outer_viewport_scroll = kOuterViewportScrollLayerId; - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); + template <typename T, typename... Args> + T* AddLayer(LayerTreeImpl* layer_tree_impl, Args&&... args) { + std::unique_ptr<T> layer = T::Create(layer_tree_impl, next_layer_id_++, + std::forward<Args>(args)...); + T* result = layer.get(); + layer_tree_impl->AddLayer(std::move(layer)); + return result; + } + LayerImpl* AddLayer() { + return AddLayer<LayerImpl>(host_impl_->active_tree()); + } + + void SetupViewportLayers(LayerTreeImpl* layer_tree_impl, + const gfx::Size& inner_viewport_size, + const gfx::Size& outer_viewport_size, + const gfx::Size& content_size) { + DCHECK(!layer_tree_impl->root_layer()); + auto* root = + SetupRootLayer<LayerImpl>(layer_tree_impl, inner_viewport_size); + SetupViewport(root, outer_viewport_size, content_size); + + UpdateDrawProperties(layer_tree_impl); layer_tree_impl->DidBecomeActive(); - return layer_tree_impl->InnerViewportScrollLayer(); } - LayerImpl* SetupScrollAndContentsLayers(const gfx::Size& content_size) { - LayerImpl* scroll_layer = - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->DidBecomeActive(); - return scroll_layer; + // Calls SetupViewportLayers() passing |content_size| as that function's + // |outer_viewport_size| and |content_size|, which makes the outer viewport + // not scrollable, and scrolls will be applied directly to the inner viewport. + void SetupViewportLayersInnerScrolls(const gfx::Size& inner_viewport_size, + const gfx::Size& content_size) { + const auto& outer_viewport_size = content_size; + SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size, + outer_viewport_size, content_size); + } + + // Calls SetupViewportLayers() passing |viewport_size| as that function's + // |inner_viewport_size| and |outer_viewport_size|, which makes the inner + // viewport not scrollable, and scrolls will be applied to the outer + // viewport only. + void SetupViewportLayersOuterScrolls(const gfx::Size& viewport_size, + const gfx::Size& content_size) { + SetupViewportLayers(host_impl_->active_tree(), viewport_size, viewport_size, + content_size); + } + + LayerImpl* AddContentLayer() { + LayerImpl* scroll_layer = OuterViewportScrollLayer(); + DCHECK(scroll_layer); + LayerImpl* layer = AddLayer(); + layer->SetBounds(scroll_layer->bounds()); + layer->SetDrawsContent(true); + CopyProperties(scroll_layer, layer); + return layer; } - void CreateAndTestNonScrollableLayers(const bool& transparent_layer) { + // Calls SetupViewportLayers() with the same |viewport_bounds|, + // |inner_scroll_bounds| and |outer_scroll_bounds|, which makes neither + // of inner viewport and outer viewport scrollable. + void SetupViewportLayersNoScrolls(const gfx::Size& bounds) { + SetupViewportLayers(host_impl_->active_tree(), bounds, bounds, bounds); + } + + void CreateAndTestNonScrollableLayers(bool transparent_layer) { LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); gfx::Size content_size = gfx::Size(360, 600); gfx::Size scroll_content_size = gfx::Size(345, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(content_size)); - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(content_size); - root->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); - scroll->SetBounds(scroll_content_size); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar = - PaintedScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, false, - true); + LayerImpl* root = SetupRootLayer<LayerImpl>(layer_tree_impl, content_size); + LayerImpl* scroll = + AddScrollableLayer(root, content_size, scroll_content_size); + + auto* squash2 = AddLayer<LayerImpl>(layer_tree_impl); + squash2->SetBounds(gfx::Size(140, 300)); + squash2->SetDrawsContent(true); + squash2->SetHitTestable(true); + CopyProperties(scroll, squash2); + squash2->SetOffsetToTransformParent(gfx::Vector2dF(220, 300)); + + auto* scrollbar = AddLayer<PaintedScrollbarLayerImpl>( + layer_tree_impl, VERTICAL, false, true); + SetupScrollbarLayer(scroll, scrollbar); scrollbar->SetBounds(scrollbar_size); - scrollbar->test_properties()->position = gfx::PointF(345, 0); - scrollbar->SetScrollElementId(scroll->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->SetHitTestable(true); - scrollbar->test_properties()->opacity = 1.f; + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); - std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5); + auto* squash1 = AddLayer<LayerImpl>(layer_tree_impl); squash1->SetBounds(gfx::Size(140, 300)); - squash1->test_properties()->position = gfx::PointF(220, 0); + CopyProperties(root, squash1); + squash1->SetOffsetToTransformParent(gfx::Vector2dF(220, 0)); if (transparent_layer) { - squash1->test_properties()->opacity = 0.0f; + CreateEffectNode(squash1).opacity = 0.0f; // The transparent layer should still participate in hit testing even // through it does not draw content. squash1->SetHitTestable(true); @@ -499,19 +482,7 @@ class LayerTreeHostImplTest : public testing::Test, squash1->SetHitTestable(true); } - std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6); - squash2->SetBounds(gfx::Size(140, 300)); - squash2->test_properties()->position = gfx::PointF(220, 300); - squash2->SetDrawsContent(true); - squash2->SetHitTestable(true); - - scroll->test_properties()->AddChild(std::move(squash2)); - root->test_properties()->AddChild(std::move(scroll)); - root->test_properties()->AddChild(std::move(scrollbar)); - root->test_properties()->AddChild(std::move(squash1)); - - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); + UpdateDrawProperties(layer_tree_impl); layer_tree_impl->DidBecomeActive(); // The point hits squash1 layer and also scroll layer, because scroll layer @@ -536,58 +507,66 @@ class LayerTreeHostImplTest : public testing::Test, ASSERT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); } - // Sets up a typical virtual viewport setup with one child content layer. - // Returns a pointer to the content layer. - LayerImpl* CreateBasicVirtualViewportLayers(const gfx::Size& viewport_size, - const gfx::Size& content_size) { - // CreateScrollAndContentsLayers makes the outer viewport unscrollable and - // the inner a different size from the outer. We'll reuse its layer - // hierarchy but adjust the sizing to our needs. - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - - LayerImpl* content_layer = host_impl_->OuterViewportScrollLayer() - ->test_properties() - ->children.back(); - content_layer->SetBounds(content_size); - host_impl_->OuterViewportScrollLayer()->SetBounds(content_size); - host_impl_->OuterViewportScrollLayer()->SetScrollable(viewport_size); - host_impl_->OuterViewportScrollLayer()->SetHitTestable(true); - - LayerImpl* outer_clip = - host_impl_->OuterViewportScrollLayer()->test_properties()->parent; - outer_clip->SetBounds(viewport_size); - - LayerImpl* inner_clip_layer = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - inner_clip_layer->SetBounds(viewport_size); - host_impl_->InnerViewportScrollLayer()->SetBounds(viewport_size); - host_impl_->InnerViewportScrollLayer()->SetScrollable(viewport_size); - host_impl_->InnerViewportScrollLayer()->SetHitTestable(true); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - host_impl_->active_tree()->DidBecomeActive(); - - return content_layer; - } - - std::unique_ptr<LayerImpl> CreateScrollableLayer(int id, - const gfx::Size& size) { - std::unique_ptr<LayerImpl> layer = - LayerImpl::Create(host_impl_->active_tree(), id); + LayerImpl* AddScrollableLayer(LayerImpl* container, + const gfx::Size& scroll_container_bounds, + const gfx::Size& content_size) { + LayerImpl* layer = AddLayer<LayerImpl>(container->layer_tree_impl()); layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); layer->SetDrawsContent(true); - layer->SetBounds(size); - gfx::Size scroll_container_bounds = - gfx::Size(size.width() / 2, size.height() / 2); + layer->SetBounds(content_size); layer->SetScrollable(scroll_container_bounds); layer->SetHitTestable(true); + CopyProperties(container, layer); + CreateTransformNode(layer); + CreateScrollNode(layer); return layer; } + void SetupScrollbarLayerCommon(LayerImpl* scroll_layer, + ScrollbarLayerImplBase* scrollbar) { + auto* tree_impl = scroll_layer->layer_tree_impl(); + scrollbar->SetScrollElementId(scroll_layer->element_id()); + scrollbar->SetDrawsContent(true); + CopyProperties(scroll_layer, scrollbar); + auto* property_trees = tree_impl->property_trees(); + if (scroll_layer == tree_impl->OuterViewportScrollLayerForTesting()) { + scrollbar->SetTransformTreeIndex(tree_impl->PageScaleTransformNode()->id); + scrollbar->SetScrollTreeIndex( + tree_impl->root_layer()->scroll_tree_index()); + } else { + scrollbar->SetTransformTreeIndex( + property_trees->transform_tree + .Node(scroll_layer->transform_tree_index()) + ->parent_id); + scrollbar->SetScrollTreeIndex( + property_trees->scroll_tree.Node(scroll_layer->scroll_tree_index()) + ->parent_id); + } + } + + void SetupScrollbarLayer(LayerImpl* scroll_layer, + SolidColorScrollbarLayerImpl* scrollbar) { + scrollbar->SetElementId(LayerIdToElementIdForTesting(scrollbar->id())); + SetupScrollbarLayerCommon(scroll_layer, scrollbar); + auto& effect = CreateEffectNode(scrollbar); + effect.opacity = 0.f; + effect.has_potential_opacity_animation = true; + } + + void SetupScrollbarLayer(LayerImpl* scroll_layer, + PaintedScrollbarLayerImpl* scrollbar) { + SetupScrollbarLayerCommon(scroll_layer, scrollbar); + scrollbar->SetHitTestable(true); + CreateEffectNode(scrollbar).opacity = 1.f; + } + + LayerImpl* InnerViewportScrollLayer() { + return host_impl_->active_tree()->InnerViewportScrollLayerForTesting(); + } + LayerImpl* OuterViewportScrollLayer() { + return host_impl_->active_tree()->OuterViewportScrollLayerForTesting(); + } + std::unique_ptr<ScrollState> BeginState(const gfx::Point& point) { ScrollStateData scroll_state_data; scroll_state_data.is_beginning = true; @@ -619,6 +598,7 @@ class LayerTreeHostImplTest : public testing::Test, } void DrawFrame() { + PrepareForUpdateDrawProperties(host_impl_->active_tree()); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame); @@ -645,14 +625,10 @@ class LayerTreeHostImplTest : public testing::Test, // Create the pending tree. host_impl_->BeginCommit(); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->SetDeviceViewportRect(gfx::Rect(layer_size)); - pending_tree->SetRootLayerForTesting( - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 1, - raster_source)); - auto* root = static_cast<FakePictureLayerImpl*>(*pending_tree->begin()); - root->SetBounds(layer_size); + LayerImpl* root = SetupRootLayer<FakePictureLayerImpl>( + pending_tree, layer_size, raster_source); root->SetDrawsContent(true); - pending_tree->BuildPropertyTreesForTesting(); + UpdateDrawProperties(pending_tree); // CompleteCommit which should perform a PrepareTiles, adding tilings for // the root layer, each one having a raster task. @@ -669,10 +645,8 @@ class LayerTreeHostImplTest : public testing::Test, void WhiteListedTouchActionTestHelper(float device_scale_factor, float page_scale_factor) { - LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); DrawFrame(); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); // Just hard code some random number, we care about the actual page scale // factor on the active tree. @@ -682,18 +656,14 @@ class LayerTreeHostImplTest : public testing::Test, page_scale_factor, min_page_scale_factor, max_page_scale_factor); host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor); - std::unique_ptr<LayerImpl> child_layer = - LayerImpl::Create(host_impl_->active_tree(), 6); - LayerImpl* child = child_layer.get(); - child_layer->SetDrawsContent(true); - child_layer->test_properties()->position = gfx::PointF(0, 0); - child_layer->SetBounds(gfx::Size(25, 25)); - scroll->test_properties()->AddChild(std::move(child_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* child = AddLayer(); + child->SetDrawsContent(true); + child->SetBounds(gfx::Size(25, 25)); + CopyProperties(InnerViewportScrollLayer(), child); TouchActionRegion root_touch_action_region; root_touch_action_region.Union(kTouchActionPanX, gfx::Rect(0, 0, 50, 50)); - root->SetTouchActionRegion(root_touch_action_region); + root_layer()->SetTouchActionRegion(root_touch_action_region); TouchActionRegion child_touch_action_region; child_touch_action_region.Union(kTouchActionPanLeft, gfx::Rect(0, 0, 25, 25)); @@ -722,38 +692,31 @@ class LayerTreeHostImplTest : public testing::Test, } LayerImpl* CreateLayerForSnapping() { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - LayerImpl* scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); gfx::Size overflow_size(400, 400); - EXPECT_EQ(1u, scroll_layer->test_properties()->children.size()); - LayerImpl* overflow = scroll_layer->test_properties()->children[0]; - overflow->SetBounds(overflow_size); - overflow->SetScrollable(gfx::Size(100, 100)); - overflow->SetHitTestable(true); - overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); - overflow->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), - gfx::ScrollOffset()); - overflow->test_properties()->position = gfx::PointF(0, 0); - + LayerImpl* overflow = AddScrollableLayer( + OuterViewportScrollLayer(), gfx::Size(100, 100), overflow_size); SnapContainerData container_data( ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory), gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(300, 300)); SnapAreaData area_data(ScrollSnapAlign(SnapAlignment::kStart), gfx::RectF(50, 50, 100, 100), false); container_data.AddSnapAreaData(area_data); - overflow->test_properties()->snap_container_data.emplace(container_data); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(overflow)->snap_container_data.emplace(container_data); DrawFrame(); return overflow; } + void ClearLayersAndPropertyTrees(LayerTreeImpl* layer_tree_impl) { + layer_tree_impl->SetRootLayerForTesting(nullptr); + layer_tree_impl->DetachLayers(); + layer_tree_impl->property_trees()->clear(); + layer_tree_impl->SetViewportPropertyIds( + LayerTreeImpl::ViewportPropertyIds()); + } + void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor); void pinch_zoom_pan_viewport_test(float device_scale_factor); void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor); @@ -772,6 +735,7 @@ class LayerTreeHostImplTest : public testing::Test, } void DrawOneFrame() { + PrepareForUpdateDrawProperties(host_impl_->active_tree()); TestFrameData frame_data; host_impl_->PrepareToDraw(&frame_data); host_impl_->DidDrawAllLayers(frame_data); @@ -828,6 +792,7 @@ class LayerTreeHostImplTest : public testing::Test, viz::RenderPassList last_on_draw_render_passes_; scoped_refptr<AnimationTimeline> timeline_; std::unique_ptr<base::Thread> image_worker_; + int next_layer_id_ = 2; }; class CommitToPendingTreeLayerTreeHostImplTest : public LayerTreeHostImplTest { @@ -931,19 +896,18 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { on_can_draw_state_changed_called_ = false; // Set up the root layer, which allows us to draw. - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_TRUE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; // Toggle the root layer to make sure it toggles can_draw - host_impl_->active_tree()->SetRootLayerForTesting(nullptr); - host_impl_->active_tree()->DetachLayers(); + ClearLayersAndPropertyTrees(host_impl_->active_tree()); EXPECT_FALSE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_TRUE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; @@ -962,8 +926,7 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::CreateSoftware()); - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_TRUE(host_impl_->CanDraw()); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect()); @@ -980,7 +943,7 @@ TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { } TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { - ASSERT_FALSE(host_impl_->active_tree()->root_layer_for_testing()); + host_impl_->active_tree()->SetRootLayerForTesting(nullptr); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); @@ -988,26 +951,19 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { } TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) { + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); { - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 2)); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 3)); - root->test_properties()->children[1]->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 4)); - root->test_properties()->children[1]->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 5)); - root->test_properties() - ->children[1] - ->test_properties() - ->children[0] - ->test_properties() - ->AddChild(LayerImpl::Create(host_impl_->active_tree(), 6)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - } - LayerImpl* root = *host_impl_->active_tree()->begin(); + LayerImpl* child1 = AddLayer(); + CopyProperties(root, child1); + LayerImpl* child2 = AddLayer(); + CopyProperties(root, child2); + LayerImpl* grand_child1 = AddLayer(); + CopyProperties(child2, grand_child1); + LayerImpl* grand_child2 = AddLayer(); + CopyProperties(child2, grand_child2); + LayerImpl* great_grand_child = AddLayer(); + CopyProperties(grand_child1, great_grand_child); + } ExpectClearedScrollDeltasRecursive(root); @@ -1026,19 +982,15 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { gfx::ScrollOffset scroll_offset(20, 30); gfx::ScrollOffset scroll_delta(11, -15); - auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1); - auto* root = root_owned.get(); - - root->SetBounds(gfx::Size(110, 110)); - root->SetScrollable(gfx::Size(10, 10)); + auto* root = SetupDefaultRootLayer(gfx::Size(110, 110)); root->SetHitTestable(true); - root->SetElementId(LayerIdToElementIdForTesting(root->id())); + root->SetScrollable(gfx::Size(10, 10)); + CreateScrollNode(root); root->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->element_id(), scroll_offset); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_owned)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); std::unique_ptr<ScrollAndScaleSet> scroll_info; @@ -1102,10 +1054,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRootLayerAttached) { } TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1124,10 +1073,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { } TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1162,7 +1108,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)))); - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); // We should not crash when trying to scroll after the renderer initialization // fails. @@ -1174,8 +1120,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { } TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); // We should not crash if the tree is replaced while we are scrolling. @@ -1184,9 +1129,10 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { host_impl_ ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) .thread); - host_impl_->active_tree()->DetachLayers(); + ClearLayersAndPropertyTrees(host_impl_->active_tree()); - scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); // We should still be scrolling, because the scrolled layer also exists in the // new tree. @@ -1202,8 +1148,8 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { } TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { - LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll = InnerViewportScrollLayer(); scroll->SetWheelEventHandlerRegion(Region(gfx::Rect(20, 20))); DrawFrame(); @@ -1229,22 +1175,16 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { } TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { - LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - LayerImpl* child = nullptr; - { - std::unique_ptr<LayerImpl> child_layer = - LayerImpl::Create(host_impl_->active_tree(), 6); - child = child_layer.get(); - child_layer->SetDrawsContent(true); - child_layer->test_properties()->position = gfx::PointF(0, 20); - child_layer->SetBounds(gfx::Size(50, 50)); - scroll->test_properties()->AddChild(std::move(child_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - } + LayerImpl* root = root_layer(); + LayerImpl* scroll = InnerViewportScrollLayer(); + LayerImpl* child = AddLayer(); + child->SetDrawsContent(true); + child->SetBounds(gfx::Size(50, 50)); + CopyProperties(scroll, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(0, 20)); // Touch handler regions determine whether touch events block scroll. TouchAction touch_action; @@ -1283,13 +1223,9 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { } TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - - root->test_properties()->main_thread_scrolling_reasons = + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + host_impl_->InnerViewportScrollNode()->main_thread_scrolling_reasons = MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1320,41 +1256,24 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { gfx::Size scroll_content_size = gfx::Size(345, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(content_size)); - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(content_size); - root->test_properties()->position = gfx::PointF(); + LayerImpl* root = SetupDefaultRootLayer(content_size); + LayerImpl* scroll = + AddScrollableLayer(root, content_size, scroll_content_size); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); - scroll->SetBounds(scroll_content_size); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - scroll->SetHitTestable(true); - - std::unique_ptr<PaintedScrollbarLayerImpl> drawn_scrollbar = - PaintedScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, false, - true); + auto* drawn_scrollbar = AddLayer<PaintedScrollbarLayerImpl>( + layer_tree_impl, VERTICAL, false, true); + SetupScrollbarLayer(scroll, drawn_scrollbar); drawn_scrollbar->SetBounds(scrollbar_size); - drawn_scrollbar->test_properties()->position = gfx::PointF(345, 0); - drawn_scrollbar->SetScrollElementId(scroll->element_id()); - drawn_scrollbar->SetDrawsContent(true); - drawn_scrollbar->SetHitTestable(true); - drawn_scrollbar->test_properties()->opacity = 1.f; + drawn_scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); - std::unique_ptr<LayerImpl> squash = LayerImpl::Create(layer_tree_impl, 5); + LayerImpl* squash = AddLayer(); squash->SetBounds(gfx::Size(140, 300)); - squash->test_properties()->position = gfx::PointF(220, 0); squash->SetDrawsContent(true); squash->SetHitTestable(true); + CopyProperties(scroll, squash); + squash->SetOffsetToTransformParent(gfx::Vector2dF(220, 0)); - scroll->test_properties()->AddChild(std::move(drawn_scrollbar)); - scroll->test_properties()->AddChild(std::move(squash)); - root->test_properties()->AddChild(std::move(scroll)); - - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); + UpdateDrawProperties(layer_tree_impl); layer_tree_impl->DidBecomeActive(); // The point hits squash layer and also scrollbar layer, but because the @@ -1375,13 +1294,11 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { } TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); outer_scroll->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); // All scroll types inside the non-fast scrollable region should fail. @@ -1424,15 +1341,13 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { } TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); outer_scroll->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); - outer_scroll->test_properties()->position = gfx::PointF(-25.f, 0.f); + SetPostTranslation(outer_scroll, gfx::Vector2dF(-25.f, 0.f)); outer_scroll->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); // This point would fall into the non-fast scrollable region except that we've @@ -1456,9 +1371,8 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { } TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); EXPECT_FALSE(host_impl_->active_tree()->have_scroll_event_handlers()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); @@ -1470,9 +1384,8 @@ TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) { } TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); host_impl_->active_tree()->set_have_scroll_event_handlers(true); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); @@ -1484,9 +1397,7 @@ TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) { } TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); - + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1728,6 +1639,41 @@ TEST_F(LayerTreeHostImplTest, SnapAnimationCancelledByScroll) { overflow->CurrentScrollOffset()); } +TEST_F(LayerTreeHostImplTest, + SnapAnimationShouldNotStartWhenScrollEndsAtSnapTarget) { + LayerImpl* overflow = CreateLayerForSnapping(); + + gfx::Point pointer_position(10, 10); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL) + .thread); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + // There is a snap target at 50, scroll to it directly. + gfx::Vector2dF x_delta(50, 0); + host_impl_->ScrollBy(UpdateState(pointer_position, x_delta).get()); + EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing()); + + viz::BeginFrameArgs begin_frame_args = + viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1); + host_impl_->ScrollEnd(EndState().get(), true); + base::TimeTicks start_time = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(100); + BeginImplFrameAndAnimate(begin_frame_args, start_time); + + // We are already at a snap target so we should not animate for snap. + EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing()); + + // Verify that we are not actually animating by running one frame and ensuring + // scroll offset has not changed. + BeginImplFrameAndAnimate(begin_frame_args, + start_time + base::TimeDelta::FromMilliseconds(100)); + EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), overflow->CurrentScrollOffset()); +} + TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoWhenZoomed) { LayerImpl* overflow = CreateLayerForSnapping(); // Scales the page to its 1/5. @@ -1759,26 +1705,14 @@ TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoWhenZoomed) { TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { const gfx::Size kViewportSize(100, 100); const gfx::Size kContentSize(200, 200); - CreateBasicVirtualViewportLayers(kViewportSize, kContentSize); + SetupViewportLayersOuterScrolls(kViewportSize, kContentSize); - LayerImpl* scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(kViewportSize)); + LayerImpl* scroll_layer = OuterViewportScrollLayer(); gfx::Size overflow_size(400, 400); - ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); - LayerImpl* overflow = scroll_layer->test_properties()->children[0]; - overflow->SetBounds(overflow_size); - overflow->SetScrollable(gfx::Size(100, 100)); - overflow->SetHitTestable(true); - overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); - overflow->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), - gfx::ScrollOffset()); - overflow->test_properties()->position = gfx::PointF(40, 40); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(30, 30)); + LayerImpl* overflow = AddScrollableLayer(OuterViewportScrollLayer(), + gfx::Size(100, 100), overflow_size); + SetScrollOffset(scroll_layer, gfx::ScrollOffset(30, 30)); DrawFrame(); gfx::Point pointer_position(50, 50); @@ -1931,25 +1865,13 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { const gfx::Size kViewportSize(100, 100); const gfx::Size kContentSize(200, 200); - CreateBasicVirtualViewportLayers(kViewportSize, kContentSize); + SetupViewportLayersOuterScrolls(kViewportSize, kContentSize); - LayerImpl* scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(kViewportSize)); + LayerImpl* scroll_layer = OuterViewportScrollLayer(); gfx::Size overflow_size(400, 400); - ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); - LayerImpl* overflow = scroll_layer->test_properties()->children[0]; - overflow->SetBounds(overflow_size); - overflow->SetScrollable(gfx::Size(100, 100)); - overflow->SetHitTestable(true); - overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); - overflow->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), - gfx::ScrollOffset()); - overflow->test_properties()->position = gfx::PointF(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* overflow = + AddScrollableLayer(scroll_layer, gfx::Size(100, 100), overflow_size); DrawFrame(); gfx::Point scroll_position(10, 10); @@ -1968,8 +1890,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset()); - overflow->test_properties()->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(overflow)->user_scrollable_horizontal = false; DrawFrame(); @@ -1986,8 +1907,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset()); - overflow->test_properties()->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(overflow)->user_scrollable_vertical = false; DrawFrame(); EXPECT_EQ( @@ -2005,13 +1925,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { } TEST_F(LayerTreeHostImplTest, ForceMainThreadScrollWithoutScrollLayer) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - ScrollNode* scroll_node = - host_impl_->active_tree()->property_trees()->scroll_tree.Node( - host_impl_->OuterViewportScrollLayer()->scroll_tree_index()); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); + ScrollNode* scroll_node = host_impl_->OuterViewportScrollNode(); // Change the scroll node so that it no longer has an associated layer. scroll_node->element_id = ElementId(42); @@ -2028,29 +1943,23 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, AnimationSchedulingPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - CreatePendingTree(); - auto root_owned = LayerImpl::Create(host_impl_->pending_tree(), 1); - auto* root = root_owned.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned)); - root->SetBounds(gfx::Size(50, 50)); - root->test_properties()->force_render_surface = true; + auto* root = + SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), gfx::Size(50, 50)); root->SetNeedsPushProperties(); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->pending_tree(), 2)); - LayerImpl* child = root->test_properties()->children[0]; + auto* child = AddLayer<LayerImpl>(host_impl_->pending_tree()); child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); child->SetDrawsContent(true); child->SetNeedsPushProperties(); host_impl_->pending_tree()->SetElementIdsForTesting(); + CopyProperties(root, child); + CreateTransformNode(child); AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(), 10.0, 3, 0); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); @@ -2088,21 +1997,14 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, AnimationSchedulingActiveTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - - host_impl_->active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_->active_tree(), 1)); - LayerImpl* root = *host_impl_->active_tree()->begin(); - root->SetBounds(gfx::Size(50, 50)); - root->test_properties()->force_render_surface = true; - - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 2)); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(50, 50)); + LayerImpl* child = AddLayer(); child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); child->SetDrawsContent(true); + host_impl_->active_tree()->SetElementIdsForTesting(); + CopyProperties(root, child); + CreateTransformNode(child); // Add a translate from 6,7 to 8,9. TransformOperations start; @@ -2111,7 +2013,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, end.AppendTranslate(8.f, 9.f, 0.f); AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(), 4.0, start, end); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); base::TimeTicks now = base::TimeTicks::Now(); host_impl_->WillBeginImplFrame( @@ -2150,36 +2052,24 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { - FakeImplTaskRunnerProvider provider(nullptr); - CreateHostImplWithTaskRunnerProvider(DefaultSettings(), - CreateLayerTreeFrameSink(), &provider); EXPECT_TRUE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - - auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1); - auto* root = root_owned.get(); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_owned)); - root->SetBounds(gfx::Size(50, 50)); + auto* root = SetupDefaultRootLayer(gfx::Size(50, 50)); - auto child_owned = LayerImpl::Create(host_impl_->active_tree(), 2); - auto* child = child_owned.get(); - root->test_properties()->AddChild(std::move(child_owned)); + auto* child = AddLayer(); child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); child->SetDrawsContent(true); host_impl_->active_tree()->SetElementIdsForTesting(); + CopyProperties(root, child); + CreateTransformNode(child); AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(), 10.0, 3, 0); // Set up the property trees so that UpdateDrawProperties will work in // CommitComplete below. - RenderSurfaceList list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Rect(50, 50), &list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); @@ -2199,21 +2089,15 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { } TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) { - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - - host_impl_->active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_->active_tree(), 1)); - LayerImpl* root = *host_impl_->active_tree()->begin(); - root->SetBounds(gfx::Size(50, 50)); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(50, 50)); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 2)); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = AddLayer(); child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); child->SetDrawsContent(true); host_impl_->active_tree()->SetElementIdsForTesting(); + CopyProperties(root, child); + CreateTransformNode(child); // Add a translate animation. TransformOperations start; @@ -2222,7 +2106,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) { end.AppendTranslate(8.f, 9.f, 0.f); AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(), 4.0, start, end); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); base::TimeTicks now = base::TimeTicks::Now(); host_impl_->WillBeginImplFrame( @@ -2243,18 +2127,13 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) { EXPECT_TRUE(did_request_next_frame_); did_request_next_frame_ = false; - // Destroy layer, unregister animation target (element). - child->test_properties()->parent = nullptr; - root->test_properties()->RemoveChild(child); - - // Calling LayerImplTestProperties::RemoveChild above does not actually - // remove the property tree nodes for the removed layer. In the real code, - // you cannot remove a child on LayerImpl, but a child removed on Layer - // will force a full tree sync which will rebuild property trees without that - // child's property tree nodes. Call BuildPropertyTrees to simulate the - // rebuild that would happen during the commit. - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - child = nullptr; + // In the real code, you cannot remove a child on LayerImpl, but a child + // removed on Layer will force a full tree sync which will rebuild property + // trees without that child's property tree nodes. Clear active_tree (which + // also clears property trees) to simulate the rebuild that would happen + // before/during the commit. + host_impl_->active_tree()->property_trees()->clear(); + host_impl_->UpdateElements(ElementListType::ACTIVE); // On updating state, we will send an animation event and request one last // frame. @@ -2289,15 +2168,11 @@ class MissingTilesLayer : public LayerImpl { }; TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); - LayerImpl* container_layer = host_impl_->InnerViewportContainerLayer(); - EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); + EXPECT_EQ(gfx::Size(50, 50), root_layer()->bounds()); float min_page_scale = 1.f, max_page_scale = 4.f; float page_scale_factor = 1.f; @@ -2320,7 +2195,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { EXPECT_FALSE(did_request_next_frame_); EXPECT_TRUE(did_request_redraw_); EXPECT_TRUE(did_request_commit_); - EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); + EXPECT_EQ(gfx::Size(50, 50), root_layer()->bounds()); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); @@ -2383,50 +2258,31 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollbarGeometry) { // size. const gfx::Size outer_viewport_size = content_size; - PaintedScrollbarLayerImpl* v_scrollbar; - PaintedScrollbarLayerImpl* h_scrollbar; - // Setup - { - LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateLayerTreeFrameSink()); - LayerTreeImpl* active_tree = host_impl_->active_tree(); - active_tree->PushPageScaleFromMainThread(1.f, minimum_scale, 4.f); - - CreateBasicVirtualViewportLayers(viewport_size, content_size); - - // When Chrome on Android loads a non-mobile page, it resizes the main - // frame (outer viewport) such that it matches the width of the content, - // preventing horizontal scrolling. Replicate that behavior here. - host_impl_->OuterViewportScrollLayer()->SetScrollable(outer_viewport_size); - host_impl_->OuterViewportScrollLayer()->SetHitTestable(true); - LayerImpl* outer_clip = - host_impl_->OuterViewportScrollLayer()->test_properties()->parent; - outer_clip->SetBounds(outer_viewport_size); - - // Add scrollbars. They will always exist - even if unscrollable - but their - // visibility will be determined by whether the content can be scrolled. - { - std::unique_ptr<PaintedScrollbarLayerImpl> v_scrollbar_unique = - PaintedScrollbarLayerImpl::Create(active_tree, 400, VERTICAL, false, - true); - std::unique_ptr<PaintedScrollbarLayerImpl> h_scrollbar_unique = - PaintedScrollbarLayerImpl::Create(active_tree, 401, HORIZONTAL, false, - true); - v_scrollbar = v_scrollbar_unique.get(); - h_scrollbar = h_scrollbar_unique.get(); - - LayerImpl* scroll = active_tree->OuterViewportScrollLayer(); - LayerImpl* root = active_tree->InnerViewportContainerLayer(); - v_scrollbar_unique->SetScrollElementId(scroll->element_id()); - h_scrollbar_unique->SetScrollElementId(scroll->element_id()); - root->test_properties()->AddChild(std::move(v_scrollbar_unique)); - root->test_properties()->AddChild(std::move(h_scrollbar_unique)); - } + LayerTreeImpl* active_tree = host_impl_->active_tree(); + active_tree->PushPageScaleFromMainThread(1.f, minimum_scale, 4.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->DidBecomeActive(); - } + // When Chrome on Android loads a non-mobile page, it resizes the main + // frame (outer viewport) such that it matches the width of the content, + // preventing horizontal scrolling. Replicate that behavior here. + SetupViewportLayersInnerScrolls(viewport_size, content_size); + + LayerImpl* scroll = OuterViewportScrollLayer(); + ASSERT_EQ(scroll->scroll_container_bounds(), outer_viewport_size); + scroll->SetHitTestable(true); + ClipNode* outer_clip = host_impl_->active_tree()->OuterViewportClipNode(); + ASSERT_EQ(gfx::SizeF(outer_viewport_size), outer_clip->clip.size()); + + // Add scrollbars. They will always exist - even if unscrollable - but their + // visibility will be determined by whether the content can be scrolled. + auto* v_scrollbar = + AddLayer<PaintedScrollbarLayerImpl>(active_tree, VERTICAL, false, true); + auto* h_scrollbar = + AddLayer<PaintedScrollbarLayerImpl>(active_tree, HORIZONTAL, false, true); + SetupScrollbarLayer(scroll, v_scrollbar); + SetupScrollbarLayer(scroll, h_scrollbar); + + host_impl_->active_tree()->DidBecomeActive(); // Zoom out to the minimum scale. The scrollbars shoud not be scrollable. host_impl_->active_tree()->SetPageScaleOnActiveTree(0.f); @@ -2446,13 +2302,13 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); outer_scroll_layer->SetDrawsContent(true); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); inner_scroll_layer->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_VECTOR_EQ(gfx::Vector2dF(500, 500), outer_scroll_layer->MaxScrollOffset()); @@ -2499,19 +2355,17 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) { // Make sure scrolls smaller than a unit applied to the viewport don't get // dropped. crbug.com/539334. TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) { - LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); outer_scroll_layer->SetDrawsContent(true); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); inner_scroll_layer->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // Sanity checks. EXPECT_VECTOR_EQ(gfx::Vector2dF(500, 500), @@ -2554,13 +2408,13 @@ TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); outer_scroll_layer->SetDrawsContent(true); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); inner_scroll_layer->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_VECTOR_EQ(gfx::Vector2dF(500, 500), outer_scroll_layer->MaxScrollOffset()); @@ -2608,7 +2462,7 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); int offsetFromEdge = Viewport::kPinchZoomSnapMarginDips - 5; gfx::Point anchor(viewport_size.width() - offsetFromEdge, @@ -2622,14 +2476,13 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { host_impl_->PinchGestureEnd(anchor, true); host_impl_->ScrollEnd(EndState().get()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(250, 250), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(250, 250), + InnerViewportScrollLayer()->CurrentScrollOffset()); // Reset. host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f); - SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d()); - SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d()); // Pinch in within the margins. The scroll should stay exactly locked to the // top and left. @@ -2640,14 +2493,13 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { host_impl_->PinchGestureEnd(anchor, true); host_impl_->ScrollEnd(EndState().get()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + InnerViewportScrollLayer()->CurrentScrollOffset()); // Reset. host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f); - SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d()); - SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d()); // Pinch in just outside the margin. There should be no snapping. offsetFromEdge = Viewport::kPinchZoomSnapMarginDips; @@ -2658,14 +2510,13 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { host_impl_->PinchGestureEnd(anchor, true); host_impl_->ScrollEnd(EndState().get()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(50, 50), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50), + InnerViewportScrollLayer()->CurrentScrollOffset()); // Reset. host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f); - SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d()); - SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d()); // Pinch in just outside the margin. There should be no snapping. offsetFromEdge = Viewport::kPinchZoomSnapMarginDips; @@ -2677,18 +2528,17 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { host_impl_->PinchGestureEnd(anchor, true); host_impl_->ScrollEnd(EndState().get()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(200, 200), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(200, 200), + InnerViewportScrollLayer()->CurrentScrollOffset()); } TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) { const gfx::Size content_size(200, 200); const gfx::Size viewport_size(100, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); // Zoom into the page by a 2X factor float min_page_scale = 1.f, max_page_scale = 4.f; @@ -2743,7 +2593,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { std::unique_ptr<SwapPromise> swap_promise( new LatencyInfoSwapPromise(latency_info)); - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ ->ScrollBegin(BeginState(gfx::Point()).get(), @@ -2763,45 +2613,23 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { // Test that scrolls targeting a layer with a non-null scroll_parent() don't // bubble up. TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { - LayerImpl* viewport_scroll = - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - // This is to build property tree for viewport layers. The remaining part of - // this test is in layer list mode. - // TODO(crbug.com/994361): Avoid PropertyTreeBuilder. - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + LayerImpl* viewport_scroll = InnerViewportScrollLayer(); // Set up two scrolling children of the root, one of which is a scroll parent // to the other. Scrolls shouldn't bubbling from the child. - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - LayerImpl* parent; - LayerImpl* child; - LayerImpl* child_clip; - - std::unique_ptr<LayerImpl> scroll_parent = - CreateScrollableLayer(7, gfx::Size(10, 10)); - parent = scroll_parent.get(); - root->test_properties()->AddChild(std::move(scroll_parent)); - CopyProperties(viewport_scroll, parent); - CreateTransformNode(parent); - CreateScrollNode(parent); - - std::unique_ptr<LayerImpl> scroll_child_clip = - LayerImpl::Create(host_impl_->active_tree(), 8); - child_clip = scroll_child_clip.get(); - root->test_properties()->AddChild(std::move(scroll_child_clip)); - CopyProperties(viewport_scroll, child_clip); - // child_clip scrolls in scroll_parent. - child_clip->SetScrollTreeIndex(parent->scroll_tree_index()); - child_clip->SetTransformTreeIndex(parent->transform_tree_index()); - - std::unique_ptr<LayerImpl> scroll_child = - CreateScrollableLayer(9, gfx::Size(10, 10)); - child = scroll_child.get(); - root->test_properties()->AddChild(std::move(scroll_child)); - CopyProperties(child_clip, child); - CreateTransformNode(child).post_translation = gfx::Vector2d(20, 20); - CreateScrollNode(child); + LayerImpl* scroll_parent = + AddScrollableLayer(viewport_scroll, gfx::Size(5, 5), gfx::Size(10, 10)); + + LayerImpl* scroll_child_clip = AddLayer(); + // scroll_child_clip scrolls in scroll_parent, but under viewport_scroll's + // effect. + CopyProperties(scroll_parent, scroll_child_clip); + scroll_child_clip->SetEffectTreeIndex(viewport_scroll->effect_tree_index()); + + LayerImpl* scroll_child = + AddScrollableLayer(scroll_child_clip, gfx::Size(5, 5), gfx::Size(10, 10)); + GetTransformNode(scroll_child)->post_translation = gfx::Vector2d(20, 20); DrawFrame(); @@ -2815,18 +2643,17 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { host_impl_->ScrollEnd(EndState().get()); // The child should be fully scrolled by the first ScrollBy. - EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), child->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), scroll_child->CurrentScrollOffset()); // The scroll_parent shouldn't receive the second ScrollBy. - EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), parent->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + scroll_parent->CurrentScrollOffset()); // The viewport shouldn't have been scrolled at all. - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->OuterViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + OuterViewportScrollLayer()->CurrentScrollOffset()); } { @@ -2843,25 +2670,22 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { host_impl_->ScrollEnd(EndState().get()); // The ScrollBy's should scroll the parent to its extent. - EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), parent->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), + scroll_parent->CurrentScrollOffset()); // The viewport shouldn't receive any scroll delta. - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->OuterViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + OuterViewportScrollLayer()->CurrentScrollOffset()); } } TEST_F(LayerTreeHostImplTest, PinchGesture) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 1.f; @@ -3031,12 +2855,10 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { } TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 1.f; @@ -3079,11 +2901,10 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) { } TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollFromFractionalActiveBase) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); SetScrollOffsetDelta(scroll_layer, gfx::Vector2d()); @@ -3115,8 +2936,7 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollFromFractionalActiveBase) { } TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); float min_page_scale = 1.f; @@ -3238,11 +3058,10 @@ TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) { } TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 0.5f; @@ -3368,11 +3187,10 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { } TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 0.5f; @@ -3430,13 +3248,12 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), - gfx::Size(100, 100)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50), + gfx::Size(100, 100), gfx::Size(100, 100)); host_impl_->ActivateSyncTree(); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 0.5f; @@ -3553,11 +3370,10 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { } TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); base::TimeTicks start_time = @@ -3603,29 +3419,29 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { } TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - LayerImpl* inner_container = host_impl_->InnerViewportContainerLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); DCHECK(inner_scroll); - DCHECK(inner_container); EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset()); - inner_container->SetViewportBoundsDelta(gfx::Vector2dF(15.f, 15.f)); - inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF(7.f, 7.f)); + PropertyTrees* property_trees = host_impl_->active_tree()->property_trees(); + property_trees->SetInnerViewportContainerBoundsDelta( + gfx::Vector2dF(15.f, 15.f)); + property_trees->SetOuterViewportContainerBoundsDelta( + gfx::Vector2dF(7.f, 7.f)); EXPECT_EQ(gfx::ScrollOffset(42, 42), inner_scroll->MaxScrollOffset()); - inner_container->SetViewportBoundsDelta(gfx::Vector2dF()); - inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF()); + property_trees->SetInnerViewportContainerBoundsDelta(gfx::Vector2dF()); + property_trees->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF()); inner_scroll->SetBounds(gfx::Size()); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(inner_scroll)->bounds = inner_scroll->bounds(); DrawFrame(); - inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF(60.f, 60.f)); + property_trees->SetOuterViewportContainerBoundsDelta( + gfx::Vector2dF(60.f, 60.f)); EXPECT_EQ(gfx::ScrollOffset(10, 10), inner_scroll->MaxScrollOffset()); } @@ -3644,6 +3460,7 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { task_graph_runner, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, + nullptr, nullptr) {} viz::BeginFrameArgs CurrentBeginFrameArgs() const override { @@ -3665,6 +3482,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = @@ -3676,28 +3494,20 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { host_impl_->SetVisible(true); host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get()); - SetupScrollAndContentsLayers(content_size); + SetupViewportLayersInnerScrolls(viewport_size, content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(content_size.width() / 2, content_size.height() / 2)); - - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 400, - VERTICAL, 10, 0, false, true); - scrollbar->test_properties()->opacity = 0.f; - EXPECT_FLOAT_EQ(0.f, scrollbar->test_properties()->opacity); - - LayerImpl* scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - LayerImpl* root = host_impl_->active_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollElementId(scroll->element_id()); - root->test_properties()->AddChild(std::move(scrollbar)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 10, 0, false); + SetupScrollbarLayer(OuterViewportScrollLayer(), scrollbar); + host_impl_->active_tree()->DidBecomeActive(); host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain(); host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent( viz::LocalSurfaceIdAllocation( viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)), base::TimeTicks::Now())); + DrawFrame(); // SetScrollElementId will initialize the scrollbar which will cause it to @@ -3842,10 +3652,10 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { if (host_impl_->active_tree() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - host_impl_->InnerViewportScrollLayer()->element_id(), + InnerViewportScrollLayer()->element_id(), gfx::ScrollOffset(5, 5))) host_impl_->active_tree()->DidUpdateScrollOffset( - host_impl_->InnerViewportScrollLayer()->element_id()); + InnerViewportScrollLayer()->element_id()); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); EXPECT_EQ(base::TimeDelta(), requested_animation_delay_); @@ -3888,6 +3698,7 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { settings.scrollbar_animator = animator; settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); // If no animator is set, scrollbar won't show and no animation is expected. @@ -3895,30 +3706,24 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { CreateHostImpl(settings, CreateLayerTreeFrameSink()); CreatePendingTree(); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size); - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400, - VERTICAL, 10, 0, false, true); - scrollbar->test_properties()->opacity = 0.f; - LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer(); - LayerImpl* container = - host_impl_->pending_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollElementId(scroll->element_id()); - scrollbar->SetBounds(gfx::Size(10, 100)); - scrollbar->test_properties()->position = gfx::PointF(90, 0); - scrollbar->SetNeedsPushProperties(); - container->test_properties()->AddChild(std::move(scrollbar)); + SetupViewportLayers(host_impl_->pending_tree(), viewport_size, content_size, + content_size); + + LayerImpl* scroll = + host_impl_->pending_tree()->OuterViewportScrollLayerForTesting(); + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->pending_tree(), VERTICAL, 10, 0, false); + SetupScrollbarLayer(scroll, scrollbar); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(90, 0)); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); host_impl_->ActivateSyncTree(); LayerImpl* active_scrollbar_layer = - host_impl_->active_tree()->LayerById(400); + host_impl_->active_tree()->LayerById(scrollbar->id()); - EffectNode* active_tree_node = - host_impl_->active_tree()->property_trees()->effect_tree.Node( - active_scrollbar_layer->effect_tree_index()); + EffectNode* active_tree_node = GetEffectNode(active_scrollbar_layer); EXPECT_FLOAT_EQ(active_scrollbar_layer->Opacity(), active_tree_node->opacity); @@ -3933,22 +3738,23 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { InputHandler::WHEEL); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 5)).get()); host_impl_->ScrollEnd(EndState().get()); + CreatePendingTree(); // To test the case where the effect tree index of scrollbar layer changes, - // we force the container layer to create a render surface. - container = host_impl_->pending_tree()->InnerViewportContainerLayer(); - container->test_properties()->force_render_surface = true; - container->SetBounds(gfx::Size(10, 10)); - container->SetNeedsPushProperties(); - - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - + // we create an effect node with a render surface above the scrollbar's + // effect node. + auto* pending_root = host_impl_->pending_tree()->root_layer(); + auto& new_effect_node = CreateEffectNode( + GetPropertyTrees(pending_root), pending_root->effect_tree_index(), + pending_root->transform_tree_index(), pending_root->clip_tree_index()); + new_effect_node.render_surface_reason = RenderSurfaceReason::kTest; LayerImpl* pending_scrollbar_layer = - host_impl_->pending_tree()->LayerById(400); + host_impl_->pending_tree()->LayerById(scrollbar->id()); + GetEffectNode(pending_scrollbar_layer)->parent_id = new_effect_node.id; pending_scrollbar_layer->SetNeedsPushProperties(); - EffectNode* pending_tree_node = - host_impl_->pending_tree()->property_trees()->effect_tree.Node( - pending_scrollbar_layer->effect_tree_index()); + UpdateDrawProperties(host_impl_->pending_tree()); + + EffectNode* pending_tree_node = GetEffectNode(pending_scrollbar_layer); if (expecting_animations) { EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity); EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity()); @@ -3957,10 +3763,9 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { EXPECT_FLOAT_EQ(0.f, active_scrollbar_layer->Opacity()); } EXPECT_FLOAT_EQ(0.f, pending_tree_node->opacity); + host_impl_->ActivateSyncTree(); - active_tree_node = - host_impl_->active_tree()->property_trees()->effect_tree.Node( - active_scrollbar_layer->effect_tree_index()); + active_tree_node = GetEffectNode(active_scrollbar_layer); if (expecting_animations) { EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity); EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity()); @@ -3994,65 +3799,32 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest { gfx::Size scrollbar_size_1(gfx::Size(15, viewport_size.height())); gfx::Size scrollbar_size_2(gfx::Size(15, child_layer_size.height())); - const int scrollbar_1_id = 10; - const int scrollbar_2_id = 11; - const int child_scroll_id = 13; - CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + SetupViewportLayers(host_impl_->active_tree(), viewport_size, content_size, + content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); // scrollbar_1 on root scroll. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_1 = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_1_id, VERTICAL, 15, 0, - true, true); - scrollbar_1_ = scrollbar_1.get(); - scrollbar_1->SetScrollElementId(root_scroll->element_id()); - scrollbar_1->SetDrawsContent(true); - scrollbar_1->SetBounds(scrollbar_size_1); + scrollbar_1_ = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + SetupScrollbarLayer(root_scroll, scrollbar_1_); + scrollbar_1_->SetBounds(scrollbar_size_1); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1)); - scrollbar_1->SetTouchActionRegion(touch_action_region); - scrollbar_1->SetCurrentPos(0); - scrollbar_1->test_properties()->position = gfx::PointF(0, 0); - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar_1)); + scrollbar_1_->SetTouchActionRegion(touch_action_region); // scrollbar_2 on child. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_2 = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_2_id, VERTICAL, 15, 0, - true, true); - scrollbar_2_ = scrollbar_2.get(); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->test_properties()->position = gfx::PointF(50, 50); - child->SetBounds(child_layer_size); - child->SetDrawsContent(true); - child->SetHitTestable(true); - child->SetScrollable(gfx::Size(100, 100)); - child->SetHitTestable(true); - child->SetElementId(LayerIdToElementIdForTesting(child->id())); - ElementId child_element_id = child->element_id(); - - scrollbar_2->SetScrollElementId(child_element_id); - scrollbar_2->SetDrawsContent(true); - scrollbar_2->SetBounds(scrollbar_size_2); - scrollbar_2->SetCurrentPos(0); - scrollbar_2->test_properties()->position = gfx::PointF(0, 0); - - child->test_properties()->AddChild(std::move(scrollbar_2)); - root_scroll->test_properties()->AddChild(std::move(child)); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + auto* child = + AddScrollableLayer(root_scroll, gfx::Size(100, 100), child_layer_size); + GetTransformNode(child)->post_translation = gfx::Vector2dF(50, 50); + + scrollbar_2_ = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + SetupScrollbarLayer(child, scrollbar_2_); + scrollbar_2_->SetBounds(scrollbar_size_2); + + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->UpdateScrollbarGeometries(); host_impl_->active_tree()->DidBecomeActive(); @@ -4060,10 +3832,9 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest { } void ResetScrollbars() { - scrollbar_1_->test_properties()->opacity = 0.f; - scrollbar_2_->test_properties()->opacity = 0.f; - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetEffectNode(scrollbar_1_)->opacity = 0.f; + GetEffectNode(scrollbar_2_)->opacity = 0.f; + UpdateDrawProperties(host_impl_->active_tree()); if (is_aura_scrollbar_) animation_task_.Reset(); @@ -4149,66 +3920,32 @@ TEST_F(LayerTreeHostImplTest, ScrollHitTestOnScrollbar) { gfx::Size scrollbar_size_1(gfx::Size(15, viewport_size.height())); gfx::Size scrollbar_size_2(gfx::Size(15, child_layer_size.height())); - const int scrollbar_1_id = 10; - const int scrollbar_2_id = 11; - const int child_scroll_id = 13; - CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); // scrollbar_1 on root scroll. - std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar_1 = - PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_1_id, VERTICAL, true, true); - scrollbar_1->SetScrollElementId(root_scroll->element_id()); - scrollbar_1->SetDrawsContent(true); - scrollbar_1->SetHitTestable(true); + auto* scrollbar_1 = AddLayer<PaintedScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, true, true); + SetupScrollbarLayer(root_scroll, scrollbar_1); scrollbar_1->SetBounds(scrollbar_size_1); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1)); scrollbar_1->SetTouchActionRegion(touch_action_region); - scrollbar_1->SetCurrentPos(0); - scrollbar_1->test_properties()->position = gfx::PointF(0, 0); - scrollbar_1->test_properties()->opacity = 0.f; - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar_1)); - // scrollbar_2 on child. - std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar_2 = - PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_2_id, VERTICAL, true, true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->test_properties()->position = gfx::PointF(50, 50); - child->SetBounds(child_layer_size); - child->SetDrawsContent(true); - child->SetHitTestable(true); - child->SetScrollable(gfx::Size(100, 100)); - child->SetHitTestable(true); - child->SetElementId(LayerIdToElementIdForTesting(child->id())); - ElementId child_element_id = child->element_id(); + LayerImpl* child = + AddScrollableLayer(root_scroll, gfx::Size(100, 100), child_layer_size); + GetTransformNode(child)->post_translation = gfx::Vector2dF(50, 50); - scrollbar_2->SetScrollElementId(child_element_id); - scrollbar_2->SetDrawsContent(true); - scrollbar_2->SetHitTestable(true); + // scrollbar_2 on child. + auto* scrollbar_2 = AddLayer<PaintedScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, true, true); + SetupScrollbarLayer(child, scrollbar_2); scrollbar_2->SetBounds(scrollbar_size_2); - scrollbar_2->SetCurrentPos(0); - scrollbar_2->test_properties()->position = gfx::PointF(0, 0); - scrollbar_2->test_properties()->opacity = 0.f; - - child->test_properties()->AddChild(std::move(scrollbar_2)); - root_scroll->test_properties()->AddChild(std::move(child)); + scrollbar_2->SetOffsetToTransformParent(gfx::Vector2dF(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateScrollbarGeometries(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); // Wheel scroll on root scrollbar should process on impl thread. @@ -4251,26 +3988,21 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) { settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY; settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); CreateHostImpl(settings, CreateLayerTreeFrameSink()); CreatePendingTree(); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size); - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400, - VERTICAL, 10, 0, false, true); - scrollbar->test_properties()->opacity = 0.f; - LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer(); - LayerImpl* container = - host_impl_->pending_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollElementId(scroll->element_id()); - scrollbar->SetBounds(gfx::Size(10, 100)); - scrollbar->test_properties()->position = gfx::PointF(90, 0); - scrollbar->SetNeedsPushProperties(); - container->test_properties()->AddChild(std::move(scrollbar)); + SetupViewportLayers(host_impl_->pending_tree(), viewport_size, content_size, + content_size); + LayerImpl* scroll = + host_impl_->pending_tree()->OuterViewportScrollLayerForTesting(); + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->pending_tree(), VERTICAL, 10, 0, false); + SetupScrollbarLayer(scroll, scrollbar); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(90, 0)); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); host_impl_->ActivateSyncTree(); ScrollbarAnimationController* scrollbar_controller = @@ -4327,32 +4059,16 @@ TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) { gfx::Size inner_viewport_size(315, 200); gfx::Size outer_viewport_size(300, 200); gfx::Size content_size(1000, 1000); - - const int horiz_id = 11; - const int child_scroll_id = 15; - - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - inner_viewport_size); - host_impl_->active_tree()->InnerViewportScrollLayer()->SetScrollable( - inner_viewport_size); - host_impl_->active_tree()->OuterViewportContainerLayer()->SetBounds( - outer_viewport_size); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetScrollable( - outer_viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); - std::unique_ptr<PaintedScrollbarLayerImpl> horiz_scrollbar = - PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), horiz_id, - HORIZONTAL, true, true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size, + outer_viewport_size, content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); + auto* horiz_scrollbar = AddLayer<PaintedScrollbarLayerImpl>( + host_impl_->active_tree(), HORIZONTAL, true, true); + SetupScrollbarLayer(root_scroll, horiz_scrollbar); + LayerImpl* child = AddLayer(); child->SetBounds(content_size); child->SetBounds(inner_viewport_size); - horiz_scrollbar->SetScrollElementId(root_scroll->element_id()); - - host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl_->active_tree()->UpdateScrollbarGeometries(); EXPECT_EQ(300, horiz_scrollbar->clip_layer_length()); @@ -4368,45 +4084,27 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { gfx::Size viewport_size(300, 200); gfx::Size content_size(1000, 1000); - const int vert_1_id = 10; - const int horiz_1_id = 11; - const int vert_2_id = 12; - const int horiz_2_id = 13; - const int child_scroll_id = 15; - - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - LayerImpl* container = - host_impl_->active_tree()->InnerViewportContainerLayer(); - container->SetBounds(viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), vert_1_id, VERTICAL, 5, 5, true, true)); - auto* vert_1_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[1]); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), horiz_1_id, HORIZONTAL, 5, 5, true, true)); - auto* horiz_1_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[2]); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), vert_2_id, VERTICAL, 5, 5, true, true)); - auto* vert_2_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[3]); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), horiz_2_id, HORIZONTAL, 5, 5, true, true)); - auto* horiz_2_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[4]); - - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->SetBounds(viewport_size); - LayerImpl* child_ptr = child.get(); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + + auto* container = InnerViewportScrollLayer(); + auto* root_scroll = OuterViewportScrollLayer(); + auto* vert_1_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 5, 5, true); + CopyProperties(container, vert_1_scrollbar); + + auto* horiz_1_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), HORIZONTAL, 5, 5, true); + CopyProperties(container, horiz_1_scrollbar); + + auto* vert_2_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 5, 5, true); + CopyProperties(container, vert_2_scrollbar); + + auto* horiz_2_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), HORIZONTAL, 5, 5, true); + CopyProperties(container, horiz_2_scrollbar); + + UpdateDrawProperties(host_impl_->active_tree()); // Check scrollbar registration on the viewport layers. EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); @@ -4430,11 +4128,9 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { animation_task_.Reset(); // Check scrollbar registration on a sublayer. - child->SetScrollable(viewport_size); - child->SetHitTestable(true); - child->SetElementId(LayerIdToElementIdForTesting(child->id())); + LayerImpl* child = + AddScrollableLayer(root_scroll, viewport_size, gfx::Size(200, 200)); ElementId child_scroll_element_id = child->element_id(); - root_scroll->test_properties()->AddChild(std::move(child)); EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( child_scroll_element_id)); @@ -4450,39 +4146,21 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { // Changing one of the child layers should result in a scrollbar animation // update. animation_task_.Reset(); - child_ptr->SetBounds(gfx::Size(200, 200)); - child_ptr->set_needs_show_scrollbars(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + child->set_needs_show_scrollbars(true); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain(); EXPECT_FALSE(animation_task_.is_null()); animation_task_.Reset(); // Check scrollbar unregistration. - container->test_properties()->RemoveChild(vert_1_scrollbar); - EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForElementId( - root_scroll->element_id())); - container->test_properties()->RemoveChild(horiz_1_scrollbar); - EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); + ElementId root_scroll_element_id = root_scroll->element_id(); + host_impl_->active_tree()->DetachLayers(); + EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll_element_id).size()); EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( - root_scroll->element_id())); - - EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); - container->test_properties()->RemoveChild(vert_2_scrollbar); - EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForElementId( - child_scroll_element_id)); - container->test_properties()->RemoveChild(horiz_2_scrollbar); + root_scroll_element_id)); EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( - root_scroll->element_id())); - - // Changing scroll offset should no longer trigger any animation. - host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset( - gfx::ScrollOffset(20, 20)); - EXPECT_TRUE(animation_task_.is_null()); - child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(20, 20)); - EXPECT_TRUE(animation_task_.is_null()); + root_scroll_element_id)); } TEST_F(LayerTreeHostImplTest, ScrollBeforeMouseMove) { @@ -4495,23 +4173,15 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeMouseMove) { gfx::Size viewport_size(300, 200); gfx::Size content_size(1000, 1000); - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - auto* container = host_impl_->active_tree()->InnerViewportContainerLayer(); - container->SetBounds(viewport_size); - auto* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), 10, VERTICAL, 5, 0, false, true)); - auto* vert_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[1]); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + auto* root_scroll = OuterViewportScrollLayer(); - vert_scrollbar->SetScrollElementId(root_scroll->element_id()); + auto* vert_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 5, 0, false); + SetupScrollbarLayer(root_scroll, vert_scrollbar); vert_scrollbar->SetBounds(gfx::Size(10, 200)); - vert_scrollbar->test_properties()->position = gfx::PointF(300, 0); - vert_scrollbar->test_properties()->opacity_can_animate = true; - vert_scrollbar->SetCurrentPos(0); + vert_scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(300, 0)); - host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl_->active_tree()->UpdateScrollbarGeometries(); EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); @@ -4559,40 +4229,24 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY; gfx::Size viewport_size(300, 200); - gfx::Size device_viewport_size = - gfx::ScaleToFlooredSize(viewport_size, device_scale_factor); gfx::Size content_size(1000, 1000); gfx::Size scrollbar_size(gfx::Size(15, viewport_size.height())); CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(device_viewport_size)); - - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); // The scrollbar is on the left side. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 6, - VERTICAL, 15, 0, true, true); - scrollbar->SetScrollElementId(root_scroll->element_id()); - scrollbar->SetDrawsContent(true); + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + SetupScrollbarLayer(root_scroll, scrollbar); scrollbar->SetBounds(scrollbar_size); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size)); scrollbar->SetTouchActionRegion(touch_action_region); - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); - host_impl_->active_tree()->UpdateDrawProperties(); ScrollbarAnimationController* scrollbar_animation_controller = host_impl_->ScrollbarAnimationControllerForElementId( @@ -4649,9 +4303,8 @@ TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) { // that are different are included in viz::CompositorFrameMetadata's // |activation_dependencies|. TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + LayerImpl* root = root_layer(); std::vector<viz::SurfaceId> primary_surfaces = { MakeSurfaceId(viz::FrameSinkId(1, 1), 1), @@ -4664,14 +4317,13 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { MakeSurfaceId(viz::FrameSinkId(4, 4), 3)}; for (size_t i = 0; i < primary_surfaces.size(); ++i) { - std::unique_ptr<SurfaceLayerImpl> child = - SurfaceLayerImpl::Create(host_impl_->active_tree(), i + 6); - child->test_properties()->position = gfx::PointF(25.f * i, 0.f); + auto* child = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); child->SetRange( viz::SurfaceRange(fallback_surfaces[i], primary_surfaces[i]), 2u); - root->test_properties()->AddChild(std::move(child)); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(25.f * i, 0.f)); } base::flat_set<viz::SurfaceRange> surfaces_set; @@ -4681,7 +4333,6 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { viz::SurfaceRange(fallback_surfaces[i], primary_surfaces[i])); } - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->SetSurfaceRanges(std::move(surfaces_set)); host_impl_->SetFullViewportDamage(); DrawFrame(); @@ -4706,7 +4357,6 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { // Verify that on the next frame generation that the deadline is reset. host_impl_->SetFullViewportDamage(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); { @@ -4732,13 +4382,11 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { // causes a new CompositorFrame to be submitted, even if there is no other // damage. TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); auto* fake_layer_tree_frame_sink = static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); // Submit an initial CompositorFrame with an empty set of referenced surfaces. - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->SetSurfaceRanges({}); host_impl_->SetFullViewportDamage(); DrawFrame(); @@ -4754,7 +4402,6 @@ TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) { // Update the set of referenced surfaces to contain |surface_id| but don't // make any other changes that would cause damage. This mimics updating the // SurfaceLayer for an offscreen tab. - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->SetSurfaceRanges({viz::SurfaceRange(surface_id)}); DrawFrame(); @@ -4767,8 +4414,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) { } TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); { @@ -4831,7 +4477,8 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { class DidDrawCheckLayer : public LayerImpl { public: - static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { + static std::unique_ptr<DidDrawCheckLayer> Create(LayerTreeImpl* tree_impl, + int id) { return base::WrapUnique(new DidDrawCheckLayer(tree_impl, id)); } @@ -4868,11 +4515,6 @@ class DidDrawCheckLayer : public LayerImpl { did_draw_called_ = false; } - void AddCopyRequest() { - test_properties()->copy_requests.push_back( - viz::CopyOutputRequest::CreateStubForTesting()); - } - protected: DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id) : LayerImpl(tree_impl, id), @@ -4893,22 +4535,17 @@ class DidDrawCheckLayer : public LayerImpl { }; TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) { - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); // Make a child layer that draws. - root->test_properties()->AddChild( - SolidColorLayerImpl::Create(host_impl_->active_tree(), 2)); - auto* layer = - static_cast<SolidColorLayerImpl*>(root->test_properties()->children[0]); + auto* layer = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree()); layer->SetBounds(gfx::Size(10, 10)); layer->SetDrawsContent(true); layer->SetBackgroundColor(SK_ColorRED); + CopyProperties(root, layer); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); { TestFrameData frame; @@ -4927,9 +4564,9 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) { // Stops the child layer from drawing. We should have damage from this but // should not have any quads. This should clear the damaged area. layer->SetDrawsContent(false); - root->test_properties()->opacity = 0.f; + GetEffectNode(root)->opacity = 0.f; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // The background is default to transparent. If the background is opaque, we // would fill the frame with background colour when no layers are contributing // quads. This means we would end up with 0 quad. @@ -4969,73 +4606,43 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) { TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) { // The root layer is always drawn, so run this test on a child layer that // will be masked out by the root layer's bounds. - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - root->test_properties()->force_render_surface = true; - auto* layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + auto* layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); + CopyProperties(root, layer); - { - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); - - EXPECT_TRUE(layer->will_draw_returned_true()); - EXPECT_TRUE(layer->append_quads_called()); - EXPECT_TRUE(layer->did_draw_called()); - } + DrawFrame(); + EXPECT_TRUE(layer->will_draw_returned_true()); + EXPECT_TRUE(layer->append_quads_called()); + EXPECT_TRUE(layer->did_draw_called()); host_impl_->SetViewportDamage(gfx::Rect(10, 10)); - { - TestFrameData frame; - - layer->set_will_draw_returns_false(); - layer->ClearDidDrawCheck(); - - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); - - EXPECT_FALSE(layer->will_draw_returned_true()); - EXPECT_FALSE(layer->append_quads_called()); - EXPECT_FALSE(layer->did_draw_called()); - } + layer->set_will_draw_returns_false(); + layer->ClearDidDrawCheck(); + DrawFrame(); + EXPECT_FALSE(layer->will_draw_returned_true()); + EXPECT_FALSE(layer->append_quads_called()); + EXPECT_FALSE(layer->did_draw_called()); } TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { // The root layer is always drawn, so run this test on a child layer that // will be masked out by the root layer's bounds. - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - root->SetMasksToBounds(true); - root->test_properties()->force_render_surface = true; - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - auto* layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); - // Ensure visible_layer_rect for layer is empty. - layer->test_properties()->position = gfx::PointF(100.f, 100.f); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + CreateClipNode(root); + auto* layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); layer->SetBounds(gfx::Size(10, 10)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - TestFrameData frame; + CopyProperties(root, layer); + // Ensure visible_layer_rect for layer is not empty + layer->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(layer->will_draw_returned_true()); EXPECT_FALSE(layer->did_draw_called()); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_FALSE(layer->will_draw_returned_true()); EXPECT_FALSE(layer->did_draw_called()); @@ -5043,16 +4650,14 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { EXPECT_TRUE(layer->visible_layer_rect().IsEmpty()); // Ensure visible_layer_rect for layer is not empty - layer->test_properties()->position = gfx::PointF(); + layer->SetOffsetToTransformParent(gfx::Vector2dF()); layer->NoteLayerPropertyChanged(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(layer->will_draw_returned_true()); EXPECT_FALSE(layer->did_draw_called()); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_TRUE(layer->will_draw_returned_true()); EXPECT_TRUE(layer->did_draw_called()); @@ -5062,39 +4667,25 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { gfx::Size big_size(1000, 1000); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(big_size)); - - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - auto* occluded_layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); - - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); - root->test_properties()->force_render_surface = true; - auto* top_layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[1]); + SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), big_size); + + auto* occluded_layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); + CopyProperties(root, occluded_layer); + auto* top_layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); // This layer covers the occluded_layer above. Make this layer large so it can // occlude. top_layer->SetBounds(big_size); top_layer->SetContentsOpaque(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - TestFrameData frame; + CopyProperties(occluded_layer, top_layer); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(occluded_layer->will_draw_returned_true()); EXPECT_FALSE(occluded_layer->did_draw_called()); EXPECT_FALSE(top_layer->will_draw_returned_true()); EXPECT_FALSE(top_layer->did_draw_called()); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_FALSE(occluded_layer->will_draw_returned_true()); EXPECT_FALSE(occluded_layer->did_draw_called()); @@ -5103,34 +4694,23 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { } TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + auto* layer1 = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); + auto* layer2 = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - root->test_properties()->force_render_surface = true; - auto* layer1 = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); + CopyProperties(root, layer1); + CreateTransformNode(layer1).flattens_inherited_transform = true; + CreateEffectNode(layer1).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(layer1, layer2); - layer1->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); - auto* layer2 = - static_cast<DidDrawCheckLayer*>(layer1->test_properties()->children[0]); - - layer1->test_properties()->force_render_surface = true; - layer1->test_properties()->should_flatten_transform = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(root->did_draw_called()); EXPECT_FALSE(layer1->did_draw_called()); EXPECT_FALSE(layer2->did_draw_called()); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_TRUE(root->did_draw_called()); EXPECT_TRUE(layer1->did_draw_called()); @@ -5142,7 +4722,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { class MissingTextureAnimatingLayer : public DidDrawCheckLayer { public: - static std::unique_ptr<LayerImpl> Create( + static std::unique_ptr<MissingTextureAnimatingLayer> Create( LayerTreeImpl* tree_impl, int id, bool tile_missing, @@ -5191,7 +4771,6 @@ struct PrepareToDrawSuccessTestCase { bool has_missing_tile = false; bool has_incomplete_tile = false; bool is_animating = false; - bool has_copy_request = false; }; bool high_res_required = false; @@ -5201,24 +4780,26 @@ struct PrepareToDrawSuccessTestCase { DrawResult expected_result; }; -static void CreateLayerFromState( - DidDrawCheckLayer* root, - const scoped_refptr<AnimationTimeline>& timeline, - const PrepareToDrawSuccessTestCase::State& state) { - static int layer_id = 2; - root->test_properties()->AddChild(MissingTextureAnimatingLayer::Create( - root->layer_tree_impl(), layer_id++, state.has_missing_tile, - state.has_incomplete_tile, state.is_animating, timeline)); - auto* layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); - if (state.has_copy_request) - layer->AddCopyRequest(); -} +class LayerTreeHostImplPrepareToDrawTest : public LayerTreeHostImplTest { + public: + void CreateLayerFromState(DidDrawCheckLayer* root, + const scoped_refptr<AnimationTimeline>& timeline, + const PrepareToDrawSuccessTestCase::State& state) { + auto* layer = AddLayer<MissingTextureAnimatingLayer>( + root->layer_tree_impl(), state.has_missing_tile, + state.has_incomplete_tile, state.is_animating, timeline); + CopyProperties(root, layer); + if (state.is_animating) + CreateTransformNode(layer).has_potential_animation = true; + } +}; -TEST_F(CommitToPendingTreeLayerTreeHostImplTest, - PrepareToDrawSucceedsAndFails) { - std::vector<PrepareToDrawSuccessTestCase> cases; +TEST_F(LayerTreeHostImplPrepareToDrawTest, PrepareToDrawSucceedsAndFails) { + LayerTreeSettings settings = DefaultSettings(); + settings.commit_to_active_tree = false; + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + std::vector<PrepareToDrawSuccessTestCase> cases; // 0. Default case. cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS)); // 1. Animated layer first. @@ -5287,28 +4868,16 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, cases.back().layer_before.has_missing_tile = true; cases.back().layer_before.is_animating = true; - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); - { - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); - } + DrawFrame(); for (size_t i = 0; i < cases.size(); ++i) { // Clean up host_impl_ state. const auto& testcase = cases[i]; - std::vector<LayerImpl*> to_remove; - for (auto* child : root->test_properties()->children) - to_remove.push_back(child); - for (auto* child : to_remove) - root->test_properties()->RemoveChild(child); + host_impl_->active_tree()->DetachLayersKeepingRootLayerForTesting(); timeline()->ClearAnimations(); std::ostringstream scope; @@ -5318,7 +4887,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CreateLayerFromState(root, timeline(), testcase.layer_before); CreateLayerFromState(root, timeline(), testcase.layer_between); CreateLayerFromState(root, timeline(), testcase.layer_after); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); if (testcase.high_res_required) host_impl_->SetRequiresHighResToDraw(); @@ -5330,7 +4899,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, } } -TEST_F(LayerTreeHostImplTest, +TEST_F(LayerTreeHostImplPrepareToDrawTest, PrepareToDrawWhenDrawAndSwapFullViewportEveryFrame) { CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::CreateSoftware()); @@ -5357,23 +4926,16 @@ TEST_F(LayerTreeHostImplTest, cases.back().high_res_required = true; cases.back().layer_between.has_missing_tile = true; - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = static_cast<DidDrawCheckLayer*>( - host_impl_->active_tree()->root_layer_for_testing()); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->OnDraw(external_transform, external_viewport, resourceless_software_draw, false); for (size_t i = 0; i < cases.size(); ++i) { const auto& testcase = cases[i]; - std::vector<LayerImpl*> to_remove; - for (auto* child : root->test_properties()->children) - to_remove.push_back(child); - for (auto* child : to_remove) - root->test_properties()->RemoveChild(child); + host_impl_->active_tree()->DetachLayersKeepingRootLayerForTesting(); std::ostringstream scope; scope << "Test case: " << i; @@ -5382,7 +4944,6 @@ TEST_F(LayerTreeHostImplTest, CreateLayerFromState(root, timeline(), testcase.layer_before); CreateLayerFromState(root, timeline(), testcase.layer_between); CreateLayerFromState(root, timeline(), testcase.layer_after); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); if (testcase.high_res_required) host_impl_->SetRequiresHighResToDraw(); @@ -5393,12 +4954,7 @@ TEST_F(LayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupDefaultRootLayer(gfx::Size(10, 10)); DrawFrame(); // Scroll event is ignored because layer is not scrollable. @@ -5414,17 +4970,15 @@ TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { TEST_F(LayerTreeHostImplTest, ClampingAfterActivation) { CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), - gfx::Size(100, 100)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50), + gfx::Size(100, 100), gfx::Size(100, 100)); host_impl_->ActivateSyncTree(); CreatePendingTree(); const gfx::ScrollOffset pending_scroll = gfx::ScrollOffset(-100, -100); - LayerImpl* active_outer_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* active_outer_layer = OuterViewportScrollLayer(); LayerImpl* pending_outer_layer = - host_impl_->pending_tree()->OuterViewportScrollLayer(); + host_impl_->pending_tree()->OuterViewportScrollLayerForTesting(); pending_outer_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( @@ -5440,9 +4994,7 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { LayerTreeHostImplBrowserControlsTest() // Make the clip size the same as the layer (content) size so the layer is // non-scrollable. - : layer_size_(10, 10), - clip_size_(layer_size_), - top_controls_height_(50) { + : layer_size_(10, 10), clip_size_(layer_size_), top_controls_height_(50) { viewport_size_ = gfx::Size(clip_size_.width(), clip_size_.height() + top_controls_height_); } @@ -5460,30 +5012,29 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { return init; } + protected: void SetupBrowserControlsAndScrollLayerWithVirtualViewport( const gfx::Size& inner_viewport_size, const gfx::Size& outer_viewport_size, - const gfx::Size& scroll_layer_size, - base::OnceCallback<void(LayerTreeSettings*)> modify_settings = - base::DoNothing()) { - settings_ = DefaultSettings(); - settings_.use_layer_lists = true; - std::move(modify_settings).Run(&settings_); - CreateHostImpl(settings_, CreateLayerTreeFrameSink()); + const gfx::Size& scroll_layer_size) { SetupBrowserControlsAndScrollLayerWithVirtualViewport( host_impl_->active_tree(), inner_viewport_size, outer_viewport_size, scroll_layer_size); } - protected: void SetupBrowserControlsAndScrollLayerWithVirtualViewport( LayerTreeImpl* tree_impl, const gfx::Size& inner_viewport_size, const gfx::Size& outer_viewport_size, const gfx::Size& scroll_layer_size) { - LayerTestCommon::SetupBrowserControlsAndScrollLayerWithVirtualViewport( - host_impl_.get(), tree_impl, top_controls_height_, inner_viewport_size, - outer_viewport_size, scroll_layer_size); + tree_impl->set_browser_controls_shrink_blink_size(true); + tree_impl->SetTopControlsHeight(top_controls_height_); + tree_impl->SetCurrentBrowserControlsShownRatio(1.f); + tree_impl->PushPageScaleFromMainThread(1.f, 1.f, 1.f); + host_impl_->DidChangeBrowserControlsPosition(); + + SetupViewportLayers(tree_impl, inner_viewport_size, outer_viewport_size, + scroll_layer_size); } gfx::Size layer_size_; @@ -5494,6 +5045,30 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { LayerTreeSettings settings_; }; // class LayerTreeHostImplBrowserControlsTest +#define EXPECT_VIEWPORT_GEOMETRIES(expected_browser_controls_shown_ratio) \ + do { \ + auto* tree = host_impl_->active_tree(); \ + auto* property_trees = tree->property_trees(); \ + EXPECT_EQ(expected_browser_controls_shown_ratio, \ + tree->CurrentBrowserControlsShownRatio()); \ + EXPECT_EQ( \ + tree->top_controls_height() * expected_browser_controls_shown_ratio, \ + host_impl_->browser_controls_manager()->ContentTopOffset()); \ + int delta = \ + (tree->top_controls_height() + tree->bottom_controls_height()) * \ + (1 - expected_browser_controls_shown_ratio); \ + int scaled_delta = delta / tree->min_page_scale_factor(); \ + gfx::Size inner_scroll_bounds = tree->InnerViewportScrollNode()->bounds; \ + inner_scroll_bounds.Enlarge(0, scaled_delta); \ + EXPECT_EQ(inner_scroll_bounds, InnerViewportScrollLayer()->bounds()); \ + EXPECT_EQ(gfx::RectF(gfx::SizeF(inner_scroll_bounds)), \ + tree->OuterViewportClipNode()->clip); \ + EXPECT_EQ(gfx::Vector2dF(0, delta), \ + property_trees->inner_viewport_container_bounds_delta()); \ + EXPECT_EQ(gfx::Vector2dF(0, scaled_delta), \ + property_trees->outer_viewport_container_bounds_delta()); \ + } while (false) + // Tests that, on a page with content the same size as the viewport, hiding // the browser controls also increases the ScrollableSize (i.e. the content // size). Since the viewport got larger, the effective scrollable "content" also @@ -5505,26 +5080,11 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, gfx::Size(50, 50), gfx::Size(50, 50), gfx::Size(50, 50)); LayerTreeImpl* active_tree = host_impl_->active_tree(); - - // Create a content layer beneath the outer viewport scroll layer. - int id = host_impl_->OuterViewportScrollLayer()->id(); - host_impl_->OuterViewportScrollLayer()->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), id + 2)); - LayerImpl* content = - active_tree->OuterViewportScrollLayer()->test_properties()->children[0]; - content->SetBounds(gfx::Size(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawFrame(); - LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); - LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); - // The browser controls should start off showing so the viewport should be // shrunk. - ASSERT_EQ(gfx::Size(50, 50), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 50), outer_container->bounds()); - + EXPECT_VIEWPORT_GEOMETRIES(1); EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -5537,31 +5097,19 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // Hide the browser controls by a bit, the scrollable size should increase but // the actual content bounds shouldn't. - { - host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); - ASSERT_EQ(gfx::Size(50, 75), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 75), outer_container->bounds()); - EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize()); - EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling()); - } + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + EXPECT_VIEWPORT_GEOMETRIES(0.5f); + EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize()); // Fully hide the browser controls. - { - host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); - ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); - EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); - EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling()); - } + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + EXPECT_VIEWPORT_GEOMETRIES(0); + EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); // Scrolling additionally shouldn't have any effect. - { - host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); - ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); - EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); - EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling()); - } + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + EXPECT_VIEWPORT_GEOMETRIES(0); + EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); host_impl_->browser_controls_manager()->ScrollEnd(); host_impl_->ScrollEnd(EndState().get()); @@ -5582,31 +5130,17 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, LayerTreeImpl* active_tree = host_impl_->active_tree(); // Create a content layer beneath the outer viewport scroll layer. - int id = host_impl_->OuterViewportScrollLayer()->id(); - host_impl_->OuterViewportScrollLayer()->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), id + 2)); - LayerImpl* content = - active_tree->OuterViewportScrollLayer()->test_properties()->children[0]; + LayerImpl* content = AddLayer(); content->SetBounds(gfx::Size(100, 100)); - host_impl_->active_tree()->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(OuterViewportScrollLayer(), content); + active_tree->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f); DrawFrame(); - LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); - LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); - LayerImpl* outer_scroll = active_tree->OuterViewportScrollLayer(); - auto* property_trees = host_impl_->active_tree()->property_trees(); - ClipNode* outer_clip_node = - property_trees->clip_tree.Node(outer_scroll->clip_tree_index()); - // The browser controls should start off showing so the viewport should be // shrunk. - ASSERT_EQ(50, host_impl_->browser_controls_manager()->ContentTopOffset()); - ASSERT_EQ(gfx::Size(100, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(100, 100), outer_container->bounds()); - ASSERT_EQ(gfx::SizeF(200, 1000), active_tree->ScrollableSize()); - ASSERT_EQ(gfx::SizeF(100, 100), outer_clip_node->clip.size()); + EXPECT_VIEWPORT_GEOMETRIES(1.0f); + EXPECT_EQ(gfx::SizeF(200, 1000), active_tree->ScrollableSize()); ASSERT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -5614,16 +5148,13 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, InputHandler::TOUCHSCREEN) .thread); - // Hide the browser controls by 10px. The outer clip should expand by 20px as + // Hide the browser controls by 25px. The outer clip should expand by 50px as // because the outer viewport is sized based on the minimum scale, in this // case 0.5. Therefore, changes to the outer viewport need to be divided by // the minimum scale as well. - { - host_impl_->ScrollBy( - UpdateState(gfx::Point(0, 0), gfx::Vector2dF(0.f, 10.f)).get()); - ASSERT_EQ(40, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_EQ(gfx::SizeF(100, 120), outer_clip_node->clip.size()); - } + host_impl_->ScrollBy( + UpdateState(gfx::Point(0, 0), gfx::Vector2dF(0.f, 25.f)).get()); + EXPECT_VIEWPORT_GEOMETRIES(0.5f); host_impl_->ScrollEnd(EndState().get()); } @@ -5637,39 +5168,23 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, LayerTreeImpl* active_tree = host_impl_->active_tree(); // Create a horizontal scrollbar. - const int scrollbar_id = 23; gfx::Size scrollbar_size(gfx::Size(50, 15)); - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_id, HORIZONTAL, 3, 20, - false, true); - scrollbar->SetScrollElementId( - host_impl_->OuterViewportScrollLayer()->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->SetBounds(scrollbar_size); + auto* scrollbar_layer = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), HORIZONTAL, 3, 20, false); + SetupScrollbarLayer(OuterViewportScrollLayer(), scrollbar_layer); + scrollbar_layer->SetBounds(scrollbar_size); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size)); - scrollbar->SetTouchActionRegion(touch_action_region); - scrollbar->SetCurrentPos(0); - scrollbar->test_properties()->position = gfx::PointF(0, 35); - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + scrollbar_layer->SetTouchActionRegion(touch_action_region); + scrollbar_layer->SetOffsetToTransformParent(gfx::Vector2dF(0, 35)); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->UpdateScrollbarGeometries(); DrawFrame(); - LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); - LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); - auto* scrollbar_layer = static_cast<SolidColorScrollbarLayerImpl*>( - active_tree->LayerById(scrollbar_id)); - // The browser controls should start off showing so the viewport should be // shrunk. - EXPECT_EQ(gfx::Size(50, 50), inner_container->bounds()); - EXPECT_EQ(gfx::Size(50, 50), outer_container->bounds()); + EXPECT_VIEWPORT_GEOMETRIES(1.0f); EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize()); EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); EXPECT_EQ(gfx::Rect(20, 0, 10, 3), scrollbar_layer->ComputeThumbQuadRect()); @@ -5687,8 +5202,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, { host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); host_impl_->active_tree()->UpdateScrollbarGeometries(); - ASSERT_EQ(gfx::Size(50, 75), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 75), outer_container->bounds()); + EXPECT_VIEWPORT_GEOMETRIES(0.5f); EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize()); EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); EXPECT_EQ(gfx::Rect(20, 25, 10, 3), @@ -5699,8 +5213,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, { host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); host_impl_->active_tree()->UpdateScrollbarGeometries(); - ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); + EXPECT_VIEWPORT_GEOMETRIES(0); EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); EXPECT_EQ(gfx::Rect(20, 50, 10, 3), @@ -5710,8 +5223,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // Additional scrolling shouldn't have any effect. { host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); - ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); + EXPECT_VIEWPORT_GEOMETRIES(0); EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); EXPECT_EQ(gfx::Rect(20, 50, 10, 3), @@ -5758,16 +5270,10 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100)); DrawFrame(); - LayerImpl* inner_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); inner_scroll->SetDrawsContent(true); - LayerImpl* inner_container = - host_impl_->active_tree()->InnerViewportContainerLayer(); - LayerImpl* outer_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); outer_scroll->SetDrawsContent(true); - LayerImpl* outer_container = - host_impl_->active_tree()->OuterViewportContainerLayer(); // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer. outer_scroll->SetDrawsContent(true); @@ -5785,8 +5291,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // The viewport layers should be resized back to their full sizes. EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y()); - EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height()); - EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height()); + EXPECT_EQ(100, inner_scroll->bounds().height()); + EXPECT_EQ(100, outer_scroll->bounds().height()); // The inner viewport should be scrollable by 50px * page_scale. host_impl_->ScrollBy( @@ -5812,8 +5318,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // The outer viewport should be resized to accomodate and scrolled to the // bottom of the document to keep the viewport in place. EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height()); - EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height()); + EXPECT_EQ(50, inner_scroll->bounds().height()); + EXPECT_EQ(100, outer_scroll->bounds().height()); EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y()); EXPECT_EQ(25.f, inner_scroll->CurrentScrollOffset().y()); @@ -5899,11 +5405,9 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsPushUnsentRatio) { DrawFrame(); // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer. - LayerImpl* inner_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); inner_scroll->SetDrawsContent(true); - LayerImpl* outer_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); outer_scroll->SetDrawsContent(true); host_impl_->active_tree()->PushBrowserControlsFromMainThread(1); @@ -5932,26 +5436,22 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // Show browser controls EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - LayerImpl* outer_viewport_scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - int id = outer_viewport_scroll_layer->id(); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), id + 2); + LayerImpl* outer_viewport_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* child = AddLayer(); child->SetScrollable(sub_content_layer_size); child->SetHitTestable(true); child->SetElementId(LayerIdToElementIdForTesting(child->id())); child->SetBounds(sub_content_size); - child->test_properties()->position = gfx::PointF(); child->SetDrawsContent(true); - child->test_properties()->is_container_for_fixed_position_layers = true; - LayerImpl* child_ptr = child.get(); - outer_viewport_scroll_layer->test_properties()->AddChild(std::move(child)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(outer_viewport_scroll_layer, child); + CreateTransformNode(child); + CreateScrollNode(child); + UpdateDrawProperties(host_impl_->active_tree()); // Scroll child to the limit. - SetScrollOffsetDelta(child_ptr, gfx::Vector2dF(0, 100.f)); + SetScrollOffsetDelta(child, gfx::Vector2dF(0, 100.f)); // Scroll 25px to hide browser controls gfx::Vector2dF scroll_delta(0.f, 25.f); @@ -5995,12 +5495,9 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->DidChangeBrowserControlsPosition(); - // Now that browser controls have moved, expect the clip to resize. - LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0, 50), + property_trees->inner_viewport_container_bounds_delta()); } // Ensure setting the browser controls position explicitly using the setters on @@ -6069,22 +5566,16 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, ApplyDeltaOnTreeActivation) { 15.f / top_controls_height_); host_impl_->DidChangeBrowserControlsPosition(); - LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0.f, 50.f), + property_trees->inner_viewport_container_bounds_delta()); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); host_impl_->ActivateSyncTree(); - inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); - + EXPECT_EQ(gfx::Vector2dF(0.f, 50.f), + property_trees->inner_viewport_container_bounds_delta()); EXPECT_FLOAT_EQ( -15.f, host_impl_->active_tree()->top_controls_shown_ratio()->Delta() * top_controls_height_); @@ -6112,31 +5603,20 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f); host_impl_->DidChangeBrowserControlsPosition(); - LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0, 50), + property_trees->inner_viewport_container_bounds_delta()); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); - host_impl_->sync_tree()->root_layer_for_testing()->SetBounds( - gfx::Size(inner_clip_ptr->bounds().width(), - inner_clip_ptr->bounds().height() - 50.f)); - host_impl_->ActivateSyncTree(); - inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); // The total bounds should remain unchanged since the bounds delta should // account for the difference between the layout height and the current // browser controls offset. - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); - EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), - inner_clip_ptr->ViewportBoundsDelta()); + EXPECT_EQ(gfx::Vector2dF(0, 50), + property_trees->inner_viewport_container_bounds_delta()); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); host_impl_->DidChangeBrowserControlsPosition(); @@ -6145,10 +5625,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->browser_controls_manager()->TopControlsShownRatio()); EXPECT_EQ(50.f, host_impl_->browser_controls_manager()->TopControlsHeight()); EXPECT_EQ(50.f, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), - inner_clip_ptr->ViewportBoundsDelta()); - EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() - 50.f), - inner_clip_ptr->bounds()); + EXPECT_EQ(gfx::Vector2dF(), + property_trees->inner_viewport_container_bounds_delta()); } // Test that showing/hiding the browser controls when the viewport is fully @@ -6162,8 +5640,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); // Scroll the viewports to max scroll offset. SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200.f)); @@ -6250,21 +5728,14 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsAspectRatio) { // Browser controls were hidden by 25px so the inner viewport should have // expanded by that much. - LayerImpl* outer_container = - host_impl_->active_tree()->OuterViewportContainerLayer(); - LayerImpl* inner_container = - host_impl_->active_tree()->InnerViewportContainerLayer(); - EXPECT_EQ(gfx::SizeF(100.f, 100.f + 25.f), - inner_container->BoundsForScrolling()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0, 25), + property_trees->inner_viewport_container_bounds_delta()); // Outer viewport should match inner's aspect ratio. The bounds are ceiled. - float aspect_ratio = inner_container->BoundsForScrolling().width() / - inner_container->BoundsForScrolling().height(); - gfx::SizeF expected = - gfx::SizeF(gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio))); - EXPECT_EQ(expected, outer_container->BoundsForScrolling()); - EXPECT_EQ(expected, - host_impl_->InnerViewportScrollLayer()->BoundsForScrolling()); + float aspect_ratio = 100.0f / 125.0f; + auto expected = gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio)); + EXPECT_EQ(expected, InnerViewportScrollLayer()->bounds()); } // Test that scrolling the outer viewport affects the browser controls. @@ -6287,7 +5758,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); - EXPECT_EQ(host_impl_->OuterViewportScrollLayer()->scroll_tree_index(), + EXPECT_EQ(OuterViewportScrollLayer()->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); host_impl_->ScrollEnd(EndState().get()); @@ -6305,17 +5776,15 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_EQ(host_impl_->OuterViewportScrollLayer()->scroll_tree_index(), + EXPECT_EQ(OuterViewportScrollLayer()->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); host_impl_->ScrollEnd(EndState().get()); // Position the viewports such that the inner viewport will be scrolled. gfx::Vector2dF inner_viewport_offset(0.f, 25.f); - SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), - gfx::Vector2dF()); - SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), - inner_viewport_offset); + SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2dF()); + SetScrollOffsetDelta(InnerViewportScrollLayer(), inner_viewport_offset); scroll_delta = gfx::Vector2dF(0.f, -65.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -6329,7 +5798,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_FLOAT_EQ( inner_viewport_offset.y() + (scroll_delta.y() + top_controls_height_), - ScrollDelta(host_impl_->InnerViewportScrollLayer()).y()); + ScrollDelta(InnerViewportScrollLayer()).y()); host_impl_->ScrollEnd(EndState().get()); } @@ -6351,11 +5820,9 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->browser_controls_manager()->ScrollEnd(); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); // Now that browser controls have moved, expect the clip to resize. - LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0, 50), + property_trees->inner_viewport_container_bounds_delta()); host_impl_->ScrollEnd(EndState().get()); @@ -6372,9 +5839,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_FLOAT_EQ(-scroll_increment_y, host_impl_->browser_controls_manager()->ContentTopOffset()); // Now that browser controls have moved, expect the clip to resize. - EXPECT_EQ(gfx::Size(viewport_size_.width(), - viewport_size_.height() + scroll_increment_y), - inner_clip_ptr->bounds()); + EXPECT_EQ(gfx::Vector2dF(0, 25), + property_trees->inner_viewport_container_bounds_delta()); host_impl_->browser_controls_manager()->ScrollBy( gfx::Vector2dF(0.f, scroll_increment_y)); @@ -6382,14 +5848,13 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_FLOAT_EQ(-2 * scroll_increment_y, host_impl_->browser_controls_manager()->ContentTopOffset()); // Now that browser controls have moved, expect the clip to resize. - EXPECT_EQ(clip_size_, inner_clip_ptr->bounds()); + EXPECT_EQ(gfx::Vector2dF(), + property_trees->inner_viewport_container_bounds_delta()); host_impl_->ScrollEnd(EndState().get()); // Verify the layer is once-again non-scrollable. - EXPECT_EQ( - gfx::ScrollOffset(), - host_impl_->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset()); + EXPECT_EQ(gfx::ScrollOffset(), InnerViewportScrollLayer()->MaxScrollOffset()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -6424,6 +5889,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->pending_tree(), inner_viewport_size, outer_viewport_size, content_size); host_impl_->pending_tree()->set_browser_controls_shrink_blink_size(false); + UpdateDrawProperties(host_impl_->pending_tree()); // Fully scroll the viewport. host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(), @@ -6433,8 +5899,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->ScrollEnd(EndState().get()); } - LayerImpl* outer_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); ASSERT_FLOAT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset()); @@ -6527,29 +5992,20 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { gfx::Size surface_size(10, 10); gfx::Size contents_size(20, 20); - std::unique_ptr<LayerImpl> content_layer = - LayerImpl::Create(host_impl_->active_tree(), 11); - content_layer->SetDrawsContent(true); - content_layer->test_properties()->position = gfx::PointF(); - content_layer->SetBounds(contents_size); + SetupViewportLayersNoScrolls(surface_size); - LayerImpl* scroll_container_layer = - CreateBasicVirtualViewportLayers(surface_size, surface_size); + LayerImpl* scroll_container_layer = AddContentLayer(); + CreateEffectNode(scroll_container_layer).render_surface_reason = + RenderSurfaceReason::kTest; - std::unique_ptr<LayerImpl> scroll_layer = - LayerImpl::Create(host_impl_->active_tree(), 12); - scroll_layer->SetScrollable(surface_size); - scroll_layer->SetHitTestable(true); - scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); - scroll_layer->SetBounds(contents_size); - scroll_layer->test_properties()->position = gfx::PointF(); - scroll_layer->test_properties()->AddChild(std::move(content_layer)); - scroll_container_layer->test_properties()->AddChild(std::move(scroll_layer)); + LayerImpl* scroll_layer = + AddScrollableLayer(scroll_container_layer, surface_size, contents_size); - scroll_container_layer->test_properties()->force_render_surface = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* content_layer = AddLayer(); + content_layer->SetDrawsContent(true); + content_layer->SetBounds(contents_size); + CopyProperties(scroll_layer, content_layer); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); EXPECT_EQ( @@ -6567,14 +6023,13 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { gfx::Size surface_size(10, 10); gfx::Size contents_size(20, 20); - LayerImpl* root = - CreateBasicVirtualViewportLayers(surface_size, surface_size); + SetupViewportLayersNoScrolls(surface_size); - root->test_properties()->AddChild(CreateScrollableLayer(12, contents_size)); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* content_root = AddContentLayer(); + CreateEffectNode(content_root).render_surface_reason = + RenderSurfaceReason::kTest; + AddScrollableLayer(content_root, surface_size, contents_size); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); EXPECT_EQ( @@ -6589,15 +6044,10 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { } TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { + gfx::Size viewport_size(5, 5); gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->AddChild(CreateScrollableLayer(2, surface_size)); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); + LayerImpl* root = SetupDefaultRootLayer(surface_size); + AddScrollableLayer(root, viewport_size, surface_size); DrawFrame(); // Scroll event is ignored because the input coordinate is outside the layer @@ -6613,22 +6063,16 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { } TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { + gfx::Size viewport_size(5, 5); gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); + LayerImpl* root = SetupDefaultRootLayer(viewport_size); + LayerImpl* child = AddScrollableLayer(root, viewport_size, surface_size); gfx::Transform matrix; matrix.RotateAboutXAxis(180.0); - child->test_properties()->transform = matrix; - child->test_properties()->double_sided = false; - root->test_properties()->AddChild(std::move(child)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); + GetTransformNode(child)->local = matrix; + CreateEffectNode(child).double_sided = false; DrawFrame(); // Scroll event is ignored because the scrollable layer is not facing the @@ -6644,21 +6088,18 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { } TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { + gfx::Size scroll_container_size(5, 5); gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> content_layer = - CreateScrollableLayer(1, surface_size); - content_layer->test_properties()->main_thread_scrolling_reasons = - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; + LayerImpl* root = SetupDefaultRootLayer(surface_size); // Note: we can use the same clip layer for both since both calls to - // CreateScrollableLayer() use the same surface size. - std::unique_ptr<LayerImpl> scroll_layer = - CreateScrollableLayer(2, surface_size); - scroll_layer->test_properties()->AddChild(std::move(content_layer)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(scroll_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); + // AddScrollableLayer() use the same surface size. + LayerImpl* scroll_layer = + AddScrollableLayer(root, scroll_container_size, surface_size); + LayerImpl* content_layer = + AddScrollableLayer(scroll_layer, scroll_container_size, surface_size); + GetScrollNode(content_layer)->main_thread_scrolling_reasons = + MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; DrawFrame(); // Scrolling fails because the content layer is asking to be scrolled on the @@ -6671,25 +6112,18 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { } TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { - gfx::Size viewport_size(20, 20); - float page_scale = 2.f; - - SetupScrollAndContentsLayers(viewport_size); - - // Setup the layers so that the outer viewport is scrollable. - host_impl_->InnerViewportScrollLayer()->test_properties()->parent->SetBounds( - viewport_size); - host_impl_->OuterViewportScrollLayer()->SetBounds(gfx::Size(40, 40)); + gfx::Size inner_viewport_size(20, 20); + gfx::Size outer_viewport_size(40, 40); + gfx::Size content_size(80, 80); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size, + outer_viewport_size, content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); DrawFrame(); - LayerImpl* root_container = host_impl_->OuterViewportContainerLayer(); - EXPECT_EQ(viewport_size, root_container->bounds()); - gfx::Vector2d scroll_delta(0, 10); gfx::ScrollOffset expected_scroll_delta(scroll_delta); - LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); - gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + gfx::ScrollOffset expected_max_scroll = outer_scroll->MaxScrollOffset(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -6699,16 +6133,17 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { host_impl_->ScrollEnd(EndState().get()); // Set new page scale from main thread. + float page_scale = 2.f; host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); // The scroll range should also have been updated. - EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset()); + EXPECT_EQ(expected_max_scroll, outer_scroll->MaxScrollOffset()); // The page scale delta remains constant because the impl thread did not // scale. @@ -6716,27 +6151,18 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { } TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { - gfx::Size viewport_size(20, 20); - float page_scale = 2.f; - - SetupScrollAndContentsLayers(viewport_size); - - // Setup the layers so that the outer viewport is scrollable. - host_impl_->InnerViewportScrollLayer()->test_properties()->parent->SetBounds( - viewport_size); - host_impl_->OuterViewportScrollLayer()->SetBounds(gfx::Size(40, 40)); + gfx::Size inner_viewport_size(20, 20); + gfx::Size outer_viewport_size(40, 40); + gfx::Size content_size(80, 80); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size, + outer_viewport_size, content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawFrame(); - LayerImpl* root_container = host_impl_->OuterViewportContainerLayer(); - EXPECT_EQ(viewport_size, root_container->bounds()); - gfx::Vector2d scroll_delta(0, 10); gfx::ScrollOffset expected_scroll_delta(scroll_delta); - LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); - gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + gfx::ScrollOffset expected_max_scroll = outer_scroll->MaxScrollOffset(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -6746,6 +6172,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { host_impl_->ScrollEnd(EndState().get()); // Set new page scale on impl thread by pinching. + float page_scale = 2.f; host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN); host_impl_->PinchGestureBegin(); @@ -6758,12 +6185,12 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { // The scroll delta is not scaled because the main thread did not scale. std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); // The scroll range should also have been updated. - EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset()); + EXPECT_EQ(expected_max_scroll, outer_scroll->MaxScrollOffset()); // The page scale delta should match the new scale on the impl side. EXPECT_EQ(page_scale, host_impl_->active_tree()->current_page_scale_factor()); @@ -6771,6 +6198,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); + gfx::Size viewport_size(5, 5); gfx::Size surface_size(10, 10); float default_page_scale = 1.f; gfx::Transform default_page_scale_matrix; @@ -6780,23 +6208,16 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { gfx::Transform new_page_scale_matrix; new_page_scale_matrix.Scale(new_page_scale, new_page_scale); - // Create a normal scrollable root layer and another scrollable child layer. - LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size); - scroll->SetDrawsContent(true); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - LayerImpl* child = scroll->test_properties()->children[0]; - child->SetDrawsContent(true); + SetupViewportLayersInnerScrolls(viewport_size, surface_size); + LayerImpl* root = root_layer(); + auto* inner_scroll = InnerViewportScrollLayer(); + auto* outer_scroll = OuterViewportScrollLayer(); - std::unique_ptr<LayerImpl> scrollable_child_clip = - LayerImpl::Create(host_impl_->active_tree(), 6); - std::unique_ptr<LayerImpl> scrollable_child = - CreateScrollableLayer(7, surface_size); - scrollable_child_clip->test_properties()->AddChild( - std::move(scrollable_child)); - child->test_properties()->AddChild(std::move(scrollable_child_clip)); - LayerImpl* grand_child = child->test_properties()->children[0]; - grand_child->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + // Create a normal scrollable root layer and another scrollable child layer. + LayerImpl* scrollable_child_clip = AddLayer(); + CopyProperties(inner_scroll, scrollable_child_clip); + AddScrollableLayer(scrollable_child_clip, viewport_size, surface_size); + UpdateDrawProperties(host_impl_->active_tree()); // Set new page scale on impl thread by pinching. host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), @@ -6809,33 +6230,25 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { // Make sure all the layers are drawn with the page scale delta applied, i.e., // the page scale delta on the root layer is applied hierarchically. - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(0, 0)); EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(1, 1)); - EXPECT_EQ(new_page_scale, scroll->DrawTransform().matrix().getDouble(0, 0)); - EXPECT_EQ(new_page_scale, scroll->DrawTransform().matrix().getDouble(1, 1)); - EXPECT_EQ(new_page_scale, child->DrawTransform().matrix().getDouble(0, 0)); - EXPECT_EQ(new_page_scale, child->DrawTransform().matrix().getDouble(1, 1)); EXPECT_EQ(new_page_scale, - grand_child->DrawTransform().matrix().getDouble(0, 0)); + inner_scroll->DrawTransform().matrix().getDouble(0, 0)); + EXPECT_EQ(new_page_scale, + inner_scroll->DrawTransform().matrix().getDouble(1, 1)); + EXPECT_EQ(new_page_scale, + outer_scroll->DrawTransform().matrix().getDouble(0, 0)); EXPECT_EQ(new_page_scale, - grand_child->DrawTransform().matrix().getDouble(1, 1)); + outer_scroll->DrawTransform().matrix().getDouble(1, 1)); } TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { - SetupScrollAndContentsLayers(gfx::Size(30, 30)); - - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - - // Make the outer scroll layer scrollable. - outer_scroll->SetBounds(gfx::Size(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupViewportLayers(host_impl_->active_tree(), gfx::Size(15, 15), + gfx::Size(30, 30), gfx::Size(50, 50)); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); DrawFrame(); gfx::Vector2d scroll_delta(0, 10); @@ -6852,8 +6265,6 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { float page_scale = 2.f; host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, page_scale); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawOneFrame(); std::unique_ptr<ScrollAndScaleSet> scroll_info = @@ -6875,21 +6286,14 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); - LayerImpl* root = - CreateBasicVirtualViewportLayers(surface_size, surface_size); - - root->test_properties()->force_render_surface = true; - - std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(13, content_size); + SetupViewportLayersNoScrolls(surface_size); + LayerImpl* top = AddContentLayer(); + CreateEffectNode(top).render_surface_reason = RenderSurfaceReason::kTest; + LayerImpl* child_layer = AddScrollableLayer(top, surface_size, content_size); + LayerImpl* grand_child_layer = + AddScrollableLayer(child_layer, surface_size, content_size); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); - LayerImpl* grand_child_layer = grand_child.get(); - child->test_properties()->AddChild(std::move(grand_child)); - - LayerImpl* child_layer = child.get(); - root->test_properties()->AddChild(std::move(child)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); grand_child_layer->layer_tree_impl() @@ -6901,7 +6305,6 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(3, 0)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { gfx::Vector2d scroll_delta(-8, -7); @@ -6932,20 +6335,14 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { gfx::Size surface_size(100, 100); gfx::Size content_size(150, 150); - LayerImpl* root = - CreateBasicVirtualViewportLayers(surface_size, surface_size); - root->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(13, content_size); - - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); - LayerImpl* grand_child_layer = grand_child.get(); - child->test_properties()->AddChild(std::move(grand_child)); + SetupViewportLayersNoScrolls(surface_size); + LayerImpl* top = AddContentLayer(); + CreateEffectNode(top).render_surface_reason = RenderSurfaceReason::kTest; + LayerImpl* child_layer = AddScrollableLayer(top, surface_size, content_size); + LayerImpl* grand_child_layer = + AddScrollableLayer(child_layer, surface_size, content_size); - LayerImpl* child_layer = child.get(); - root->test_properties()->AddChild(std::move(child)); - host_impl_->active_tree()->SetElementIdsForTesting(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); grand_child_layer->layer_tree_impl() @@ -6957,7 +6354,6 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(0, 50)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); base::TimeTicks start_time = @@ -7027,43 +6423,13 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { // the scroll doesn't bubble up to the parent layer. gfx::Size surface_size(20, 20); gfx::Size viewport_size(10, 10); - const int kRootLayerId = 1; - const int kPageScaleLayerId = 2; - const int kViewportClipLayerId = 3; - const int kViewportScrollLayerId = 4; - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_->active_tree(), kRootLayerId); - std::unique_ptr<LayerImpl> page_scale = - LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); - std::unique_ptr<LayerImpl> root_clip = - LayerImpl::Create(host_impl_->active_tree(), kViewportClipLayerId); - root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scrolling = - CreateScrollableLayer(kViewportScrollLayerId, surface_size); - root_scrolling->test_properties()->is_container_for_fixed_position_layers = - true; - - std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(5, surface_size); - - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(6, surface_size); - LayerImpl* grand_child_layer = grand_child.get(); - child->test_properties()->AddChild(std::move(grand_child)); - - LayerImpl* child_layer = child.get(); - root_scrolling->test_properties()->AddChild(std::move(child)); - root_clip->test_properties()->AddChild(std::move(root_scrolling)); - page_scale->test_properties()->AddChild(std::move(root_clip)); - root_ptr->test_properties()->AddChild(std::move(page_scale)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = kPageScaleLayerId; - viewport_ids.inner_viewport_container = kViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kViewportScrollLayerId; - host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersNoScrolls(surface_size); + LayerImpl* child_layer = AddScrollableLayer(InnerViewportScrollLayer(), + viewport_size, surface_size); + LayerImpl* grand_child_layer = + AddScrollableLayer(child_layer, viewport_size, surface_size); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); grand_child_layer->layer_tree_impl() ->property_trees() @@ -7174,30 +6540,18 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { } // Ensure that layers who's scroll parent is the InnerViewportScrollNode are -// still able to scroll on thte compositor. +// still able to scroll on the compositor. TEST_F(LayerTreeHostImplTest, ChildrenOfInnerScrollNodeCanScrollOnThread) { gfx::Size viewport_size(10, 10); gfx::Size content_size(20, 20); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - - constexpr int kFixedLayerId = 300; + SetupViewportLayersOuterScrolls(viewport_size, content_size); // Simulate adding a "fixed" layer to the tree. { - std::unique_ptr<LayerImpl> fixed_layer = - LayerImpl::Create(host_impl_->active_tree(), kFixedLayerId); + LayerImpl* fixed_layer = AddLayer(); fixed_layer->SetBounds(viewport_size); fixed_layer->SetDrawsContent(true); - content_layer->test_properties()->AddChild(std::move(fixed_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - // This is very hackish but we want to simulate the kind of property tree - // that blink would create where a fixed layer's ScrollNode is parented to - // the inner viewport, rather than the outer. - host_impl_->active_tree() - ->LayerById(kFixedLayerId) - ->SetScrollTreeIndex( - host_impl_->active_tree()->InnerViewportScrollNode()->id); + CopyProperties(InnerViewportScrollLayer(), fixed_layer); } host_impl_->active_tree()->DidBecomeActive(); @@ -7221,8 +6575,7 @@ TEST_F(LayerTreeHostImplTest, ChildrenOfInnerScrollNodeCanScrollOnThread) { // The outer viewport should have scrolled. ASSERT_EQ(scroll_info->scrolls.size(), 1u); EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), - host_impl_->active_tree()->OuterViewportScrollNode()->element_id, + *scroll_info.get(), host_impl_->OuterViewportScrollNode()->element_id, scroll_delta)); } } @@ -7232,26 +6585,14 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { // should be applied to one of its ancestors if possible. gfx::Size viewport_size(10, 10); gfx::Size content_size(20, 20); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - - constexpr int kScrollChildClipId = 300; - constexpr int kScrollChildScrollId = 301; + SetupViewportLayersOuterScrolls(viewport_size, content_size); // Add a scroller whose scroll bounds and scroll container bounds are equal. // Since the max_scroll_offset is 0, scrolls will bubble. - std::unique_ptr<LayerImpl> scroll_child_clip = - LayerImpl::Create(host_impl_->active_tree(), kScrollChildClipId); - std::unique_ptr<LayerImpl> scroll_child = - CreateScrollableLayer(kScrollChildScrollId, gfx::Size(10, 10)); - scroll_child->test_properties()->is_container_for_fixed_position_layers = - true; - scroll_child->SetScrollable(gfx::Size(10, 10)); - - scroll_child_clip->test_properties()->AddChild(std::move(scroll_child)); - content_layer->test_properties()->AddChild(std::move(scroll_child_clip)); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* scroll_child_clip = AddContentLayer(); + AddScrollableLayer(scroll_child_clip, gfx::Size(10, 10), gfx::Size(10, 10)); + + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); { @@ -7272,87 +6613,23 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { // Only the root scroll should have scrolled. ASSERT_EQ(scroll_info->scrolls.size(), 1u); EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), - host_impl_->active_tree()->OuterViewportScrollNode()->element_id, + *scroll_info.get(), host_impl_->OuterViewportScrollNode()->element_id, scroll_delta)); } } TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { - const int kRootLayerId = 1; - const int kInnerViewportClipLayerId = 2; - const int kOuterViewportClipLayerId = 7; - const int kInnerViewportScrollLayerId = 3; - const int kOuterViewportScrollLayerId = 8; gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_->active_tree(), kRootLayerId); - std::unique_ptr<LayerImpl> inner_clip = - LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); - std::unique_ptr<LayerImpl> inner_scroll = - CreateScrollableLayer(kInnerViewportScrollLayerId, surface_size); - std::unique_ptr<LayerImpl> outer_clip = - LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId); - std::unique_ptr<LayerImpl> outer_scroll = - CreateScrollableLayer(kOuterViewportScrollLayerId, surface_size); - inner_clip->test_properties()->force_render_surface = true; - inner_scroll->test_properties()->is_container_for_fixed_position_layers = - true; - outer_scroll->test_properties()->is_container_for_fixed_position_layers = - true; - outer_clip->test_properties()->AddChild(std::move(outer_scroll)); - inner_scroll->test_properties()->AddChild(std::move(outer_clip)); - inner_clip->test_properties()->AddChild(std::move(inner_scroll)); - root_ptr->test_properties()->AddChild(std::move(inner_clip)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; - viewport_ids.outer_viewport_container = kOuterViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; - viewport_ids.outer_viewport_scroll = kOuterViewportScrollLayerId; - host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersNoScrolls(surface_size); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); - // Draw one frame and then immediately rebuild the layer tree to mimic a tree // synchronization. DrawFrame(); - const int kInnerViewportClipLayerId2 = 5; - const int kOuterViewportClipLayerId2 = 9; - const int kInnerViewportScrollLayerId2 = 6; - const int kOuterViewportScrollLayerId2 = 10; - host_impl_->active_tree()->DetachLayers(); - std::unique_ptr<LayerImpl> root_ptr2 = - LayerImpl::Create(host_impl_->active_tree(), 4); - std::unique_ptr<LayerImpl> inner_clip2 = - LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId2); - std::unique_ptr<LayerImpl> inner_scroll2 = - CreateScrollableLayer(kInnerViewportScrollLayerId2, surface_size); - std::unique_ptr<LayerImpl> outer_clip2 = - LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId2); - std::unique_ptr<LayerImpl> outer_scroll2 = - CreateScrollableLayer(kOuterViewportScrollLayerId2, surface_size); - inner_scroll2->test_properties()->is_container_for_fixed_position_layers = - true; - outer_scroll2->test_properties()->is_container_for_fixed_position_layers = - true; - outer_clip2->test_properties()->AddChild(std::move(outer_scroll2)); - inner_scroll2->test_properties()->AddChild(std::move(outer_clip2)); - inner_clip2->test_properties()->AddChild(std::move(inner_scroll2)); - inner_clip2->test_properties()->force_render_surface = true; - root_ptr2->test_properties()->AddChild(std::move(inner_clip2)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr2)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - LayerTreeImpl::ViewportLayerIds viewport_ids2; - viewport_ids2.inner_viewport_container = kInnerViewportClipLayerId2; - viewport_ids2.outer_viewport_container = kOuterViewportClipLayerId2; - viewport_ids2.inner_viewport_scroll = kInnerViewportScrollLayerId2; - viewport_ids2.outer_viewport_scroll = kOuterViewportScrollLayerId2; - host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids2); - host_impl_->active_tree()->DidBecomeActive(); + ClearLayersAndPropertyTrees(host_impl_->active_tree()); + SetupViewportLayersNoScrolls(surface_size); // Scrolling should still work even though we did not draw yet. EXPECT_EQ( @@ -7363,7 +6640,8 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { } TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); scroll_layer->SetDrawsContent(true); // Rotate the root layer 90 degrees counter-clockwise about its center. @@ -7371,10 +6649,6 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { rotate_transform.Rotate(-90.0); // Set external transform. host_impl_->OnDraw(rotate_transform, gfx::Rect(0, 0, 50, 50), false, false); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scroll to the right in screen coordinates with a gesture. @@ -7414,43 +6688,35 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { } TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - int child_clip_layer_id = 6; - int child_layer_id = 7; + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); float child_layer_angle = -20.f; // Create a child layer that is rotated to a non-axis-aligned angle. - std::unique_ptr<LayerImpl> clip_layer = - LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(child_layer_id, scroll_layer->bounds()); + // Only allow vertical scrolling. + gfx::Size content_size = scroll_layer->bounds(); + gfx::Size scroll_container_bounds(content_size.width(), + content_size.height() / 2); + LayerImpl* clip_layer = AddLayer(); + clip_layer->SetBounds(scroll_container_bounds); + CopyProperties(scroll_layer, clip_layer); gfx::Transform rotate_transform; rotate_transform.Translate(-50.0, -50.0); rotate_transform.Rotate(child_layer_angle); rotate_transform.Translate(50.0, 50.0); - clip_layer->test_properties()->transform = rotate_transform; - - // Only allow vertical scrolling. - gfx::Size scroll_container_bounds = - gfx::Size(child->bounds().width(), child->bounds().height() / 2); - clip_layer->SetBounds(scroll_container_bounds); - child->SetScrollable(scroll_container_bounds); - child->SetHitTestable(true); + auto& clip_layer_transform_node = CreateTransformNode(clip_layer); // The rotation depends on the layer's transform origin, and the child layer // is a different size than the clip, so make sure the clip layer's origin // lines up over the child. - clip_layer->test_properties()->transform_origin = gfx::Point3F( + clip_layer_transform_node.origin = gfx::Point3F( clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f); - LayerImpl* child_ptr = child.get(); - clip_layer->test_properties()->AddChild(std::move(child)); - // TODO(pdr): Shouldn't clip_layer be scroll_layer's parent? - scroll_layer->test_properties()->AddChild(std::move(clip_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + clip_layer_transform_node.local = rotate_transform; + + LayerImpl* child = + AddScrollableLayer(clip_layer, scroll_container_bounds, content_size); - ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id); + ElementId child_scroll_id = child->element_id(); - gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { // Scroll down in screen coordinates with a gesture. @@ -7479,7 +6745,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { } { // Now reset and scroll the same amount horizontally. - SetScrollOffsetDelta(child_ptr, gfx::Vector2dF()); + SetScrollOffsetDelta(child, gfx::Vector2dF()); gfx::Vector2d gesture_scroll_delta(10, 0); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -7507,36 +6773,30 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { // When scrolling an element with perspective, the distance scrolled // depends on the point at which the scroll begins. - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - int child_clip_layer_id = 6; - int child_layer_id = 7; + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); // Create a child layer that is rotated on its x axis, with perspective. - std::unique_ptr<LayerImpl> clip_layer = - LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(child_layer_id, scroll_layer->bounds()); - LayerImpl* child_ptr = child.get(); + LayerImpl* clip_layer = AddLayer(); + clip_layer->SetBounds(gfx::Size(50, 50)); + CopyProperties(scroll_layer, clip_layer); gfx::Transform perspective_transform; perspective_transform.Translate(-50.0, -50.0); perspective_transform.ApplyPerspectiveDepth(20); perspective_transform.RotateAboutXAxis(45); perspective_transform.Translate(50.0, 50.0); - clip_layer->test_properties()->transform = perspective_transform; - - clip_layer->SetBounds(gfx::Size(child_ptr->bounds().width() / 2, - child_ptr->bounds().height() / 2)); + auto& clip_layer_transform_node = CreateTransformNode(clip_layer); // The transform depends on the layer's transform origin, and the child layer // is a different size than the clip, so make sure the clip layer's origin // lines up over the child. - clip_layer->test_properties()->transform_origin = gfx::Point3F( + clip_layer_transform_node.origin = gfx::Point3F( clip_layer->bounds().width(), clip_layer->bounds().height(), 0.f); - clip_layer->test_properties()->AddChild(std::move(child)); - scroll_layer->test_properties()->AddChild(std::move(clip_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + clip_layer_transform_node.local = perspective_transform; + + LayerImpl* child = AddScrollableLayer(clip_layer, clip_layer->bounds(), + scroll_layer->bounds()); - gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); + UpdateDrawProperties(host_impl_->active_tree()); std::unique_ptr<ScrollAndScaleSet> scroll_info; @@ -7562,7 +6822,7 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { // where the previous scroll ended, but the scroll position is reset // for each scroll. for (int i = 0; i < 4; ++i) { - SetScrollOffsetDelta(child_ptr, gfx::Vector2dF()); + SetScrollOffsetDelta(child, gfx::Vector2dF()); DrawFrame(); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -7578,8 +6838,7 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { host_impl_->ScrollEnd(EndState().get()); scroll_info = host_impl_->ProcessScrollDeltas(); - ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id, + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(), expected_scroll_deltas[i])); // The root scroll layer should not have scrolled, because the input delta @@ -7589,7 +6848,8 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { } TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); // Scale the layer to twice its normal size. int scale = 2; @@ -7597,10 +6857,6 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { scale_transform.Scale(scale, scale); // Set external transform above root. host_impl_->OnDraw(scale_transform, gfx::Rect(0, 0, 50, 50), false, false); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scroll down in screen coordinates with a gesture. @@ -7644,33 +6900,23 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) { int width = 332; int height = 20; int scale = 3; - SetupScrollAndContentsLayers(gfx::Size(width, height)); gfx::Size container_bounds = gfx::Size(width * scale - 1, height * scale); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - container_bounds); - host_impl_->active_tree()->InnerViewportScrollLayer()->SetScrollable( - container_bounds); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(container_bounds, gfx::Size(width, height)); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->SetDeviceScaleFactor(scale); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); - LayerImpl* inner_viewport_scroll_layer = - host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl* inner_viewport_scroll_layer = InnerViewportScrollLayer(); EXPECT_EQ(gfx::ScrollOffset(0, 0), inner_viewport_scroll_layer->MaxScrollOffset()); } TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { TestInputHandlerClient scroll_watcher; - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 20)); - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - LayerImpl* clip_layer = - scroll_layer->test_properties()->parent->test_properties()->parent; - clip_layer->SetBounds(gfx::Size(10, 20)); - scroll_layer->SetScrollable(gfx::Size(10, 20)); - scroll_layer->SetHitTestable(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(10, 20), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->BindToClient(&scroll_watcher); @@ -7752,13 +6998,14 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { // Forces a full tree synchronization and ensures that the scroll delegate // sees the correct size of the new tree. - gfx::Size new_size(42, 24); + gfx::Size new_viewport_size(21, 12); + gfx::Size new_content_size(42, 24); CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayers(host_impl_->pending_tree(), new_viewport_size, + new_content_size, new_content_size); host_impl_->ActivateSyncTree(); - EXPECT_EQ(gfx::SizeF(new_size), scroll_watcher.scrollable_size()); + EXPECT_EQ(gfx::SizeF(new_content_size), scroll_watcher.scrollable_size()); // Tear down the LayerTreeHostImpl before the InputHandlerClient. host_impl_->ReleaseLayerTreeFrameSink(); @@ -7777,13 +7024,8 @@ void CheckLayerScrollDelta(LayerImpl* layer, gfx::Vector2dF scroll_delta) { TEST_F(LayerTreeHostImplTest, ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw) { - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 20)); - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - LayerImpl* clip_layer = - scroll_layer->test_properties()->parent->test_properties()->parent; - clip_layer->SetBounds(gfx::Size(10, 20)); - scroll_layer->SetScrollable(gfx::Size(10, 20)); - scroll_layer->SetHitTestable(true); + SetupViewportLayersInnerScrolls(gfx::Size(10, 20), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); scroll_layer->SetDrawsContent(true); // Draw first frame to clear any pending draws and check scroll. @@ -7794,7 +7036,8 @@ TEST_F(LayerTreeHostImplTest, // Set external scroll delta on delegate and notify LayerTreeHost. gfx::ScrollOffset scroll_offset(10.f, 10.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0.f, 0.f)); + EXPECT_TRUE(host_impl_->active_tree()->needs_update_draw_properties()); // Check scroll delta reflected in layer. TestFrameData frame; @@ -7812,17 +7055,16 @@ TEST_F(LayerTreeHostImplTest, TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { gfx::Size viewport_size(100, 100); gfx::Size content_size(200, 200); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - auto* outer_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - auto* inner_scroll = host_impl_->active_tree()->InnerViewportScrollLayer(); + auto* outer_scroll = OuterViewportScrollLayer(); + auto* inner_scroll = InnerViewportScrollLayer(); ScrollTree& scroll_tree = host_impl_->active_tree()->property_trees()->scroll_tree; ElementId inner_element_id = inner_scroll->element_id(); ElementId outer_element_id = outer_scroll->element_id(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); // Ensure that the scroll offset is interpreted as a content offset so it @@ -7835,9 +7077,8 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { // Disable scrolling the inner viewport. Only the outer should scroll. { ASSERT_FALSE(did_request_redraw_); - inner_scroll->test_properties()->user_scrollable_vertical = false; - inner_scroll->test_properties()->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(inner_scroll)->user_scrollable_vertical = false; + GetScrollNode(inner_scroll)->user_scrollable_horizontal = false; gfx::ScrollOffset scroll_offset(25.f, 30.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7849,18 +7090,17 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { // Reset did_request_redraw_ = false; - inner_scroll->test_properties()->user_scrollable_vertical = true; - inner_scroll->test_properties()->user_scrollable_horizontal = true; - outer_scroll->SetCurrentScrollOffset(gfx::ScrollOffset(0, 0)); + GetScrollNode(inner_scroll)->user_scrollable_vertical = true; + GetScrollNode(inner_scroll)->user_scrollable_horizontal = true; + SetScrollOffset(outer_scroll, gfx::ScrollOffset(0, 0)); } // Disable scrolling the outer viewport. The inner should scroll to its // extent but there should be no bubbling over to the outer viewport. { ASSERT_FALSE(did_request_redraw_); - outer_scroll->test_properties()->user_scrollable_vertical = false; - outer_scroll->test_properties()->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(outer_scroll)->user_scrollable_vertical = false; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = false; gfx::ScrollOffset scroll_offset(120.f, 140.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7872,20 +7112,19 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { // Reset did_request_redraw_ = false; - inner_scroll->test_properties()->user_scrollable_vertical = true; - inner_scroll->test_properties()->user_scrollable_horizontal = true; - inner_scroll->SetCurrentScrollOffset(gfx::ScrollOffset(0, 0)); + GetScrollNode(outer_scroll)->user_scrollable_vertical = true; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = true; + SetScrollOffset(inner_scroll, gfx::ScrollOffset(0, 0)); } // Disable both viewports. No scrolling should take place, no redraw should // be requested. { ASSERT_FALSE(did_request_redraw_); - outer_scroll->test_properties()->user_scrollable_vertical = false; - outer_scroll->test_properties()->user_scrollable_horizontal = false; - inner_scroll->test_properties()->user_scrollable_vertical = false; - inner_scroll->test_properties()->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(inner_scroll)->user_scrollable_vertical = false; + GetScrollNode(inner_scroll)->user_scrollable_horizontal = false; + GetScrollNode(outer_scroll)->user_scrollable_vertical = false; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = false; gfx::ScrollOffset scroll_offset(60.f, 70.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7896,20 +7135,19 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { EXPECT_FALSE(did_request_redraw_); // Reset - inner_scroll->test_properties()->user_scrollable_vertical = true; - inner_scroll->test_properties()->user_scrollable_horizontal = true; - outer_scroll->test_properties()->user_scrollable_vertical = true; - outer_scroll->test_properties()->user_scrollable_horizontal = true; + GetScrollNode(inner_scroll)->user_scrollable_vertical = true; + GetScrollNode(inner_scroll)->user_scrollable_horizontal = true; + GetScrollNode(outer_scroll)->user_scrollable_vertical = true; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = true; } // If the inner is at its extent but the outer cannot scroll, we shouldn't // request a redraw. { ASSERT_FALSE(did_request_redraw_); - outer_scroll->test_properties()->user_scrollable_vertical = false; - outer_scroll->test_properties()->user_scrollable_horizontal = false; - inner_scroll->SetCurrentScrollOffset(gfx::ScrollOffset(50.f, 50.f)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(outer_scroll)->user_scrollable_vertical = false; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = false; + SetScrollOffset(inner_scroll, gfx::ScrollOffset(50.f, 50.f)); gfx::ScrollOffset scroll_offset(60.f, 70.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7920,18 +7158,15 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { EXPECT_FALSE(did_request_redraw_); // Reset - outer_scroll->test_properties()->user_scrollable_vertical = true; - outer_scroll->test_properties()->user_scrollable_horizontal = true; + GetScrollNode(outer_scroll)->user_scrollable_vertical = true; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = true; } } // The SetSynchronousInputHandlerRootScrollOffset API can be called while there // is no inner viewport set. This test passes if we don't crash. TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetNoViewportCrash) { - host_impl_->active_tree()->ClearViewportLayers(); - host_impl_->active_tree()->DidBecomeActive(); - - auto* inner_scroll = host_impl_->active_tree()->InnerViewportScrollLayer(); + auto* inner_scroll = InnerViewportScrollLayer(); ASSERT_FALSE(inner_scroll); gfx::ScrollOffset scroll_offset(25.f, 30.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7939,10 +7174,8 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetNoViewportCrash) { TEST_F(LayerTreeHostImplTest, OverscrollRoot) { InputHandlerScrollResult scroll_result; - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); @@ -8071,33 +7304,21 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { // Scroll child layers beyond their maximum scroll range and make sure root // overscroll does not accumulate. InputHandlerScrollResult scroll_result; + gfx::Size scroll_container_size(5, 5); gfx::Size surface_size(10, 10); - const int kInnerViewportClipLayerId = 4; - const int kInnerViewportScrollLayerId = 1; - std::unique_ptr<LayerImpl> root_clip = - LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); - root_clip->test_properties()->force_render_surface = true; - - std::unique_ptr<LayerImpl> root = - CreateScrollableLayer(kInnerViewportScrollLayerId, surface_size); - - std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(3, surface_size); - - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); - LayerImpl* grand_child_layer = grand_child.get(); - child->test_properties()->AddChild(std::move(grand_child)); - - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; - host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); - - LayerImpl* child_layer = child.get(); - root->test_properties()->AddChild(std::move(child)); - root_clip->test_properties()->AddChild(std::move(root)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* root_clip = SetupDefaultRootLayer(surface_size); + LayerImpl* root = + AddScrollableLayer(root_clip, scroll_container_size, surface_size); + LayerImpl* child_layer = + AddScrollableLayer(root, scroll_container_size, surface_size); + LayerImpl* grand_child_layer = + AddScrollableLayer(child_layer, scroll_container_size, surface_size); + + LayerTreeImpl::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.inner_scroll = root->scroll_tree_index(); + host_impl_->active_tree()->SetViewportPropertyIds(viewport_property_ids); + + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); child_layer->layer_tree_impl() @@ -8109,7 +7330,6 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { ->scroll_tree.UpdateScrollOffsetBaseForTesting( grand_child_layer->element_id(), gfx::ScrollOffset(0, 2)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { gfx::Vector2d scroll_delta(0, -10); @@ -8177,9 +7397,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) { // should be applied to one of its ancestors if possible. Overscroll should // be reflected only when it has bubbled up to the root scrolling layer. InputHandlerScrollResult scroll_result; - SetupScrollAndContentsLayers(gfx::Size(20, 20)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupViewportLayersInnerScrolls(gfx::Size(10, 10), gfx::Size(20, 20)); DrawFrame(); { gfx::Vector2d scroll_delta(0, 8); @@ -8212,16 +7430,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) { LayerTreeSettings settings = DefaultSettings(); CreateHostImpl(settings, CreateLayerTreeFrameSink()); - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(50, 50)); - LayerImpl* clip_layer = - scroll_layer->test_properties()->parent->test_properties()->parent; + SetupViewportLayersNoScrolls(gfx::Size(50, 50)); + UpdateDrawProperties(host_impl_->active_tree()); - clip_layer->SetBounds(gfx::Size(50, 50)); - scroll_layer->SetScrollable(gfx::Size(50, 50)); - scroll_layer->SetHitTestable(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); @@ -8243,13 +7454,7 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { InputHandlerScrollResult scroll_result; gfx::Size viewport_size(100, 100); gfx::Size content_size(200, 200); - LayerImpl* root_scroll_layer = - CreateBasicVirtualViewportLayers(viewport_size, viewport_size); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds( - content_size); - root_scroll_layer->SetBounds(content_size); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); { // Edge glow effect should be applicable only upon reaching Edges @@ -8315,27 +7520,12 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollOnNonViewportLayers) { const gfx::Size content_size(200, 200); const gfx::Size viewport_size(100, 100); - LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* scroll_layer = nullptr; - + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* content_layer = AddContentLayer(); // Initialization: Add a nested scrolling layer, simulating a scrolling div. - { - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - scroll_layer = scroll.get(); - - content_layer->test_properties()->AddChild(std::move(scroll)); - layer_tree_impl->BuildPropertyTreesForTesting(); - } + LayerImpl* scroll_layer = + AddScrollableLayer(content_layer, content_size, gfx::Size(400, 400)); InputHandlerScrollResult scroll_result; DrawFrame(); @@ -8387,23 +7577,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) { LayerTreeSettings settings = DefaultSettings(); CreateHostImpl(settings, CreateLayerTreeFrameSink()); - const gfx::Size content_size(50, 50); const gfx::Size viewport_size(50, 50); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersNoScrolls(viewport_size); - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->main_thread_scrolling_reasons = + GetScrollNode(InnerViewportScrollLayer())->main_thread_scrolling_reasons = MainThreadScrollingReason::kThreadedScrollingDisabled; - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->main_thread_scrolling_reasons = + GetScrollNode(OuterViewportScrollLayer())->main_thread_scrolling_reasons = MainThreadScrollingReason::kThreadedScrollingDisabled; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawFrame(); // Overscroll initiated outside layers will be handled by the main thread. @@ -8430,47 +7611,25 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) { TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) { const gfx::Size viewport_size(100, 100); - LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - - CreateBasicVirtualViewportLayers(viewport_size, viewport_size); + SetupViewportLayersNoScrolls(viewport_size); host_impl_->active_tree()->SetTopControlsHeight(10); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); - - LayerImpl* scroll_layer = nullptr; + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); // Create a scrolling layer that's parented directly to the inner viewport. // This will test that scrolls that chain up to the inner viewport without // passing through the outer viewport still scroll correctly and affect // browser controls. - { - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollable(viewport_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); + LayerImpl* scroll_layer = AddScrollableLayer( + inner_scroll_layer, viewport_size, gfx::Size(400, 400)); - scroll_layer = scroll.get(); - - inner_scroll_layer->test_properties()->AddChild(std::move(scroll)); - - // Move the outer viewport layer away so that scrolls won't target it. - host_impl_->active_tree() - ->OuterViewportContainerLayer() - ->test_properties() - ->position = gfx::PointF(400, 400); - - layer_tree_impl->BuildPropertyTreesForTesting(); - - float min_page_scale = 1.f, max_page_scale = 4.f; - float page_scale_factor = 2.f; - host_impl_->active_tree()->PushPageScaleFromMainThread( - page_scale_factor, min_page_scale, max_page_scale); - host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - } + float min_page_scale = 1.f, max_page_scale = 4.f; + float page_scale_factor = 2.f; + host_impl_->active_tree()->PushPageScaleFromMainThread( + page_scale_factor, min_page_scale, max_page_scale); + host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); // Fully scroll the child. { @@ -8523,44 +7682,24 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) { LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); - - LayerImpl* scroll_layer = nullptr; - LayerImpl* child_scroll_layer = nullptr; + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); + LayerImpl* content_layer = AddContentLayer(); // Initialization: Add two nested scrolling layers, simulating a scrolling div // with another scrolling div inside it. Set the outer "div" to be the outer // viewport. - { - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 13); - scroll2->SetBounds(gfx::Size(500, 500)); - scroll2->SetScrollable(gfx::Size(300, 300)); - scroll2->SetHitTestable(true); - scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id())); - scroll2->SetDrawsContent(true); - - scroll_layer = scroll.get(); - child_scroll_layer = scroll2.get(); - - scroll->test_properties()->AddChild(std::move(scroll2)); - content_layer->test_properties()->AddChild(std::move(scroll)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = layer_tree_impl->PageScaleLayer()->id(); - viewport_ids.inner_viewport_scroll = inner_scroll_layer->id(); - viewport_ids.outer_viewport_scroll = scroll_layer->id(); - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); - layer_tree_impl->BuildPropertyTreesForTesting(); - } + LayerImpl* scroll_layer = + AddScrollableLayer(content_layer, content_size, gfx::Size(400, 400)); + GetScrollNode(scroll_layer)->scrolls_outer_viewport = true; + LayerImpl* child_scroll_layer = AddScrollableLayer( + scroll_layer, gfx::Size(300, 300), gfx::Size(500, 500)); + + auto viewport_property_ids = layer_tree_impl->ViewportPropertyIdsForTesting(); + viewport_property_ids.outer_scroll = scroll_layer->scroll_tree_index(); + layer_tree_impl->SetViewportPropertyIds(viewport_property_ids); + UpdateDrawProperties(layer_tree_impl); // Scroll should target the nested scrolling layer in the content and then // chain to the parent scrolling layer which is now set as the outer @@ -8639,6 +7778,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) { scroll_layer->CurrentScrollOffset()); } } + // Test that scrolls chain correctly when a child scroller on the page (e.g. a // scrolling div) is set as the outer viewport but scrolls start from a layer // that's not a descendant of the outer viewport. This happens in the @@ -8649,52 +7789,25 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) { LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); - - LayerImpl* outer_scroll_layer = nullptr; - LayerImpl* sibling_scroll_layer = nullptr; + SetupViewportLayersInnerScrolls(viewport_size, content_size); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); + LayerImpl* content_layer = AddContentLayer(); // Initialization: Add a scrolling layer, simulating an ordinary DIV, to be // set as the outer viewport. Add a sibling scrolling layer that isn't a child // of the outer viewport scroll layer. - { - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(gfx::Size(1200, 1200)); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - outer_scroll_layer = scroll.get(); + LayerImpl* outer_scroll_layer = + AddScrollableLayer(content_layer, content_size, gfx::Size(1200, 1200)); + GetScrollNode(outer_scroll_layer)->scrolls_outer_viewport = true; + LayerImpl* sibling_scroll_layer = AddScrollableLayer( + content_layer, gfx::Size(600, 600), gfx::Size(1200, 1200)); - content_layer->test_properties()->AddChild(std::move(scroll)); + auto viewport_property_ids = layer_tree_impl->ViewportPropertyIdsForTesting(); + viewport_property_ids.outer_scroll = outer_scroll_layer->scroll_tree_index(); + layer_tree_impl->SetViewportPropertyIds(viewport_property_ids); - // Create the non-descendant. - std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 15); - scroll2->SetBounds(gfx::Size(1200, 1200)); - scroll2->SetScrollable(gfx::Size(600, 600)); - scroll2->SetHitTestable(true); - scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id())); - scroll2->SetDrawsContent(true); - - sibling_scroll_layer = scroll2.get(); - - content_layer->test_properties()->AddChild(std::move(scroll2)); - - LayerImpl* inner_container = - host_impl_->active_tree()->InnerViewportContainerLayer(); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = layer_tree_impl->PageScaleLayer()->id(); - viewport_ids.inner_viewport_container = inner_container->id(); - viewport_ids.inner_viewport_scroll = inner_scroll_layer->id(); - viewport_ids.outer_viewport_scroll = outer_scroll_layer->id(); - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); - layer_tree_impl->BuildPropertyTreesForTesting(); - - ASSERT_EQ(outer_scroll_layer, layer_tree_impl->OuterViewportScrollLayer()); - } + ASSERT_EQ(outer_scroll_layer, + layer_tree_impl->OuterViewportScrollLayerForTesting()); // Scrolls should target the non-descendant scroller. Chaining should not // propagate to the outer viewport scroll layer. @@ -8819,12 +7932,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) { CreateHostImpl(settings, CreateLayerTreeFrameSink()); const gfx::Size content_size(50, 50); - const gfx::Size viewport_size(50, 50); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersNoScrolls(content_size); // By default, no main thread scrolling reasons should exist. - LayerImpl* scroll_layer = - host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); ScrollNode* scroll_node = host_impl_->active_tree()->property_trees()->scroll_tree.Node( scroll_layer->scroll_tree_index()); @@ -8854,6 +7965,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) { class BlendStateCheckLayer : public LayerImpl { public: + static std::unique_ptr<BlendStateCheckLayer> Create( + LayerTreeImpl* tree_impl, + int id, + viz::ClientResourceProvider* resource_provider) { + return base::WrapUnique( + new BlendStateCheckLayer(tree_impl, id, resource_provider)); + } + BlendStateCheckLayer(LayerTreeImpl* tree_impl, int id, viz::ClientResourceProvider* resource_provider) @@ -8935,93 +8054,63 @@ class BlendStateCheckLayer : public LayerImpl { }; TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { - { - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(false); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - } - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); + root->SetDrawsContent(false); - root->test_properties()->AddChild(std::make_unique<BlendStateCheckLayer>( - host_impl_->active_tree(), 2, host_impl_->resource_provider())); - auto* layer1 = - static_cast<BlendStateCheckLayer*>(root->test_properties()->children[0]); - layer1->test_properties()->position = gfx::PointF(2.f, 2.f); - - TestFrameData frame; + auto* layer1 = AddLayer<BlendStateCheckLayer>( + host_impl_->active_tree(), host_impl_->resource_provider()); + CopyProperties(root, layer1); + CreateTransformNode(layer1).post_translation = gfx::Vector2dF(2.f, 2.f); + CreateEffectNode(layer1); // Opaque layer, drawn without blending. layer1->SetContentsOpaque(true); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with translucent content and painting, so drawn with blending. layer1->SetContentsOpaque(false); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with translucent opacity, drawn with blending. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 0.5f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 0.5f); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with translucent opacity and painting, drawn with blending. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 0.5f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 0.5f); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); - layer1->test_properties()->AddChild(std::make_unique<BlendStateCheckLayer>( - host_impl_->active_tree(), 3, host_impl_->resource_provider())); - auto* layer2 = static_cast<BlendStateCheckLayer*>( - layer1->test_properties()->children[0]); - layer2->test_properties()->position = gfx::PointF(4.f, 4.f); + auto* layer2 = AddLayer<BlendStateCheckLayer>( + host_impl_->active_tree(), host_impl_->resource_provider()); + CopyProperties(layer1, layer2); + CreateTransformNode(layer2).post_translation = gfx::Vector2dF(4.f, 4.f); + CreateEffectNode(layer2); // 2 opaque layers, drawn without blending. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 1.f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 1.f); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); - layer2->test_properties()->opacity = 1.f; - layer2->NoteLayerPropertyChanged(); + SetOpacity(layer2, 1.f); layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Parent layer with translucent content, drawn with blending. // Child layer with opaque content, drawn without blending. @@ -9030,13 +8119,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Parent layer with translucent content but opaque painting, drawn without // blending. @@ -9046,12 +8131,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Parent layer with translucent opacity and opaque content. Since it has a // drawing child, it's drawn to a render surface which carries the opacity, @@ -9059,76 +8141,57 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Child layer with opaque content, drawn without blending (parent surface // carries the inherited opacity). layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 0.5f; - layer1->NoteLayerPropertyChanged(); - layer1->test_properties()->force_render_surface = true; + SetOpacity(layer1, 0.5f); + GetEffectNode(layer1)->render_surface_reason = RenderSurfaceReason::kTest; layer1->SetExpectation(false, true, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetExpectation(false, false, layer1); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); - layer1->test_properties()->force_render_surface = false; + GetEffectNode(layer1)->render_surface_reason = RenderSurfaceReason::kNone; // Draw again, but with child non-opaque, to make sure // layer1 not culled. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 1.f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 1.f); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); - layer2->test_properties()->opacity = 0.5f; - layer2->NoteLayerPropertyChanged(); + SetOpacity(layer2, 0.5f); layer2->SetExpectation(true, false, layer1); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // A second way of making the child non-opaque. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 1.f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 1.f); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(false); - layer2->test_properties()->opacity = 1.f; - layer2->NoteLayerPropertyChanged(); + SetOpacity(layer2, 1.f); layer2->SetExpectation(true, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // And when the layer says its not opaque but is painted opaque, it is not // blended. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 1.f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 1.f); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); - layer2->test_properties()->opacity = 1.f; - layer2->NoteLayerPropertyChanged(); + SetOpacity(layer2, 1.f); layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with partially opaque contents, drawn with blending. layer1->SetContentsOpaque(false); @@ -9137,12 +8200,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with partially opaque contents partially culled, drawn with blending. layer1->SetContentsOpaque(false); @@ -9151,12 +8210,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with partially opaque contents culled, drawn with blending. layer1->SetContentsOpaque(false); @@ -9165,12 +8220,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with partially opaque contents and translucent contents culled, drawn // without blending. @@ -9180,16 +8231,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); } static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) { - host_impl->active_tree()->BuildPropertyTreesForTesting(); host_impl->active_tree()->set_needs_update_draw_properties(); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl->PrepareToDraw(&frame)); @@ -9200,40 +8246,40 @@ static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) { TEST_F(LayerTreeHostImplTest, MayContainVideo) { gfx::Size big_size(1000, 1000); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(big_size)); - - int layer_id = 1; - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); - auto* video_layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); + SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), big_size); + auto* video_layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); video_layer->set_may_contain_video(true); + CopyProperties(root, video_layer); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get())); // Test with the video layer occluded. - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); - auto* large_layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); + auto* large_layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); large_layer->SetBounds(big_size); large_layer->SetContentsOpaque(true); + CopyProperties(root, large_layer); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get())); - // Remove the large layer. - root->test_properties()->RemoveChild(large_layer); + { + // Remove the large layer. + OwnedLayerImplList layers = + host_impl_->active_tree()->DetachLayersKeepingRootLayerForTesting(); + ASSERT_EQ(video_layer, layers[1].get()); + host_impl_->active_tree()->AddLayer(std::move(layers[1])); + } + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get())); // Move the video layer so it goes beyond the root. - video_layer->test_properties()->position = gfx::PointF(100.f, 100.f); + video_layer->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get())); - video_layer->test_properties()->position = gfx::PointF(0.f, 0.f); + video_layer->SetOffsetToTransformParent(gfx::Vector2dF(0.f, 0.f)); video_layer->NoteLayerPropertyChanged(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get())); } @@ -9253,34 +8299,26 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { void SetupActiveTreeLayers() { host_impl_->active_tree()->set_background_color(SK_ColorGRAY); - host_impl_->active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->force_render_surface = true; - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::make_unique<BlendStateCheckLayer>( - host_impl_->active_tree(), 2, host_impl_->resource_provider())); - child_ = static_cast<BlendStateCheckLayer*>(host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0]); - child_->SetExpectation(false, false, - host_impl_->active_tree()->root_layer_for_testing()); + LayerImpl* root = SetupDefaultRootLayer(viewport_size_); + child_ = AddLayer<BlendStateCheckLayer>(host_impl_->active_tree(), + host_impl_->resource_provider()); + child_->SetExpectation(false, false, root); child_->SetContentsOpaque(true); + CopyProperties(root, child_); + UpdateDrawProperties(host_impl_->active_tree()); } - // Expect no gutter rects. - void TestLayerCoversFullViewport() { - gfx::Rect layer_rect(viewport_size_); - child_->test_properties()->position = gfx::PointF(layer_rect.origin()); + void SetLayerGeometry(const gfx::Rect& layer_rect) { child_->SetBounds(layer_rect.size()); child_->SetQuadRect(gfx::Rect(layer_rect.size())); child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + child_->SetOffsetToTransformParent( + gfx::Vector2dF(layer_rect.OffsetFromOrigin())); + } + + // Expect no gutter rects. + void TestLayerCoversFullViewport() { + SetLayerGeometry(gfx::Rect(viewport_size_)); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -9295,14 +8333,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { } // Expect fullscreen gutter rect. - void SetUpEmptylayer() { - gfx::Rect layer_rect(0, 0, 0, 0); - child_->test_properties()->position = gfx::PointF(layer_rect.origin()); - child_->SetBounds(layer_rect.size()); - child_->SetQuadRect(gfx::Rect(layer_rect.size())); - child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - } + void SetUpEmptylayer() { SetLayerGeometry(gfx::Rect()); } void VerifyEmptyLayerRenderPasses(const viz::RenderPassList& render_passes) { ASSERT_EQ(1u, render_passes.size()); @@ -9316,10 +8347,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { void TestEmptyLayer() { SetUpEmptylayer(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - VerifyEmptyLayerRenderPasses(frame.render_passes); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); } void TestEmptyLayerWithOnDraw() { @@ -9333,12 +8361,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { // Expect four surrounding gutter rects. void SetUpLayerInMiddleOfViewport() { - gfx::Rect layer_rect(500, 500, 200, 200); - child_->test_properties()->position = gfx::PointF(layer_rect.origin()); - child_->SetBounds(layer_rect.size()); - child_->SetQuadRect(gfx::Rect(layer_rect.size())); - child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetLayerGeometry(gfx::Rect(500, 500, 200, 200)); } void VerifyLayerInMiddleOfViewport(const viz::RenderPassList& render_passes) { @@ -9353,10 +8376,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { void TestLayerInMiddleOfViewport() { SetUpLayerInMiddleOfViewport(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - VerifyLayerInMiddleOfViewport(frame.render_passes); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); } void TestLayerInMiddleOfViewportWithOnDraw() { @@ -9370,13 +8390,8 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { // Expect no gutter rects. void SetUpLayerIsLargerThanViewport() { - gfx::Rect layer_rect(viewport_size_.width() + 10, - viewport_size_.height() + 10); - child_->test_properties()->position = gfx::PointF(layer_rect.origin()); - child_->SetBounds(layer_rect.size()); - child_->SetQuadRect(gfx::Rect(layer_rect.size())); - child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetLayerGeometry( + gfx::Rect(viewport_size_.width() + 10, viewport_size_.height() + 10)); } void VerifyLayerIsLargerThanViewport( @@ -9390,10 +8405,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { void TestLayerIsLargerThanViewport() { SetUpLayerIsLargerThanViewport(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - VerifyLayerIsLargerThanViewport(frame.render_passes); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); } void TestLayerIsLargerThanViewportWithOnDraw() { @@ -9427,8 +8439,8 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { } void VerifyQuadsExactlyCoverViewport(const viz::QuadList& quad_list) { - LayerTestCommon::VerifyQuadsExactlyCoverRect( - quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_))); + VerifyQuadsExactlyCoverRect(quad_list, + gfx::Rect(DipSizeToPixelSize(viewport_size_))); } // Make sure that the texture coordinates match their expectations. @@ -9454,11 +8466,6 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { } } - gfx::Size DipSizeToPixelSize(const gfx::Size& size) { - return gfx::ScaleToRoundedSize( - size, host_impl_->active_tree()->device_scale_factor()); - } - viz::DrawQuad::Material gutter_quad_material_; gfx::Size gutter_texture_size_; gfx::Size viewport_size_; @@ -9471,9 +8478,6 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) { bool software = false; CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); - - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestLayerCoversFullViewport()); EXPECT_SCOPED(TestEmptyLayer()); @@ -9488,8 +8492,6 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) { CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); host_impl_->active_tree()->SetDeviceScaleFactor(2.f); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestLayerCoversFullViewport()); EXPECT_SCOPED(TestEmptyLayer()); @@ -9505,8 +8507,6 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) { // Pending tree to force active_tree size invalid. Not used otherwise. CreatePendingTree(); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestEmptyLayerWithOnDraw()); @@ -9573,31 +8573,25 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, - AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr); + AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr, + nullptr); layer_tree_host_impl->SetVisible(true); layer_tree_host_impl->InitializeFrameSink(layer_tree_frame_sink.get()); layer_tree_host_impl->WillBeginImplFrame( viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2)); - layer_tree_host_impl->active_tree()->SetDeviceViewportRect( - gfx::Rect(500, 500)); - - std::unique_ptr<LayerImpl> root = - FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1); - root->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> child = - FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2); - child->test_properties()->position = gfx::PointF(12.f, 13.f); + + LayerImpl* root = SetupRootLayer<LayerImpl>( + layer_tree_host_impl->active_tree(), gfx::Size(500, 500)); + LayerImpl* child = AddLayer<LayerImpl>(layer_tree_host_impl->active_tree()); child->SetBounds(gfx::Size(14, 15)); child->SetDrawsContent(true); - root->SetBounds(gfx::Size(500, 500)); - root->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child)); - layer_tree_host_impl->active_tree()->SetRootLayerForTesting(std::move(root)); - layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(12.f, 13.f)); layer_tree_host_impl->active_tree()->SetLocalSurfaceIdAllocationFromParent( viz::LocalSurfaceIdAllocation( viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)), base::TimeTicks::Now())); + UpdateDrawProperties(layer_tree_host_impl->active_tree()); TestFrameData frame; @@ -9611,18 +8605,8 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { // Second frame, only the damaged area should get swapped. Damage should be // the union of old and new child rects: gfx::Rect(26, 28). - layer_tree_host_impl->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0] - ->test_properties() - ->position = gfx::PointF(); - layer_tree_host_impl->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0] - ->NoteLayerPropertyChanged(); - layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + child->NoteLayerPropertyChanged(); EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame)); layer_tree_host_impl->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); @@ -9633,9 +8617,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { layer_tree_host_impl->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); // This will damage everything. - layer_tree_host_impl->active_tree() - ->root_layer_for_testing() - ->SetBackgroundColor(SK_ColorBLACK); + root->SetBackgroundColor(SK_ColorBLACK); EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame)); layer_tree_host_impl->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); @@ -9648,19 +8630,15 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { } TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { - std::unique_ptr<LayerImpl> root = - FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); - std::unique_ptr<LayerImpl> child = - FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); + LayerImpl* child = AddLayer(); child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; - root->test_properties()->AddChild(std::move(child)); + CopyProperties(root, child); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); TestFrameData frame; @@ -9704,45 +8682,36 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { FakeLayerTreeFrameSink::Create3d(context_provider)); CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink)); - std::unique_ptr<LayerImpl> root_layer = - LayerImpl::Create(host_impl_->active_tree(), 1); - root_layer->SetBounds(gfx::Size(10, 10)); - root_layer->test_properties()->force_render_surface = true; + LayerImpl* root_layer = SetupDefaultRootLayer(gfx::Size(10, 10)); scoped_refptr<VideoFrame> softwareFrame = media::VideoFrame::CreateColorFrame( gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta()); FakeVideoFrameProvider provider; provider.set_frame(softwareFrame); - std::unique_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( - host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0); + auto* video_layer = AddLayer<VideoLayerImpl>( + host_impl_->active_tree(), &provider, media::VIDEO_ROTATION_0); video_layer->SetBounds(gfx::Size(10, 10)); video_layer->SetDrawsContent(true); - root_layer->test_properties()->AddChild(std::move(video_layer)); + CopyProperties(root_layer, video_layer); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_EQ(0u, sii->shared_image_count()); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_GT(sii->shared_image_count(), 0u); // Kill the layer tree. - host_impl_->active_tree()->DetachLayers(); + ClearLayersAndPropertyTrees(host_impl_->active_tree()); // There should be no textures left in use after. EXPECT_EQ(0u, sii->shared_image_count()); } - TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupDefaultRootLayer(gfx::Size(10, 10)); host_impl_->active_tree()->set_background_color(SK_ColorWHITE); + UpdateDrawProperties(host_impl_->active_tree()); // Verify one quad is drawn when transparent background set is not set. TestFrameData frame; @@ -9791,7 +8760,8 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest { return FakeLayerTreeFrameSink::Create3d(); } - void DrawFrameAndTestDamage(const gfx::Rect& expected_damage) { + void DrawFrameAndTestDamage(const gfx::Rect& expected_damage, + const LayerImpl* child) { bool expect_to_draw = !expected_damage.IsEmpty(); TestFrameData frame; @@ -9812,15 +8782,11 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest { // culled. ASSERT_EQ(2u, root_render_pass->quad_list.size()); - LayerImpl* child = host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0]; gfx::Rect expected_child_visible_rect(child->bounds()); EXPECT_EQ(expected_child_visible_rect, root_render_pass->quad_list.front()->visible_rect); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); + LayerImpl* root = root_layer(); gfx::Rect expected_root_visible_rect(root->bounds()); EXPECT_EQ(expected_root_visible_rect, root_render_pass->quad_list.ElementAt(1)->visible_rect); @@ -9832,41 +8798,35 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest { }; TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) { - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); + auto* root = SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(), + gfx::Size(10, 10)); root->SetDrawsContent(true); root->SetBackgroundColor(SK_ColorRED); - root->test_properties()->force_render_surface = true; // Child layer is in the bottom right corner. - std::unique_ptr<SolidColorLayerImpl> child = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 2); - child->test_properties()->position = gfx::PointF(9.f, 9.f); + auto* child = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree()); child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); child->SetBackgroundColor(SK_ColorRED); - root->test_properties()->AddChild(std::move(child)); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(9.f, 9.f)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // Draw a frame. In the first frame, the entire viewport should be damaged. gfx::Rect full_frame_damage( host_impl_->active_tree()->GetDeviceViewport().size()); - DrawFrameAndTestDamage(full_frame_damage); + DrawFrameAndTestDamage(full_frame_damage, child); // The second frame has damage that doesn't touch the child layer. Its quads // should still be generated. gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1); - host_impl_->active_tree()->root_layer_for_testing()->SetUpdateRect( - small_damage); - DrawFrameAndTestDamage(small_damage); + root->SetUpdateRect(small_damage); + DrawFrameAndTestDamage(small_damage, child); // The third frame should have no damage, so no quads should be generated. gfx::Rect no_damage; - DrawFrameAndTestDamage(no_damage); + DrawFrameAndTestDamage(no_damage, child); } class GLRendererWithSetupQuadForAntialiasing : public viz::GLRenderer { @@ -9879,59 +8839,39 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { // away quads can end up thinking they need AA. float device_scale_factor = 4.f / 3.f; gfx::Size root_size(2000, 1000); - gfx::Size device_viewport_size = - gfx::ScaleToCeiledSize(root_size, device_scale_factor); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(device_viewport_size)); - CreatePendingTree(); host_impl_->pending_tree()->SetDeviceScaleFactor(device_scale_factor); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f / 16.f, 16.f); - std::unique_ptr<LayerImpl> scoped_root = - LayerImpl::Create(host_impl_->pending_tree(), 1); - LayerImpl* root = scoped_root.get(); - root->test_properties()->force_render_surface = true; + auto* root = SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), root_size); root->SetNeedsPushProperties(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); - - std::unique_ptr<LayerImpl> scoped_scrolling_layer = - LayerImpl::Create(host_impl_->pending_tree(), 2); - LayerImpl* scrolling_layer = scoped_scrolling_layer.get(); - root->test_properties()->AddChild(std::move(scoped_scrolling_layer)); + gfx::Size content_layer_bounds(100001, 100); + auto* scrolling_layer = + AddScrollableLayer(root, content_layer_bounds, gfx::Size()); scrolling_layer->SetNeedsPushProperties(); - gfx::Size content_layer_bounds(100001, 100); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(content_layer_bounds)); - std::unique_ptr<FakePictureLayerImpl> scoped_content_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 3, raster_source); - LayerImpl* content_layer = scoped_content_layer.get(); - scrolling_layer->test_properties()->AddChild(std::move(scoped_content_layer)); + auto* content_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), raster_source); + CopyProperties(scrolling_layer, content_layer); content_layer->SetBounds(content_layer_bounds); content_layer->SetDrawsContent(true); content_layer->SetNeedsPushProperties(); - root->SetBounds(root_size); + UpdateDrawProperties(host_impl_->pending_tree()); gfx::ScrollOffset scroll_offset(100000, 0); - scrolling_layer->SetScrollable(content_layer_bounds); - scrolling_layer->SetHitTestable(true); - scrolling_layer->SetElementId( - LayerIdToElementIdForTesting(scrolling_layer->id())); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - scrolling_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( scrolling_layer->element_id(), scroll_offset); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); ASSERT_EQ(1u, host_impl_->active_tree()->GetRenderSurfaceList().size()); TestFrameData frame; @@ -9966,14 +8906,10 @@ class CompositorFrameMetadataTest : public LayerTreeHostImplTest { }; TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { - SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - { - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); - } + SetupRootLayer<FakeLayerWithQuads>(host_impl_->active_tree(), + gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); + DrawFrame(); host_impl_->ReclaimResources(std::vector<viz::ReturnedResource>()); host_impl_->DidReceiveCompositorFrameAck(); EXPECT_EQ(acks_received_, 1); @@ -10008,24 +8944,24 @@ TEST_F(LayerTreeHostImplTest, external_transform); // SolidColorLayerImpl will be drawn. - std::unique_ptr<SolidColorLayerImpl> root_layer = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); + auto* root = SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(), + gfx::Size(10, 10)); + root->SetDrawsContent(true); // VideoLayerImpl will not be drawn. FakeVideoFrameProvider provider; - std::unique_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( - host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0); + LayerImpl* video_layer = AddLayer<VideoLayerImpl>( + host_impl_->active_tree(), &provider, media::VIDEO_ROTATION_0); video_layer->SetBounds(gfx::Size(10, 10)); video_layer->SetDrawsContent(true); - root_layer->test_properties()->AddChild(std::move(video_layer)); - SetupRootLayerImpl(std::move(root_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root, video_layer); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->OnDraw(external_transform, external_viewport, resourceless_software_draw, false); EXPECT_EQ(1u, last_on_draw_frame_->will_draw_layers.size()); - EXPECT_EQ(host_impl_->active_tree()->root_layer_for_testing(), + EXPECT_EQ(host_impl_->active_tree()->root_layer(), last_on_draw_frame_->will_draw_layers[0]); } @@ -10052,7 +8988,8 @@ TEST_F(LayerTreeHostImplTest, MemoryLimits) { host_impl_ = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, - AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr); + AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr, + nullptr); // Gpu compositing. layer_tree_frame_sink_ = FakeLayerTreeFrameSink::Create3d(); @@ -10130,12 +9067,10 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, RequireHighResAndRedrawWhenVisible) { ASSERT_TRUE(host_impl_->active_tree()); - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); + LayerImpl* root = SetupRootLayer<SolidColorLayerImpl>( + host_impl_->active_tree(), gfx::Size(10, 10)); root->SetBackgroundColor(SK_ColorRED); - SetupRootLayerImpl(std::move(root)); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // RequiresHighResToDraw is set when new output surface is used. EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); @@ -10163,9 +9098,16 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, EXPECT_SCOPED(ExpectFullDamageAndDraw(host_impl_.get())); } -TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { +TEST_F(LayerTreeHostImplTest, RequireHighResAfterMSAAToggles) { + // Create a host impl with MSAA support and a forced sample count of 4. + LayerTreeSettings msaaSettings = DefaultSettings(); + msaaSettings.gpu_rasterization_msaa_sample_count = 4; + EXPECT_TRUE(CreateHostImpl( + msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization( + msaaSettings.gpu_rasterization_msaa_sample_count))); + ASSERT_TRUE(host_impl_->active_tree()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_FALSE(host_impl_->use_msaa()); // RequiresHighResToDraw is set when new output surface is used. EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); @@ -10173,15 +9115,14 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { host_impl_->ResetRequiresHighResToDraw(); host_impl_->SetContentHasSlowPaths(false); - host_impl_->SetHasGpuRasterizationTrigger(false); host_impl_->CommitComplete(); EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); host_impl_->NotifyReadyToActivate(); - host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->NotifyReadyToActivate(); - host_impl_->SetHasGpuRasterizationTrigger(false); + host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->NotifyReadyToActivate(); @@ -10189,7 +9130,7 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { host_impl_->ResetRequiresHighResToDraw(); EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); - host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->NotifyReadyToActivate(); @@ -10295,7 +9236,6 @@ TEST_F(LayerTreeHostImplTest, msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization( msaaSettings.gpu_rasterization_msaa_sample_count))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -10310,7 +9250,6 @@ TEST_F(LayerTreeHostImplTest, EXPECT_NE(viz::kInvalidResourceId, resource_id); EXPECT_FALSE(host_impl_->EvictedUIResourcesExist()); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, @@ -10335,7 +9274,6 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) { FakeLayerTreeFrameSink::Create3dForGpuRasterization( msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); @@ -10354,7 +9292,6 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) { FakeLayerTreeFrameSink::Create3dForGpuRasterization( msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); @@ -10373,7 +9310,6 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) { FakeLayerTreeFrameSink::Create3dForOopRasterization( msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); @@ -10392,7 +9328,6 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) { FakeLayerTreeFrameSink::Create3dForOopRasterization( msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); @@ -10466,30 +9401,26 @@ TEST_P(LayerTreeHostImplTestWithRenderer, ShutdownReleasesContext) { CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink)); - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); struct Helper { std::unique_ptr<viz::CopyOutputResult> unprocessed_result; void OnResult(std::unique_ptr<viz::CopyOutputResult> result) { unprocessed_result = std::move(result); } } helper; - root->test_properties()->copy_requests.push_back( + + GetEffectNode(root)->has_copy_request = true; + GetPropertyTrees(root)->effect_tree.AddCopyRequest( + root->effect_tree_index(), std::make_unique<viz::CopyOutputRequest>( viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE, base::BindOnce(&Helper::OnResult, base::Unretained(&helper)))); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); auto* sii = context_provider->SharedImageInterface(); // The CopyOutputResult has a ref on the viz::ContextProvider and a shared // image allocated. - ASSERT_TRUE(helper.unprocessed_result); + EXPECT_TRUE(helper.unprocessed_result); EXPECT_FALSE(context_provider->HasOneRef()); EXPECT_EQ(1u, sii->shared_image_count()); @@ -10509,30 +9440,19 @@ TEST_P(LayerTreeHostImplTestWithRenderer, ShutdownReleasesContext) { TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) { // If we ray cast a scroller that is not on the first layer's ancestor chain, // we should return SCROLL_UNKNOWN. + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); - SetupScrollAndContentsLayers(content_size); + SetupViewportLayersInnerScrolls(viewport_size, content_size); - int scroll_layer_id = 2; - LayerImpl* scroll_layer = - host_impl_->active_tree()->LayerById(scroll_layer_id); - scroll_layer->SetDrawsContent(true); - scroll_layer->SetHitTestable(true); - - int page_scale_layer_id = 5; - LayerImpl* page_scale_layer = - host_impl_->active_tree()->LayerById(page_scale_layer_id); - - int occluder_layer_id = 6; - std::unique_ptr<LayerImpl> occluder_layer = - LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id); + LayerImpl* occluder_layer = AddLayer(); occluder_layer->SetDrawsContent(true); occluder_layer->SetHitTestable(true); occluder_layer->SetBounds(content_size); - occluder_layer->test_properties()->position = gfx::PointF(); // The parent of the occluder is *above* the scroller. - page_scale_layer->test_properties()->AddChild(std::move(occluder_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root_layer(), occluder_layer); + occluder_layer->SetTransformTreeIndex( + host_impl_->active_tree()->PageScaleTransformNode()->id); DrawFrame(); @@ -10547,37 +9467,25 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { // If we ray cast a scroller this is on the first layer's ancestor chain, but // is not the first scroller we encounter when walking up from the layer, we // should also return SCROLL_UNKNOWN. + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); - SetupScrollAndContentsLayers(content_size); + SetupViewportLayersInnerScrolls(viewport_size, content_size); - int scroll_layer_id = 2; - LayerImpl* scroll_layer = - host_impl_->active_tree()->LayerById(scroll_layer_id); - scroll_layer->SetDrawsContent(true); - scroll_layer->SetHitTestable(true); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); + + LayerImpl* child_scroll_clip = AddLayer(); + CopyProperties(scroll_layer, child_scroll_clip); - int occluder_layer_id = 6; - std::unique_ptr<LayerImpl> occluder_layer = - LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id); + LayerImpl* child_scroll = + AddScrollableLayer(child_scroll_clip, viewport_size, content_size); + child_scroll->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); + + LayerImpl* occluder_layer = AddLayer(); occluder_layer->SetDrawsContent(true); occluder_layer->SetHitTestable(true); occluder_layer->SetBounds(content_size); - occluder_layer->test_properties()->position = gfx::PointF(-10.f, -10.f); - - int child_scroll_clip_layer_id = 7; - std::unique_ptr<LayerImpl> child_scroll_clip = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id); - - int child_scroll_layer_id = 8; - std::unique_ptr<LayerImpl> child_scroll = - CreateScrollableLayer(child_scroll_layer_id, content_size); - - child_scroll->test_properties()->position = gfx::PointF(10.f, 10.f); - - child_scroll->test_properties()->AddChild(std::move(occluder_layer)); - child_scroll_clip->test_properties()->AddChild(std::move(child_scroll)); - scroll_layer->test_properties()->AddChild(std::move(child_scroll_clip)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(child_scroll, occluder_layer); + occluder_layer->SetOffsetToTransformParent(gfx::Vector2dF(-10.f, -10.f)); DrawFrame(); @@ -10589,21 +9497,15 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { } TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) { + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); - SetupScrollAndContentsLayers(content_size); - - int scroll_layer_id = 2; - LayerImpl* scroll_layer = - host_impl_->active_tree()->LayerById(scroll_layer_id); + SetupViewportLayersInnerScrolls(viewport_size, content_size); - int child_scroll_layer_id = 7; - std::unique_ptr<LayerImpl> child_scroll = - CreateScrollableLayer(child_scroll_layer_id, content_size); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); + LayerImpl* child_scroll = + AddScrollableLayer(scroll_layer, viewport_size, content_size); child_scroll->SetDrawsContent(false); - scroll_layer->test_properties()->AddChild(std::move(child_scroll)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawFrame(); // We should have scrolled |child_scroll| even though it does not move @@ -10614,111 +9516,23 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) { ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) .thread); - EXPECT_EQ(host_impl_->active_tree()->LayerById(7)->scroll_tree_index(), + EXPECT_EQ(child_scroll->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); } -template <bool commit_to_active_tree> -class LayerTreeHostImplLatencyInfoTest : public LayerTreeHostImplTest { - public: - void SetUp() override { - LayerTreeSettings settings = DefaultSettings(); - settings.commit_to_active_tree = commit_to_active_tree; - CreateHostImpl(settings, CreateLayerTreeFrameSink()); - - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; - - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - } -}; - -// Make sure LatencyInfo are passed in viz::CompositorFrameMetadata properly in -// the Renderer. This includes components added by LatencyInfoSwapPromise and -// the default LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT. -using LayerTreeHostImplLatencyInfoRendererTest = - LayerTreeHostImplLatencyInfoTest<false>; -TEST_F(LayerTreeHostImplLatencyInfoRendererTest, - LatencyInfoPassedToCompositorFrameMetadataRenderer) { - auto* fake_layer_tree_frame_sink = - static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); - - // The first frame should only have the default BeginFrame component. - TestFrameData frame1; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame1)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame1)); - host_impl_->DidDrawAllLayers(frame1); - - const std::vector<ui::LatencyInfo>& metadata_latency_after1 = - fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; - EXPECT_EQ(1u, metadata_latency_after1.size()); - EXPECT_TRUE(metadata_latency_after1[0].FindLatency( - ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, nullptr)); - EXPECT_TRUE(metadata_latency_after1[0].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); - - // The second frame should have the default BeginFrame component and the - // component attached via LatencyInfoSwapPromise. - ui::LatencyInfo latency_info; - latency_info.set_trace_id(5); - latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT); - std::unique_ptr<SwapPromise> swap_promise( - new LatencyInfoSwapPromise(latency_info)); - host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise)); - - TestFrameData frame2; - host_impl_->SetFullViewportDamage(); - host_impl_->SetNeedsRedraw(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame2)); - host_impl_->DidDrawAllLayers(frame2); +// Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed +// in viz::CompositorFrameMetadata. +TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { + LayerTreeSettings settings = DefaultSettings(); + settings.commit_to_active_tree = false; + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(), + gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); - const std::vector<ui::LatencyInfo>& metadata_latency_after2 = - fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; - EXPECT_EQ(2u, metadata_latency_after2.size()); - EXPECT_TRUE(metadata_latency_after2[0].FindLatency( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr)); - EXPECT_TRUE(metadata_latency_after2[1].FindLatency( - ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, nullptr)); - - // Renderer should also record INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT. - EXPECT_TRUE(metadata_latency_after2[0].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); - EXPECT_TRUE(metadata_latency_after2[1].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); -} - -// Make sure LatencyInfo are passed in viz::CompositorFrameMetadata properly in -// the UI. This includes components added by LatencyInfoSwapPromise and -// the default LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT. -using LayerTreeHostImplLatencyInfoUITest = - LayerTreeHostImplLatencyInfoTest<true>; -TEST_F(LayerTreeHostImplLatencyInfoUITest, - LatencyInfoPassedToCompositorFrameMetadataUI) { auto* fake_layer_tree_frame_sink = static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); - // The first frame should only have the default BeginFrame component. - TestFrameData frame1; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame1)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame1)); - host_impl_->DidDrawAllLayers(frame1); - - const std::vector<ui::LatencyInfo>& metadata_latency_after1 = - fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; - EXPECT_EQ(1u, metadata_latency_after1.size()); - EXPECT_TRUE(metadata_latency_after1[0].FindLatency( - ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, nullptr)); - EXPECT_FALSE(metadata_latency_after1[0].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); - - // The second frame should have the default BeginFrame component and the - // component attached via LatencyInfoSwapPromise. ui::LatencyInfo latency_info; latency_info.set_trace_id(5); latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT); @@ -10726,47 +9540,29 @@ TEST_F(LayerTreeHostImplLatencyInfoUITest, new LatencyInfoSwapPromise(latency_info)); host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise)); - TestFrameData frame2; host_impl_->SetFullViewportDamage(); host_impl_->SetNeedsRedraw(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame2)); - host_impl_->DidDrawAllLayers(frame2); + DrawFrame(); - const std::vector<ui::LatencyInfo>& metadata_latency_after2 = + const auto& metadata_latency_after = fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; - EXPECT_EQ(2u, metadata_latency_after2.size()); - EXPECT_TRUE(metadata_latency_after2[0].FindLatency( + EXPECT_EQ(1u, metadata_latency_after.size()); + EXPECT_TRUE(metadata_latency_after[0].FindLatency( ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr)); - EXPECT_TRUE(metadata_latency_after2[1].FindLatency( - ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, nullptr)); - - // UI should not record INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT. - EXPECT_FALSE(metadata_latency_after2[0].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); - EXPECT_FALSE(metadata_latency_after2[1].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); } #if defined(OS_ANDROID) TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { - int root_layer_id = 1; - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; - - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* root = SetupRootLayer<SolidColorLayerImpl>( + host_impl_->active_tree(), gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); // Plumb the layer-local selection bounds. gfx::Point selection_top(5, 0); gfx::Point selection_bottom(5, 5); LayerSelection selection; selection.start.type = gfx::SelectionBound::CENTER; - selection.start.layer_id = root_layer_id; + selection.start.layer_id = root->id(); selection.start.edge_bottom = selection_bottom; selection.start.edge_top = selection_top; selection.end = selection.start; @@ -10787,16 +9583,9 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { } TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) { - int root_layer_id = 1; - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // Plumb the layer-local selection bounds. gfx::Point selection_top(5, 0); @@ -10807,7 +9596,7 @@ TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) { selection.start.hidden = true; selection.start.type = gfx::SelectionBound::CENTER; - selection.start.layer_id = root_layer_id; + selection.start.layer_id = root->id(); selection.start.edge_bottom = selection_bottom; selection.start.edge_top = selection_top; selection.end = selection.start; @@ -10833,15 +9622,13 @@ class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, LayerTreeHostImpl* layer_tree_host_impl, int* set_needs_commit_count, - int* set_needs_redraw_count, - int* forward_to_main_count) + int* set_needs_redraw_count) : SwapPromiseMonitor( (layer_tree_host ? layer_tree_host->GetSwapPromiseManager() : nullptr), layer_tree_host_impl), set_needs_commit_count_(set_needs_commit_count), - set_needs_redraw_count_(set_needs_redraw_count), - forward_to_main_count_(forward_to_main_count) {} + set_needs_redraw_count_(set_needs_redraw_count) {} ~SimpleSwapPromiseMonitor() override = default; @@ -10849,30 +9636,23 @@ class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { void OnSetNeedsRedrawOnImpl() override { (*set_needs_redraw_count_)++; } - void OnForwardScrollUpdateToMainThreadOnImpl() override { - (*forward_to_main_count_)++; - } - private: int* set_needs_commit_count_; int* set_needs_redraw_count_; - int* forward_to_main_count_; }; TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { int set_needs_commit_count = 0; int set_needs_redraw_count = 0; - int forward_to_main_count = 0; { std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } // Now the monitor is destroyed, SetNeedsRedraw() is no longer being @@ -10880,43 +9660,39 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); { std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); // Redraw with damage. host_impl_->SetFullViewportDamage(); host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(2, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } { std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); // Redraw without damage. host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(3, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } set_needs_commit_count = 0; set_needs_redraw_count = 0; - forward_to_main_count = 0; { std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); // Scrolling normally should not trigger any forwarding. EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -10932,7 +9708,6 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); // Scrolling with a scroll handler should defer the swap to the main // thread. @@ -10950,7 +9725,6 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(2, set_needs_redraw_count); - EXPECT_EQ(1, forward_to_main_count); } } @@ -10971,7 +9745,8 @@ class LayerTreeHostImplWithBrowserControlsTest : public LayerTreeHostImplTest { const int LayerTreeHostImplWithBrowserControlsTest::top_controls_height_ = 50; TEST_F(LayerTreeHostImplWithBrowserControlsTest, NoIdleAnimations) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), @@ -10986,7 +9761,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, NoIdleAnimations) { TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsHeightIsCommitted) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_FALSE(did_request_redraw_); CreatePendingTree(); host_impl_->sync_tree()->SetTopControlsHeight(100); @@ -10996,7 +9771,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsStayFullyVisibleOnHeightChange) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ControlsTopOffset()); CreatePendingTree(); @@ -11012,7 +9787,8 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsAnimationScheduling) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), @@ -11025,10 +9801,10 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, ScrollHandledByBrowserControls) { InputHandlerScrollResult result; - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11101,14 +9877,13 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, WheelUnhandledByBrowserControls) { - SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); host_impl_->active_tree()->set_browser_controls_shrink_blink_size(true); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); - LayerImpl* viewport_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* viewport_layer = InnerViewportScrollLayer(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -11142,10 +9917,10 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsAnimationAtOrigin) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 200)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11222,10 +9997,10 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsAnimationAfterScroll) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); float initial_scroll_offset = 50; @@ -11302,10 +10077,10 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsScrollDeltaInOverScroll) { // Verifies that the overscroll delta should not have accumulated in // the browser controls if we do a hide and show without releasing finger. - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11390,45 +10165,27 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, SetupBrowserControlsAndScrollLayerWithVirtualViewport( viewport_size, viewport_size, root_layer_size); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - LayerImpl* scroll_layer = nullptr; - LayerImpl* clip_layer = nullptr; + LayerImpl* outer_scroll = OuterViewportScrollLayer(); // Initialization: Add a child scrolling layer to the outer scroll layer and // set its scroll layer as the outer viewport. This simulates setting a // scrolling element as the root scroller on the page. - { - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10); - clip->SetBounds(root_layer_size); - clip->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(scroll_content_size); - scroll->SetScrollable(root_layer_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - scroll_layer = scroll.get(); - clip_layer = clip.get(); - - clip->test_properties()->AddChild(std::move(scroll)); - outer_scroll->test_properties()->AddChild(std::move(clip)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = layer_tree_impl->PageScaleLayer()->id(); - viewport_ids.inner_viewport_container = - layer_tree_impl->InnerViewportContainerLayer()->id(); - viewport_ids.outer_viewport_container = clip_layer->id(); - viewport_ids.inner_viewport_scroll = inner_scroll->id(); - viewport_ids.outer_viewport_scroll = scroll_layer->id(); - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); - layer_tree_impl->BuildPropertyTreesForTesting(); - DrawFrame(); - } + LayerImpl* clip_layer = AddLayer(); + clip_layer->SetBounds(root_layer_size); + CopyProperties(outer_scroll, clip_layer); + CreateClipNode(clip_layer); + LayerImpl* scroll_layer = + AddScrollableLayer(clip_layer, root_layer_size, scroll_content_size); + GetScrollNode(scroll_layer)->scrolls_outer_viewport = true; + + auto viewport_property_ids = layer_tree_impl->ViewportPropertyIdsForTesting(); + viewport_property_ids.outer_clip = clip_layer->clip_tree_index(); + viewport_property_ids.outer_scroll = scroll_layer->scroll_tree_index(); + layer_tree_impl->SetViewportPropertyIds(viewport_property_ids); + DrawFrame(); - ASSERT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); + ASSERT_EQ(1.f, layer_tree_impl->CurrentBrowserControlsShownRatio()); // Scrolling should scroll the child content and the browser controls. The // original outer viewport should get no scroll. @@ -11442,100 +10199,22 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(100.f, 50.f), scroll_layer->CurrentScrollOffset()); - EXPECT_EQ(0.f, - host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); + EXPECT_EQ(0.f, layer_tree_impl->CurrentBrowserControlsShownRatio()); } } -class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { - public: - void SetupVirtualViewportLayers(const gfx::Size& content_size, - const gfx::Size& outer_viewport, - const gfx::Size& inner_viewport) { - LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - const int kOuterViewportClipLayerId = 6; - const int kOuterViewportScrollLayerId = 7; - const int kInnerViewportScrollLayerId = 2; - const int kInnerViewportClipLayerId = 4; - const int kPageScaleLayerId = 5; - - std::unique_ptr<LayerImpl> inner_scroll = - LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); - inner_scroll->test_properties()->is_container_for_fixed_position_layers = - true; - inner_scroll->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - inner_scroll->element_id(), gfx::ScrollOffset()); - - std::unique_ptr<LayerImpl> inner_clip = - LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); - inner_clip->SetBounds(inner_viewport); - - std::unique_ptr<LayerImpl> page_scale = - LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); - - inner_scroll->SetScrollable(inner_viewport); - inner_scroll->SetHitTestable(true); - inner_scroll->SetElementId( - LayerIdToElementIdForTesting(inner_scroll->id())); - inner_scroll->SetBounds(outer_viewport); - inner_scroll->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> outer_clip = - LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId); - outer_clip->SetBounds(outer_viewport); - outer_clip->test_properties()->is_container_for_fixed_position_layers = - true; - - std::unique_ptr<LayerImpl> outer_scroll = - LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); - outer_scroll->SetScrollable(outer_viewport); - outer_scroll->SetHitTestable(true); - outer_scroll->SetElementId( - LayerIdToElementIdForTesting(outer_scroll->id())); - outer_scroll->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - outer_scroll->element_id(), gfx::ScrollOffset()); - outer_scroll->SetBounds(content_size); - outer_scroll->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> contents = LayerImpl::Create(layer_tree_impl, 8); - contents->SetDrawsContent(true); - contents->SetBounds(content_size); - contents->test_properties()->position = gfx::PointF(); - - outer_scroll->test_properties()->AddChild(std::move(contents)); - outer_clip->test_properties()->AddChild(std::move(outer_scroll)); - inner_scroll->test_properties()->AddChild(std::move(outer_clip)); - page_scale->test_properties()->AddChild(std::move(inner_scroll)); - inner_clip->test_properties()->AddChild(std::move(page_scale)); - - inner_clip->test_properties()->force_render_surface = true; - layer_tree_impl->SetRootLayerForTesting(std::move(inner_clip)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = kPageScaleLayerId; - viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; - viewport_ids.outer_viewport_container = kOuterViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; - viewport_ids.outer_viewport_scroll = kOuterViewportScrollLayerId; - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->DidBecomeActive(); - } -}; +using LayerTreeHostImplVirtualViewportTest = LayerTreeHostImplTest; TEST_F(LayerTreeHostImplVirtualViewportTest, RootScrollBothInnerAndOuterLayer) { gfx::Size content_size = gfx::Size(100, 160); gfx::Size outer_viewport = gfx::Size(50, 80); gfx::Size inner_viewport = gfx::Size(25, 40); - SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport, outer_viewport, + content_size); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); DrawFrame(); { @@ -11565,10 +10244,11 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, gfx::Size outer_viewport = gfx::Size(100, 160); gfx::Size inner_viewport = gfx::Size(50, 80); - SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport, outer_viewport, + content_size); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); DrawFrame(); { @@ -11617,16 +10297,14 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, gfx::Size outer_viewport = gfx::Size(50, 80); gfx::Size inner_viewport = gfx::Size(25, 40); - SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); - - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport, outer_viewport, + content_size); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport); - LayerImpl* child_scroll = child.get(); - outer_scroll->test_properties()->children[0]->test_properties()->AddChild( - std::move(child)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* child_scroll = + AddScrollableLayer(outer_scroll, inner_viewport, outer_viewport); + UpdateDrawProperties(host_impl_->active_tree()); DrawFrame(); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -11634,8 +10312,8 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, ->RootScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, - host_impl_->ViewportMainScrollLayer()->scroll_tree_index()); + EXPECT_EQ(host_impl_->CurrentlyScrollingNode(), + host_impl_->ViewportMainScrollNode()); host_impl_->ScrollEnd(EndState().get()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -11653,12 +10331,12 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, gfx::Size content_size = gfx::Size(100, 160); gfx::Size outer_viewport = gfx::Size(50, 80); gfx::Size inner_viewport = gfx::Size(25, 40); - SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport, outer_viewport, + content_size); // Make inner viewport unscrollable. - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - inner_scroll->test_properties()->user_scrollable_horizontal = false; - inner_scroll->test_properties()->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); + GetScrollNode(inner_scroll)->user_scrollable_horizontal = false; + GetScrollNode(inner_scroll)->user_scrollable_vertical = false; DrawFrame(); @@ -11701,11 +10379,13 @@ TEST_F(LayerTreeHostImplWithImplicitLimitsTest, ImplicitMemoryLimits) { } TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { + const gfx::Size viewport_size(50, 50); const gfx::Size layer_size(100, 100); gfx::Transform external_transform; const gfx::Rect external_viewport(layer_size); const bool resourceless_software_draw = false; - LayerImpl* layer = SetupScrollAndContentsLayers(layer_size); + SetupViewportLayersInnerScrolls(viewport_size, layer_size); + auto* layer = InnerViewportScrollLayer(); layer->SetDrawsContent(true); host_impl_->SetExternalTilePriorityConstraints(external_viewport, @@ -11725,11 +10405,9 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { } TEST_F(LayerTreeHostImplTest, ExternalTransformSetNeedsRedraw) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); + SetupDefaultRootLayer(viewport_size); + UpdateDrawProperties(host_impl_->active_tree()); const gfx::Transform transform_for_tile_priority; const gfx::Transform draw_transform; @@ -11778,11 +10456,9 @@ TEST_F(LayerTreeHostImplTest, OnMemoryPressure) { } TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); + SetupDefaultRootLayer(viewport_size); + UpdateDrawProperties(host_impl_->active_tree()); const gfx::Transform draw_transform; const gfx::Rect draw_viewport1(viewport_size); @@ -11813,11 +10489,9 @@ TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) { // This test verifies that the viewport damage rect is the full viewport and not // just part of the viewport in the presence of an external viewport. TEST_F(LayerTreeHostImplTest, FullViewportDamageAfterOnDraw) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); + SetupDefaultRootLayer(viewport_size); + UpdateDrawProperties(host_impl_->active_tree()); const gfx::Transform draw_transform; const gfx::Rect draw_viewport(gfx::Point(5, 5), viewport_size); @@ -11841,11 +10515,9 @@ class ResourcelessSoftwareLayerTreeHostImplTest : public LayerTreeHostImplTest { TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, ResourcelessSoftwareSetNeedsRedraw) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); + SetupDefaultRootLayer(viewport_size); + UpdateDrawProperties(host_impl_->active_tree()); const gfx::Transform draw_transform; const gfx::Rect draw_viewport(viewport_size); @@ -11873,19 +10545,16 @@ TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, ResourcelessSoftwareDrawSkipsUpdateTiles) { const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); CreatePendingTree(); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(viewport_size)); - std::unique_ptr<FakePictureLayerImpl> layer( - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 11, raster_source)); - layer->SetBounds(viewport_size); - layer->SetDrawsContent(true); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer)); + auto* root = SetupRootLayer<FakePictureLayerImpl>( + host_impl_->pending_tree(), viewport_size, raster_source); + root->SetBounds(viewport_size); + root->SetDrawsContent(true); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); host_impl_->ActivateSyncTree(); const gfx::Transform draw_transform; @@ -11912,25 +10581,19 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, ExternalTileConstraintReflectedInPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); const gfx::Size layer_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_size)); // Set up active and pending tree. CreatePendingTree(); - host_impl_->pending_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_->pending_tree(), 1)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - host_impl_->pending_tree()->UpdateDrawProperties(); - host_impl_->pending_tree() - ->root_layer_for_testing() - ->SetNeedsPushProperties(); + SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), layer_size); + UpdateDrawProperties(host_impl_->pending_tree()); + host_impl_->pending_tree()->root_layer()->SetNeedsPushProperties(); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); CreatePendingTree(); - host_impl_->pending_tree()->UpdateDrawProperties(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->pending_tree()); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(host_impl_->pending_tree()->needs_update_draw_properties()); EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties()); @@ -11946,15 +10609,13 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, ExternalViewportAffectsVisibleRects) { + const gfx::Size viewport_size(50, 50); const gfx::Size layer_size(100, 100); - SetupScrollAndContentsLayers(layer_size); - LayerImpl* content_layer = host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->children[0]; + SetupViewportLayersInnerScrolls(viewport_size, layer_size); + LayerImpl* content_layer = AddContentLayer(); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(90, 90)); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_EQ(gfx::Rect(90, 90), content_layer->visible_layer_rect()); gfx::Transform external_transform; @@ -11977,15 +10638,13 @@ TEST_F(LayerTreeHostImplTest, ExternalViewportAffectsVisibleRects) { } TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsVisibleRects) { + const gfx::Size viewport_size(50, 50); const gfx::Size layer_size(100, 100); - SetupScrollAndContentsLayers(layer_size); - LayerImpl* content_layer = host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->children[0]; + SetupViewportLayersInnerScrolls(viewport_size, layer_size); + LayerImpl* content_layer = AddContentLayer(); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_EQ(gfx::Rect(50, 50), content_layer->visible_layer_rect()); gfx::Transform external_transform; @@ -12013,25 +10672,18 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsVisibleRects) { } TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { + const gfx::Size viewport_size(50, 50); const gfx::Size layer_size(100, 100); - SetupScrollAndContentsLayers(layer_size); - LayerImpl* content_layer = host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->children[0]; - content_layer->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 100)); - LayerImpl* test_layer = host_impl_->active_tree()->LayerById(100); - test_layer->test_properties()->force_render_surface = true; - test_layer->SetDrawsContent(true); - test_layer->SetBounds(layer_size); + SetupViewportLayersInnerScrolls(viewport_size, layer_size); + LayerImpl* test_layer = AddContentLayer(); gfx::Transform perspective_transform; perspective_transform.ApplyPerspectiveDepth(2); - test_layer->test_properties()->transform = perspective_transform; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CreateTransformNode(test_layer).local = perspective_transform; + CreateEffectNode(test_layer).render_surface_reason = + RenderSurfaceReason::kTest; host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); EffectNode* node = host_impl_->active_tree()->property_trees()->effect_tree.Node( test_layer->effect_tree_index()); @@ -12067,7 +10719,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { TEST_F(LayerTreeHostImplTest, ScrollAnimated) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12082,21 +10734,19 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { // for LatencyInfo's to be propagated along with the CompositorFrame int set_needs_commit_count = 0; int set_needs_redraw_count = 0; - int forward_to_main_count = 0; std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12124,11 +10774,10 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { // for LatencyInfo's to be propagated along with the CompositorFrame int set_needs_commit_count = 0; int set_needs_redraw_count = 0; - int forward_to_main_count = 0; std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); // Update target. EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -12136,7 +10785,6 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } host_impl_->DidFinishImplFrame(); @@ -12174,8 +10822,8 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { TEST_F(LayerTreeHostImplTest, ScrollAnimatedWhileZoomed) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* scrolling_layer = host_impl_->InnerViewportScrollLayer(); + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* scrolling_layer = InnerViewportScrollLayer(); DrawFrame(); @@ -12246,21 +10894,16 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { // Setup the viewport. const gfx::Size viewport_size = gfx::Size(360, 600); const gfx::Size content_size = gfx::Size(345, 3800); - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* scroll_layer = host_impl_->OuterViewportScrollLayer(); + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* scroll_layer = OuterViewportScrollLayer(); // Set up the scrollbar and its dimensions. LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar = - PaintedScrollbarLayerImpl::Create(layer_tree_impl, 99, VERTICAL, false, - true); + auto* scrollbar = AddLayer<PaintedScrollbarLayerImpl>(layer_tree_impl, + VERTICAL, false, true); + SetupScrollbarLayer(scroll_layer, scrollbar); const gfx::Size scrollbar_size = gfx::Size(15, 600); scrollbar->SetBounds(scrollbar_size); - scrollbar->test_properties()->position = gfx::PointF(345, 0); - scrollbar->SetScrollElementId(scroll_layer->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->SetHitTestable(true); - scrollbar->test_properties()->opacity = 1.f; // Set up the thumb dimensions. scrollbar->SetThumbThickness(15); @@ -12274,10 +10917,8 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { scrollbar->SetForwardButtonRect( gfx::Rect(gfx::Point(345, 570), gfx::Size(15, 15))); - // Add the scrollbar to the outer viewport. - scroll_layer->test_properties()->AddChild(std::move(scrollbar)); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); - host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl_->ScrollBegin(BeginState(gfx::Point(350, 18)).get(), InputHandler::SCROLLBAR); TestInputHandlerClient input_handler_client; @@ -12294,7 +10935,7 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { // MouseDown on the thumb should not produce a scroll. InputHandlerPointerResult result = - host_impl_->MouseDown(gfx::PointF(350, 18)); + host_impl_->MouseDown(gfx::PointF(350, 18), /*shift_modifier*/ false); EXPECT_EQ(result.scroll_offset.y(), 0u); // The first request for a GSU should be processed as expected. @@ -12333,7 +10974,7 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -12350,7 +10991,7 @@ TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) { TEST_F(LayerTreeHostImplTest, AnimatedScrollUpdateTargetBeforeStarting) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12391,7 +11032,7 @@ TEST_F(LayerTreeHostImplTest, AnimatedScrollUpdateTargetBeforeStarting) { host_impl_->UpdateAnimationState(true); host_impl_->DidFinishImplFrame(); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12403,7 +11044,7 @@ TEST_F(LayerTreeHostImplTest, AnimatedScrollUpdateTargetBeforeStarting) { TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12419,7 +11060,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) { base::TimeDelta::FromMilliseconds(100)) .thread); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12465,7 +11106,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) { TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12480,7 +11121,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12535,7 +11176,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12549,7 +11190,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12609,11 +11250,11 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) { const gfx::Size content_size(200, 200); const gfx::Size viewport_size(100, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersOuterScrolls(viewport_size, content_size); + UpdateDrawProperties(host_impl_->active_tree()); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); // Zoom into the page by a 2X factor float min_page_scale = 1.f, max_page_scale = 4.f; @@ -12707,10 +11348,10 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) { TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimatedUpdate) { const gfx::Size content_size(200, 200); const gfx::Size viewport_size(100, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); // Zoom into the page by a 2X factor float min_page_scale = 1.f, max_page_scale = 4.f; @@ -12767,15 +11408,11 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimatedUpdate) { TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - host_impl_->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = true; - host_impl_->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); + GetScrollNode(scrolling_layer)->user_scrollable_vertical = true; + GetScrollNode(scrolling_layer)->user_scrollable_horizontal = false; DrawFrame(); @@ -12789,7 +11426,6 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) { InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12852,8 +11488,9 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) { const gfx::Size new_content_size(750, 750); const gfx::Size viewport_size(500, 500); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, old_content_size); + SetupViewportLayersOuterScrolls(viewport_size, old_content_size); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); + LayerImpl* content_layer = AddContentLayer(); DrawFrame(); @@ -12864,7 +11501,6 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) { host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(500, 500)); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12877,7 +11513,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) { content_layer->SetBounds(new_content_size); scrolling_layer->SetBounds(new_content_size); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(scrolling_layer)->bounds = new_content_size; DrawFrame(); @@ -12900,9 +11536,8 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) { scoped_refptr<RasterSource> raster_source_with_tiles( FakeRasterSource::CreateFilled(gfx::Size(10, 10))); - std::unique_ptr<FakePictureLayerImpl> layer = - FakePictureLayerImpl::Create(host_impl_->pending_tree(), 11); - layer->SetBounds(gfx::Size(10, 10)); + auto* layer = SetupRootLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), + gfx::Size(10, 10)); layer->set_gpu_raster_max_texture_size( host_impl_->active_tree()->GetDeviceViewport().size()); layer->SetDrawsContent(true); @@ -12914,18 +11549,14 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) { layer->tilings()->tiling_at(0)->CreateAllTilesForTesting(); layer->tilings()->UpdateTilePriorities(gfx::Rect(gfx::Size(10, 10)), 1.f, 1.0, Occlusion(), true); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer)); - auto* root_layer = static_cast<FakePictureLayerImpl*>( - host_impl_->pending_tree()->root_layer_for_testing()); - - root_layer->set_has_valid_tile_priorities(true); + layer->set_has_valid_tile_priorities(true); std::unique_ptr<RasterTilePriorityQueue> non_empty_raster_priority_queue_all = host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL); EXPECT_FALSE(non_empty_raster_priority_queue_all->IsEmpty()); - root_layer->set_has_valid_tile_priorities(false); + layer->set_has_valid_tile_priorities(false); std::unique_ptr<RasterTilePriorityQueue> empty_raster_priority_queue_all = host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL); @@ -12939,44 +11570,39 @@ TEST_F(LayerTreeHostImplTest, DidBecomeActive) { LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::Create(pending_tree, 10); - FakePictureLayerImpl* raw_pending_layer = pending_layer.get(); - pending_tree->SetRootLayerForTesting(std::move(pending_layer)); - ASSERT_EQ(raw_pending_layer, pending_tree->root_layer_for_testing()); + auto* pending_layer = + SetupRootLayer<FakePictureLayerImpl>(pending_tree, gfx::Size(10, 10)); - EXPECT_EQ(0u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(0u, pending_layer->did_become_active_call_count()); pending_tree->DidBecomeActive(); - EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(1u, pending_layer->did_become_active_call_count()); std::unique_ptr<FakePictureLayerImpl> mask_layer = - FakePictureLayerImpl::Create(pending_tree, 11); + FakePictureLayerImpl::Create(pending_tree, next_layer_id_++); FakePictureLayerImpl* raw_mask_layer = mask_layer.get(); - raw_pending_layer->test_properties()->SetMaskLayer(std::move(mask_layer)); - ASSERT_EQ(raw_mask_layer, raw_pending_layer->test_properties()->mask_layer); - pending_tree->BuildPropertyTreesForTesting(); + SetupMaskProperties(pending_layer, raw_mask_layer); + pending_tree->AddLayer(std::move(mask_layer)); - EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(1u, pending_layer->did_become_active_call_count()); EXPECT_EQ(0u, raw_mask_layer->did_become_active_call_count()); pending_tree->DidBecomeActive(); - EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(2u, pending_layer->did_become_active_call_count()); EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); - pending_tree->BuildPropertyTreesForTesting(); - - EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(2u, pending_layer->did_become_active_call_count()); EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); pending_tree->DidBecomeActive(); - EXPECT_EQ(3u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(3u, pending_layer->did_become_active_call_count()); EXPECT_EQ(2u, raw_mask_layer->did_become_active_call_count()); } TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); - EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); + EXPECT_EQ(scroll_layer, InnerViewportScrollLayer()); float min_page_scale = 1.f, max_page_scale = 4.f; float page_scale_factor = 1.f; @@ -13223,33 +11849,6 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) { EXPECT_FALSE(controller.did_draw_frame()); } -// Tests that SetHasGpuRasterizationTrigger behaves as expected. -TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusTrigger) { - // Set initial state, before varying GPU rasterization trigger. - host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->SetContentHasSlowPaths(false); - host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, - host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); - host_impl_->NotifyReadyToActivate(); - - // Toggle the trigger on. - host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); - EXPECT_TRUE(host_impl_->use_gpu_rasterization()); - host_impl_->NotifyReadyToActivate(); - - // And off. - host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, - host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); - host_impl_->NotifyReadyToActivate(); -} - // Tests that SetContentHasSlowPaths behaves as expected. TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSlowPaths) { LayerTreeSettings msaaSettings = DefaultSettings(); @@ -13259,7 +11858,6 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSlowPaths) { msaaSettings.gpu_rasterization_msaa_sample_count))); // Set initial state, with slow paths on. - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, @@ -13294,7 +11892,6 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) { msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(4))); // Set initial state, before varying scale factor. - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -13329,7 +11926,6 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusExplicitMSAACount) { msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization( msaaSettings.gpu_rasterization_msaa_sample_count))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, @@ -13349,10 +11945,8 @@ class GpuRasterizationDisabledLayerTreeHostImplTest // Tests that GPU rasterization overrides work as expected. TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest, GpuRasterizationStatusOverrides) { - // GPU rasterization explicitly disabled. LayerTreeSettings settings = DefaultSettings(); EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d())); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, @@ -13363,7 +11957,6 @@ TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest, settings.gpu_rasterization_forced = true; EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d())); - host_impl_->SetHasGpuRasterizationTrigger(false); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON_FORCED, @@ -13394,7 +11987,6 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // Ensure that without the msaa_is_slow or avoid_stencil_buffers caps // we raster slow paths with msaa. CreateHostImplWithCaps(false, false); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, @@ -13405,7 +11997,6 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // we don't raster slow paths with msaa (we'll still use GPU raster, though). // msaa_is_slow = true, avoid_stencil_buffers = false CreateHostImplWithCaps(true, false); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -13414,7 +12005,6 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // msaa_is_slow = false, avoid_stencil_buffers = true CreateHostImplWithCaps(false, true); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -13423,7 +12013,6 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // msaa_is_slow = true, avoid_stencil_buffers = true CreateHostImplWithCaps(true, true); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -13455,7 +12044,6 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, // Ensure that without non-aa paint and without multisample compatibility, we // raster slow paths with msaa. CreateHostImplWithMultisampleCompatibility(false); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->SetContentHasNonAAPaint(false); host_impl_->CommitComplete(); @@ -13466,7 +12054,6 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, // Ensure that without non-aa paint and with multisample compatibility, we // raster slow paths with msaa. CreateHostImplWithMultisampleCompatibility(true); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->SetContentHasNonAAPaint(false); host_impl_->CommitComplete(); @@ -13477,7 +12064,6 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, // Ensure that with non-aa paint and without multisample compatibility, we do // not raster slow paths with msaa. CreateHostImplWithMultisampleCompatibility(false); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->SetContentHasNonAAPaint(true); host_impl_->CommitComplete(); @@ -13487,7 +12073,6 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, // Ensure that with non-aa paint and with multisample compatibility, we raster // slow paths with msaa. CreateHostImplWithMultisampleCompatibility(true); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->SetContentHasNonAAPaint(true); host_impl_->CommitComplete(); @@ -13501,45 +12086,44 @@ TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { // on the active tree. CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), - gfx::Size(100, 100)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50), + gfx::Size(100, 100), gfx::Size(100, 100)); host_impl_->ActivateSyncTree(); DrawFrame(); CreatePendingTree(); host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f); - LayerImpl* page_scale_layer = host_impl_->active_tree()->PageScaleLayer(); TransformNode* active_tree_node = - host_impl_->active_tree()->property_trees()->transform_tree.Node( - page_scale_layer->transform_tree_index()); + host_impl_->active_tree()->PageScaleTransformNode(); // SetPageScaleOnActiveTree also updates the factors in property trees. EXPECT_TRUE(active_tree_node->local.IsScale2d()); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), active_tree_node->local.Scale2d()); EXPECT_EQ(gfx::Point3F(), active_tree_node->origin); - EXPECT_EQ(host_impl_->active_tree()->current_page_scale_factor(), 2.f); + EXPECT_EQ(2.f, host_impl_->active_tree()->current_page_scale_factor()); TransformNode* pending_tree_node = - host_impl_->pending_tree()->property_trees()->transform_tree.Node( - page_scale_layer->transform_tree_index()); + host_impl_->pending_tree()->PageScaleTransformNode(); + // Before pending tree updates draw properties, its properties are still + // based on 1.0 page scale, except for current_page_scale_factor() which is a + // shared data between the active and pending trees. EXPECT_TRUE(pending_tree_node->local.IsIdentity()); EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin); - EXPECT_EQ(host_impl_->pending_tree()->current_page_scale_factor(), 2.f); - - host_impl_->pending_tree()->UpdateDrawProperties(); - pending_tree_node = - host_impl_->pending_tree()->property_trees()->transform_tree.Node( - page_scale_layer->transform_tree_index()); + EXPECT_EQ(2.f, host_impl_->pending_tree()->current_page_scale_factor()); + EXPECT_EQ(1.f, host_impl_->pending_tree() + ->property_trees() + ->transform_tree.page_scale_factor()); + + host_impl_->pending_tree()->set_needs_update_draw_properties(); + UpdateDrawProperties(host_impl_->pending_tree()); + pending_tree_node = host_impl_->pending_tree()->PageScaleTransformNode(); EXPECT_TRUE(pending_tree_node->local.IsScale2d()); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), pending_tree_node->local.Scale2d()); EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->UpdateDrawProperties(); - active_tree_node = - host_impl_->active_tree()->property_trees()->transform_tree.Node( - page_scale_layer->transform_tree_index()); + UpdateDrawProperties(host_impl_->active_tree()); + active_tree_node = host_impl_->active_tree()->PageScaleTransformNode(); EXPECT_TRUE(active_tree_node->local.IsScale2d()); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), active_tree_node->local.Scale2d()); EXPECT_EQ(gfx::Point3F(), active_tree_node->origin); @@ -13549,102 +12133,27 @@ TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) { // Checks that the sublayer scale of a transform node in the subtree of the // page scale layer is updated without a property tree rebuild. host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f); - CreateScrollAndContentsLayers(host_impl_->active_tree(), gfx::Size(100, 100)); - LayerImpl* page_scale_layer = host_impl_->active_tree()->PageScaleLayer(); - page_scale_layer->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 100)); - - LayerImpl* in_subtree_of_page_scale_layer = - host_impl_->active_tree()->LayerById(100); - in_subtree_of_page_scale_layer->test_properties()->force_render_surface = - true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + LayerImpl* in_subtree_of_page_scale_layer = AddLayer(); + CopyProperties(root_layer(), in_subtree_of_page_scale_layer); + in_subtree_of_page_scale_layer->SetTransformTreeIndex( + host_impl_->active_tree()->PageScaleTransformNode()->id); + CreateEffectNode(in_subtree_of_page_scale_layer).render_surface_reason = + RenderSurfaceReason::kTest; DrawFrame(); - EffectNode* node = - host_impl_->active_tree()->property_trees()->effect_tree.Node( - in_subtree_of_page_scale_layer->effect_tree_index()); + EffectNode* node = GetEffectNode(in_subtree_of_page_scale_layer); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f)); host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f); DrawFrame(); - in_subtree_of_page_scale_layer = host_impl_->active_tree()->LayerById(100); - node = host_impl_->active_tree()->property_trees()->effect_tree.Node( - in_subtree_of_page_scale_layer->effect_tree_index()); + node = GetEffectNode(in_subtree_of_page_scale_layer); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f)); } -TEST_F(LayerTreeHostImplTest, JitterTest) { - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); - - CreatePendingTree(); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), - gfx::Size(100, 100)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - - host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - const int scroll = 5; - int accumulated_scroll = 0; - for (int i = 0; i < host_impl_->pending_tree()->kFixedPointHitsThreshold + 1; - ++i) { - host_impl_->ActivateSyncTree(); - host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::TOUCHSCREEN); - host_impl_->ScrollBy( - UpdateState(gfx::Point(), gfx::Vector2dF(0, scroll)).get()); - accumulated_scroll += scroll; - host_impl_->ScrollEnd(EndState().get()); - host_impl_->active_tree()->UpdateDrawProperties(); - - CreatePendingTree(); - host_impl_->pending_tree()->set_source_frame_number(i + 1); - LayerImpl* content_layer = host_impl_->pending_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->children[0]; - // The scroll done on the active tree is undone on the pending tree. - gfx::Transform translate; - translate.Translate(0, accumulated_scroll); - content_layer->test_properties()->transform = translate; - - LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - LayerImpl* last_scrolled_layer = pending_tree->LayerById( - host_impl_->active_tree()->InnerViewportScrollLayer()->id()); - - // When building property trees from impl side, the builder uses the scroll - // offset of layer_impl to initialize the scroll offset in scroll tree: - // scroll_tree.synced_scroll_offset.PushMainToPending( - // layer->CurrentScrollOffset()). - // However, layer_impl does not store scroll_offset, so it is using scroll - // tree's scroll offset to initialize itself. Usually this approach works - // because this is a simple assignment. However if scroll_offset's pending - // delta is not zero, the delta would be counted twice. - // This hacking here is to restore the damaged scroll offset. - gfx::ScrollOffset pending_base = - pending_tree->property_trees() - ->scroll_tree.GetScrollOffsetBaseForTesting( - last_scrolled_layer->element_id()); - pending_tree->BuildPropertyTreesForTesting(); - pending_tree->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - last_scrolled_layer->element_id(), pending_base); - pending_tree->LayerById(content_layer->id())->SetNeedsPushProperties(); - - pending_tree->set_needs_update_draw_properties(); - pending_tree->UpdateDrawProperties(); - float jitter = LayerTreeHostCommon::CalculateLayerJitter(content_layer); - // There should not be any jitter measured till we hit the fixed point hits - // threshold. - float expected_jitter = - (i == pending_tree->kFixedPointHitsThreshold) ? 500 : 0; - EXPECT_EQ(jitter, expected_jitter); - } -} - // Checks that if we lose a GPU raster enabled LayerTreeFrameSink and replace // it with a software LayerTreeFrameSink, LayerTreeHostImpl correctly // re-computes GPU rasterization status. @@ -13658,7 +12167,8 @@ TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnLayerTreeFrameSinkChange) { host_impl_ = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, - AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr); + AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr, + nullptr); host_impl_->SetVisible(true); // InitializeFrameSink with a gpu-raster enabled output surface. @@ -13685,48 +12195,29 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( gfx::Size scrollbar_size_1(gfx::Size(15, viewport_size.height())); gfx::Size scrollbar_size_2(gfx::Size(15, child_layer_size.height())); - const int scrollbar_1_id = 10; - const int scrollbar_2_id = 11; - const int child_scroll_id = 13; - CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); if (main_thread_scrolling) { - root_scroll->test_properties()->main_thread_scrolling_reasons = + GetScrollNode(root_scroll)->main_thread_scrolling_reasons = MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; } // scrollbar_1 on root scroll. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_1 = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_1_id, VERTICAL, 15, 0, - true, true); - scrollbar_1->SetScrollElementId(root_scroll->element_id()); - scrollbar_1->SetDrawsContent(true); + auto* scrollbar_1 = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + SetupScrollbarLayer(root_scroll, scrollbar_1); scrollbar_1->SetBounds(scrollbar_size_1); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1)); scrollbar_1->SetTouchActionRegion(touch_action_region); - scrollbar_1->SetCurrentPos(0); - scrollbar_1->test_properties()->position = gfx::PointF(0, 0); - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar_1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->UpdateScrollbarGeometries(); host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); - host_impl_->active_tree()->UpdateDrawProperties(); ScrollbarAnimationController* scrollbar_1_animation_controller = host_impl_->ScrollbarAnimationControllerForElementId( @@ -13800,40 +12291,26 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); // scrollbar_2 on child. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_2 = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_2_id, VERTICAL, 15, 0, - true, true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->test_properties()->position = gfx::PointF(50, 50); - child->SetBounds(child_layer_size); - child->SetDrawsContent(true); - child->SetScrollable(gfx::Size(100, 100)); - child->SetHitTestable(true); - child->SetElementId(LayerIdToElementIdForTesting(child->id())); - ElementId child_element_id = child->element_id(); - + auto* scrollbar_2 = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + LayerImpl* child = + AddScrollableLayer(root_scroll, gfx::Size(100, 100), child_layer_size); + child->SetOffsetToTransformParent(gfx::Vector2dF(50, 50)); if (main_thread_scrolling) { - child->test_properties()->main_thread_scrolling_reasons = + GetScrollNode(child)->main_thread_scrolling_reasons = MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; } - scrollbar_2->SetScrollElementId(child_element_id); - scrollbar_2->SetDrawsContent(true); + SetupScrollbarLayer(child, scrollbar_2); scrollbar_2->SetBounds(scrollbar_size_2); - scrollbar_2->SetCurrentPos(0); - scrollbar_2->test_properties()->position = gfx::PointF(0, 0); - - child->test_properties()->AddChild(std::move(scrollbar_2)); - root_scroll->test_properties()->AddChild(std::move(child)); + scrollbar_2->SetOffsetToTransformParent(child->offset_to_transform_parent()); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->UpdateScrollbarGeometries(); host_impl_->active_tree()->DidBecomeActive(); ScrollbarAnimationController* scrollbar_2_animation_controller = - host_impl_->ScrollbarAnimationControllerForElementId(child_element_id); + host_impl_->ScrollbarAnimationControllerForElementId(child->element_id()); EXPECT_TRUE(scrollbar_2_animation_controller); // Mouse goes over scrollbar_2, moves close to scrollbar_2, moves close to @@ -13896,7 +12373,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( animation_task_.Reset(); // Only the MouseMove's location will affect the overlay scrollbar. - host_impl_->MouseDown(gfx::PointF(60, 50)); + host_impl_->MouseDown(gfx::PointF(60, 50), /*shift_modifier*/ false); host_impl_->MouseMoveAt(gfx::Point(60, 50)); host_impl_->MouseUp(gfx::PointF(60, 50)); @@ -13907,14 +12384,14 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( host_impl_->MouseMoveAt(gfx::Point(40, 150)); animation_task_.Reset(); - host_impl_->MouseDown(gfx::PointF(40, 150)); + host_impl_->MouseDown(gfx::PointF(40, 150), /*shift_modifier*/ false); host_impl_->MouseUp(gfx::PointF(40, 150)); EXPECT_TRUE(animation_task_.is_null()); // Near scrollbar_1, then mouse down and unregister // scrollbar_2_animation_controller, then mouse up should not cause crash. host_impl_->MouseMoveAt(gfx::Point(40, 150)); - host_impl_->MouseDown(gfx::PointF(40, 150)); + host_impl_->MouseDown(gfx::PointF(40, 150), /*shift_modifier*/ false); host_impl_->UnregisterScrollbarAnimationController(root_scroll->element_id()); host_impl_->MouseUp(gfx::PointF(40, 150)); } @@ -13930,7 +12407,7 @@ TEST_F(LayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { - LayerTreeSettings settings = DefaultSettings(); + LayerTreeSettings settings = LegacySWSettings(); settings.commit_to_active_tree = false; settings.enable_checker_imaging = true; settings.min_image_bytes_to_checker = 512 * 1024; @@ -13966,14 +12443,10 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { // Create the pending tree. host_impl_->BeginCommit(); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->SetDeviceViewportRect(gfx::Rect(layer_size)); - pending_tree->SetRootLayerForTesting( - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 1, - raster_source)); - auto* root = static_cast<FakePictureLayerImpl*>(*pending_tree->begin()); - root->SetBounds(layer_size); + auto* root = SetupRootLayer<FakePictureLayerImpl>(pending_tree, layer_size, + raster_source); root->SetDrawsContent(true); - pending_tree->BuildPropertyTreesForTesting(); + UpdateDrawProperties(pending_tree); // Update the decoding state map for the tracker so it knows the correct // decoding preferences for the image. @@ -14004,7 +12477,7 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { // invalidated on the pending tree. host_impl_->InvalidateContentOnImplSide(); pending_tree = host_impl_->pending_tree(); - root = static_cast<FakePictureLayerImpl*>(*pending_tree->begin()); + root = static_cast<FakePictureLayerImpl*>(pending_tree->root_layer()); for (auto* tile : root->tilings()->tiling_at(0)->AllTilesForTesting()) { if (tile->tiling_i_index() < 2 && tile->tiling_j_index() < 2) EXPECT_TRUE(tile->HasRasterTask()); @@ -14043,34 +12516,29 @@ TEST_F(LayerTreeHostImplTest, RasterColorSpaceSoftware) { TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { gfx::Size layer_bounds(500, 500); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds)); CreatePendingTree(); - std::unique_ptr<LayerImpl> scoped_root = - LayerImpl::Create(host_impl_->pending_tree(), 1); - scoped_root->SetBounds(layer_bounds); - LayerImpl* root = scoped_root.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); + auto* root = + SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), layer_bounds); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(layer_bounds)); - std::unique_ptr<FakePictureLayerImpl> scoped_animated_transform_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 2, raster_source); - scoped_animated_transform_layer->SetBounds(layer_bounds); - scoped_animated_transform_layer->SetDrawsContent(true); + auto* animated_transform_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), raster_source); + animated_transform_layer->SetBounds(layer_bounds); + animated_transform_layer->SetDrawsContent(true); + + host_impl_->pending_tree()->SetElementIdsForTesting(); gfx::Transform singular; singular.Scale3d(6.f, 6.f, 0.f); - scoped_animated_transform_layer->test_properties()->transform = singular; - FakePictureLayerImpl* animated_transform_layer = - scoped_animated_transform_layer.get(); - root->test_properties()->AddChild(std::move(scoped_animated_transform_layer)); + CopyProperties(root, animated_transform_layer); + CreateTransformNode(animated_transform_layer).local = singular; // A layer with a non-invertible transform is not drawn or rasterized. Since // this layer is not rasterized, we shouldn't be creating any tilings for it. - host_impl_->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); EXPECT_FALSE(animated_transform_layer->HasValidTilePriorities()); EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 0u); - host_impl_->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->pending_tree()); EXPECT_FALSE(animated_transform_layer->raster_even_if_not_drawn()); EXPECT_FALSE(animated_transform_layer->contributes_to_drawn_render_surface()); EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 0u); @@ -14078,7 +12546,6 @@ TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { // Now add a transform animation to this layer. While we don't drawn layers // with non-invertible transforms, we still raster them if there is a // transform animation. - host_impl_->pending_tree()->SetElementIdsForTesting(); TransformOperations start_transform_operations; start_transform_operations.AppendMatrix(singular); TransformOperations end_transform_operations; @@ -14089,11 +12556,10 @@ TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { // The layer is still not drawn, but it will be rasterized. Since the layer is // rasterized, we should be creating tilings for it in UpdateDrawProperties. // However, none of these tiles should be required for activation. - host_impl_->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl_->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->pending_tree()); EXPECT_TRUE(animated_transform_layer->raster_even_if_not_drawn()); EXPECT_FALSE(animated_transform_layer->contributes_to_drawn_render_surface()); - EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 1u); + ASSERT_EQ(animated_transform_layer->tilings()->num_tilings(), 1u); EXPECT_FALSE(animated_transform_layer->tilings() ->tiling_at(0) ->can_require_tiles_for_activation()); @@ -14101,38 +12567,29 @@ TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { TEST_F(LayerTreeHostImplTest, RasterTilePrioritizationForNonDrawingLayers) { gfx::Size layer_bounds(500, 500); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds)); CreatePendingTree(); - std::unique_ptr<LayerImpl> scoped_root = - LayerImpl::Create(host_impl_->pending_tree(), 1); - scoped_root->SetBounds(layer_bounds); - LayerImpl* root = scoped_root.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); + auto* root = + SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), layer_bounds); + root->SetBounds(layer_bounds); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(layer_bounds)); - std::unique_ptr<FakePictureLayerImpl> scoped_hidden_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 2, raster_source); - scoped_hidden_layer->SetBounds(layer_bounds); - scoped_hidden_layer->SetDrawsContent(true); - scoped_hidden_layer->set_contributes_to_drawn_render_surface(true); - FakePictureLayerImpl* hidden_layer = scoped_hidden_layer.get(); - root->test_properties()->AddChild(std::move(scoped_hidden_layer)); - - std::unique_ptr<FakePictureLayerImpl> scoped_drawing_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 3, raster_source); - scoped_drawing_layer->SetBounds(layer_bounds); - scoped_drawing_layer->SetDrawsContent(true); - scoped_drawing_layer->set_contributes_to_drawn_render_surface(true); - FakePictureLayerImpl* drawing_layer = scoped_drawing_layer.get(); - root->test_properties()->AddChild(std::move(scoped_drawing_layer)); + auto* hidden_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), raster_source); + hidden_layer->SetBounds(layer_bounds); + hidden_layer->SetDrawsContent(true); + hidden_layer->set_contributes_to_drawn_render_surface(true); + CopyProperties(root, hidden_layer); + + auto* drawing_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), raster_source); + drawing_layer->SetBounds(layer_bounds); + drawing_layer->SetDrawsContent(true); + drawing_layer->set_contributes_to_drawn_render_surface(true); + CopyProperties(root, drawing_layer); gfx::Rect layer_rect(0, 0, 500, 500); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); hidden_layer->tilings()->AddTiling(gfx::AxisTransform2d(), raster_source); PictureLayerTiling* hidden_tiling = hidden_layer->tilings()->tiling_at(0); @@ -14179,19 +12636,13 @@ TEST_F(LayerTreeHostImplTest, DrawAfterDroppingTileResources) { gfx::Size bounds(100, 100); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(bounds)); - { - std::unique_ptr<FakePictureLayerImpl> scoped_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 1, raster_source); - scoped_layer->SetBounds(bounds); - scoped_layer->SetDrawsContent(true); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_layer)); - } - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + auto* root = SetupRootLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), + bounds, raster_source); + root->SetDrawsContent(true); host_impl_->ActivateSyncTree(); FakePictureLayerImpl* layer = static_cast<FakePictureLayerImpl*>( - host_impl_->active_tree()->FindActiveTreeLayerById(1)); + host_impl_->active_tree()->FindActiveTreeLayerById(root->id())); DrawFrame(); EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties()); @@ -14213,11 +12664,6 @@ TEST_F(LayerTreeHostImplTest, DrawAfterDroppingTileResources) { TEST_F(LayerTreeHostImplTest, NeedUpdateGpuRasterization) { EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting()); - host_impl_->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting()); - host_impl_->CommitComplete(); - EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting()); - host_impl_->SetContentHasSlowPaths(true); EXPECT_TRUE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting()); host_impl_->CommitComplete(); @@ -14278,7 +12724,7 @@ class TestRenderFrameMetadataObserver : public RenderFrameMetadataObserver { }; TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); @@ -14319,22 +12765,16 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { // Root "overflow: hidden" properties should be reflected on the outer // viewport scroll layer. { - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_horizontal = false; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_FALSE(metadata.root_overflow_y_hidden); } { - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_vertical = false; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_TRUE(metadata.root_overflow_y_hidden); @@ -14343,15 +12783,9 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { // Re-enable scrollability and verify that overflows are no longer // hidden. { - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = true; - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_horizontal = true; + host_impl_->OuterViewportScrollNode()->user_scrollable_vertical = true; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_FALSE(metadata.root_overflow_y_hidden); @@ -14360,22 +12794,16 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { // Root "overflow: hidden" properties should also be reflected on the // inner viewport scroll layer. { - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_horizontal = false; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_FALSE(metadata.root_overflow_y_hidden); } { - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_vertical = false; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_TRUE(metadata.root_overflow_y_hidden); @@ -14423,16 +12851,8 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { } TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { - const int root_layer_id = 1; - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; - - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); auto observer = std::make_unique<TestRenderFrameMetadataObserver>(false); auto* observer_ptr = observer.get(); @@ -14441,10 +12861,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { // Trigger a draw-swap sequence. host_impl_->SetNeedsRedraw(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame)); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); // Ensure the selection bounds propagated to the render frame metadata // represent an empty selection. @@ -14463,7 +12880,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { gfx::Point selection_bottom(5, 5); LayerSelection selection; selection.start.type = gfx::SelectionBound::CENTER; - selection.start.layer_id = root_layer_id; + selection.start.layer_id = root->id(); selection.start.edge_bottom = selection_bottom; selection.start.edge_top = selection_top; selection.end = selection.start; @@ -14471,9 +12888,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { // Trigger a draw-swap sequence. host_impl_->SetNeedsRedraw(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame)); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); // Ensure the selection bounds have propagated to the render frame metadata. ASSERT_TRUE(observer_ptr->last_metadata()); @@ -14490,8 +12905,8 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { // Tests ScrollBy() to see if the method sets the scroll tree's currently // scrolling node and the ScrollState properly. TEST_F(LayerTreeHostImplTest, ScrollByScrollingNode) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + UpdateDrawProperties(host_impl_->active_tree()); // Create a ScrollState object with no scrolling element. ScrollStateData scroll_state_data; @@ -14544,8 +12959,8 @@ class HitTestRegionListGeneratingLayerTreeHostImplTest // Enable hit test data generation with the CompositorFrame. LayerTreeSettings new_settings = settings; new_settings.build_hit_test_data = true; - return CreateHostImplWithTaskRunnerProvider( - new_settings, std::move(layer_tree_frame_sink), &task_runner_provider_); + return LayerTreeHostImplTest::CreateHostImpl( + new_settings, std::move(layer_tree_frame_sink)); } }; @@ -14556,22 +12971,18 @@ TEST_F(LayerTreeHostImplTest, DisabledBuildHitTestData) { // Setup surface layers in LayerTreeHostImpl. host_impl_->CreatePendingTree(); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - std::unique_ptr<SurfaceLayerImpl> surface_child = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); + auto* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* surface_child = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); - surface_child->test_properties()->position = gfx::PointF(50, 50); surface_child->SetBounds(gfx::Size(100, 100)); surface_child->SetDrawsContent(true); surface_child->SetSurfaceHitTestable(true); - root->test_properties()->AddChild(std::move(surface_child)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); + CopyProperties(root, surface_child); + surface_child->SetOffsetToTransformParent(gfx::Vector2dF(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); base::Optional<viz::HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); @@ -14591,36 +13002,26 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) { // +-----surface_child1 (50, 50), 100x100, Rotate(45) // +---surface_child2 (450, 300), 100x100 // +---overlapping_layer (500, 350), 200x200 - std::unique_ptr<LayerImpl> intermediate_layer = - LayerImpl::Create(host_impl_->active_tree(), 2); - std::unique_ptr<SurfaceLayerImpl> surface_child1 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); - std::unique_ptr<SurfaceLayerImpl> surface_child2 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 4); - std::unique_ptr<LayerImpl> overlapping_layer = - LayerImpl::Create(host_impl_->active_tree(), 5); + auto* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* intermediate_layer = AddLayer(); + auto* surface_child1 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); + auto* surface_child2 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); + auto* overlapping_layer = AddLayer(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); - - intermediate_layer->test_properties()->position = gfx::PointF(200, 300); intermediate_layer->SetBounds(gfx::Size(200, 200)); - surface_child1->test_properties()->position = gfx::PointF(50, 50); surface_child1->SetBounds(gfx::Size(100, 100)); gfx::Transform rotate; rotate.Rotate(45); - surface_child1->test_properties()->transform = rotate; surface_child1->SetDrawsContent(true); surface_child1->SetHitTestable(true); surface_child1->SetSurfaceHitTestable(true); - surface_child2->test_properties()->position = gfx::PointF(450, 300); surface_child2->SetBounds(gfx::Size(100, 100)); surface_child2->SetDrawsContent(true); surface_child2->SetHitTestable(true); surface_child2->SetSurfaceHitTestable(true); - overlapping_layer->test_properties()->position = gfx::PointF(500, 350); overlapping_layer->SetBounds(gfx::Size(200, 200)); overlapping_layer->SetDrawsContent(true); overlapping_layer->SetHitTestable(true); @@ -14634,24 +13035,20 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) { surface_child2->SetRange(viz::SurfaceRange(base::nullopt, child_surface_id), base::nullopt); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - intermediate_layer->test_properties()->AddChild(std::move(surface_child1)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(intermediate_layer)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child2)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(overlapping_layer)); + CopyProperties(root, intermediate_layer); + intermediate_layer->SetOffsetToTransformParent(gfx::Vector2dF(200, 300)); + CopyProperties(root, surface_child2); + surface_child2->SetOffsetToTransformParent(gfx::Vector2dF(450, 300)); + CopyProperties(root, overlapping_layer); + overlapping_layer->SetOffsetToTransformParent(gfx::Vector2dF(500, 350)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(intermediate_layer, surface_child1); + auto& surface_child1_transform_node = CreateTransformNode(surface_child1); + // The post_translation includes offset of intermediate_layer. + surface_child1_transform_node.post_translation = gfx::Vector2dF(250, 350); + surface_child1_transform_node.local = rotate; + + UpdateDrawProperties(host_impl_->active_tree()); draw_property_utils::ComputeEffects( &host_impl_->active_tree()->property_trees()->effect_tree); @@ -14710,26 +13107,24 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, PointerEvents) { // +---surface_child1 (0, 0), 100x100 // +---overlapping_surface_child2 (50, 50), 100x100, pointer-events: none, // does not generate hit test region - std::unique_ptr<SurfaceLayerImpl> surface_child1 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 2); - std::unique_ptr<SurfaceLayerImpl> surface_child2 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); + auto* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* surface_child1 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); + auto* surface_child2 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); - - surface_child1->test_properties()->position = gfx::PointF(0, 0); surface_child1->SetBounds(gfx::Size(100, 100)); surface_child1->SetDrawsContent(true); surface_child1->SetHitTestable(true); surface_child1->SetSurfaceHitTestable(true); surface_child1->SetHasPointerEventsNone(false); + CopyProperties(root, surface_child1); - surface_child2->test_properties()->position = gfx::PointF(50, 50); surface_child2->SetBounds(gfx::Size(100, 100)); surface_child2->SetDrawsContent(true); surface_child2->SetHitTestable(true); surface_child2->SetSurfaceHitTestable(false); surface_child2->SetHasPointerEventsNone(true); + CopyProperties(root, surface_child2); + surface_child2->SetOffsetToTransformParent(gfx::Vector2dF(50, 50)); viz::LocalSurfaceId child_local_surface_id(2, base::UnguessableToken::Create()); @@ -14738,22 +13133,9 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, PointerEvents) { surface_child1->SetRange(viz::SurfaceRange(base::nullopt, child_surface_id), base::nullopt); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child1)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child2)); - constexpr gfx::Rect kFrameRect(0, 0, 1024, 768); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); base::Optional<viz::HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); // Generating HitTestRegionList should have been enabled for this test. @@ -14792,12 +13174,9 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, ComplexPage) { // +-Root (1024x768) // +---surface_child (0, 0), 100x100 // +---100x non overlapping layers (110, 110), 1x1 - std::unique_ptr<SurfaceLayerImpl> surface_child = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 2); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* surface_child = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); - surface_child->test_properties()->position = gfx::PointF(0, 0); surface_child->SetBounds(gfx::Size(100, 100)); surface_child->SetDrawsContent(true); surface_child->SetHitTestable(true); @@ -14811,32 +13190,20 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, ComplexPage) { surface_child->SetRange(viz::SurfaceRange(base::nullopt, child_surface_id), base::nullopt); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child)); + CopyProperties(root, surface_child); // Create 101 non overlapping layers. for (size_t i = 0; i <= 100; ++i) { - std::unique_ptr<LayerImpl> layer = - LayerImpl::Create(host_impl_->active_tree(), i + 3); - layer->test_properties()->position = gfx::PointF(110, 110); + LayerImpl* layer = AddLayer(); layer->SetBounds(gfx::Size(1, 1)); layer->SetDrawsContent(true); layer->SetHitTestable(true); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(layer)); + CopyProperties(root, layer); } constexpr gfx::Rect kFrameRect(0, 0, 1024, 768); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); base::Optional<viz::HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); // Generating HitTestRegionList should have been enabled for this test. @@ -14875,17 +13242,17 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, InvalidFrameSinkId) { // +-Root (1024x768) // +---surface_child1 (0, 0), 100x100 // +---surface_child2 (0, 0), 50x50, frame_sink_id = (0, 0) - std::unique_ptr<SurfaceLayerImpl> surface_child1 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 2); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* surface_child1 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); - surface_child1->test_properties()->position = gfx::PointF(0, 0); surface_child1->SetBounds(gfx::Size(100, 100)); surface_child1->SetDrawsContent(true); surface_child1->SetHitTestable(true); surface_child1->SetSurfaceHitTestable(true); surface_child1->SetHasPointerEventsNone(false); + CopyProperties(root, surface_child1); viz::LocalSurfaceId child_local_surface_id(2, base::UnguessableToken::Create()); @@ -14894,36 +13261,21 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, InvalidFrameSinkId) { surface_child1->SetRange(viz::SurfaceRange(base::nullopt, child_surface_id), base::nullopt); - std::unique_ptr<SurfaceLayerImpl> surface_child2 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); + auto* surface_child2 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); - surface_child2->test_properties()->position = gfx::PointF(0, 0); surface_child2->SetBounds(gfx::Size(50, 50)); surface_child2->SetDrawsContent(true); surface_child2->SetHitTestable(true); surface_child2->SetSurfaceHitTestable(true); surface_child2->SetHasPointerEventsNone(false); + CopyProperties(root, surface_child2); surface_child2->SetRange(viz::SurfaceRange(base::nullopt, viz::SurfaceId()), base::nullopt); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child1)); - - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child2)); - constexpr gfx::Rect kFrameRect(0, 0, 1024, 768); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); base::Optional<viz::HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); // Generating HitTestRegionList should have been enabled for this test. @@ -14977,7 +13329,8 @@ TEST_F(LayerTreeHostImplTest, ImplThreadPhaseUponImplSideInvalidation) { TEST_F(LayerTreeHostImplTest, SkipOnDrawDoesNotUpdateDrawParams) { EXPECT_TRUE(CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::CreateSoftware())); - LayerImpl* layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* layer = InnerViewportScrollLayer(); layer->SetDrawsContent(true); gfx::Transform transform; transform.Translate(20, 20); @@ -15008,32 +13361,17 @@ TEST_F(LayerTreeHostImplTest, TouchScrollOnAndroidScrollbar) { gfx::Size scroll_content_size = gfx::Size(360, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(viewport_size); - root->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> content = LayerImpl::Create(layer_tree_impl, 2); - content->SetBounds(scroll_content_size); - content->SetScrollable(viewport_size); - content->SetHitTestable(true); - content->SetElementId(LayerIdToElementIdForTesting(content->id())); - content->SetDrawsContent(true); - - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 3, VERTICAL, 10, 0, - false, true); - scrollbar->SetBounds(scrollbar_size); - scrollbar->test_properties()->position = gfx::PointF(345, 0); - scrollbar->SetScrollElementId(content->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->test_properties()->opacity = 1.f; + LayerImpl* root = SetupDefaultRootLayer(viewport_size); + LayerImpl* content = + AddScrollableLayer(root, viewport_size, scroll_content_size); - root->test_properties()->AddChild(std::move(content)); - root->test_properties()->AddChild(std::move(scrollbar)); + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + layer_tree_impl, VERTICAL, 10, 0, false); + SetupScrollbarLayer(content, scrollbar); + scrollbar->SetBounds(scrollbar_size); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); + UpdateDrawProperties(layer_tree_impl); layer_tree_impl->DidBecomeActive(); // Do a scroll over the scrollbar layer as well as the content layer, which @@ -15076,13 +13414,8 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CommitWithDirtyPaintWorklets) { // Setup the pending tree with a PictureLayerImpl that will contain // PaintWorklets. host_impl_->CreatePendingTree(); - std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create( - host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK); - PictureLayerImpl* root = root_owned.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned)); - - root->SetBounds(gfx::Size(100, 100)); - root->test_properties()->force_render_surface = true; + auto* root = SetupRootLayer<PictureLayerImpl>(host_impl_->pending_tree(), + gfx::Size(100, 100)); root->SetNeedsPushProperties(); // Add a PaintWorkletInput to the PictureLayerImpl. @@ -15092,8 +13425,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CommitWithDirtyPaintWorklets) { root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr, nullptr); - host_impl_->pending_tree()->SetElementIdsForTesting(); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); // Since we have dirty PaintWorklets, committing will not cause tile // preparation to happen. Instead, it will be delayed until the callback @@ -15131,13 +13463,8 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, std::make_unique<TestPaintWorkletLayerPainter>()); host_impl_->CreatePendingTree(); - std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create( - host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK); - PictureLayerImpl* root = root_owned.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned)); - - root->SetBounds(gfx::Size(100, 100)); - root->test_properties()->force_render_surface = true; + auto* root = SetupRootLayer<PictureLayerImpl>(host_impl_->pending_tree(), + gfx::Size(100, 100)); root->SetNeedsPushProperties(); // Add some PaintWorklets. @@ -15147,8 +13474,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr, nullptr); - host_impl_->pending_tree()->SetElementIdsForTesting(); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); // Pretend that our worklets were already painted. ASSERT_EQ(root->GetPaintWorkletRecordMap().size(), 1u); @@ -15184,13 +13510,8 @@ TEST_F(ForceActivateAfterPaintWorkletPaintLayerTreeHostImplTest, // Setup the pending tree with a PictureLayerImpl that will contain // PaintWorklets. host_impl_->CreatePendingTree(); - std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create( - host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK); - PictureLayerImpl* root = root_owned.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned)); - - root->SetBounds(gfx::Size(100, 100)); - root->test_properties()->force_render_surface = true; + auto* root = SetupRootLayer<PictureLayerImpl>(host_impl_->pending_tree(), + gfx::Size(100, 100)); root->SetNeedsPushProperties(); // Add a PaintWorkletInput to the PictureLayerImpl. @@ -15200,8 +13521,7 @@ TEST_F(ForceActivateAfterPaintWorkletPaintLayerTreeHostImplTest, root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr, nullptr); - host_impl_->pending_tree()->SetElementIdsForTesting(); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); // Since we have dirty PaintWorklets, committing will not cause tile // preparation to happen. Instead, it will be delayed until the callback diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc index 379d099def3..7d9e9d4f2a9 100644 --- a/chromium/cc/trees/layer_tree_host_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_perftest.cc @@ -27,7 +27,7 @@ #include "components/viz/test/paths.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/sync_token.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -99,6 +99,13 @@ class LayerTreeHostPerfTest : public LayerTreeTest { host_impl->SetFullViewportDamage(); } + void SetUpReporter(const std::string& story_name) { + reporter_ = std::make_unique<perf_test::PerfResultReporter>( + "layer_tree_host", story_name); + reporter_->RegisterImportantMetric("_frame_time", "us"); + reporter_->RegisterImportantMetric("_commit_time", "us"); + } + virtual void CleanUpAndEndTest() { EndTest(); } virtual bool CleanUpStarted() { return false; } @@ -106,14 +113,12 @@ class LayerTreeHostPerfTest : public LayerTreeTest { virtual void BuildTree() {} void AfterTest() override { - CHECK(!test_name_.empty()) << "Must SetTestName() before AfterTest()."; - perf_test::PrintResult("layer_tree_host_frame_time", "", test_name_, - draw_timer_.TimePerLap().InMicrosecondsF(), "us", - true); + CHECK(reporter_) << "Must SetUpReporter() before AfterTest()."; + reporter_->AddResult("_frame_time", + draw_timer_.TimePerLap().InMicrosecondsF()); if (measure_commit_cost_) { - perf_test::PrintResult("layer_tree_host_commit_time", "", test_name_, - commit_timer_.TimePerLap().InMicrosecondsF(), "us", - true); + reporter_->AddResult("_commit_time", + commit_timer_.TimePerLap().InMicrosecondsF()); } } @@ -121,7 +126,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest { base::LapTimer draw_timer_; base::LapTimer commit_timer_; - std::string test_name_; + std::unique_ptr<perf_test::PerfResultReporter> reporter_; FakeContentLayerClient fake_content_layer_client_; bool full_damage_each_frame_; bool begin_frame_driven_drawing_; @@ -136,10 +141,6 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { : LayerTreeHostPerfTest() { } - void SetTestName(const std::string& name) { - test_name_ = name; - } - void ReadTestFile(const std::string& name) { base::FilePath test_data_dir; ASSERT_TRUE( @@ -171,7 +172,7 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { #define MAYBE_TenTenSingleThread TenTenSingleThread #endif TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenSingleThread) { - SetTestName("10_10_single_thread"); + SetUpReporter("10_10_single_thread"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::SINGLE_THREADED); } @@ -183,7 +184,7 @@ TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenSingleThread) { #define MAYBE_TenTenThreaded TenTenThreaded #endif TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenThreaded) { - SetTestName("10_10_threaded_impl_side"); + SetUpReporter("10_10_threaded_impl_side"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::THREADED); } @@ -192,14 +193,14 @@ TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenThreaded) { TEST_F(LayerTreeHostPerfTestJsonReader, TenTenSingleThread_FullDamageEachFrame) { full_damage_each_frame_ = true; - SetTestName("10_10_single_thread_full_damage_each_frame"); + SetUpReporter("10_10_single_thread_full_damage_each_frame"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::SINGLE_THREADED); } TEST_F(LayerTreeHostPerfTestJsonReader, TenTenThreaded_FullDamageEachFrame) { full_damage_each_frame_ = true; - SetTestName("10_10_threaded_impl_side_full_damage_each_frame"); + SetUpReporter("10_10_threaded_impl_side_full_damage_each_frame"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::THREADED); } @@ -233,14 +234,14 @@ class LayerTreeHostPerfTestLeafInvalidates // Simulates a tab switcher scene with two stacks of 10 tabs each. Invalidate a // property on a leaf layer in the tree every commit. TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenSingleThread) { - SetTestName("10_10_single_thread_leaf_invalidates"); + SetUpReporter("10_10_single_thread_leaf_invalidates"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::SINGLE_THREADED); } // Timed out on Android: http://crbug.com/723821 TEST_F(LayerTreeHostPerfTestLeafInvalidates, MAYBE_TenTenThreaded) { - SetTestName("10_10_threaded_impl_side_leaf_invalidates"); + SetUpReporter("10_10_threaded_impl_side_leaf_invalidates"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::THREADED); } @@ -278,7 +279,7 @@ class ScrollingLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader { #define MAYBE_LongScrollablePageSingleThread LongScrollablePageSingleThread #endif TEST_F(ScrollingLayerTreePerfTest, MAYBE_LongScrollablePageSingleThread) { - SetTestName("long_scrollable_page"); + SetUpReporter("long_scrollable_page"); ReadTestFile("long_scrollable_page"); RunTest(CompositorMode::SINGLE_THREADED); } @@ -290,7 +291,7 @@ TEST_F(ScrollingLayerTreePerfTest, MAYBE_LongScrollablePageSingleThread) { #define MAYBE_LongScrollablePageThreaded LongScrollablePageThreaded #endif TEST_F(ScrollingLayerTreePerfTest, MAYBE_LongScrollablePageThreaded) { - SetTestName("long_scrollable_page_threaded_impl_side"); + SetUpReporter("long_scrollable_page_threaded_impl_side"); ReadTestFile("long_scrollable_page"); RunTest(CompositorMode::THREADED); } @@ -382,7 +383,7 @@ class BrowserCompositorInvalidateLayerTreePerfTest TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUIThreaded) { measure_commit_cost_ = true; - SetTestName("dense_layer_tree"); + SetUpReporter("dense_layer_tree"); ReadTestFile("dense_layer_tree"); RunTest(CompositorMode::THREADED); } @@ -397,7 +398,7 @@ TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUIThreaded) { TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_HeavyPageThreaded) { begin_frame_driven_drawing_ = true; measure_commit_cost_ = true; - SetTestName("heavy_page"); + SetUpReporter("heavy_page"); ReadTestFile("heavy_layer_tree"); RunTest(CompositorMode::THREADED); } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc index 6c045aa5ff5..09802cdbac2 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc @@ -132,7 +132,6 @@ class LayerTreeHostBlendingPixelTest gfx::Size bounds = layer->bounds(); scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create(); mask->SetIsDrawable(true); - mask->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); mask->SetBounds(bounds); sk_sp<SkSurface> surface = @@ -224,7 +223,7 @@ class LayerTreeHostBlendingPixelTest scoped_refptr<Layer> background = CreateColorfulBackdropLayer(kRootWidth, kRootHeight); - background->SetIsRootForIsolatedGroup(true); + background->SetForceRenderSurfaceForTesting(true); root->AddChild(background); CreateBlendingColorLayers(kRootWidth, kRootHeight, background.get(), flags); @@ -352,7 +351,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithTransparent) { CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange); root->AddChild(background); - background->SetIsRootForIsolatedGroup(true); + background->SetForceRenderSurfaceForTesting(true); // Orange child layers will blend with the green background gfx::Rect child_rect(kRootWidth, kRootHeight); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc index b43b7336343..4af1f35d30f 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -138,6 +138,26 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRect) { : base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur.png"))); } +TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterInvalid) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(50, 50, 100, 100), kCSSGreen); + scoped_refptr<SolidColorLayer> blur = + CreateSolidColorLayer(gfx::Rect(30, 30, 140, 140), SK_ColorTRANSPARENT); + background->AddChild(green); + background->AddChild(blur); + + // This should be an invalid filter, and result in just the original green. + FilterOperations filters; + filters.Append(FilterOperation::CreateHueRotateFilter(9e99)); + blur->SetBackdropFilters(filters); + + RunPixelTest( + renderer_type(), background, + base::FilePath(FILE_PATH_LITERAL("backdrop_filter_invalid.png"))); +} + TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRadius) { if (renderer_type() == RENDERER_SOFTWARE) { // TODO(989238): Software renderer does not support/implement @@ -280,52 +300,82 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) { base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_outsets.png"))); } -TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOffAxis) { - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorTRANSPARENT); +class LayerTreeHostFiltersPixelTestGPULayerList + : public LayerTreeHostFiltersPixelTest { + public: + LayerTreeHostFiltersPixelTestGPULayerList() { SetUseLayerLists(); } - // This verifies that the perspective of the clear layer (with black border) - // does not influence the blending of the green box behind it. Also verifies - // that the blur is correctly clipped inside the transformed clear layer. - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(50, 50, 100, 100), kCSSGreen); - scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayerWithBorder( - gfx::Rect(30, 30, 120, 120), SK_ColorTRANSPARENT, 1, SK_ColorBLACK); - background->AddChild(green); - background->AddChild(blur); + void SetupTree() override { + SetInitialRootBounds(gfx::Size(200, 200)); + LayerTreePixelTest::SetupTree(); - background->SetShouldFlattenTransform(false); - background->Set3dSortingContextId(1); - green->SetShouldFlattenTransform(false); - green->Set3dSortingContextId(1); - gfx::Transform background_transform; - background_transform.ApplyPerspectiveDepth(200.0); - background->SetTransform(background_transform); + Layer* root = layer_tree_host()->root_layer(); - blur->SetShouldFlattenTransform(false); - blur->Set3dSortingContextId(1); - for (size_t i = 0; i < blur->children().size(); ++i) - blur->children()[i]->Set3dSortingContextId(1); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorTRANSPARENT); + CopyProperties(root, background.get()); + root->AddChild(background); - gfx::Transform blur_transform; - blur_transform.Translate(55.0, 65.0); - blur_transform.RotateAboutXAxis(85.0); - blur_transform.RotateAboutYAxis(180.0); - blur_transform.RotateAboutZAxis(20.0); - blur_transform.Translate(-60.0, -60.0); - blur->SetTransform(blur_transform); + TransformNode& background_transform_node = + CreateTransformNode(background.get()); + background_transform_node.local.ApplyPerspectiveDepth(200.0); + background_transform_node.flattens_inherited_transform = true; + background_transform_node.sorting_context_id = 1; + + // This verifies that the perspective of the clear layer (with black border) + // does not influence the blending of the green box behind it. Also verifies + // that the blur is correctly clipped inside the transformed clear layer. + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(50, 50, 100, 100), kCSSGreen); + CopyProperties(background.get(), green.get()); + root->AddChild(green); + + std::vector<scoped_refptr<SolidColorLayer>> blur_layers; + CreateSolidColorLayerPlusBorders(gfx::Rect(0, 0, 120, 120), + SK_ColorTRANSPARENT, 1, SK_ColorBLACK, + blur_layers); + CopyProperties(background.get(), blur_layers[0].get()); + TransformNode& blur_transform_node = + CreateTransformNode(blur_layers[0].get(), background_transform_node.id); + + blur_transform_node.local.Translate(55.0, 65.0); + blur_transform_node.local.RotateAboutXAxis(85.0); + blur_transform_node.local.RotateAboutYAxis(180.0); + blur_transform_node.local.RotateAboutZAxis(20.0); + blur_transform_node.local.Translate(-60.0, -60.0); + blur_transform_node.flattens_inherited_transform = false; + blur_transform_node.post_translation = gfx::Vector2dF(30, 30); + blur_transform_node.sorting_context_id = 1; + + EffectNode& blur_effect_node = CreateEffectNode(blur_layers[0].get()); - FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter( - 2.f, SkBlurImageFilter::kClamp_TileMode)); - blur->SetBackdropFilters(filters); - // TODO(916311): We should be able to set the bounds like this, but the - // resulting output is clipped incorrectly. - // gfx::RRectF - // backdrop_filter_bounds(gfx::RectF(gfx::SizeF(blur->bounds())),0); - // blur->SetBackdropFilterBounds(backdrop_filter_bounds); - blur->ClearBackdropFilterBounds(); + FilterOperations filters; + filters.Append(FilterOperation::CreateBlurFilter( + 2.f, SkBlurImageFilter::kClamp_TileMode)); + blur_effect_node.backdrop_filters = filters; + blur_effect_node.render_surface_reason = + RenderSurfaceReason::kBackdropFilter; + blur_effect_node.closest_ancestor_with_copy_request_id = 1; + + // TODO(916311): We should be able to set the bounds like this, but the + // resulting output is clipped incorrectly. + // gfx::RRectF + // backdrop_filter_bounds(gfx::RectF(gfx::SizeF(blur->bounds())),0); + // blur_effect_node.backdrop_filter_bounds.emplace(backdrop_filter_bounds); + + root->AddChild(blur_layers[0]); + for (unsigned i = 1; i < blur_layers.size(); i++) { + CopyProperties(blur_layers[0].get(), blur_layers[i].get()); + root->AddChild(blur_layers[i]); + } + } +}; +INSTANTIATE_TEST_SUITE_P(PixelResourceTest, + LayerTreeHostFiltersPixelTestGPULayerList, + ::testing::ValuesIn(kRendererTypesGpu)); + +TEST_P(LayerTreeHostFiltersPixelTestGPULayerList, BackdropFilterBlurOffAxis) { #if defined(OS_WIN) || defined(ARCH_CPU_ARM64) #if defined(OS_WIN) // Windows has 116 pixels off by at most 2: crbug.com/225027 @@ -347,8 +397,8 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOffAxis) { small_error_allowed)); #endif - RunPixelTest( - renderer_type(), background, + RunPixelTestWithLayerList( + renderer_type(), base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_off_axis_.png")) .InsertBeforeExtensionASCII(GetRendererSuffix())); } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc index ba32c9bdd0c..ad9f2838cf7 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -26,13 +26,6 @@ namespace cc { namespace { -auto CombineWithLayerMaskTypes( - const std::vector<PixelResourceTestCase>& test_cases) { - return ::testing::Combine( - ::testing::ValuesIn(test_cases), - ::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK)); -} - // TODO(penghuang): Fix vulkan with one copy or zero copy // https://crbug.com/979703 std::vector<PixelResourceTestCase> const kTestCases = { @@ -52,7 +45,7 @@ using LayerTreeHostMasksPixelTest = ParameterizedPixelResourceTest; INSTANTIATE_TEST_SUITE_P(PixelResourceTest, LayerTreeHostMasksPixelTest, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); class MaskContentLayerClient : public ContentLayerClient { public: @@ -111,7 +104,6 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) { scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); green->SetMaskLayer(mask); pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true); @@ -164,7 +156,7 @@ class LayerTreeHostMaskPixelTestWithLayerList INSTANTIATE_TEST_SUITE_P(PixelResourceTest, LayerTreeHostMaskPixelTestWithLayerList, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); TEST_P(LayerTreeHostMaskPixelTestWithLayerList, MaskWithEffect) { MaskContentLayerClient client(mask_bounds_); @@ -237,7 +229,7 @@ class LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface INSTANTIATE_TEST_SUITE_P( PixelResourceTest, LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); TEST_P(LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface, Test) { @@ -272,7 +264,7 @@ class LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask INSTANTIATE_TEST_SUITE_P( PixelResourceTest, LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); TEST_P(LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask, Test) { MaskContentLayerClient client(mask_bounds_); @@ -297,7 +289,7 @@ class LayerTreeHostMaskPixelTest_ScaledMaskWithEffect INSTANTIATE_TEST_SUITE_P(PixelResourceTest, LayerTreeHostMaskPixelTest_ScaledMaskWithEffect, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); TEST_P(LayerTreeHostMaskPixelTest_ScaledMaskWithEffect, Test) { MaskContentLayerClient client(mask_bounds_); @@ -361,7 +353,6 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create(); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); mask->SetBounds(mask_bounds); sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(200, 200); @@ -411,7 +402,6 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); green->SetMaskLayer(mask); pixel_comparator_ = @@ -435,7 +425,6 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayerNonExactTextureSize) { scoped_refptr<FakePictureLayer> mask = FakePictureLayer::Create(&client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); mask->set_fixed_tile_size(gfx::Size(173, 135)); green->SetMaskLayer(mask); @@ -537,43 +526,59 @@ class CircleContentLayerClient : public ContentLayerClient { gfx::Size bounds_; }; -using LayerTreeHostMasksForBackdropFiltersPixelTest = - ParameterizedPixelResourceTest; +class LayerTreeHostMasksForBackdropFiltersPixelTest + : public ParameterizedPixelResourceTest { + protected: + LayerTreeHostMasksForBackdropFiltersPixelTest() + : bounds_(100, 100), + picture_client_(bounds_, SK_ColorGREEN, true), + mask_client_(bounds_) { + SetUseLayerLists(); + } -INSTANTIATE_TEST_SUITE_P(PixelResourceTest, - LayerTreeHostMasksForBackdropFiltersPixelTest, - CombineWithLayerMaskTypes(kTestCases)); + // Setup three layers for testing masks: a white background, a green layer, + // and a mask layer with kDstIn blend mode. + void SetupTree() override { + SetInitialRootBounds(bounds_); + ParameterizedPixelResourceTest::SetupTree(); -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, - MaskOfLayerWithBackdropFilter) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorWHITE); + Layer* root = layer_tree_host()->root_layer(); + + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorWHITE); + CopyProperties(root, background.get()); + root->AddChild(background); - gfx::Size picture_bounds(100, 100); - CheckerContentLayerClient picture_client(picture_bounds, SK_ColorGREEN, true); - scoped_refptr<PictureLayer> picture = PictureLayer::Create(&picture_client); - picture->SetBounds(picture_bounds); - picture->SetIsDrawable(true); + scoped_refptr<PictureLayer> picture = + PictureLayer::Create(&picture_client_); + picture->SetBounds(bounds_); + picture->SetIsDrawable(true); + CopyProperties(background.get(), picture.get()); + root->AddChild(picture); - scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorTRANSPARENT); - background->AddChild(picture); - background->AddChild(blur); + scoped_refptr<SolidColorLayer> blur = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorTRANSPARENT); + CopyProperties(background.get(), blur.get()); + CreateEffectNode(blur.get()) + .backdrop_filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); + root->AddChild(blur); - FilterOperations filters; - filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); - blur->SetBackdropFilters(filters); - blur->ClearBackdropFilterBounds(); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client_); + SetupMaskProperties(blur.get(), mask.get()); - gfx::Size mask_bounds(100, 100); - CircleContentLayerClient mask_client(mask_bounds); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); - blur->SetMaskLayer(mask); - CHECK_EQ(Layer::LayerMaskType::SINGLE_TEXTURE_MASK, mask->mask_type()); + root->AddChild(mask); + } + const gfx::Size bounds_; + CheckerContentLayerClient picture_client_; + CircleContentLayerClient mask_client_; +}; + +INSTANTIATE_TEST_SUITE_P(PixelResourceTest, + LayerTreeHostMasksForBackdropFiltersPixelTest, + ::testing::ValuesIn(kTestCases)); + +TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, Test) { base::FilePath image_name = (raster_type() == GPU) ? base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter_gpu.png")) @@ -593,10 +598,10 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, large_error_allowed, small_error_allowed); } - RunPixelResourceTest(background, image_name); + RunPixelResourceTestWithLayerList(image_name); } -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, MaskOfLayerWithBlend) { +TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayerWithBlend) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(128, 128), SK_ColorWHITE); @@ -625,7 +630,6 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, MaskOfLayerWithBlend) { scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); picture_horizontal->SetMaskLayer(mask); float percentage_pixels_large_error = 0.04f; // 0.04%, ~6px / (128*128) @@ -684,9 +688,7 @@ class LayerTreeHostMaskAsBlendingPixelTest public ::testing::WithParamInterface<MaskTestConfig> { public: LayerTreeHostMaskAsBlendingPixelTest() - : LayerTreeHostPixelResourceTest( - GetParam().test_case, - Layer::LayerMaskType::SINGLE_TEXTURE_MASK), + : LayerTreeHostPixelResourceTest(GetParam().test_case), use_antialiasing_(GetParam().flags & kUseAntialiasing), force_shaders_(GetParam().flags & kForceShaders) { float percentage_pixels_error = 0.f; @@ -831,7 +833,6 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, PixelAlignedNoop) { mask_isolation->SetPosition(gfx::PointF(20, 20)); mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -856,7 +857,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, PixelAlignedClippedCircle) { mask_isolation->SetPosition(gfx::PointF(20, 20)); mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); + mask_isolation->SetForceRenderSurfaceForTesting(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -893,7 +894,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, mask_isolation->SetPosition(gfx::PointF(20, 20)); mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); + mask_isolation->SetForceRenderSurfaceForTesting(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -934,7 +935,6 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircle) { } mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -981,7 +981,6 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) { } mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -1013,44 +1012,64 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) { RunPixelResourceTest(root, image_name); } -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, - MaskOfLayerWithBackdropFilterAndBlend) { - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(128, 128), SK_ColorWHITE); +class LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest + : public ParameterizedPixelResourceTest { + protected: + LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest() + : bounds_(128, 128), + picture_client_vertical_(bounds_, SK_ColorGREEN, true), + picture_client_horizontal_(bounds_, SK_ColorMAGENTA, false), + mask_client_(bounds_) { + SetUseLayerLists(); + } - gfx::Size picture_bounds(128, 128); - CheckerContentLayerClient picture_client_vertical(picture_bounds, - SK_ColorGREEN, true); - scoped_refptr<PictureLayer> picture_vertical = - PictureLayer::Create(&picture_client_vertical); - picture_vertical->SetBounds(picture_bounds); - picture_vertical->SetIsDrawable(true); + void SetupTree() override { + SetInitialRootBounds(bounds_); + ParameterizedPixelResourceTest::SetupTree(); - CheckerContentLayerClient picture_client_horizontal(picture_bounds, - SK_ColorMAGENTA, false); - scoped_refptr<PictureLayer> picture_horizontal = - PictureLayer::Create(&picture_client_horizontal); - picture_horizontal->SetBounds(picture_bounds); - picture_horizontal->SetIsDrawable(true); - picture_horizontal->SetContentsOpaque(false); - picture_horizontal->SetBlendMode(SkBlendMode::kMultiply); + Layer* root = layer_tree_host()->root_layer(); - FilterOperations filters; - filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); - picture_horizontal->SetBackdropFilters(filters); - picture_horizontal->ClearBackdropFilterBounds(); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorWHITE); + CopyProperties(root, background.get()); + root->AddChild(background); - background->AddChild(picture_vertical); - background->AddChild(picture_horizontal); + scoped_refptr<PictureLayer> picture_vertical = + PictureLayer::Create(&picture_client_vertical_); + picture_vertical->SetBounds(bounds_); + picture_vertical->SetIsDrawable(true); + CopyProperties(background.get(), picture_vertical.get()); + root->AddChild(picture_vertical); + + scoped_refptr<PictureLayer> picture_horizontal = + PictureLayer::Create(&picture_client_horizontal_); + picture_horizontal->SetBounds(bounds_); + picture_horizontal->SetIsDrawable(true); + picture_horizontal->SetContentsOpaque(false); + CopyProperties(background.get(), picture_horizontal.get()); + auto& effect_node = CreateEffectNode(picture_horizontal.get()); + effect_node.backdrop_filters.Append( + FilterOperation::CreateGrayscaleFilter(1.0)); + effect_node.blend_mode = SkBlendMode::kMultiply; + root->AddChild(picture_horizontal); + + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client_); + mask->SetBounds(bounds_); + SetupMaskProperties(picture_horizontal.get(), mask.get()); + root->AddChild(mask); + } - gfx::Size mask_bounds(128, 128); - CircleContentLayerClient mask_client(mask_bounds); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); - picture_horizontal->SetMaskLayer(mask); + const gfx::Size bounds_; + CheckerContentLayerClient picture_client_vertical_; + CheckerContentLayerClient picture_client_horizontal_; + CircleContentLayerClient mask_client_; +}; + +INSTANTIATE_TEST_SUITE_P(PixelResourceTest, + LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest, + ::testing::ValuesIn(kTestCases)); +TEST_P(LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest, Test) { base::FilePath result_path( FILE_PATH_LITERAL("mask_of_backdrop_filter_and_blend_.png")); if (raster_type() != GPU) { @@ -1058,7 +1077,7 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, } else { result_path = result_path.InsertBeforeExtensionASCII(GetRendererSuffix()); } - RunPixelResourceTest(background, result_path); + RunPixelResourceTestWithLayerList(result_path); } } // namespace diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc index 52317bb5fa2..345dc9cab6b 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc @@ -416,7 +416,7 @@ TEST_P(LayerTreeHostReadbackPixelTest, MultipleReadbacksOnLayer) { base::FilePath(FILE_PATH_LITERAL("green.png"))); } -// TODO(crbug.com/963446): Enable these tests for Skia Vulkan using texture +// TODO(crbug.com/971257): Enable these tests for Skia Vulkan using texture // readback. ReadbackTestConfig const kTestConfigs[] = { ReadbackTestConfig{LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP}, diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc index b271f513c0c..4be54575240 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc @@ -11,6 +11,7 @@ #include "cc/layers/solid_color_layer.h" #include "cc/paint/paint_canvas.h" #include "cc/paint/paint_flags.h" +#include "cc/test/fake_scrollbar.h" #include "cc/test/layer_tree_pixel_test.h" #include "cc/test/pixel_comparator.h" #include "cc/trees/layer_tree_impl.h" @@ -38,32 +39,23 @@ class LayerTreeHostScrollbarsPixelTest float device_scale_factor_ = 1.f; }; -class PaintedScrollbar : public Scrollbar { +class PaintedScrollbar : public FakeScrollbar { public: - ~PaintedScrollbar() override = default; - - ScrollbarOrientation Orientation() const override { return VERTICAL; } - bool IsLeftSideVerticalScrollbar() const override { return false; } - gfx::Point Location() const override { return gfx::Point(); } - bool IsOverlay() const override { return false; } - bool HasThumb() const override { return thumb_; } - int ThumbThickness() const override { return rect_.width(); } - int ThumbLength() const override { return rect_.height(); } - gfx::Rect TrackRect() const override { return rect_; } - gfx::Rect BackButtonRect() const override { return rect_; } - gfx::Rect ForwardButtonRect() const override { return rect_; } - float ThumbOpacity() const override { return 1.f; } - bool NeedsPaintPart(ScrollbarPart part) const override { return true; } - bool HasTickmarks() const override { return false; } - void PaintPart(PaintCanvas* canvas, - ScrollbarPart part, - const gfx::Rect& content_rect) override { + explicit PaintedScrollbar(const gfx::Size& size) + : FakeScrollbar(/*paint*/ true, + /*has_thumb*/ false, + HORIZONTAL, + /*is_left_side_vertical_scrollbar*/ false, + /*is_overlay*/ false) { + set_track_rect(gfx::Rect(size)); + } + + void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override { PaintFlags flags; flags.setStyle(PaintFlags::kStroke_Style); flags.setStrokeWidth(SkIntToScalar(paint_scale_)); flags.setColor(color_); - - gfx::Rect inset_rect = content_rect; + gfx::Rect inset_rect = GetPartRect(part); while (!inset_rect.IsEmpty()) { int big = paint_scale_ + 2; int small = paint_scale_; @@ -72,17 +64,12 @@ class PaintedScrollbar : public Scrollbar { inset_rect.Inset(big, big, small, small); } } - bool UsesNinePatchThumbResource() const override { return false; } - gfx::Size NinePatchThumbCanvasSize() const override { return gfx::Size(); } - gfx::Rect NinePatchThumbAperture() const override { return gfx::Rect(); } void set_paint_scale(int scale) { paint_scale_ = scale; } private: int paint_scale_ = 4; - bool thumb_ = false; SkColor color_ = SK_ColorGREEN; - gfx::Rect rect_; }; LayerTreeTest::RendererType const kRendererTypes[] = { @@ -101,7 +88,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, NoScale) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - auto scrollbar = std::make_unique<PaintedScrollbar>(); + auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(200, 200)); scoped_refptr<PaintedScrollbarLayer> layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); @@ -120,7 +107,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, DeviceScaleFactor) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - auto scrollbar = std::make_unique<PaintedScrollbar>(); + auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(100, 100)); scoped_refptr<PaintedScrollbarLayer> layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); @@ -135,7 +122,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, TransformScale) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - auto scrollbar = std::make_unique<PaintedScrollbar>(); + auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(100, 100)); scoped_refptr<PaintedScrollbarLayer> layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); @@ -162,7 +149,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE); - auto scrollbar = std::make_unique<PaintedScrollbar>(); + auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(10, 400)); scrollbar->set_paint_scale(1); scoped_refptr<PaintedScrollbarLayer> layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); @@ -215,18 +202,20 @@ class LayerTreeHostOverlayScrollbarsPixelTest float thickness_scale_; }; -class PaintedOverlayScrollbar : public PaintedScrollbar { +class PaintedOverlayScrollbar : public FakeScrollbar { public: - ~PaintedOverlayScrollbar() override = default; - - int ThumbThickness() const override { return 15; } - int ThumbLength() const override { return 50; } - gfx::Rect TrackRect() const override { return gfx::Rect(0, 0, 15, 400); } - bool HasThumb() const override { return true; } - bool IsOverlay() const override { return true; } - void PaintPart(PaintCanvas* canvas, - ScrollbarPart part, - const gfx::Rect& content_rect) override { + PaintedOverlayScrollbar() + : FakeScrollbar(/*paint*/ true, + /*has_thumb*/ true, + VERTICAL, + /*is_left_side_vertical_scrollbar*/ false, + /*is_overlay*/ true) { + set_thumb_thickness(15); + set_thumb_length(50); + set_track_rect(gfx::Rect(0, 0, 15, 400)); + } + + void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override { // The outside of the rect will be painted with a 1 pixel black, red, then // blue border. The inside will be solid blue. This will allow the test to // ensure that scaling the thumb doesn't scale the border at all. Note @@ -237,8 +226,7 @@ class PaintedOverlayScrollbar : public PaintedScrollbar { flags.setStrokeWidth(SkIntToScalar(1)); flags.setColor(SK_ColorBLACK); - gfx::Rect inset_rect = content_rect; - + gfx::Rect inset_rect = GetPartRect(part); canvas->drawRect(RectToSkRect(inset_rect), flags); flags.setColor(SK_ColorRED); @@ -249,6 +237,7 @@ class PaintedOverlayScrollbar : public PaintedScrollbar { inset_rect.Inset(1, 1); canvas->drawRect(RectToSkRect(inset_rect), flags); } + bool UsesNinePatchThumbResource() const override { return true; } gfx::Size NinePatchThumbCanvasSize() const override { return gfx::Size(7, 7); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc index 708eefad33a..7b3f854f7f9 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc @@ -24,6 +24,7 @@ class LayerTreeHostSynchronousPixelTest LayerTreePixelTest::InitializeSettings(settings); settings->single_thread_proxy_scheduler = false; settings->gpu_rasterization_forced = gpu_rasterization_forced_; + settings->gpu_rasterization_disabled = !settings->gpu_rasterization_forced; settings->use_zero_copy = use_zero_copy_; } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc index e87aef895c7..8e27a3ef68b 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -45,6 +45,8 @@ class LayerTreeHostTilesPixelTest switch (raster_mode()) { case ONE_COPY: settings->use_zero_copy = false; + settings->gpu_rasterization_disabled = true; + settings->gpu_rasterization_forced = false; break; case GPU: settings->gpu_rasterization_forced = true; diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index aec7ad3b5db..03d02988fce 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -51,9 +51,9 @@ #include "cc/trees/clip_node.h" #include "cc/trees/effect_node.h" #include "cc/trees/frame_rate_counter.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/swap_promise.h" @@ -255,6 +255,32 @@ class LayerTreeHostTestRequestedMainFrame : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestedMainFrame); +class LayerTreeHostTestSchedulingClient : public LayerTreeHostTest { + public: + void BeginTest() override { + PostSetNeedsCommitToMainThread(); + EXPECT_EQ(0, main_frame_scheduled_count_); + EXPECT_EQ(0, main_frame_run_count_); + } + + void DidScheduleBeginMainFrame() override { main_frame_scheduled_count_++; } + void DidRunBeginMainFrame() override { main_frame_run_count_++; } + + void DidBeginMainFrame() override { + EXPECT_EQ(1, main_frame_scheduled_count_); + EXPECT_EQ(1, main_frame_run_count_); + EndTest(); + } + + void AfterTest() override {} + + private: + int main_frame_scheduled_count_ = 0; + int main_frame_run_count_ = 0; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestSchedulingClient); + class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest { protected: void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -615,13 +641,13 @@ MULTI_THREAD_TEST_F( class LayerTreeHostFreeContextResourcesOnDestroy : public LayerTreeHostContextCacheTest { public: - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; - } - void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, const viz::BeginFrameArgs& args) override { + if (!first_will_begin_impl_frame_) + return; + + first_will_begin_impl_frame_ = false; + // Ensure that our initialization expectations have completed. Mock::VerifyAndClearExpectations(mock_main_context_support_); Mock::VerifyAndClearExpectations(mock_worker_context_support_); @@ -633,6 +659,9 @@ class LayerTreeHostFreeContextResourcesOnDestroy SetAggressivelyFreeResources(true)); EndTest(); } + + private: + bool first_will_begin_impl_frame_ = true; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostFreeContextResourcesOnDestroy); @@ -779,7 +808,7 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - VerifyAfterValues(impl->active_tree()->root_layer_for_testing()); + VerifyAfterValues(impl->active_tree()->root_layer()); } void DidCommitAndDrawFrame() override { @@ -966,13 +995,13 @@ class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest { switch (layer_tree_host()->SourceFrameNumber()) { case 1: child_->SetForceRenderSurfaceForTesting(true); - child_->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); + // Add a non-fast region to ensure a scroll node is created. + child_->SetNonFastScrollableRegion(Region(gfx::Rect(50, 50, 50, 50))); break; case 2: child_->SetForceRenderSurfaceForTesting(false); - child_->ClearMainThreadScrollingReasons( - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); + // Remove the non-fast region to ensure a scroll node is removed. + child_->SetNonFastScrollableRegion(Region()); break; } } @@ -1129,7 +1158,8 @@ class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest { scoped_refptr<Layer> grand_child_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage); +// TODO(crbug.com/1014263): Disable because this test is flaky. +// SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage); class LayerTreeHostTestLayerListSurfaceDamage : public LayerTreeHostTest { protected: @@ -1644,7 +1674,7 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { gfx::Transform transform; FilterOperations filters; - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = impl->active_tree()->root_layer(); switch (static_cast<Animations>(index_)) { case OPACITY: index_++; @@ -1750,22 +1780,28 @@ SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists); class LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists : public LayerTreeHostTest { protected: - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; + void SetupTree() override { + root_ = Layer::Create(); + child_ = Layer::Create(); + root_->AddChild(child_); + layer_tree_host()->SetRootLayer(root_); + LayerTreeHostTest::SetupTree(); } void BeginTest() override { - Layer* root = layer_tree_host()->root_layer(); - EXPECT_EQ(gfx::Transform(), root->transform()); + EXPECT_EQ(gfx::Transform(), child_->transform()); gfx::Transform expected_transform; expected_transform.Translate(42, 42); layer_tree_host()->SetElementTransformMutated( - root->element_id(), ElementListType::ACTIVE, expected_transform); + child_->element_id(), ElementListType::ACTIVE, expected_transform); // When not using layer lists, transform is stored on the layer. - EXPECT_EQ(expected_transform, root->transform()); + EXPECT_EQ(expected_transform, child_->transform()); EndTest(); } + + private: + scoped_refptr<Layer> root_; + scoped_refptr<Layer> child_; }; SINGLE_THREAD_TEST_F( @@ -1914,7 +1950,7 @@ class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest { void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EffectTree& effect_tree = impl->sync_tree()->property_trees()->effect_tree; - LayerImpl* root = impl->sync_tree()->root_layer_for_testing(); + LayerImpl* root = impl->sync_tree()->root_layer(); EffectNode* node = effect_tree.Node(root->effect_tree_index()); switch (impl->sync_tree()->source_frame_number()) { case 0: @@ -2151,10 +2187,12 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { void SetupTree() override { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(10, 10)); + // child_layer_ is not drawable. child_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_); child_layer_->SetBounds(gfx::Size(10, 10)); mask_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_); mask_layer_->SetBounds(gfx::Size(10, 10)); + mask_layer_->SetIsDrawable(true); child_layer_->SetMaskLayer(mask_layer_); root->AddChild(child_layer_); layer_tree_host()->SetRootLayer(root); @@ -2170,8 +2208,8 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { switch (layer_tree_host()->SourceFrameNumber()) { case 1: // Root and mask layer should have the same source frame number as they - // will be in the layer update list but the child is not as it has empty - // bounds. + // will be in the layer update list but the child is not as it doesn't + // draw content. EXPECT_EQ(mask_layer_->update_count(), 1); EXPECT_EQ(child_layer_->update_count(), 0); @@ -2182,17 +2220,21 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { } void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { + auto* mask_surface = + GetRenderSurface(impl->sync_tree()->LayerById(mask_layer_->id())); + auto* root_surface = GetRenderSurface(impl->sync_tree()->root_layer()); + ASSERT_TRUE(mask_surface); switch (index_) { - case 0: + case 0: { index_++; - EXPECT_FALSE( - GetRenderSurface(impl->sync_tree()->root_layer_for_testing()) - ->MaskLayer()); + auto* child_surface = + GetRenderSurface(impl->sync_tree()->LayerById(child_layer_->id())); + EXPECT_EQ(child_surface, mask_surface->render_target()); + EXPECT_NE(child_surface, root_surface); break; + } case 1: - EXPECT_TRUE( - GetRenderSurface(impl->sync_tree()->root_layer_for_testing()) - ->MaskLayer()); + EXPECT_EQ(mask_surface->render_target(), root_surface); EndTest(); break; } @@ -2527,10 +2569,8 @@ class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest { } else { gfx::Rect root_damage_rect = frame_data->render_passes.back()->damage_rect; - EXPECT_EQ( - gfx::Rect( - host_impl->active_tree()->root_layer_for_testing()->bounds()), - root_damage_rect); + EXPECT_EQ(gfx::Rect(host_impl->active_tree()->root_layer()->bounds()), + root_damage_rect); EXPECT_EQ(4.f, host_impl->active_tree()->device_scale_factor()); EndTest(); } @@ -2614,10 +2654,8 @@ class LayerTreeHostTestRasterColorSpaceChange : public LayerTreeHostTest { if (!frame_data->has_no_damage) { gfx::Rect root_damage_rect = frame_data->render_passes.back()->damage_rect; - EXPECT_EQ( - gfx::Rect( - host_impl->active_tree()->root_layer_for_testing()->bounds()), - root_damage_rect); + EXPECT_EQ(gfx::Rect(host_impl->active_tree()->root_layer()->bounds()), + root_damage_rect); } return draw_result; @@ -3106,16 +3144,15 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw); // from LayerTreeHost to LayerTreeHostImpl in the MT compositor. class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { public: - LayerTreeHostTestStartPageScaleAnimation() = default; + LayerTreeHostTestStartPageScaleAnimation() { SetUseLayerLists(); } void SetupTree() override { LayerTreeHostTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); - scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client_); - layer->set_always_update_resources(true); - scroll_layer_ = layer; + scroll_layer_ = FakePictureLayer::Create(&client_); + scroll_layer_->set_always_update_resources(true); scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(), 2 * root_layer->bounds().height())); @@ -3169,7 +3206,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { } FakeContentLayerClient client_; - scoped_refptr<Layer> scroll_layer_; + scoped_refptr<FakePictureLayer> scroll_layer_; }; // Single thread proxy does not support impl-side page scale changes. @@ -3177,28 +3214,16 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation); class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest { protected: - ViewportDeltasAppliedDuringPinch() : sent_gesture_(false) {} + ViewportDeltasAppliedDuringPinch() : sent_gesture_(false) { + SetUseLayerLists(); + } void SetupTree() override { - scoped_refptr<Layer> root_clip = Layer::Create(); - root_clip->SetBounds(gfx::Size(500, 500)); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - page_scale_layer->SetBounds(gfx::Size(500, 500)); - - scoped_refptr<Layer> pinch = Layer::Create(); - pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollable(gfx::Size(200, 200)); - page_scale_layer->AddChild(pinch); - root_clip->AddChild(page_scale_layer); - - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root_clip; - viewport_layers.inner_viewport_scroll = pinch; - layer_tree_host()->RegisterViewportLayers(viewport_layers); - layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); - layer_tree_host()->SetRootLayer(root_clip); + SetInitialRootBounds(gfx::Size(200, 200)); LayerTreeHostTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); + SetupViewport(root, gfx::Size(500, 500), gfx::Size(500, 500)); + layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -3217,7 +3242,8 @@ class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest { EXPECT_EQ(gfx::ScrollOffset(50, 50), args.inner_delta); EXPECT_EQ(2, args.page_scale_delta); - auto* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer(); + auto* scroll_layer = + layer_tree_host()->InnerViewportScrollLayerForTesting(); EXPECT_EQ(gfx::ScrollOffset(50, 50), scroll_layer->CurrentScrollOffset()); EndTest(); } @@ -3299,8 +3325,8 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers // Device viewport is scaled. EXPECT_EQ(gfx::Rect(60, 60), impl->active_tree()->GetDeviceViewport()); - FakePictureLayerImpl* root = static_cast<FakePictureLayerImpl*>( - impl->active_tree()->root_layer_for_testing()); + FakePictureLayerImpl* root = + static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>( impl->active_tree()->LayerById(child_layer_->id())); @@ -3864,10 +3890,10 @@ class LayerTreeHostTestLCDChange : public LayerTreeHostTest { } void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - PictureLayerImpl* root_layer = static_cast<PictureLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()); + PictureLayerImpl* root_layer = + static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer()); bool can_use_lcd_text = - host_impl->active_tree()->root_layer_for_testing()->CanUseLCDText(); + host_impl->active_tree()->root_layer()->CanUseLCDText(); switch (host_impl->active_tree()->source_frame_number()) { case 0: // The first draw. @@ -4456,7 +4482,7 @@ class LayerTreeHostTestImplLayersPushProperties // Make sure the new root is pushed. EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()) + host_impl->active_tree()->root_layer()) ->push_properties_count()); return; case 4: @@ -4562,7 +4588,7 @@ class LayerTreeHostTestImplLayersPushProperties // Pull the layers that we need from the tree assuming the same structure // as LayerTreeHostTestLayersPushProperties root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()); + host_impl->active_tree()->root_layer()); LayerTreeImpl* impl = root_impl_->layer_tree_impl(); if (impl->LayerById(child_->id())) { @@ -4639,8 +4665,7 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed // avoid causing a second commit to be scheduled. If a property change // is made during this, however, it needs to be pushed in the upcoming // commit. - std::unique_ptr<base::AutoReset<bool>> ignore = - scrollbar_layer_->IgnoreSetNeedsCommit(); + auto ignore = scrollbar_layer_->IgnoreSetNeedsCommit(); scrollbar_layer_->SetBounds(gfx::Size(30, 30)); @@ -5381,45 +5406,26 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { public: LayerTreeHostTestElasticOverscroll() - : scroll_elasticity_helper_(nullptr), num_draws_(0) {} + : scroll_elasticity_helper_(nullptr), num_draws_(0) { + SetUseLayerLists(); + } void InitializeSettings(LayerTreeSettings* settings) override { settings->enable_elastic_overscroll = true; } void SetupTree() override { - root_layer_ = Layer::Create(); - root_layer_->SetBounds(gfx::Size(10, 10)); - - scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create(); - inner_viewport_container_layer->SetBounds(gfx::Size(10, 10)); - scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); - overscroll_elasticity_layer->SetElementId( - LayerIdToElementIdForTesting(overscroll_elasticity_layer->id())); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); - inner_viewport_scroll_layer->SetScrollable( - inner_viewport_container_layer->bounds()); - - root_layer_->AddChild(inner_viewport_container_layer); - inner_viewport_container_layer->AddChild(overscroll_elasticity_layer); - overscroll_elasticity_layer->AddChild(page_scale_layer); - page_scale_layer->AddChild(inner_viewport_scroll_layer); + LayerTreeHostTest::SetupTree(); + root_layer_ = layer_tree_host()->root_layer(); + SetupViewport(root_layer_, root_layer_->bounds(), root_layer_->bounds()); scoped_refptr<Layer> content_layer = FakePictureLayer::Create(&client_); content_layer_id_ = content_layer->id(); content_layer->SetBounds(gfx::Size(10, 10)); - inner_viewport_scroll_layer->AddChild(content_layer); + CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(), + content_layer.get()); + root_layer_->AddChild(content_layer); - layer_tree_host()->SetRootLayer(root_layer_); - ViewportLayers viewport_layers; - viewport_layers.overscroll_elasticity_element_id = - overscroll_elasticity_layer->element_id(); - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = inner_viewport_container_layer; - viewport_layers.inner_viewport_scroll = inner_viewport_scroll_layer; - layer_tree_host()->RegisterViewportLayers(viewport_layers); - LayerTreeHostTest::SetupTree(); client_.set_bounds(content_layer->bounds()); } @@ -5468,7 +5474,7 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { private: FakeContentLayerClient client_; - scoped_refptr<Layer> root_layer_; + Layer* root_layer_; ScrollElasticityHelper* scroll_elasticity_helper_; int content_layer_id_; int num_draws_; @@ -5972,10 +5978,6 @@ class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { ADD_FAILURE() << "Should not get called on main thread."; } - void OnForwardScrollUpdateToMainThreadOnImpl() override { - ADD_FAILURE() << "Should not get called on main thread."; - } - private: int* set_needs_commit_count_; }; @@ -6155,13 +6157,6 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { } void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Setting gpu rasterization trigger does not enable gpu rasterization. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - PostSetNeedsCommitToMainThread(); } @@ -6170,6 +6165,7 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { @@ -6177,6 +6173,7 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); EndTest(); } @@ -6187,57 +6184,12 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault); -class LayerTreeHostTestEmptyLayerGpuRasterization : public LayerTreeHostTest { +class LayerTreeHostWithGpuRasterizationSupportedTest + : public LayerTreeHostTest { protected: - void SetupTree() override { - LayerTreeHostTest::SetupTree(); - - std::unique_ptr<FakeRecordingSource> recording_source( - new FakeRecordingSource); - recording_source_ = recording_source.get(); - - scoped_refptr<FakePictureLayer> layer = - FakePictureLayer::CreateWithRecordingSource( - &layer_client_, std::move(recording_source)); - layer_ = layer.get(); - layer->SetBounds(gfx::Size()); - layer->SetIsDrawable(true); - layer_tree_host()->root_layer()->AddChild(layer); - layer_client_.set_bounds(layer->bounds()); - } - - void BeginTest() override { - // Setting gpu rasterization trigger does not enable gpu rasterization. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - - PostSetNeedsCommitToMainThread(); - } - - void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_FALSE(layer_->HasSlowPaths()); - - EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); - EXPECT_FALSE(host_impl->use_gpu_rasterization()); - } - - void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_FALSE(layer_->HasSlowPaths()); - - EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); - EXPECT_FALSE(host_impl->use_gpu_rasterization()); - EndTest(); + void InitializeSettings(LayerTreeSettings* settings) override { + settings->gpu_rasterization_msaa_sample_count = 4; } - - FakeContentLayerClient layer_client_; - FakePictureLayer* layer_; - FakeRecordingSource* recording_source_; -}; - -MULTI_THREAD_TEST_F(LayerTreeHostTestEmptyLayerGpuRasterization); - -class LayerTreeHostWithGpuRasterizationTest : public LayerTreeHostTest { - protected: std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const viz::RendererSettings& renderer_settings, double refresh_rate, @@ -6282,20 +6234,36 @@ class LayerTreeHostWithGpuRasterizationTest : public LayerTreeHostTest { }; class LayerTreeHostTestGpuRasterizationEnabled - : public LayerTreeHostWithGpuRasterizationTest { + : public LayerTreeHostWithGpuRasterizationSupportedTest { protected: - void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_FALSE(layer_->HasSlowPaths()); + EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_FALSE(layer_->HasSlowPaths()); + EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); + EndTest(); + } +}; - // Gpu rasterization trigger is relevant. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); - // Content-based veto is relevant as well. +class LayerTreeHostTestGpuRasterizationEnabledWithMSAA + : public LayerTreeHostWithGpuRasterizationSupportedTest { + protected: + void BeginTest() override { + // Content-based MSAA trigger. layer_->set_force_content_has_slow_paths(true); - // Veto will take effect when layers are updated. + // MSAA trigger will take effect when layers are updated. // The results will be verified after commit is completed below. // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. @@ -6309,6 +6277,7 @@ class LayerTreeHostTestGpuRasterizationEnabled EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_msaa()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { @@ -6316,31 +6285,25 @@ class LayerTreeHostTestGpuRasterizationEnabled EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_msaa()); EndTest(); } }; -MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabledWithMSAA); -class LayerTreeHostTestGpuRasterizationReenabled - : public LayerTreeHostWithGpuRasterizationTest { +class LayerTreeHostTestGpuRasterizationMSAAReenabled + : public LayerTreeHostWithGpuRasterizationSupportedTest { protected: void InitializeSettings(LayerTreeSettings* settings) override { settings->gpu_rasterization_msaa_sample_count = 4; } void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Gpu rasterization trigger is relevant. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Content-based veto is relevant as well. + // Content-based MSAA trigger is relevant. layer_->set_force_content_has_slow_paths(true); - // Veto will take effect when layers are updated. + // MSAA trigger will take effect when layers are updated. // The results will be verified after commit is completed below. // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. @@ -6380,23 +6343,16 @@ class LayerTreeHostTestGpuRasterizationReenabled bool expected_use_msaa_ = true; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationReenabled); +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationMSAAReenabled); class LayerTreeHostTestGpuRasterizationNonAASticky - : public LayerTreeHostWithGpuRasterizationTest { + : public LayerTreeHostWithGpuRasterizationSupportedTest { protected: void InitializeSettings(LayerTreeSettings* settings) override { settings->gpu_rasterization_msaa_sample_count = 4; } void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Gpu rasterization trigger is relevant. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - // Start without slow paths, but no non-aa paint. layer_->set_force_content_has_slow_paths(true); layer_->set_force_content_has_non_aa_paint(false); @@ -6461,14 +6417,7 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { } void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // With gpu rasterization forced, gpu rasterization trigger is irrelevant. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Content-based veto is irrelevant as well. + // Content-based MSAA trigger is irrelevant as well. layer_->set_force_content_has_slow_paths(true); // Veto will take effect when layers are updated. @@ -6502,6 +6451,29 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced); +class LayerTreeHostTestGpuRasterizationSupportedButDisabled + : public LayerTreeHostWithGpuRasterizationSupportedTest { + protected: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->gpu_rasterization_disabled = true; + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_FALSE(host_impl->sync_tree()->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_gpu_rasterization()); + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EndTest(); + } +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationSupportedButDisabled); + class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame : public LayerTreeHostTest { public: @@ -6890,23 +6862,19 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { protected: LayerTreeHostTestCrispUpAfterPinchEnds() : playback_allowed_event_(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::SIGNALED) {} + base::WaitableEvent::InitialState::SIGNALED) { + SetUseLayerLists(); + } void SetupTree() override { frame_ = 1; posted_ = false; client_.set_fill_with_nonsolid_color(true); - scoped_refptr<Layer> root_clip = Layer::Create(); - root_clip->SetBounds(gfx::Size(500, 500)); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - page_scale_layer->SetBounds(gfx::Size(500, 500)); - - scoped_refptr<Layer> pinch = Layer::Create(); - pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollable(gfx::Size(500, 500)); - page_scale_layer->AddChild(pinch); - root_clip->AddChild(page_scale_layer); + SetInitialRootBounds(gfx::Size(500, 500)); + LayerTreeHostTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); + SetupViewport(root, root->bounds(), root->bounds()); std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); recording->SetPlaybackAllowedEvent(&playback_allowed_event_); @@ -6917,17 +6885,12 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { layer->SetContentsOpaque(true); // Avoid LCD text on the layer so we don't cause extra commits when we // pinch. - pinch->AddChild(layer); + CopyProperties(layer_tree_host()->InnerViewportScrollLayerForTesting(), + layer.get()); + root->AddChild(layer); - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root_clip; - viewport_layers.inner_viewport_scroll = pinch; - layer_tree_host()->RegisterViewportLayers(viewport_layers); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); - layer_tree_host()->SetRootLayer(root_clip); - LayerTreeHostTest::SetupTree(); - client_.set_bounds(root_clip->bounds()); + client_.set_bounds(root->bounds()); } // Returns the delta scale of all quads in the frame's root pass from their @@ -7194,23 +7157,20 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles protected: LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles() : playback_allowed_event_(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::SIGNALED) {} + base::WaitableEvent::InitialState::SIGNALED) { + SetUseLayerLists(); + } void SetupTree() override { step_ = 1; continuous_draws_ = 0; client_.set_fill_with_nonsolid_color(true); - scoped_refptr<Layer> root_clip = Layer::Create(); - root_clip->SetBounds(gfx::Size(500, 500)); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - page_scale_layer->SetBounds(gfx::Size(500, 500)); + SetInitialRootBounds(gfx::Size(500, 500)); + LayerTreeHostTest::SetupTree(); - scoped_refptr<Layer> pinch = Layer::Create(); - pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollable(gfx::Size(500, 500)); - page_scale_layer->AddChild(pinch); - root_clip->AddChild(page_scale_layer); + Layer* root = layer_tree_host()->root_layer(); + SetupViewport(root, root->bounds(), root->bounds()); std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); recording->SetPlaybackAllowedEvent(&playback_allowed_event_); @@ -7219,19 +7179,12 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles std::move(recording)); layer->SetBounds(gfx::Size(500, 500)); layer->SetContentsOpaque(true); - // Avoid LCD text on the layer so we don't cause extra commits when we - // pinch. - pinch->AddChild(layer); + CopyProperties(layer_tree_host()->InnerViewportScrollLayerForTesting(), + layer.get()); + root->AddChild(layer); - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root_clip; - viewport_layers.inner_viewport_scroll = pinch; - layer_tree_host()->RegisterViewportLayers(viewport_layers); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); - layer_tree_host()->SetRootLayer(root_clip); - LayerTreeHostTest::SetupTree(); - client_.set_bounds(root_clip->bounds()); + client_.set_bounds(root->bounds()); } // Returns the delta scale of all quads in the frame's root pass from their @@ -7564,41 +7517,33 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests); class LayerTreeTestPageScaleFlags : public LayerTreeTest { + public: + LayerTreeTestPageScaleFlags() { SetUseLayerLists(); } + protected: void SetupTree() override { // -root // -pre page scale - // -page scale - // -inner viewport scroll - // -page scale grandchild + // -viewport layers // -post page scale - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> pre_page_scale = Layer::Create(); - scoped_refptr<Layer> page_scale = Layer::Create(); - scoped_refptr<Layer> inner_viewport_scroll = Layer::Create(); - scoped_refptr<Layer> page_scale_grandchild = Layer::Create(); - scoped_refptr<Layer> post_page_scale = Layer::Create(); + LayerTreeTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); + scoped_refptr<Layer> pre_page_scale = Layer::Create(); + CopyProperties(root, pre_page_scale.get()); root->AddChild(pre_page_scale); - root->AddChild(page_scale); - root->AddChild(post_page_scale); - page_scale->AddChild(inner_viewport_scroll); - inner_viewport_scroll->AddChild(page_scale_grandchild); + SetupViewport(root, root->bounds(), root->bounds()); - layer_tree_host()->SetRootLayer(root); - LayerTreeTest::SetupTree(); - - ViewportLayers viewport_layers; - viewport_layers.inner_viewport_container = root; - viewport_layers.page_scale = page_scale; - viewport_layers.inner_viewport_scroll = inner_viewport_scroll; - layer_tree_host()->RegisterViewportLayers(viewport_layers); + scoped_refptr<Layer> post_page_scale = Layer::Create(); + CopyProperties(root, post_page_scale.get()); + root->AddChild(post_page_scale); - affected_by_page_scale_.push_back(page_scale->id()); - affected_by_page_scale_.push_back(inner_viewport_scroll->id()); - affected_by_page_scale_.push_back(page_scale_grandchild->id()); + affected_by_page_scale_.push_back( + layer_tree_host()->InnerViewportScrollLayerForTesting()->id()); + affected_by_page_scale_.push_back( + layer_tree_host()->OuterViewportScrollLayerForTesting()->id()); not_affected_by_page_scale_.push_back(root->id()); not_affected_by_page_scale_.push_back(pre_page_scale->id()); @@ -7608,14 +7553,12 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest { void BeginTest() override { PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - LayerTreeHostCommon::CallFunctionForEveryLayer( - host_impl->sync_tree(), [this](LayerImpl* layer) { - const std::vector<int>& list = - layer->IsAffectedByPageScale() - ? this->affected_by_page_scale_ - : this->not_affected_by_page_scale_; - EXPECT_TRUE(base::Contains(list, layer->id())); - }); + for (auto* layer : *host_impl->sync_tree()) { + const std::vector<int>& list = layer->IsAffectedByPageScale() + ? this->affected_by_page_scale_ + : this->not_affected_by_page_scale_; + EXPECT_TRUE(base::Contains(list, layer->id())); + } EndTest(); } @@ -8278,8 +8221,8 @@ class LayerTreeHostTestImageAnimation : public LayerTreeHostTest { void WillPrepareToDrawOnThread(LayerTreeHostImpl* host_impl) override { gfx::Rect image_rect(-1, -1, 502, 502); - auto* layer = static_cast<PictureLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()); + auto* layer = + static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer()); switch (++draw_count_) { case 1: // First draw, everything is invalid. @@ -8816,6 +8759,8 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestPartialTileDamage); class LayerTreeHostTopControlsDeltaTriggersViewportUpdate : public LayerTreeHostTest { public: + LayerTreeHostTopControlsDeltaTriggersViewportUpdate() { SetUseLayerLists(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } void SetupTree() override { @@ -8824,6 +8769,7 @@ class LayerTreeHostTopControlsDeltaTriggersViewportUpdate // Set up scrollable root. root_layer->SetBounds(gfx::Size(100, 100)); SetupViewport(root_layer, gfx::Size(50, 50), root_layer->bounds()); + layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f); // Set browser controls to be partially shown. layer_tree_host()->SetBrowserControlsHeight(kTopControlsHeight, 0.0f, true /* shrink */); diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc index 56bd3ff896d..a21e88e65bb 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -352,7 +352,7 @@ class LayerTreeHostAnimationTestAddKeyframeModelWithTimingFunction base::TimeTicks monotonic_time) override { // TODO(ajuma): This test only checks the active tree. Add checks for // pending tree too. - if (!host_impl->active_tree()->root_layer_for_testing()) + if (!host_impl->active_tree()->root_layer()) return; // Wait for the commit with the animation to happen. @@ -1155,7 +1155,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval if (!host_impl->pending_tree()) return false; - if (!host_impl->active_tree()->root_layer_for_testing()) + if (!host_impl->active_tree()->root_layer()) return false; scoped_refptr<AnimationTimeline> timeline_impl = @@ -2349,11 +2349,11 @@ class LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->pending_tree()->source_frame_number() <= 1) { EXPECT_TRUE(host_impl->pending_tree() - ->root_layer_for_testing() + ->root_layer() ->screen_space_transform_is_animating()); } else { EXPECT_FALSE(host_impl->pending_tree() - ->root_layer_for_testing() + ->root_layer() ->screen_space_transform_is_animating()); } } @@ -2373,7 +2373,7 @@ class LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction DrawResult draw_result) override { const bool screen_space_transform_is_animating = host_impl->active_tree() - ->root_layer_for_testing() + ->root_layer() ->screen_space_transform_is_animating(); // Check that screen_space_transform_is_animating changes only once. diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc index 28655847535..f841b4c7826 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc @@ -120,7 +120,7 @@ class LayerTreeHostCheckerImagingTestMergeWithMainFrame case 2: { // Ensure that the expected tiles are invalidated on the sync tree. PictureLayerImpl* sync_layer_impl = static_cast<PictureLayerImpl*>( - host_impl->sync_tree()->root_layer_for_testing()); + host_impl->sync_tree()->root_layer()); PictureLayerTiling* sync_tiling = sync_layer_impl->picture_layer_tiling_set() ->FindTilingWithResolution(TileResolution::HIGH_RESOLUTION); @@ -180,8 +180,8 @@ class LayerTreeHostCheckerImagingTestImplSideTree EXPECT_EQ(host_impl->sync_tree()->source_frame_number(), 0); // Ensure that the expected tiles are invalidated on the sync tree. - PictureLayerImpl* sync_layer_impl = static_cast<PictureLayerImpl*>( - host_impl->sync_tree()->root_layer_for_testing()); + PictureLayerImpl* sync_layer_impl = + static_cast<PictureLayerImpl*>(host_impl->sync_tree()->root_layer()); PictureLayerTiling* sync_tiling = sync_layer_impl->picture_layer_tiling_set()->FindTilingWithResolution( TileResolution::HIGH_RESOLUTION); diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc index 55bb0a7b7af..f2b8bba821c 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_context.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc @@ -750,8 +750,8 @@ class LayerTreeHostContextTestLostContextAndEvictTextures } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>( - impl->active_tree()->root_layer_for_testing()); + FakePictureLayerImpl* picture_impl = + static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); EXPECT_TRUE(picture_impl->HighResTiling() ->TileAt(0, 0) ->draw_info() @@ -829,7 +829,7 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest { // fail before second activation. if (num_commits_ >= 2) { root_picture = static_cast<FakePictureLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()); + host_impl->active_tree()->root_layer()); child_picture = static_cast<FakePictureLayerImpl*>( host_impl->active_tree()->LayerById(child_->id())); grandchild_picture = static_cast<FakePictureLayerImpl*>( @@ -984,7 +984,8 @@ class LayerTreeHostContextTestDontUseLostResources scoped_refptr<PaintedScrollbarLayer> scrollbar = PaintedScrollbarLayer::Create( - std::unique_ptr<Scrollbar>(new FakeScrollbar), layer->element_id()); + std::unique_ptr<Scrollbar>(new FakeScrollbar)); + scrollbar->SetScrollElementId(layer->element_id()); scrollbar->SetBounds(gfx::Size(10, 10)); scrollbar->SetIsDrawable(true); root->AddChild(scrollbar); diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc index 2545887eddb..2d3bc04e847 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc @@ -1319,7 +1319,7 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - LayerImpl* root = host_impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = host_impl->active_tree()->root_layer(); LayerImpl* child = host_impl->active_tree()->LayerById(child_->id()); bool saw_root = false; diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc index 945d4e9c32e..a61d2ea77d2 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc @@ -56,7 +56,7 @@ class LayerTreeHostDamageTestSetNeedsRedraw EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -118,7 +118,7 @@ class LayerTreeHostDamageTestSetViewportRectAndScale EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -258,7 +258,7 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(host_impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -378,7 +378,7 @@ class LayerTreeHostDamageTestScrollbarDoesDamage DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(host_impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -464,7 +464,7 @@ class LayerTreeHostDamageTestScrollbarCommitDoesNoDamage DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(host_impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); diff --git a/chromium/cc/trees/layer_tree_host_unittest_masks.cc b/chromium/cc/trees/layer_tree_host_unittest_masks.cc index 3a2edb4e411..ca119f3aa82 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_masks.cc @@ -22,7 +22,9 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin // the surface bounds to be larger. It also has a parent that clips the // masked layer and its surface. - scoped_refptr<Layer> root = Layer::Create(); + SetInitialRootBounds(gfx::Size(100, 100)); + LayerTreeTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); scoped_refptr<FakePictureLayer> content_layer = FakePictureLayer::Create(&client_); @@ -42,27 +44,30 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin &client_, std::move(recording_source)); content_layer->SetMaskLayer(mask_layer); - gfx::Size root_size(100, 100); - root->SetBounds(root_size); - gfx::Size layer_size(100, 100); content_layer->SetBounds(layer_size); gfx::Size mask_size(100, 100); mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); mask_layer_id_ = mask_layer->id(); - layer_tree_host()->SetRootLayer(root); - LayerTreeTest::SetupTree(); - scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create(); - outer_viewport_scroll_layer->SetBounds(layer_size); - SetupViewport(root.get(), outer_viewport_scroll_layer, gfx::Size(50, 50)); - layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true); - outer_viewport_scroll_layer->AddChild(content_layer); + scoped_refptr<Layer> clip_layer = Layer::Create(); + clip_layer->SetBounds(gfx::Size(50, 50)); + clip_layer->SetMasksToBounds(true); + + scoped_refptr<Layer> scroll_layer = Layer::Create(); + scroll_layer->SetBounds(layer_size); + scroll_layer->SetScrollable(gfx::Size(50, 50)); + scroll_layer->SetMasksToBounds(true); + scroll_layer->SetElementId( + LayerIdToElementIdForTesting(scroll_layer->id())); + + root->AddChild(clip_layer); + clip_layer->AddChild(scroll_layer); + scroll_layer->AddChild(content_layer); client_.set_bounds(root->bounds()); - outer_viewport_scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -70,7 +75,7 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -85,11 +90,13 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( render_pass_quad->shared_quad_state->quad_to_target_transform, render_pass_quad->rect); - EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), - rect_in_target_space.ToString()); - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50), rect_in_target_space); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -101,6 +108,88 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin); +class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList + : public LayerTreeTest { + protected: + LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList() { + SetUseLayerLists(); + } + + void SetupTree() override { + // The masked layer has bounds 50x50, but it has a child that causes + // the surface bounds to be larger. It also has a parent that clips the + // masked layer and its surface. + + SetInitialRootBounds(gfx::Size(100, 100)); + LayerTreeTest::SetupTree(); + + Layer* root = layer_tree_host()->root_layer(); + + gfx::Size layer_size(100, 100); + SetupViewport(root, gfx::Size(50, 50), layer_size); + + auto* scroll = layer_tree_host()->OuterViewportScrollLayerForTesting(); + SetScrollOffset(scroll, gfx::ScrollOffset(50, 50)); + + client_.set_bounds(root->bounds()); + auto content_layer = FakePictureLayer::Create(&client_); + content_layer->SetBounds(layer_size); + CopyProperties(scroll, content_layer.get()); + root->AddChild(content_layer); + + std::unique_ptr<RecordingSource> recording_source = + FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100)); + PaintFlags paint1, paint2; + static_cast<FakeRecordingSource*>(recording_source.get()) + ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1); + static_cast<FakeRecordingSource*>(recording_source.get()) + ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2); + client_.set_fill_with_nonsolid_color(true); + static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord(); + + auto mask_layer = FakePictureLayer::CreateWithRecordingSource( + &client_, std::move(recording_source)); + SetupMaskProperties(content_layer.get(), mask_layer.get()); + root->AddChild(mask_layer); + + mask_layer_id_ = mask_layer->id(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { + EXPECT_EQ(1u, frame_data->render_passes.size()); + viz::RenderPass* pass = frame_data->render_passes.back().get(); + EXPECT_EQ(3u, pass->quad_list.size()); + + // There's a solid color quad under everything. + EXPECT_EQ(viz::DrawQuad::Material::kSolidColor, + pass->quad_list.back()->material); + + EXPECT_EQ(viz::DrawQuad::Material::kTiledContent, + pass->quad_list.ElementAt(1)->material); + + auto* mask_quad = pass->quad_list.front(); + EXPECT_EQ(viz::DrawQuad::Material::kTiledContent, mask_quad->material); + gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( + mask_quad->shared_quad_state->quad_to_target_transform, + mask_quad->rect); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50), rect_in_target_space); + // We use kDstIn blend mode for mask. + EXPECT_EQ(SkBlendMode::kDstIn, mask_quad->shared_quad_state->blend_mode); + EndTest(); + return draw_result; + } + + int mask_layer_id_; + FakeContentLayerClient client_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList); + class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { protected: void SetupTree() override { @@ -156,7 +245,6 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { gfx::Size mask_size(50, 50); mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); mask_layer_id_ = mask_layer->id(); layer_tree_host()->SetRootLayer(root); @@ -169,7 +257,7 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -187,13 +275,12 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { render_pass_quad->rect); EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(), rect_in_target_space.ToString()); - // The masked layer is 50x50, but the surface size is 10x20. So the texture - // coords in the mask are scaled by 10/50 and 20/50. - // The surface is clipped to (20,10) so the mask texture coords are offset - // by 20/50 and 10/50 - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -265,7 +352,6 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale gfx::Size mask_size(50, 50); mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); // Setting will change transform on mask layer will make it not adjust // raster scale, which will remain 1. This means the mask_layer and render // surface will have a scale of 2 during draw time. @@ -282,7 +368,7 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -306,13 +392,12 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale render_pass_quad->visible_rect); EXPECT_EQ(gfx::Rect(20, 10, 20, 40).ToString(), visible_rect_in_target_space.ToString()); - // The masked layer is 50x50, but the surface size is 10x20. So the texture - // coords in the mask are scaled by 10/50 and 20/50. - // The surface is clipped to (20,10) so the mask texture coords are offset - // by 20/50 and 10/50 - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -368,9 +453,7 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { scaling_layer->SetTransform(scale); content_layer->SetBounds(scaling_layer_size); - mask_layer->SetBounds(scaling_layer_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); layer_tree_host()->SetRootLayer(root); LayerTreeTest::SetupTree(); @@ -382,7 +465,7 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -397,22 +480,25 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( render_pass_quad->shared_quad_state->quad_to_target_transform, render_pass_quad->rect); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); + switch (host_impl->active_tree()->source_frame_number()) { case 0: // Check that the tree scaling is correctly taken into account for the // mask, that should fully map onto the quad. EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), rect_in_target_space.ToString()); - EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); break; case 1: // Applying a DSF should change the render surface size, but won't // affect which part of the mask is used. EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), rect_in_target_space.ToString()); - EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); EndTest(); break; } @@ -471,7 +557,6 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { gfx::Size mask_size(100, 100); gfx::Size mask_texture_size(120, 150); mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); mask_layer->set_fixed_tile_size(mask_texture_size); layer_tree_host()->SetRootLayer(root); @@ -484,7 +569,7 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -499,9 +584,12 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), render_pass_quad->rect.ToString()); - // The mask layer is 100x100, but is backed by a 120x150 image. - EXPECT_EQ(gfx::RectF(0.0f, 0.0f, 100.f / 120.0f, 100.f / 150.0f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } diff --git a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc index 244eb6f2861..e54c35ac2cf 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc @@ -49,7 +49,7 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnLayer void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); // Verify the draw properties are valid. @@ -103,7 +103,7 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnSurface void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); RenderSurfaceImpl* surface = GetRenderSurface(child); @@ -148,10 +148,10 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask make_surface_bigger->SetIsDrawable(true); child_->AddChild(make_surface_bigger); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_); - mask->SetBounds(gfx::Size(30, 40)); - mask->SetIsDrawable(true); - child_->SetMaskLayer(mask); + mask_ = PictureLayer::Create(&client_); + mask_->SetBounds(gfx::Size(30, 40)); + mask_->SetIsDrawable(true); + child_->SetMaskLayer(mask_); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 12)); @@ -168,30 +168,44 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - RenderSurfaceImpl* surface = GetRenderSurface(child); - LayerImpl* mask = surface->MaskLayer(); + RenderSurfaceImpl* child_surface = GetRenderSurface(child); + LayerImpl* mask = impl->active_tree()->LayerById(mask_->id()); + RenderSurfaceImpl* mask_surface = GetRenderSurface(mask); // Verify the draw properties are valid. EXPECT_TRUE(root->contributes_to_drawn_render_surface()); EXPECT_TRUE(child->contributes_to_drawn_render_surface()); - EXPECT_TRUE(GetRenderSurface(child)); - EXPECT_EQ(GetRenderSurface(child), child->render_target()); + EXPECT_TRUE(mask->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child_surface); + EXPECT_EQ(child_surface, child->render_target()); - gfx::Transform transform = surface->draw_transform(); + gfx::Transform transform = child_surface->draw_transform(); transform.PreconcatTransform(child->DrawTransform()); + EXPECT_OCCLUSION_EQ( + Occlusion(transform, SimpleEnclosedRegion(), + SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))), + child_surface->occlusion_in_content_space()); + // Mask layer has its own transform and render surface in layer tree mode. + EXPECT_NE(child_surface, mask_surface); EXPECT_OCCLUSION_EQ( Occlusion(transform, SimpleEnclosedRegion(), SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))), - mask->draw_properties().occlusion_in_content_space); + mask_surface->occlusion_in_content_space()); + + EXPECT_OCCLUSION_EQ(Occlusion(gfx::Transform(), + SimpleEnclosedRegion(gfx::Rect(3, 4, 10, 10)), + SimpleEnclosedRegion()), + mask->draw_properties().occlusion_in_content_space); EndTest(); } private: FakeContentLayerClient client_; scoped_refptr<Layer> child_; + scoped_refptr<PictureLayer> mask_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnMask); @@ -208,21 +222,21 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask gfx::Transform scale; scale.Scale(2, 2); - child_ = Layer::Create(); - child_->SetBounds(gfx::Size(30, 40)); - child_->SetTransform(scale); - root->AddChild(child_); + scoped_refptr<Layer> child = Layer::Create(); + child->SetBounds(gfx::Size(30, 40)); + child->SetTransform(scale); + root->AddChild(child); scoped_refptr<Layer> grand_child = Layer::Create(); grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetPosition(gfx::PointF(-10.f, -15.f)); grand_child->SetIsDrawable(true); - child_->AddChild(grand_child); + child->AddChild(grand_child); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_); - mask->SetBounds(gfx::Size(30, 40)); - mask->SetIsDrawable(true); - child_->SetMaskLayer(mask); + mask_ = PictureLayer::Create(&client_); + mask_->SetBounds(gfx::Size(30, 40)); + mask_->SetIsDrawable(true); + child->SetMaskLayer(mask_); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 11)); @@ -239,22 +253,21 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - LayerImpl* mask = GetRenderSurface(child)->MaskLayer(); + LayerImpl* mask = impl->active_tree()->LayerById(mask_->id()); gfx::Transform scale; scale.Scale(2, 2); EXPECT_OCCLUSION_EQ( - Occlusion(scale, SimpleEnclosedRegion(), - SimpleEnclosedRegion(gfx::Rect(13, 15, 10, 11))), + Occlusion(scale, SimpleEnclosedRegion(gfx::Rect(13, 15, 10, 11)), + SimpleEnclosedRegion()), mask->draw_properties().occlusion_in_content_space); EndTest(); } private: FakeContentLayerClient client_; - scoped_refptr<Layer> child_; + scoped_refptr<PictureLayer> mask_; }; SINGLE_AND_MULTI_THREAD_TEST_F( diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc index 445a2630c50..8b6af53dba0 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc @@ -77,7 +77,7 @@ class LayerTreeHostPictureTestTwinLayer } void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* active_root_impl = impl->active_tree()->root_layer_for_testing(); + LayerImpl* active_root_impl = impl->active_tree()->root_layer(); int picture_id = impl->active_tree()->source_frame_number() < 2 ? picture_id1_ : picture_id2_; @@ -293,7 +293,7 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree PictureLayerTiling* tiling = picture_impl->HighResTiling(); int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y(); - if (!impl->active_tree()->root_layer_for_testing()) { + if (!impl->active_tree()->root_layer()) { // If active tree doesn't have the layer, then pending tree should have // all needed tiles. EXPECT_TRUE(tiling->TileAt(0, 0)); @@ -420,11 +420,6 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale picture_->SetBounds(gfx::Size(100, 100)); pinch_->AddChild(picture_); - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root_clip; - viewport_layers.inner_viewport_scroll = pinch_; - layer_tree_host()->RegisterViewportLayers(viewport_layers); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); layer_tree_host()->SetRootLayer(root_clip); LayerTreeHostPictureTest::SetupTree(); diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc index 457b2d1e9b1..f9ff5d0f499 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc @@ -7,6 +7,7 @@ #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_picture_layer.h" #include "cc/test/layer_tree_test.h" +#include "cc/trees/layer_tree_impl.h" #include "cc/trees/proxy_impl.h" #include "cc/trees/proxy_main.h" @@ -82,11 +83,6 @@ class LayerTreeHostProxyTestSetNeedsAnimate : public LayerTreeHostProxyTest { LayerTreeHostProxyTestSetNeedsAnimate& operator=( const LayerTreeHostProxyTestSetNeedsAnimate&) = delete; - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; - } - void BeginTest() override { EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); @@ -102,10 +98,6 @@ class LayerTreeHostProxyTestSetNeedsAnimate : public LayerTreeHostProxyTest { GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->current_pipeline_stage()); - } - - void DidCommit() override { - EXPECT_EQ(0, update_check_layer()->update_count()); EndTest(); } }; @@ -160,14 +152,12 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating& operator=( const LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating&) = delete; - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; - } - - void BeginTest() override { proxy()->SetNeedsAnimate(); } + void BeginTest() override {} void WillBeginMainFrame() override { + if (layer_tree_host()->SourceFrameNumber() != 1) + return; + EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::ANIMATE_PIPELINE_STAGE, @@ -184,6 +174,9 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating } void DidBeginMainFrame() override { + if (layer_tree_host()->SourceFrameNumber() != 2) + return; + EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, @@ -191,8 +184,19 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating } void DidCommit() override { - EXPECT_EQ(1, update_check_layer()->update_count()); - EndTest(); + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + EXPECT_EQ(1, update_check_layer()->update_count()); + + // Wait until the first frame is committed and we enter the desired + // state to start the test. + proxy()->SetNeedsAnimate(); + break; + case 2: + EXPECT_EQ(2, update_check_layer()->update_count()); + EndTest(); + break; + } } }; @@ -209,14 +213,12 @@ class LayerTreeHostProxyTestSetNeedsCommitWhileAnimating LayerTreeHostProxyTestSetNeedsCommitWhileAnimating& operator=( const LayerTreeHostProxyTestSetNeedsCommitWhileAnimating&) = delete; - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; - } - - void BeginTest() override { proxy()->SetNeedsAnimate(); } + void BeginTest() override {} void WillBeginMainFrame() override { + if (layer_tree_host()->SourceFrameNumber() != 1) + return; + EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::ANIMATE_PIPELINE_STAGE, @@ -233,6 +235,9 @@ class LayerTreeHostProxyTestSetNeedsCommitWhileAnimating } void DidBeginMainFrame() override { + if (layer_tree_host()->SourceFrameNumber() != 2) + return; + EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, @@ -240,8 +245,19 @@ class LayerTreeHostProxyTestSetNeedsCommitWhileAnimating } void DidCommit() override { - EXPECT_EQ(1, update_check_layer()->update_count()); - EndTest(); + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + EXPECT_EQ(1, update_check_layer()->update_count()); + + // Wait until the first frame is committed and we enter the desired + // state to start the test. + proxy()->SetNeedsAnimate(); + break; + case 2: + EXPECT_EQ(2, update_check_layer()->update_count()); + EndTest(); + break; + } } }; diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc index 451a33763d6..6f6915ee368 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc @@ -27,7 +27,6 @@ #include "cc/test/test_ukm_recorder_factory.h" #include "cc/trees/clip_node.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" @@ -75,6 +74,8 @@ static ScrollTree* ScrollTreeForLayer(LayerImpl* layer_impl) { class LayerTreeHostScrollTest : public LayerTreeTest { protected: + LayerTreeHostScrollTest() { SetUseLayerLists(); } + void SetupTree() override { LayerTreeTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); @@ -84,31 +85,45 @@ class LayerTreeHostScrollTest : public LayerTreeTest { root_layer->bounds().height() + 100); SetupViewport(root_layer, root_layer->bounds(), scroll_layer_bounds); + layer_tree_host() + ->OuterViewportScrollLayerForTesting() + ->set_did_scroll_callback(base::BindRepeating( + &LayerTreeHostScrollTest::DidScrollOuterViewport, + base::Unretained(this))); + } + + // This is set as did_scroll_callback of scroll layers to automatically + // synchronize scroll delta from impl-side, which simulates cc client (e.g. + // Blink) behavior when handling impl-side scrolls. + void SyncScrollFromImpl(const gfx::ScrollOffset& scroll_offset, + const ElementId& element_id) { + SetScrollOffset(layer_tree_host()->LayerByElementId(element_id), + scroll_offset); } + + virtual void DidScrollOuterViewport(const gfx::ScrollOffset& scroll_offset, + const ElementId& element_id) { + SyncScrollFromImpl(scroll_offset, element_id); + num_outer_viewport_scrolls_++; + } + + int num_outer_viewport_scrolls_ = 0; }; class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { public: LayerTreeHostScrollTestScrollSimple() - : initial_scroll_(10, 20), - second_scroll_(40, 5), - scroll_amount_(2, -1), - num_scrolls_(0) {} + : initial_scroll_(10, 20), second_scroll_(40, 5), scroll_amount_(2, -1) {} void BeginTest() override { - outer_viewport_container_layer_id_ = - layer_tree_host()->outer_viewport_container_layer()->id(); - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestScrollSimple::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } void UpdateLayerTreeHost() override { - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); if (!layer_tree_host()->SourceFrameNumber()) { EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset()); } else { @@ -117,13 +132,14 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { scroll_layer->CurrentScrollOffset()); // Pretend like Javascript updated the scroll position itself. - scroll_layer->SetScrollOffset(second_scroll_); + SetScrollOffset(scroll_layer, second_scroll_); } } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root = impl->active_tree()->root_layer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); scroll_layer->SetBounds( @@ -148,18 +164,12 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - - void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); } private: gfx::ScrollOffset initial_scroll_; gfx::ScrollOffset second_scroll_; gfx::Vector2dF scroll_amount_; - int num_scrolls_; - int outer_viewport_container_layer_id_; }; MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple); @@ -168,14 +178,11 @@ class LayerTreeHostScrollTestScrollMultipleRedraw : public LayerTreeHostScrollTest { public: LayerTreeHostScrollTestScrollMultipleRedraw() - : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {} + : initial_scroll_(40, 10), scroll_amount_(-3, 17) {} void BeginTest() override { - scroll_layer_ = layer_tree_host()->outer_viewport_scroll_layer(); - scroll_layer_->SetScrollOffset(initial_scroll_); - scroll_layer_->set_did_scroll_callback(base::BindRepeating( - &LayerTreeHostScrollTestScrollMultipleRedraw::DidScrollOuterViewport, - base::Unretained(this))); + scroll_layer_ = layer_tree_host()->OuterViewportScrollLayerForTesting(); + SetScrollOffset(scroll_layer_.get(), initial_scroll_); PostSetNeedsCommitToMainThread(); } @@ -227,16 +234,11 @@ class LayerTreeHostScrollTestScrollMultipleRedraw } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - - void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); } private: gfx::ScrollOffset initial_scroll_; gfx::Vector2dF scroll_amount_; - int num_scrolls_; scoped_refptr<Layer> scroll_layer_; }; @@ -254,16 +256,11 @@ class LayerTreeHostScrollTestScrollAbortedCommit num_did_begin_main_frames_(0), num_will_commits_(0), num_did_commits_(0), - num_impl_commits_(0), - num_impl_scrolls_(0) {} + num_impl_commits_(0) {} void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestScrollAbortedCommit::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } @@ -271,18 +268,19 @@ class LayerTreeHostScrollTestScrollAbortedCommit LayerTreeHostScrollTest::SetupTree(); gfx::Size scroll_layer_bounds(200, 200); - layer_tree_host()->outer_viewport_scroll_layer()->SetBounds( + layer_tree_host()->OuterViewportScrollLayerForTesting()->SetBounds( scroll_layer_bounds); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); } void WillBeginMainFrame() override { num_will_begin_main_frames_++; - Layer* root_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* root_scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); switch (num_will_begin_main_frames_) { case 1: // This will not be aborted because of the initial prop changes. - EXPECT_EQ(0, num_impl_scrolls_); + EXPECT_EQ(0, num_outer_viewport_scrolls_); EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ(initial_scroll_, root_scroll_layer->CurrentScrollOffset()); @@ -291,7 +289,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit case 2: // This commit will be aborted, and another commit will be // initiated from the redraw. - EXPECT_EQ(1, num_impl_scrolls_); + EXPECT_EQ(1, num_outer_viewport_scrolls_); EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_), @@ -301,7 +299,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit break; case 3: // This commit will not be aborted because of the scroll change. - EXPECT_EQ(2, num_impl_scrolls_); + EXPECT_EQ(2, num_outer_viewport_scrolls_); // The source frame number still increases even with the abort. EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta( @@ -309,12 +307,14 @@ class LayerTreeHostScrollTestScrollAbortedCommit root_scroll_layer->CurrentScrollOffset()); EXPECT_EQ(impl_scale_ * impl_scale_, layer_tree_host()->page_scale_factor()); - root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta( - root_scroll_layer->CurrentScrollOffset(), second_main_scroll_)); + SetScrollOffset( + root_scroll_layer, + gfx::ScrollOffsetWithDelta(root_scroll_layer->CurrentScrollOffset(), + second_main_scroll_)); break; case 4: // This commit will also be aborted. - EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, num_outer_viewport_scrolls_); EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber()); gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; @@ -338,7 +338,8 @@ class LayerTreeHostScrollTestScrollAbortedCommit } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root_scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root_scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); if (impl->active_tree()->source_frame_number() == 0 && impl->SourceAnimationFrameNumberForTesting() == 1) { @@ -412,12 +413,8 @@ class LayerTreeHostScrollTestScrollAbortedCommit } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_impl_scrolls_++; - } - void AfterTest() override { - EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, num_outer_viewport_scrolls_); // Verify that the embedder sees aborted commits as real commits. EXPECT_EQ(4, num_will_begin_main_frames_); EXPECT_EQ(4, num_did_begin_main_frames_); @@ -437,7 +434,6 @@ class LayerTreeHostScrollTestScrollAbortedCommit int num_will_commits_; int num_did_commits_; int num_impl_commits_; - int num_impl_scrolls_; }; MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit); @@ -454,7 +450,8 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); // Check that a fractional scroll delta is correctly accumulated over // multiple commits. @@ -504,20 +501,41 @@ class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest { void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); - layer_tree_host() - ->outer_viewport_container_layer() - ->SetForceRenderSurfaceForTesting(true); - gfx::Transform translate; - translate.Translate(0.25f, 0.f); - layer_tree_host()->outer_viewport_container_layer()->SetTransform( - translate); + + scoped_refptr<Layer> container = Layer::Create(); + container->SetBounds(gfx::Size(100, 100)); + CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(), + container.get()); + CreateTransformNode(container.get()).post_translation = + gfx::Vector2dF(0.25, 0); + CreateEffectNode(container.get()).render_surface_reason = + RenderSurfaceReason::kTest; + layer_tree_host()->root_layer()->AddChild(container); + + scroll_layer_ = Layer::Create(); + scroll_layer_->SetBounds(gfx::Size(200, 200)); + scroll_layer_->SetScrollable(gfx::Size(100, 100)); + scroll_layer_->SetIsDrawable(true); + scroll_layer_->SetElementId( + LayerIdToElementIdForTesting(scroll_layer_->id())); + CopyProperties(container.get(), scroll_layer_.get()); + CreateTransformNode(scroll_layer_.get()); + CreateScrollNode(scroll_layer_.get()); + layer_tree_host()->root_layer()->AddChild(scroll_layer_); + + scroll_layer_->set_did_scroll_callback(base::BindRepeating( + &LayerTreeHostScrollTestScrollSnapping::SyncScrollFromImpl, + base::Unretained(this))); + layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->LayerById(scroll_layer_->id()); + gfx::Transform translate; // Check that screen space transform of the scrollable layer is correctly @@ -545,6 +563,7 @@ class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest { } private: + scoped_refptr<Layer> scroll_layer_; gfx::Vector2dF scroll_amount_; }; @@ -555,25 +574,17 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { LayerTreeHostScrollTestCaseWithChild() : initial_offset_(10, 20), javascript_scroll_(40, 5), - scroll_amount_(2, -1), - num_scrolls_(0) {} + scroll_amount_(2, -1) {} void SetupTree() override { SetInitialDeviceScaleFactor(device_scale_factor_); SetInitialRootBounds(gfx::Size(10, 10)); LayerTreeHostScrollTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); + Layer* root_scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); - root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); - root_scroll_layer_->SetElementId( - LayerIdToElementIdForTesting(root_scroll_layer_->id())); - root_scroll_layer_->SetBounds(gfx::Size(110, 110)); - root_scroll_layer_->SetPosition(gfx::PointF()); - root_scroll_layer_->SetIsDrawable(true); - - SetupViewport(root_layer, root_scroll_layer_, root_layer->bounds()); - - child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); + child_layer_ = Layer::Create(); child_layer_->set_did_scroll_callback( base::BindRepeating(&LayerTreeHostScrollTestCaseWithChild::DidScroll, base::Unretained(this))); @@ -581,14 +592,15 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { LayerIdToElementIdForTesting(child_layer_->id())); child_layer_->SetBounds(gfx::Size(110, 110)); + gfx::Vector2dF child_layer_offset; + // Adjust the child layer horizontally so that scrolls will never hit it. if (scroll_child_layer_) { // Scrolls on the child layer will happen at 5, 5. If they are treated // like device pixels, and device scale factor is 2, then they will // be considered at 2.5, 2.5 in logical pixels, and will miss this layer. - child_layer_->SetPosition(gfx::PointF(5.f, 5.f)); + child_layer_offset = gfx::Vector2dF(5.f, 5.f); } else { - // Adjust the child layer horizontally so that scrolls will never hit it. - child_layer_->SetPosition(gfx::PointF(60.f, 5.f)); + child_layer_offset = gfx::Vector2dF(60.f, 5.f); } child_layer_->SetIsDrawable(true); @@ -596,24 +608,23 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { child_layer_->SetHitTestable(true); child_layer_->SetElementId( LayerIdToElementIdForTesting(child_layer_->id())); - child_layer_->SetBounds(root_scroll_layer_->bounds()); - root_scroll_layer_->AddChild(child_layer_); + child_layer_->SetBounds(root_scroll_layer->bounds()); + root_layer->AddChild(child_layer_); + + CopyProperties(root_scroll_layer, child_layer_.get()); + CreateTransformNode(child_layer_.get()).post_translation = + child_layer_offset; + CreateScrollNode(child_layer_.get()); if (scroll_child_layer_) { - expected_scroll_layer_ = child_layer_; - expected_no_scroll_layer_ = root_scroll_layer_; + expected_scroll_layer_ = child_layer_.get(); + expected_no_scroll_layer_ = root_scroll_layer; } else { - expected_scroll_layer_ = root_scroll_layer_; - expected_no_scroll_layer_ = child_layer_; + expected_scroll_layer_ = root_scroll_layer; + expected_no_scroll_layer_ = child_layer_.get(); } - expected_scroll_layer_->SetScrollOffset(initial_offset_); - fake_content_layer_client_.set_bounds(root_layer->bounds()); - - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestCaseWithChild::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(expected_scroll_layer_, initial_offset_); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -627,15 +638,12 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { } void DidScroll(const gfx::ScrollOffset& offset, const ElementId& element_id) { + SyncScrollFromImpl(offset, element_id); final_scroll_offset_ = expected_scroll_layer_->CurrentScrollOffset(); EXPECT_VECTOR_EQ(offset, final_scroll_offset_); EXPECT_EQ(element_id, expected_scroll_layer_->element_id()); } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - void UpdateLayerTreeHost() override { EXPECT_VECTOR_EQ(gfx::Vector2d(), expected_no_scroll_layer_->CurrentScrollOffset()); @@ -651,7 +659,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { expected_scroll_layer_->CurrentScrollOffset()); // Pretend like Javascript updated the scroll position itself. - expected_scroll_layer_->SetScrollOffset(javascript_scroll_); + SetScrollOffset(expected_scroll_layer_, javascript_scroll_); break; case 2: EXPECT_VECTOR_EQ( @@ -662,12 +670,13 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* inner_scroll = impl->InnerViewportScrollLayer(); - FakePictureLayerImpl* root_scroll_layer_impl = - static_cast<FakePictureLayerImpl*>(impl->OuterViewportScrollLayer()); - FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>( + LayerImpl* inner_scroll = + impl->active_tree()->InnerViewportScrollLayerForTesting(); + LayerImpl* root_scroll_layer_impl = + impl->active_tree()->OuterViewportScrollLayerForTesting(); + LayerImpl* child_layer_impl = root_scroll_layer_impl->layer_tree_impl()->LayerById( - child_layer_->id())); + child_layer_->id()); LayerImpl* expected_scroll_layer_impl = nullptr; LayerImpl* expected_no_scroll_layer_impl = nullptr; @@ -690,8 +699,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { // GESTURE scroll on impl thread. Also tests that the last scrolled // layer id is stored even after the scrolling ends. gfx::Point scroll_point = gfx::ToCeiledPoint( - expected_scroll_layer_impl->test_properties()->position - - gfx::Vector2dF(0.5f, 0.5f)); + gfx::PointF(-0.5f, -0.5f) + + GetTransformNode(expected_scroll_layer_impl)->post_translation); InputHandler::ScrollStatus status = impl->ScrollBegin( BeginState(scroll_point).get(), InputHandler::TOUCHSCREEN); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); @@ -715,8 +724,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { case 1: { // WHEEL scroll on impl thread. gfx::Point scroll_point = gfx::ToCeiledPoint( - expected_scroll_layer_impl->test_properties()->position + - gfx::Vector2dF(0.5f, 0.5f)); + gfx::PointF(0.5f, 0.5f) + + GetTransformNode(expected_scroll_layer_impl)->post_translation); InputHandler::ScrollStatus status = impl->ScrollBegin( BeginState(scroll_point).get(), InputHandler::WHEEL); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); @@ -749,12 +758,12 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { void AfterTest() override { if (scroll_child_layer_) { - EXPECT_EQ(0, num_scrolls_); + EXPECT_EQ(0, num_outer_viewport_scrolls_); EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_), final_scroll_offset_); } else { - EXPECT_EQ(2, num_scrolls_); + EXPECT_EQ(2, num_outer_viewport_scrolls_); EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_); } } @@ -766,15 +775,11 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { gfx::ScrollOffset initial_offset_; gfx::ScrollOffset javascript_scroll_; gfx::Vector2d scroll_amount_; - int num_scrolls_; gfx::ScrollOffset final_scroll_offset_; - FakeContentLayerClient fake_content_layer_client_; - - scoped_refptr<Layer> root_scroll_layer_; scoped_refptr<Layer> child_layer_; - scoped_refptr<Layer> expected_scroll_layer_; - scoped_refptr<Layer> expected_no_scroll_layer_; + Layer* expected_scroll_layer_; + Layer* expected_no_scroll_layer_; }; TEST_F(LayerTreeHostScrollTestCaseWithChild, DeviceScaleFactor1_ScrollChild) { @@ -822,8 +827,7 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { : initial_scroll_(10, 20), main_thread_scroll_(40, 5), impl_thread_scroll1_(2, -1), - impl_thread_scroll2_(-3, 10), - num_scrolls_(0) {} + impl_thread_scroll2_(-3, 10) {} void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); @@ -831,17 +835,14 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { } void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestSimple::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } void UpdateLayerTreeHost() override { - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); if (!layer_tree_host()->SourceFrameNumber()) { EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset()); } else { @@ -851,7 +852,8 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { // Pretend like Javascript updated the scroll position itself with a // change of main_thread_scroll. - scroll_layer->SetScrollOffset( + SetScrollOffset( + scroll_layer, gfx::ScrollOffsetWithDelta( initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_)); } @@ -868,8 +870,9 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { if (impl->pending_tree()) impl->SetNeedsRedraw(); - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root = impl->active_tree()->root_layer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); LayerImpl* pending_root = impl->active_tree()->FindPendingTreeLayerById(root->id()); @@ -903,7 +906,7 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { ScrollDelta(scroll_layer)); LayerImpl* pending_scroll_layer = - impl->pending_tree()->OuterViewportScrollLayer(); + impl->pending_tree()->OuterViewportScrollLayerForTesting(); EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta( initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_), @@ -927,18 +930,13 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - - void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); } private: gfx::ScrollOffset initial_scroll_; gfx::Vector2dF main_thread_scroll_; gfx::Vector2dF impl_thread_scroll1_; gfx::Vector2dF impl_thread_scroll2_; - int num_scrolls_; }; // This tests scrolling on the impl side which is only possible with a thread. @@ -959,13 +957,14 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { } void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } void WillCommit() override { - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); switch (layer_tree_host()->SourceFrameNumber()) { case 0: EXPECT_TRUE(base::Contains( @@ -986,8 +985,9 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { void BeginCommitOnThread(LayerTreeHostImpl* impl) override { // Scroll after the 2nd commit has started. if (impl->active_tree()->source_frame_number() == 0) { - LayerImpl* active_root = impl->active_tree()->root_layer_for_testing(); - LayerImpl* active_scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* active_root = impl->active_tree()->root_layer(); + LayerImpl* active_scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); ASSERT_TRUE(active_root); ASSERT_TRUE(active_scroll_layer); active_scroll_layer->ScrollBy(impl_thread_scroll_); @@ -998,12 +998,13 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { // We force a second draw here of the first commit before activating // the second commit. - LayerImpl* active_root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* active_root = impl->active_tree()->root_layer(); LayerImpl* active_scroll_layer = - active_root ? impl->OuterViewportScrollLayer() : nullptr; - LayerImpl* pending_root = impl->pending_tree()->root_layer_for_testing(); + active_root ? impl->active_tree()->OuterViewportScrollLayerForTesting() + : nullptr; + LayerImpl* pending_root = impl->pending_tree()->root_layer(); LayerImpl* pending_scroll_layer = - impl->pending_tree()->OuterViewportScrollLayer(); + impl->pending_tree()->OuterViewportScrollLayerForTesting(); ASSERT_TRUE(pending_root); ASSERT_TRUE(pending_scroll_layer); @@ -1048,7 +1049,8 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { if (!impl->pending_tree()) return; - LayerImpl* scroll_layer = impl->pending_tree()->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->pending_tree()->OuterViewportScrollLayerForTesting(); gfx::ScrollOffset scroll_offset = scroll_layer->CurrentScrollOffset(); int transform_index = scroll_layer->transform_tree_index(); gfx::ScrollOffset transform_tree_scroll_offset = @@ -1063,7 +1065,8 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { if (impl->pending_tree()) impl->SetNeedsRedraw(); - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); switch (impl->active_tree()->source_frame_number()) { case 0: @@ -1108,10 +1111,6 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset public: LayerTreeHostScrollTestScrollZeroMaxScrollOffset() = default; - void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_layer_lists = true; - } - void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); @@ -1123,11 +1122,11 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset scroller_->SetHitTestable(true); scroller_->SetScrollable(layer_tree_host()->root_layer()->bounds()); scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id())); - CopyProperties(layer_tree_host()->outer_viewport_scroll_layer(), + CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(), scroller_.get()); CreateTransformNode(scroller_.get()); CreateScrollNode(scroller_.get()); - layer_tree_host()->outer_viewport_scroll_layer()->AddChild(scroller_.get()); + layer_tree_host()->root_layer()->AddChild(scroller_.get()); } void BeginTest() override { @@ -1202,11 +1201,12 @@ class LayerTreeHostScrollTestScrollNonDrawnLayer void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); - layer_tree_host()->outer_viewport_scroll_layer()->SetIsDrawable(false); - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - gfx::ScrollOffset(20.f, 20.f)); + layer_tree_host()->OuterViewportScrollLayerForTesting()->SetIsDrawable( + false); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + gfx::ScrollOffset(20.f, 20.f)); layer_tree_host() - ->outer_viewport_scroll_layer() + ->OuterViewportScrollLayerForTesting() ->SetNonFastScrollableRegion(gfx::Rect(20, 20, 20, 20)); } @@ -1235,21 +1235,24 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollNonDrawnLayer); class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent : public LayerTreeHostScrollTest { public: - LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent() = default; + LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent() { + SetUseLayerLists(); + } void BeginTest() override { PostSetNeedsCommitToMainThread(); } void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); - layer_tree_host() - ->inner_viewport_scroll_layer() - ->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kScrollbarScrolling); + GetScrollNode(layer_tree_host()->InnerViewportScrollLayerForTesting()) + ->main_thread_scrolling_reasons = + MainThreadScrollingReason::kScrollbarScrolling; } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* inner_scroll_layer = impl->InnerViewportScrollLayer(); - LayerImpl* outer_scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = + impl->active_tree()->InnerViewportScrollLayerForTesting(); + LayerImpl* outer_scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); ScrollTree& scroll_tree = impl->active_tree()->property_trees()->scroll_tree; @@ -1336,14 +1339,10 @@ class LayerTreeHostScrollTestLayerStructureChange : scroll_destroy_whole_tree_(false) {} void SetupTree() override { - LayerTreeTest::SetupTree(); + LayerTreeHostScrollTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); - root_layer->SetBounds(gfx::Size(10, 10)); - - SetupViewport(root_layer, root_layer->bounds(), root_layer->bounds()); - Layer* outer_scroll_layer = - layer_tree_host()->outer_viewport_scroll_layer(); + layer_tree_host()->OuterViewportScrollLayerForTesting(); Layer* root_scroll_layer = CreateScrollLayer(outer_scroll_layer, &root_scroll_layer_client_); @@ -1381,8 +1380,10 @@ class LayerTreeHostScrollTestLayerStructureChange virtual void DidScroll(Layer* layer) { if (scroll_destroy_whole_tree_) { - layer_tree_host()->RegisterViewportLayers(ViewportLayers()); layer_tree_host()->SetRootLayer(nullptr); + layer_tree_host()->property_trees()->clear(); + layer_tree_host()->RegisterViewportPropertyIds( + LayerTreeHost::ViewportPropertyIds()); EndTest(); return; } @@ -1402,7 +1403,6 @@ class LayerTreeHostScrollTestLayerStructureChange Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) { scoped_refptr<PictureLayer> scroll_layer = PictureLayer::Create(&fake_content_layer_client_); - scroll_layer->SetPosition(gfx::PointF()); scroll_layer->SetIsDrawable(true); scroll_layer->SetScrollable(parent->bounds()); scroll_layer->SetHitTestable(true); @@ -1414,7 +1414,12 @@ class LayerTreeHostScrollTestLayerStructureChange &FakeLayerScrollClient::DidScroll, base::Unretained(client))); client->owner_ = this; client->layer_ = scroll_layer.get(); - parent->AddChild(scroll_layer); + + CopyProperties(parent, scroll_layer.get()); + CreateTransformNode(scroll_layer.get()); + CreateScrollNode(scroll_layer.get()); + layer_tree_host()->root_layer()->AddChild(scroll_layer); + return scroll_layer.get(); } @@ -1456,22 +1461,16 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { second_scroll_(40, 5), third_scroll_(20, 10), scroll_amount_(2, -1), - num_commits_(0), - num_scrolls_(0) {} + num_commits_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { + LayerTreeHostScrollTest::InitializeSettings(settings); settings->main_frame_before_activation_enabled = true; } void BeginTest() override { - outer_viewport_container_layer_id_ = - layer_tree_host()->outer_viewport_container_layer()->id(); - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestScrollMFBA::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } @@ -1492,7 +1491,8 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { } void UpdateLayerTreeHost() override { - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); switch (layer_tree_host()->SourceFrameNumber()) { case 0: EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset()); @@ -1502,20 +1502,21 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_), scroll_layer->CurrentScrollOffset()); // Pretend like Javascript updated the scroll position itself. - scroll_layer->SetScrollOffset(second_scroll_); + SetScrollOffset(scroll_layer, second_scroll_); break; case 2: // Third frame does not see a scroll delta because we only did one // scroll for the second and third frames. EXPECT_VECTOR_EQ(second_scroll_, scroll_layer->CurrentScrollOffset()); // Pretend like Javascript updated the scroll position itself. - scroll_layer->SetScrollOffset(third_scroll_); + SetScrollOffset(scroll_layer, third_scroll_); break; } } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); switch (impl->active_tree()->source_frame_number()) { case 0: EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); @@ -1546,19 +1547,16 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - void AfterTest() override { EXPECT_EQ(3, num_commits_); - EXPECT_EQ(1, num_scrolls_); + EXPECT_EQ(1, num_outer_viewport_scrolls_); } private: void Scroll(LayerTreeHostImpl* impl) { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root = impl->active_tree()->root_layer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); @@ -1570,8 +1568,6 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { gfx::ScrollOffset third_scroll_; gfx::Vector2dF scroll_amount_; int num_commits_; - int num_scrolls_; - int outer_viewport_container_layer_id_; }; MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMFBA); @@ -1589,20 +1585,16 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA num_did_commits_(0), num_impl_commits_(0), num_aborted_commits_(0), - num_impl_scrolls_(0), num_draws_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { + LayerTreeHostScrollTest::InitializeSettings(settings); settings->main_frame_before_activation_enabled = true; } void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating(&LayerTreeHostScrollTestScrollAbortedCommitMFBA:: - DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } @@ -1610,35 +1602,38 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA LayerTreeHostScrollTest::SetupTree(); gfx::Size scroll_layer_bounds(200, 200); - layer_tree_host()->outer_viewport_scroll_layer()->SetBounds( + layer_tree_host()->OuterViewportScrollLayerForTesting()->SetBounds( scroll_layer_bounds); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); } void WillBeginMainFrame() override { num_will_begin_main_frames_++; - Layer* root_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* root_scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); switch (num_will_begin_main_frames_) { case 1: // This will not be aborted because of the initial prop changes. - EXPECT_EQ(0, num_impl_scrolls_); + EXPECT_EQ(0, num_outer_viewport_scrolls_); EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ(initial_scroll_, root_scroll_layer->CurrentScrollOffset()); break; case 2: // This commit will not be aborted because of the scroll change. - EXPECT_EQ(1, num_impl_scrolls_); + EXPECT_EQ(1, num_outer_viewport_scrolls_); EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_), root_scroll_layer->CurrentScrollOffset()); - root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta( - root_scroll_layer->CurrentScrollOffset(), second_main_scroll_)); + SetScrollOffset( + root_scroll_layer, + gfx::ScrollOffsetWithDelta(root_scroll_layer->CurrentScrollOffset(), + second_main_scroll_)); break; case 3: { // This commit will be aborted. - EXPECT_EQ(2, num_impl_scrolls_); + EXPECT_EQ(2, num_outer_viewport_scrolls_); // The source frame number still increases even with the abort. EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber()); gfx::Vector2dF delta = @@ -1649,7 +1644,7 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA } case 4: { // This commit will also be aborted. - EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, num_outer_viewport_scrolls_); EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber()); gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; @@ -1696,7 +1691,8 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root_scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root_scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); switch (impl->active_tree()->source_frame_number()) { case 0: { switch (num_impl_commits_) { @@ -1768,12 +1764,8 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA num_draws_++; } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_impl_scrolls_++; - } - void AfterTest() override { - EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, num_outer_viewport_scrolls_); // Verify that the embedder sees aborted commits as real commits. EXPECT_EQ(4, num_will_begin_main_frames_); EXPECT_EQ(4, num_did_begin_main_frames_); @@ -1797,7 +1789,6 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA int num_did_commits_; int num_impl_commits_; int num_aborted_commits_; - int num_impl_scrolls_; int num_draws_; }; @@ -1832,6 +1823,7 @@ class LayerTreeHostScrollTestElasticOverscroll num_begin_main_frames_main_thread_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { + LayerTreeHostScrollTest::InitializeSettings(settings); settings->enable_elastic_overscroll = true; } @@ -1985,52 +1977,44 @@ class LayerTreeHostScrollTestPropertyTreeUpdate : initial_scroll_(10, 20), second_scroll_(0, 0) {} void BeginTest() override { - layer_tree_host()->inner_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->inner_viewport_scroll_layer()->SetBounds( - gfx::Size(100, 100)); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } void UpdateLayerTreeHost() override { - Layer* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); if (layer_tree_host()->SourceFrameNumber() == 0) { EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset()); } else { EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_), scroll_layer->CurrentScrollOffset()); - scroll_layer->SetScrollOffset(second_scroll_); - scroll_layer->SetOpacity(0.5f); + SetScrollOffset(scroll_layer, second_scroll_); + SetOpacity(scroll_layer, 0.5f); } } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); switch (impl->active_tree()->source_frame_number()) { case 0: EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( scroll_layer->element_id())); - EXPECT_VECTOR_EQ( - initial_scroll_, - scroll_layer->layer_tree_impl() - ->property_trees() - ->transform_tree.Node(scroll_layer->transform_tree_index()) - ->scroll_offset); + EXPECT_VECTOR_EQ(initial_scroll_, + GetTransformNode(scroll_layer)->scroll_offset); PostSetNeedsCommitToMainThread(); break; case 1: EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( scroll_layer->element_id())); - EXPECT_VECTOR_EQ( - second_scroll_, - scroll_layer->layer_tree_impl() - ->property_trees() - ->transform_tree.Node(scroll_layer->transform_tree_index()) - ->scroll_offset); + EXPECT_VECTOR_EQ(second_scroll_, + GetTransformNode(scroll_layer)->scroll_offset); EndTest(); break; } @@ -2047,14 +2031,13 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestPropertyTreeUpdate); class LayerTreeHostScrollTestImplSideInvalidation : public LayerTreeHostScrollTest { void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating(&LayerTreeHostScrollTestImplSideInvalidation:: - DidScrollOuterViewport, - base::Unretained(this))); PostSetNeedsCommitToMainThread(); } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { + void DidScrollOuterViewport(const gfx::ScrollOffset& offset, + const ElementId& element_id) override { + LayerTreeHostScrollTest::DidScrollOuterViewport(offset, element_id); + // Defer responding to the main frame until an impl-side pending tree is // created for the invalidation request. { @@ -2073,10 +2056,11 @@ class LayerTreeHostScrollTestImplSideInvalidation // second case on activation, so add a delta from the main thread that // takes us to the final value. Layer* outer_viewport_layer = - layer_tree_host()->outer_viewport_scroll_layer(); + layer_tree_host()->OuterViewportScrollLayerForTesting(); gfx::ScrollOffset delta_to_send = outer_viewport_offsets_[2] - outer_viewport_offsets_[1]; - outer_viewport_layer->SetScrollOffset( + SetScrollOffset( + outer_viewport_layer, outer_viewport_layer->CurrentScrollOffset() + delta_to_send); } break; case 2: @@ -2105,7 +2089,7 @@ class LayerTreeHostScrollTestImplSideInvalidation return; LayerImpl* scroll_layer = - host_impl->pending_tree()->OuterViewportScrollLayer(); + host_impl->pending_tree()->OuterViewportScrollLayerForTesting(); gfx::ScrollOffset scroll_offset = scroll_layer->CurrentScrollOffset(); int transform_index = scroll_layer->transform_tree_index(); gfx::ScrollOffset transform_tree_scroll_offset = @@ -2134,7 +2118,7 @@ class LayerTreeHostScrollTestImplSideInvalidation // Add some more delta to the active tree state of the scroll offset and // a commit to send this additional delta to the main thread. host_impl->active_tree() - ->OuterViewportScrollLayer() + ->OuterViewportScrollLayerForTesting() ->SetCurrentScrollOffset(outer_viewport_offsets_[1]); host_impl->SetNeedsCommit(); @@ -2156,9 +2140,10 @@ class LayerTreeHostScrollTestImplSideInvalidation CommitEarlyOutReason reason) override { EXPECT_EQ(CommitEarlyOutReason::FINISHED_NO_UPDATES, reason); EXPECT_EQ(3, num_of_main_frames_); - EXPECT_EQ(outer_viewport_offsets_[2], host_impl->active_tree() - ->OuterViewportScrollLayer() - ->CurrentScrollOffset()); + EXPECT_EQ(outer_viewport_offsets_[2], + host_impl->active_tree() + ->OuterViewportScrollLayerForTesting() + ->CurrentScrollOffset()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { @@ -2167,7 +2152,7 @@ class LayerTreeHostScrollTestImplSideInvalidation // Now that we have the active tree, scroll a layer and ask for a commit // to send a BeginMainFrame with the scroll delta to the main thread. host_impl->active_tree() - ->OuterViewportScrollLayer() + ->OuterViewportScrollLayerForTesting() ->SetCurrentScrollOffset(outer_viewport_offsets_[0]); host_impl->SetNeedsCommit(); break; @@ -2176,16 +2161,17 @@ class LayerTreeHostScrollTestImplSideInvalidation // frame number on the active tree remains unchanged, and the scroll // offset on the active tree should also remain unchanged. EXPECT_EQ(0, host_impl->active_tree()->source_frame_number()); - EXPECT_EQ(outer_viewport_offsets_[1], host_impl->active_tree() - ->OuterViewportScrollLayer() - ->CurrentScrollOffset()); + EXPECT_EQ(outer_viewport_offsets_[1], + host_impl->active_tree() + ->OuterViewportScrollLayerForTesting() + ->CurrentScrollOffset()); break; case 3: // The third activation is from a commit. The scroll offset on the // active tree should include deltas sent from the main thread. EXPECT_EQ(host_impl->active_tree()->source_frame_number(), 1); EXPECT_EQ(host_impl->active_tree() - ->OuterViewportScrollLayer() + ->OuterViewportScrollLayerForTesting() ->CurrentScrollOffset(), outer_viewport_offsets_[2]); break; @@ -2193,9 +2179,10 @@ class LayerTreeHostScrollTestImplSideInvalidation // The fourth activation is from an impl-side pending tree, which should // leave the scroll offset unchanged. EXPECT_EQ(1, host_impl->active_tree()->source_frame_number()); - EXPECT_EQ(outer_viewport_offsets_[2], host_impl->active_tree() - ->OuterViewportScrollLayer() - ->CurrentScrollOffset()); + EXPECT_EQ(outer_viewport_offsets_[2], + host_impl->active_tree() + ->OuterViewportScrollLayerForTesting() + ->CurrentScrollOffset()); EndTest(); break; default: diff --git a/chromium/cc/trees/layer_tree_host_unittest_video.cc b/chromium/cc/trees/layer_tree_host_unittest_video.cc index c379af6ddce..f69dc76d788 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_video.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_video.cc @@ -48,7 +48,7 @@ class LayerTreeHostVideoTestSetNeedsDisplay DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame, DrawResult draw_result) override { - LayerImpl* root_layer = host_impl->active_tree()->root_layer_for_testing(); + LayerImpl* root_layer = host_impl->active_tree()->root_layer(); RenderSurfaceImpl* root_surface = GetRenderSurface(root_layer); gfx::Rect damage_rect; EXPECT_TRUE( diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index 1bb42de1429..27812c1d31e 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -31,7 +31,6 @@ #include "cc/layers/effect_tree_layer_list_iterator.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer.h" -#include "cc/layers/layer_list_iterator.h" #include "cc/layers/render_surface_impl.h" #include "cc/layers/scrollbar_layer_impl_base.h" #include "cc/resources/ui_resource_request.h" @@ -39,12 +38,10 @@ #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_frame_sink.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/occlusion_tracker.h" #include "cc/trees/property_tree.h" -#include "cc/trees/property_tree_builder.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" #include "components/viz/common/traced_value.h" @@ -61,31 +58,33 @@ namespace { class ViewportAnchor { public: ViewportAnchor(ScrollNode* inner_scroll, - LayerImpl* outer_scroll, + ScrollNode* outer_scroll, LayerTreeImpl* tree_impl) : inner_(inner_scroll), outer_(outer_scroll), tree_impl_(tree_impl) { viewport_in_content_coordinates_ = scroll_tree().current_scroll_offset(inner_->element_id); - if (outer_) - viewport_in_content_coordinates_ += outer_->CurrentScrollOffset(); + if (outer_) { + viewport_in_content_coordinates_ += + scroll_tree().current_scroll_offset(outer_->element_id); + } } void ResetViewportToAnchoredPosition() { DCHECK(outer_); scroll_tree().ClampScrollToMaxScrollOffset(inner_, tree_impl_); - outer_->ClampScrollToMaxScrollOffset(); + scroll_tree().ClampScrollToMaxScrollOffset(outer_, tree_impl_); gfx::ScrollOffset viewport_location = scroll_tree().current_scroll_offset(inner_->element_id) + - outer_->CurrentScrollOffset(); + scroll_tree().current_scroll_offset(outer_->element_id); gfx::Vector2dF delta = viewport_in_content_coordinates_.DeltaFrom(viewport_location); delta = scroll_tree().ScrollBy(inner_, delta, tree_impl_); - outer_->ScrollBy(delta); + scroll_tree().ScrollBy(outer_, delta, tree_impl_); } private: @@ -94,7 +93,7 @@ class ViewportAnchor { } ScrollNode* inner_; - LayerImpl* outer_; + ScrollNode* outer_; LayerTreeImpl* tree_impl_; gfx::ScrollOffset viewport_in_content_coordinates_; }; @@ -123,7 +122,6 @@ LayerTreeImpl::LayerTreeImpl( : host_impl_(host_impl), source_frame_number_(-1), is_first_frame_after_commit_tracker_(-1), - root_layer_for_testing_(nullptr), hud_layer_(nullptr), background_color_(0), last_scrolled_scroll_node_index_(ScrollTree::kInvalidNodeId), @@ -134,7 +132,6 @@ LayerTreeImpl::LayerTreeImpl( device_scale_factor_(1.f), painted_device_scale_factor_(1.f), elastic_overscroll_(elastic_overscroll), - layers_(new OwnedLayerImplList), needs_update_draw_properties_(true), scrollbar_geometries_need_update_(false), needs_full_tree_sync_(true), @@ -155,7 +152,6 @@ LayerTreeImpl::~LayerTreeImpl() { // Need to explicitly clear the tree prior to destroying this so that // the LayerTreeImpl pointer is still valid in the LayerImpl dtor. DCHECK(LayerListIsEmpty()); - DCHECK(layers_->empty()); } void LayerTreeImpl::Shutdown() { @@ -166,42 +162,23 @@ void LayerTreeImpl::Shutdown() { } void LayerTreeImpl::ReleaseResources() { -#if DCHECK_IS_ON() - // These DCHECKs catch tests that add layers to the tree but fail to build the - // layer list afterward. - LayerListIterator<LayerImpl> it(root_layer_for_testing_); - size_t i = 0; - for (; it != LayerListIterator<LayerImpl>(nullptr); ++it, ++i) { - DCHECK_LT(i, layer_list_.size()); - DCHECK_EQ(layer_list_[i], *it); - } -#endif - - if (!LayerListIsEmpty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->ReleaseResources(); }); - } + for (auto* layer : *this) + layer->ReleaseResources(); } void LayerTreeImpl::OnPurgeMemory() { - if (!LayerListIsEmpty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->OnPurgeMemory(); }); - } + for (auto* layer : *this) + layer->OnPurgeMemory(); } void LayerTreeImpl::ReleaseTileResources() { - if (!LayerListIsEmpty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->ReleaseTileResources(); }); - } + for (auto* layer : *this) + layer->ReleaseTileResources(); } void LayerTreeImpl::RecreateTileResources() { - if (!LayerListIsEmpty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->RecreateTileResources(); }); - } + for (auto* layer : *this) + layer->RecreateTileResources(); } void LayerTreeImpl::DidUpdateScrollOffset(ElementId id) { @@ -269,23 +246,27 @@ void LayerTreeImpl::UpdateScrollbarGeometries() { scroll_node->scrolls_outer_viewport; if (is_viewport_scrollbar) { gfx::SizeF viewport_bounds(bounds_size); - if (scroll_node->scrolls_inner_viewport && OuterViewportScrollLayer()) { - // Add offset and bounds contribution of outer viewport. - current_offset += OuterViewportScrollLayer()->CurrentScrollOffset(); - gfx::SizeF outer_viewport_bounds(scroll_tree.container_bounds( - OuterViewportScrollLayer()->scroll_tree_index())); - viewport_bounds.SetToMin(outer_viewport_bounds); - - // The scrolling size is only determined by the outer viewport. - scroll_node = scroll_tree.FindNodeFromElementId( - OuterViewportScrollLayer()->element_id()); - scrolling_size = gfx::SizeF(scroll_node->bounds); + if (scroll_node->scrolls_inner_viewport) { + DCHECK_EQ(scroll_node, InnerViewportScrollNode()); + if (auto* outer_scroll_node = OuterViewportScrollNode()) { + // Add offset and bounds contribution of outer viewport. + current_offset += + scroll_tree.current_scroll_offset(outer_scroll_node->element_id); + gfx::SizeF outer_viewport_bounds( + scroll_tree.container_bounds(outer_scroll_node->id)); + viewport_bounds.SetToMin(outer_viewport_bounds); + // The scrolling size is only determined by the outer viewport. + scrolling_size = gfx::SizeF(outer_scroll_node->bounds); + } } else { + DCHECK_EQ(scroll_node, OuterViewportScrollNode()); + auto* inner_scroll_node = InnerViewportScrollNode(); + DCHECK(inner_scroll_node); // Add offset and bounds contribution of inner viewport. - current_offset += scroll_tree.current_scroll_offset( - InnerViewportScrollNode()->element_id); + current_offset += + scroll_tree.current_scroll_offset(inner_scroll_node->element_id); gfx::SizeF inner_viewport_bounds( - scroll_tree.container_bounds(InnerViewportScrollNode()->id)); + scroll_tree.container_bounds(inner_scroll_node->id)); viewport_bounds.SetToMin(inner_viewport_bounds); } viewport_bounds.Scale(1 / current_page_scale_factor()); @@ -322,14 +303,9 @@ bool LayerTreeImpl::LayerListIsEmpty() const { } void LayerTreeImpl::SetRootLayerForTesting(std::unique_ptr<LayerImpl> layer) { - if (root_layer_for_testing_ && layer.get() != root_layer_for_testing_) - RemoveLayer(root_layer_for_testing_->id()); - root_layer_for_testing_ = layer.get(); - ClearLayerList(); - if (layer) { + DetachLayers(); + if (layer) AddLayer(std::move(layer)); - BuildLayerListForTesting(); - } host_impl_->OnCanDrawStateChangedForTree(); } @@ -337,22 +313,6 @@ void LayerTreeImpl::OnCanDrawStateChangedForTree() { host_impl_->OnCanDrawStateChangedForTree(); } -void LayerTreeImpl::AddToLayerList(LayerImpl* layer) { - layer_list_.push_back(layer); -} - -void LayerTreeImpl::ClearLayerList() { - layer_list_.clear(); -} - -void LayerTreeImpl::BuildLayerListForTesting() { - ClearLayerList(); - LayerListIterator<LayerImpl> it(root_layer_for_testing_); - for (; it != LayerListIterator<LayerImpl>(nullptr); ++it) { - AddToLayerList(*it); - } -} - void LayerTreeImpl::InvalidateRegionForImages( const PaintImageIdFlatSet& images_to_invalidate) { TRACE_EVENT_BEGIN1("cc", "LayerTreeImpl::InvalidateRegionForImages", @@ -392,7 +352,7 @@ void LayerTreeImpl::UpdateViewportContainerSizes() { if (!InnerViewportScrollNode()) return; - ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollLayer(), + ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollNode(), this); // Top/bottom controls always share the same shown ratio. @@ -424,34 +384,23 @@ void LayerTreeImpl::UpdateViewportContainerSizes() { property_trees->SetInnerViewportContainerBoundsDelta(bounds_delta); - ClipNode* inner_clip_node = property_trees->clip_tree.Node( - InnerViewportScrollLayer()->clip_tree_index()); - inner_clip_node->clip.set_height( - InnerViewportScrollNode()->container_bounds.height() + bounds_delta.y()); - // Adjust the outer viewport container as well, since adjusting only the // inner may cause its bounds to exceed those of the outer, causing scroll // clamping. - if (OuterViewportScrollNode()) { + if (auto* outer_scroll = OuterViewportScrollNode()) { gfx::Vector2dF scaled_bounds_delta = gfx::ScaleVector2d(bounds_delta, 1.f / min_page_scale_factor()); property_trees->SetOuterViewportContainerBoundsDelta(scaled_bounds_delta); - property_trees->SetInnerViewportScrollBoundsDelta(scaled_bounds_delta); - - ClipNode* outer_clip_node = property_trees->clip_tree.Node( - OuterViewportScrollLayer()->clip_tree_index()); - - float adjusted_container_height = - OuterViewportScrollNode()->container_bounds.height() + - scaled_bounds_delta.y(); - outer_clip_node->clip.set_height(adjusted_container_height); - - // Expand all clips between the outer viewport and the inner viewport. - auto* outer_ancestor = property_trees->clip_tree.parent(outer_clip_node); - while (outer_ancestor && outer_ancestor != inner_clip_node) { - outer_ancestor->clip.Union(outer_clip_node->clip); - outer_ancestor = property_trees->clip_tree.parent(outer_ancestor); + // outer_viewport_container_bounds_delta and + // inner_viewport_scroll_bounds_delta are the same thing. + DCHECK_EQ(scaled_bounds_delta, + property_trees->inner_viewport_scroll_bounds_delta()); + + if (auto* outer_clip_node = OuterViewportClipNode()) { + float adjusted_container_height = + outer_scroll->container_bounds.height() + scaled_bounds_delta.y(); + outer_clip_node->clip.set_height(adjusted_container_height); } anchor.ResetViewportToAnchoredPosition(); @@ -465,59 +414,48 @@ void LayerTreeImpl::UpdateViewportContainerSizes() { // delta. SetScrollbarGeometriesNeedUpdate(); set_needs_update_draw_properties(); - - // For pre-BlinkGenPropertyTrees mode, we need to ensure the layers are - // appropriately updated. - if (!settings().use_layer_lists) { - if (OuterViewportContainerLayer()) - OuterViewportContainerLayer()->NoteLayerPropertyChanged(); - if (InnerViewportScrollLayer()) - InnerViewportScrollLayer()->NoteLayerPropertyChanged(); - if (OuterViewportScrollLayer()) - OuterViewportScrollLayer()->NoteLayerPropertyChanged(); - } } bool LayerTreeImpl::IsRootLayer(const LayerImpl* layer) const { - return layer_list_.empty() ? false : layer_list_[0] == layer; + return !layer_list_.empty() && layer_list_[0].get() == layer; } gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const { gfx::ScrollOffset offset; - auto& scroll_tree = property_trees()->scroll_tree; + const auto& scroll_tree = property_trees()->scroll_tree; - if (InnerViewportScrollNode()) { - offset += scroll_tree.current_scroll_offset( - InnerViewportScrollNode()->element_id); - } + if (auto* inner_scroll = InnerViewportScrollNode()) + offset += scroll_tree.current_scroll_offset(inner_scroll->element_id); - if (OuterViewportScrollLayer()) - offset += OuterViewportScrollLayer()->CurrentScrollOffset(); + if (auto* outer_scroll = OuterViewportScrollNode()) + offset += scroll_tree.current_scroll_offset(outer_scroll->element_id); return offset; } gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const { gfx::ScrollOffset offset; - const ScrollTree& scroll_tree = property_trees()->scroll_tree; + const auto& scroll_tree = property_trees()->scroll_tree; - if (auto* inner_node = InnerViewportScrollNode()) - offset += scroll_tree.MaxScrollOffset(inner_node->id); + if (viewport_property_ids_.inner_scroll != ScrollTree::kInvalidNodeId) + offset += scroll_tree.MaxScrollOffset(viewport_property_ids_.inner_scroll); - if (auto* outer_node = OuterViewportScrollNode()) - offset += scroll_tree.MaxScrollOffset(outer_node->id); + if (viewport_property_ids_.outer_scroll != ScrollTree::kInvalidNodeId) + offset += scroll_tree.MaxScrollOffset(viewport_property_ids_.outer_scroll); return offset; } -std::unique_ptr<OwnedLayerImplList> LayerTreeImpl::DetachLayers() { - root_layer_for_testing_ = nullptr; - layer_list_.clear(); +OwnedLayerImplList LayerTreeImpl::DetachLayers() { render_surface_list_.clear(); set_needs_update_draw_properties(); - std::unique_ptr<OwnedLayerImplList> ret = std::move(layers_); - layers_.reset(new OwnedLayerImplList); - return ret; + return std::move(layer_list_); +} + +OwnedLayerImplList LayerTreeImpl::DetachLayersKeepingRootLayerForTesting() { + auto layers = DetachLayers(); + SetRootLayerForTesting(std::move(layers[0])); + return layers; } void LayerTreeImpl::SetPropertyTrees(PropertyTrees* property_trees) { @@ -594,18 +532,10 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->PassSwapPromises(std::move(swap_promise_list_)); swap_promise_list_.clear(); - target_tree->set_browser_controls_shrink_blink_size( - browser_controls_shrink_blink_size_); - target_tree->SetTopControlsHeight(top_controls_height_); - target_tree->SetBottomControlsHeight(bottom_controls_height_); - target_tree->PushBrowserControls(nullptr); - - target_tree->set_overscroll_behavior(overscroll_behavior_); - // The page scale factor update can affect scrolling which requires that // these ids are set, so this must be before PushPageScaleFactorAndLimits. - target_tree->SetViewportLayersFromIds(viewport_layer_ids_); - target_tree->set_viewport_property_ids(viewport_property_ids_); + // Setting browser controls below also needs viewport scroll properties. + target_tree->SetViewportPropertyIds(viewport_property_ids_); // Active tree already shares the page_scale_factor object with pending // tree so only the limits need to be provided. @@ -613,6 +543,14 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { max_page_scale_factor()); target_tree->SetExternalPageScaleFactor(external_page_scale_factor_); + target_tree->set_browser_controls_shrink_blink_size( + browser_controls_shrink_blink_size_); + target_tree->SetTopControlsHeight(top_controls_height_); + target_tree->SetBottomControlsHeight(bottom_controls_height_); + target_tree->PushBrowserControls(nullptr); + + target_tree->set_overscroll_behavior(overscroll_behavior_); + target_tree->SetRasterColorSpace(raster_color_space_id_, raster_color_space_); target_tree->elastic_overscroll()->PushPendingToActive(); @@ -664,12 +602,12 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { } void LayerTreeImpl::HandleTickmarksVisibilityChange() { - if (!host_impl_->ViewportMainScrollLayer()) + if (!host_impl_->ViewportMainScrollNode()) return; ScrollbarAnimationController* controller = host_impl_->ScrollbarAnimationControllerForElementId( - OuterViewportScrollLayer()->element_id()); + host_impl_->ViewportMainScrollNode()->element_id); if (!controller) return; @@ -687,10 +625,9 @@ void LayerTreeImpl::HandleTickmarksVisibilityChange() { } void LayerTreeImpl::HandleScrollbarShowRequestsFromMain() { - LayerTreeHostCommon::CallFunctionForEveryLayer(this, [this]( - LayerImpl* layer) { + for (auto* layer : *this) { if (!layer->needs_show_scrollbars()) - return; + continue; ScrollbarAnimationController* controller = host_impl_->ScrollbarAnimationControllerForElementId( layer->element_id()); @@ -698,7 +635,7 @@ void LayerTreeImpl::HandleScrollbarShowRequestsFromMain() { controller->DidRequestShowFromMainThread(); layer->set_needs_show_scrollbars(false); } - }); + } } void LayerTreeImpl::MoveChangeTrackingToLayers() { @@ -723,30 +660,6 @@ void LayerTreeImpl::ForceRecalculateRasterScales() { layer->ResetRasterScale(); } -LayerImplList::const_iterator LayerTreeImpl::begin() const { - return layer_list_.cbegin(); -} - -LayerImplList::const_iterator LayerTreeImpl::end() const { - return layer_list_.cend(); -} - -LayerImplList::const_reverse_iterator LayerTreeImpl::rbegin() const { - return layer_list_.crbegin(); -} - -LayerImplList::const_reverse_iterator LayerTreeImpl::rend() const { - return layer_list_.crend(); -} - -LayerImplList::reverse_iterator LayerTreeImpl::rbegin() { - return layer_list_.rbegin(); -} - -LayerImplList::reverse_iterator LayerTreeImpl::rend() { - return layer_list_.rend(); -} - bool LayerTreeImpl::IsElementInPropertyTree(ElementId element_id) const { return property_trees()->HasElement(element_id); } @@ -857,6 +770,18 @@ LayerTreeImpl::TakePresentationCallbacks() { return callbacks; } +LayerImpl* LayerTreeImpl::InnerViewportScrollLayerForTesting() const { + if (auto* scroll_node = InnerViewportScrollNode()) + return LayerByElementId(scroll_node->element_id); + return nullptr; +} + +LayerImpl* LayerTreeImpl::OuterViewportScrollLayerForTesting() const { + if (auto* scroll_node = OuterViewportScrollNode()) + return LayerByElementId(scroll_node->element_id); + return nullptr; +} + ScrollNode* LayerTreeImpl::CurrentlyScrollingNode() { DCHECK(IsActiveTree()); return property_trees_.scroll_tree.CurrentlyScrollingNode(); @@ -1005,26 +930,11 @@ void LayerTreeImpl::UpdateTransformAnimation(ElementId element_id, } } -TransformNode* LayerTreeImpl::PageScaleTransformNode() { - auto* page_scale = PageScaleLayer(); - if (!page_scale) { - // TODO(crbug.com/909750): Check all other callers of PageScaleLayer() and - // switch to viewport_property_ids_.page_scale_transform if needed. - return property_trees()->transform_tree.Node( - viewport_property_ids_.page_scale_transform); - } - - return property_trees()->transform_tree.Node( - page_scale->transform_tree_index()); -} - void LayerTreeImpl::UpdatePageScaleNode() { if (!PageScaleTransformNode()) { DCHECK(layer_list_.empty() || current_page_scale_factor() == 1); return; } - - DCHECK(!IsRootLayer(PageScaleLayer())); draw_property_utils::UpdatePageScaleFactor( property_trees(), PageScaleTransformNode(), current_page_scale_factor()); } @@ -1178,10 +1088,10 @@ void LayerTreeImpl::DidUpdatePageScale() { host_impl_->FlashAllScrollbars(true); return; } - if (host_impl_->ViewportMainScrollLayer()) { + if (auto* scroll_node = host_impl_->ViewportMainScrollNode()) { if (ScrollbarAnimationController* controller = host_impl_->ScrollbarAnimationControllerForElementId( - OuterViewportScrollLayer()->element_id())) + scroll_node->element_id)) controller->DidScrollUpdate(); } } @@ -1275,14 +1185,14 @@ gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const { } gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const { - LayerImpl* root_scroll_layer = OuterViewportScrollLayer() - ? OuterViewportScrollLayer() - : InnerViewportScrollLayer(); - if (!root_scroll_layer) + const ScrollNode* root_scroll_node = OuterViewportScrollNode(); + if (!root_scroll_node) + root_scroll_node = InnerViewportScrollNode(); + if (!root_scroll_node) return gfx::Rect(); return MathUtil::MapEnclosingClippedRect( - root_scroll_layer->ScreenSpaceTransform(), - gfx::Rect(root_scroll_layer->bounds())); + property_trees()->transform_tree.ToScreen(root_scroll_node->transform_id), + gfx::Rect(root_scroll_node->bounds)); } void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { @@ -1298,61 +1208,54 @@ void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { property_trees()->scroll_tree.ApplySentScrollDeltasFromAbortedCommit(); } -void LayerTreeImpl::SetViewportLayersFromIds(const ViewportLayerIds& ids) { - if (viewport_layer_ids_ == ids) - return; +void LayerTreeImpl::SetViewportPropertyIds(const ViewportPropertyIds& ids) { + viewport_property_ids_ = ids; + // Outer viewport properties exist only if inner viewport property exists. + DCHECK(ids.inner_scroll != ScrollTree::kInvalidNodeId || + (ids.outer_scroll == ScrollTree::kInvalidNodeId && + ids.outer_clip == ClipTree::kInvalidNodeId)); - viewport_layer_ids_ = ids; + if (auto* inner_scroll = InnerViewportScrollNode()) { + if (auto* inner_scroll_layer = LayerByElementId(inner_scroll->element_id)) + inner_scroll_layer->set_is_inner_viewport_scroll_layer(); + } +} - // Set the viewport layer types. - if (auto* inner_container = InnerViewportContainerLayer()) - inner_container->SetViewportLayerType(INNER_VIEWPORT_CONTAINER); - if (auto* inner_scroll = InnerViewportScrollLayer()) - inner_scroll->SetViewportLayerType(INNER_VIEWPORT_SCROLL); - if (auto* outer_container = OuterViewportContainerLayer()) - outer_container->SetViewportLayerType(OUTER_VIEWPORT_CONTAINER); - if (auto* outer_scroll = OuterViewportScrollLayer()) - outer_scroll->SetViewportLayerType(OUTER_VIEWPORT_SCROLL); +const TransformNode* LayerTreeImpl::OverscrollElasticityTransformNode() const { + return property_trees()->transform_tree.Node( + viewport_property_ids_.overscroll_elasticity_transform); } -void LayerTreeImpl::ClearViewportLayers() { - SetViewportLayersFromIds(ViewportLayerIds()); +const TransformNode* LayerTreeImpl::PageScaleTransformNode() const { + return property_trees()->transform_tree.Node( + viewport_property_ids_.page_scale_transform); } const ScrollNode* LayerTreeImpl::InnerViewportScrollNode() const { - auto* inner_scroll = InnerViewportScrollLayer(); - if (!inner_scroll) { - // TODO(crbug.com/909750): Check all other callers of - // InnerViewportScrollLayer() and switch to - // viewport_property_ids_.inner_scroll if needed. - return property_trees()->scroll_tree.Node( - viewport_property_ids_.inner_scroll); - } - return property_trees()->scroll_tree.Node(inner_scroll->scroll_tree_index()); + return property_trees()->scroll_tree.Node( + viewport_property_ids_.inner_scroll); +} + +const ClipNode* LayerTreeImpl::OuterViewportClipNode() const { + return property_trees()->clip_tree.Node(viewport_property_ids_.outer_clip); } const ScrollNode* LayerTreeImpl::OuterViewportScrollNode() const { - if (!OuterViewportScrollLayer()) - return nullptr; return property_trees()->scroll_tree.Node( - OuterViewportScrollLayer()->scroll_tree_index()); + viewport_property_ids_.outer_scroll); } // For unit tests, we use the layer's id as its element id. -static void SetElementIdForTesting(LayerImpl* layer) { - layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); -} - void LayerTreeImpl::SetElementIdsForTesting() { - LayerListIterator<LayerImpl> it(root_layer_for_testing_); - for (; it != LayerListIterator<LayerImpl>(nullptr); ++it) { - if (!it->element_id()) - SetElementIdForTesting(*it); + for (auto* layer : *this) { + if (!layer->element_id()) + layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); } } bool LayerTreeImpl::UpdateDrawProperties( - bool update_image_animation_controller) { + bool update_image_animation_controller, + LayerImplList* output_update_layer_list_for_testing) { if (!needs_update_draw_properties_) return true; @@ -1388,14 +1291,9 @@ bool LayerTreeImpl::UpdateDrawProperties( // We verify visible rect calculations whenever we verify clip tree // calculations except when this function is explicitly passed a flag asking // us to skip it. - LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - layer_list_[0], GetDeviceViewport(), host_impl_->DrawTransform(), - device_scale_factor(), current_page_scale_factor(), PageScaleLayer(), - InnerViewportScrollLayer(), OuterViewportScrollLayer(), - elastic_overscroll()->Current(IsActiveTree()), - OverscrollElasticityElementId(), max_texture_size(), - &render_surface_list_, &property_trees_, PageScaleTransformNode()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + draw_property_utils::CalculateDrawProperties( + this, &render_surface_list_, output_update_layer_list_for_testing); + if (const char* client_name = GetClientNameForMetrics()) { UMA_HISTOGRAM_COUNTS_1M( base::StringPrintf( @@ -1450,14 +1348,6 @@ bool LayerTreeImpl::UpdateDrawProperties( occlusion_tracker.GetCurrentOcclusionForContributingSurface( draw_transform); render_surface->set_occlusion_in_content_space(occlusion); - // Masks are used to draw the contributing surface, so should have - // the same occlusion as the surface (nothing inside the surface - // occludes them). - if (LayerImpl* mask = render_surface->MaskLayer()) { - mask->draw_properties().occlusion_in_content_space = - occlusion_tracker.GetCurrentOcclusionForContributingSurface( - draw_transform * render_surface->SurfaceScale()); - } } occlusion_tracker.LeaveLayer(it); @@ -1514,24 +1404,6 @@ void LayerTreeImpl::UpdateCanUseLCDText() { DidModifyTilePriorities(); } -void LayerTreeImpl::BuildLayerListAndPropertyTreesForTesting() { - BuildLayerListForTesting(); - BuildPropertyTreesForTesting(); -} - -void LayerTreeImpl::BuildPropertyTreesForTesting() { - SetElementIdsForTesting(); - property_trees_.needs_rebuild = true; - PropertyTreeBuilder::BuildPropertyTrees( - layer_list_[0], PageScaleLayer(), InnerViewportScrollLayer(), - OuterViewportScrollLayer(), OverscrollElasticityElementId(), - elastic_overscroll()->Current(IsActiveTree()), - current_page_scale_factor(), device_scale_factor(), - gfx::Rect(GetDeviceViewport().size()), host_impl_->DrawTransform(), - &property_trees_); - host_impl_->UpdateElements(GetElementTypeForAnimation()); -} - const RenderSurfaceList& LayerTreeImpl::GetRenderSurfaceList() const { // If this assert triggers, then the list is dirty. DCHECK(!needs_update_draw_properties_); @@ -1546,8 +1418,9 @@ const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const { } gfx::SizeF LayerTreeImpl::ScrollableSize() const { - auto* scroll_node = OuterViewportScrollNode() ? OuterViewportScrollNode() - : InnerViewportScrollNode(); + auto* scroll_node = OuterViewportScrollNode(); + if (!scroll_node) + scroll_node = InnerViewportScrollNode(); if (!scroll_node) return gfx::SizeF(); const auto& scroll_tree = property_trees()->scroll_tree; @@ -1564,11 +1437,11 @@ LayerImpl* LayerTreeImpl::LayerById(int id) const { // TODO(masonfreed): If this shows up on profiles, this could use // a layer_element_map_ approach similar to LayerById(). LayerImpl* LayerTreeImpl::LayerByElementId(ElementId element_id) const { - auto it = std::find_if(layer_list_.rbegin(), layer_list_.rend(), - [&element_id](LayerImpl* layer_impl) { - return layer_impl->element_id() == element_id; - }); - if (it == layer_list_.rend()) + auto it = + std::find_if(rbegin(), rend(), [&element_id](LayerImpl* layer_impl) { + return layer_impl->element_id() == element_id; + }); + if (it == rend()) return nullptr; return *it; } @@ -1618,26 +1491,13 @@ void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) { layer_id_map_.erase(layer->id()); } -// These manage ownership of the LayerImpl. void LayerTreeImpl::AddLayer(std::unique_ptr<LayerImpl> layer) { - DCHECK(!base::Contains(*layers_, layer)); DCHECK(layer); - layers_->push_back(std::move(layer)); + DCHECK(!base::Contains(layer_list_, layer)); + layer_list_.push_back(std::move(layer)); set_needs_update_draw_properties(); } -std::unique_ptr<LayerImpl> LayerTreeImpl::RemoveLayer(int id) { - for (auto it = layers_->begin(); it != layers_->end(); ++it) { - if ((*it) && (*it)->id() != id) - continue; - std::unique_ptr<LayerImpl> ret = std::move(*it); - set_needs_update_draw_properties(); - layers_->erase(it); - return ret; - } - return nullptr; -} - size_t LayerTreeImpl::NumLayers() { return layer_id_map_.size(); } @@ -1652,10 +1512,8 @@ void LayerTreeImpl::DidBecomeActive() { // if we were in a good state. host_impl_->ResetRequiresHighResToDraw(); - if (!layer_list_.empty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->DidBecomeActive(); }); - } + for (auto* layer : *this) + layer->DidBecomeActive(); for (const auto& swap_promise : swap_promise_list_) swap_promise->DidActivate(); @@ -1820,11 +1678,10 @@ void LayerTreeImpl::SetNeedsRedraw() { void LayerTreeImpl::GetAllPrioritizedTilesForTracing( std::vector<PrioritizedTile>* prioritized_tiles) const { - for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) { - LayerImpl* layer_impl = *it; - if (!layer_impl->contributes_to_drawn_render_surface()) + for (auto* layer : base::Reversed(*this)) { + if (!layer->contributes_to_drawn_render_surface()) continue; - layer_impl->GetAllPrioritizedTilesForTracing(prioritized_tiles); + layer->GetAllPrioritizedTilesForTracing(prioritized_tiles); } } @@ -1834,10 +1691,10 @@ void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const { state->SetInteger("source_frame_number", source_frame_number_); state->BeginArray("render_surface_layer_list"); - for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) { - if (!(*it)->contributes_to_drawn_render_surface()) + for (auto* layer : base::Reversed(*this)) { + if (layer->contributes_to_drawn_render_surface()) continue; - viz::TracedValue::AppendIDRef(*it, state); + viz::TracedValue::AppendIDRef(layer, state); } state->EndArray(); @@ -2245,11 +2102,12 @@ static void FindClosestMatchingLayer(const gfx::PointF& screen_space_point, float distance_to_intersection = 0.f; bool hit = false; - if (layer->Is3dSorted()) + if (layer->Is3dSorted()) { hit = PointHitsLayer(layer, screen_space_point, &distance_to_intersection); - else + } else { hit = PointHitsLayer(layer, screen_space_point, nullptr); + } if (!hit) continue; @@ -2287,7 +2145,7 @@ LayerImpl* LayerTreeImpl::FindFirstScrollingLayerOrScrollbarThatIsHitByPoint( return nullptr; FindClosestMatchingLayerState state; - LayerImpl* root_layer = layer_list_[0]; + LayerImpl* root_layer = layer_list_[0].get(); FindClosestMatchingLayer(screen_space_point, root_layer, HitTestScrollingLayerOrScrollbarFunctor(), &state); return state.closest_match; @@ -2304,7 +2162,7 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint( if (!UpdateDrawProperties()) return nullptr; FindClosestMatchingLayerState state; - FindClosestMatchingLayer(screen_space_point, layer_list_[0], + FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(), HitTestVisibleScrollableOrTouchableFunctor(), &state); return state.closest_match; @@ -2337,7 +2195,8 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInEventHandlerRegion( if (!UpdateDrawProperties()) return nullptr; FindClosestMatchingLayerState state; - FindClosestMatchingLayer(screen_space_point, layer_list_[0], func, &state); + FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(), func, + &state); return state.closest_match; } @@ -2506,7 +2365,7 @@ bool LayerTreeImpl::TakeForceSendMetadataRequest() { void LayerTreeImpl::ResetAllChangeTracking() { layers_that_should_push_properties_.clear(); // Iterate over all layers, including masks. - for (auto& layer : *layers_) + for (auto* layer : *this) layer->ResetChangeTracking(); property_trees_.ResetAllChangeTracking(); } @@ -2524,18 +2383,4 @@ std::string LayerTreeImpl::LayerListAsJson() const { return str; } -std::string LayerTreeImpl::LayerTreeAsJson() const { - std::string str; - if (root_layer_for_testing_) { - std::unique_ptr<base::Value> json( - root_layer_for_testing_->LayerTreeAsJson()); - base::JSONWriter::WriteWithOptions( - *json, - base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION | - base::JSONWriter::OPTIONS_PRETTY_PRINT, - &str); - } - return str; -} - } // namespace cc diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index 666701c4360..7cb74373eba 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -162,15 +162,17 @@ class CC_EXPORT LayerTreeImpl { // Other public methods // --------------------------------------------------------------------------- - LayerImpl* root_layer_for_testing() { - return layer_list_.empty() ? nullptr : layer_list_[0]; + LayerImpl* root_layer() { + return layer_list_.empty() ? nullptr : layer_list_[0].get(); } const RenderSurfaceImpl* RootRenderSurface() const; bool LayerListIsEmpty() const; void SetRootLayerForTesting(std::unique_ptr<LayerImpl>); void OnCanDrawStateChangedForTree(); bool IsRootLayer(const LayerImpl* layer) const; - std::unique_ptr<OwnedLayerImplList> DetachLayers(); + + OwnedLayerImplList DetachLayers(); + OwnedLayerImplList DetachLayersKeepingRootLayerForTesting(); void SetPropertyTrees(PropertyTrees* property_trees); PropertyTrees* property_trees() { @@ -189,12 +191,36 @@ class CC_EXPORT LayerTreeImpl { void ForceRecalculateRasterScales(); - LayerImplList::const_iterator begin() const; - LayerImplList::const_iterator end() const; - LayerImplList::const_reverse_iterator rbegin() const; - LayerImplList::const_reverse_iterator rend() const; - LayerImplList::reverse_iterator rbegin(); - LayerImplList::reverse_iterator rend(); + // Adapts an iterator of std::unique_ptr<LayerImpl> to an iterator of + // LayerImpl*. + template <typename Iterator> + class IteratorAdapter + : public std::iterator<std::forward_iterator_tag, LayerImpl*> { + public: + explicit IteratorAdapter(Iterator it) : it_(it) {} + bool operator==(IteratorAdapter o) const { return it_ == o.it_; } + bool operator!=(IteratorAdapter o) const { return !(*this == o); } + LayerImpl* operator*() const { return it_->get(); } + LayerImpl* operator->() const { return it_->get(); } + IteratorAdapter& operator++() { + ++it_; + return *this; + } + + private: + Iterator it_; + }; + using const_iterator = IteratorAdapter<OwnedLayerImplList::const_iterator>; + using const_reverse_iterator = + IteratorAdapter<OwnedLayerImplList::const_reverse_iterator>; + const_iterator begin() const { return const_iterator(layer_list_.cbegin()); } + const_iterator end() const { return const_iterator(layer_list_.cend()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(layer_list_.crbegin()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(layer_list_.crend()); + } void SetTransformMutated(ElementId element_id, const gfx::Transform& transform); @@ -251,66 +277,47 @@ class CC_EXPORT LayerTreeImpl { return !presentation_callbacks_.empty(); } - ScrollNode* CurrentlyScrollingNode(); - const ScrollNode* CurrentlyScrollingNode() const; - int LastScrolledScrollNodeIndex() const; - void SetCurrentlyScrollingNode(const ScrollNode* node); - void ClearCurrentlyScrollingNode(); + using ViewportPropertyIds = LayerTreeHost::ViewportPropertyIds; + void SetViewportPropertyIds(const ViewportPropertyIds& ids); - struct ViewportLayerIds { - ElementId overscroll_elasticity_element_id; - int page_scale = Layer::INVALID_ID; - int inner_viewport_container = Layer::INVALID_ID; - int outer_viewport_container = Layer::INVALID_ID; - int inner_viewport_scroll = Layer::INVALID_ID; - int outer_viewport_scroll = Layer::INVALID_ID; - - bool operator==(const ViewportLayerIds& other) { - return overscroll_elasticity_element_id == - other.overscroll_elasticity_element_id && - page_scale == other.page_scale && - inner_viewport_container == other.inner_viewport_container && - outer_viewport_container == other.outer_viewport_container && - inner_viewport_scroll == other.inner_viewport_scroll && - outer_viewport_scroll == other.outer_viewport_scroll; - } - }; - void SetViewportLayersFromIds(const ViewportLayerIds& viewport_layer_ids); - void ClearViewportLayers(); - ElementId OverscrollElasticityElementId() const { - return viewport_layer_ids_.overscroll_elasticity_element_id; - } - LayerImpl* PageScaleLayer() const { - return LayerById(viewport_layer_ids_.page_scale); - } - LayerImpl* InnerViewportContainerLayer() const { - return LayerById(viewport_layer_ids_.inner_viewport_container); - } - LayerImpl* OuterViewportContainerLayer() const { - return LayerById(viewport_layer_ids_.outer_viewport_container); - } - LayerImpl* InnerViewportScrollLayer() const { - return LayerById(viewport_layer_ids_.inner_viewport_scroll); + const TransformNode* OverscrollElasticityTransformNode() const; + TransformNode* OverscrollElasticityTransformNode() { + return const_cast<TransformNode*>( + const_cast<const LayerTreeImpl*>(this) + ->OverscrollElasticityTransformNode()); } - LayerImpl* OuterViewportScrollLayer() const { - return LayerById(viewport_layer_ids_.outer_viewport_scroll); + const TransformNode* PageScaleTransformNode() const; + TransformNode* PageScaleTransformNode() { + return const_cast<TransformNode*>( + const_cast<const LayerTreeImpl*>(this)->PageScaleTransformNode()); } - const ScrollNode* InnerViewportScrollNode() const; ScrollNode* InnerViewportScrollNode() { return const_cast<ScrollNode*>( const_cast<const LayerTreeImpl*>(this)->InnerViewportScrollNode()); } + const ClipNode* OuterViewportClipNode() const; + ClipNode* OuterViewportClipNode() { + return const_cast<ClipNode*>( + const_cast<const LayerTreeImpl*>(this)->OuterViewportClipNode()); + } const ScrollNode* OuterViewportScrollNode() const; ScrollNode* OuterViewportScrollNode() { return const_cast<ScrollNode*>( const_cast<const LayerTreeImpl*>(this)->OuterViewportScrollNode()); } - void set_viewport_property_ids( - const LayerTreeHost::ViewportPropertyIds& ids) { - viewport_property_ids_ = ids; + LayerTreeHost::ViewportPropertyIds ViewportPropertyIdsForTesting() const { + return viewport_property_ids_; } + LayerImpl* InnerViewportScrollLayerForTesting() const; + LayerImpl* OuterViewportScrollLayerForTesting() const; + + ScrollNode* CurrentlyScrollingNode(); + const ScrollNode* CurrentlyScrollingNode() const; + int LastScrolledScrollNodeIndex() const; + void SetCurrentlyScrollingNode(const ScrollNode* node); + void ClearCurrentlyScrollingNode(); void ApplySentScrollAndScaleDeltasFromAbortedCommit(); @@ -408,16 +415,19 @@ class CC_EXPORT LayerTreeImpl { const SyncedBrowserControls* top_controls_shown_ratio() const { return top_controls_shown_ratio_.get(); } + gfx::Vector2dF current_elastic_overscroll() const { + return elastic_overscroll()->Current(IsActiveTree()); + } void SetElementIdsForTesting(); // Updates draw properties and render surface layer list, as well as tile // priorities. Returns false if it was unable to update. Updating lcd // text may cause invalidations, so should only be done after a commit. - bool UpdateDrawProperties(bool update_image_animation_controller = true); + bool UpdateDrawProperties( + bool update_image_animation_controller = true, + LayerImplList* output_update_layer_list_for_testing = nullptr); void UpdateCanUseLCDText(); - void BuildPropertyTreesForTesting(); - void BuildLayerListAndPropertyTreesForTesting(); void set_needs_update_draw_properties() { needs_update_draw_properties_ = true; @@ -462,8 +472,6 @@ class CC_EXPORT LayerTreeImpl { LayerImpl* ScrollableLayerByElementId(ElementId element_id) const; bool IsElementInPropertyTree(ElementId element_id) const; - void AddToElementPropertyTreeList(ElementId element_id); - void RemoveFromElementPropertyTreeList(ElementId element_id); void AddToElementLayerList(ElementId element_id, LayerImpl* layer); void RemoveFromElementLayerList(ElementId element_id); @@ -484,9 +492,8 @@ class CC_EXPORT LayerTreeImpl { void RegisterLayer(LayerImpl* layer); void UnregisterLayer(LayerImpl* layer); - // These manage ownership of the LayerImpl. + // Append a layer to the list. void AddLayer(std::unique_ptr<LayerImpl> layer); - std::unique_ptr<LayerImpl> RemoveLayer(int id); size_t NumLayers(); @@ -646,12 +653,6 @@ class CC_EXPORT LayerTreeImpl { void ResetAllChangeTracking(); - void AddToLayerList(LayerImpl* layer); - - void ClearLayerList(); - - void BuildLayerListForTesting(); - void HandleTickmarksVisibilityChange(); void HandleScrollbarShowRequestsFromMain(); @@ -663,14 +664,15 @@ class CC_EXPORT LayerTreeImpl { LayerTreeLifecycle& lifecycle() { return lifecycle_; } std::string LayerListAsJson() const; - // TODO(pdr): This should be removed because there is no longer a tree - // of layers, only a list. - std::string LayerTreeAsJson() const; AnimatedPaintWorkletTracker& paint_worklet_tracker() { return host_impl_->paint_worklet_tracker(); } + const gfx::Transform& DrawTransform() const { + return host_impl_->DrawTransform(); + } + protected: float ClampPageScaleFactorToLimits(float page_scale_factor) const; void PushPageScaleFactorAndLimits(const float* page_scale_factor, @@ -685,7 +687,6 @@ class CC_EXPORT LayerTreeImpl { private: friend class LayerTreeHost; - TransformNode* PageScaleTransformNode(); void UpdatePageScaleNode(); ElementListType GetElementTypeForAnimation() const; @@ -698,14 +699,12 @@ class CC_EXPORT LayerTreeImpl { LayerTreeHostImpl* host_impl_; int source_frame_number_; int is_first_frame_after_commit_tracker_; - LayerImpl* root_layer_for_testing_; HeadsUpDisplayLayerImpl* hud_layer_; PropertyTrees property_trees_; SkColor background_color_; int last_scrolled_scroll_node_index_; - ViewportLayerIds viewport_layer_ids_; LayerTreeHost::ViewportPropertyIds viewport_property_ids_; LayerSelection selection_; @@ -728,9 +727,13 @@ class CC_EXPORT LayerTreeImpl { scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_; - std::unique_ptr<OwnedLayerImplList> layers_; + // TODO(wangxianzhu): Combine layers_ and layer_list_ when we remove + // support of mask layers. + + OwnedLayerImplList layer_list_; + // Maps from layer id to layer. LayerImplMap layer_id_map_; - LayerImplList layer_list_; + // Set of layers that need to push properties. base::flat_set<LayerImpl*> layers_that_should_push_properties_; diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc index 4b2a48a7594..bdfe90cb9bc 100644 --- a/chromium/cc/trees/layer_tree_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_impl_unittest.cc @@ -8,10 +8,9 @@ #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_raster_source.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,23 +18,20 @@ namespace cc { namespace { -class LayerTreeImplTest : public LayerTestCommon::LayerImplTest, - public testing::Test { +class LayerTreeImplTest : public LayerTreeImplTestBase, public testing::Test { public: - explicit LayerTreeImplTest( - const LayerTreeSettings& settings = LayerListSettings()) - : LayerImplTest(settings) {} + LayerTreeImplTest() = default; + explicit LayerTreeImplTest(const LayerTreeSettings& settings) + : LayerTreeImplTestBase(settings) {} void SetUp() override { root_layer()->SetBounds(gfx::Size(100, 100)); - SetupRootProperties(root_layer()); UpdateDrawProperties(host_impl().active_tree()); } FakeLayerTreeHostImpl& host_impl() const { - return *LayerImplTest::host_impl(); + return *LayerTreeImplTestBase::host_impl(); } - LayerImpl* root_layer() { return root_layer_for_testing(); } const RenderSurfaceList& GetRenderSurfaceList() const { return host_impl().active_tree()->GetRenderSurfaceList(); @@ -108,14 +104,6 @@ class LayerTreeImplTest : public LayerTestCommon::LayerImplTest, LayerImpl* top_ = nullptr; LayerImpl* left_child_ = nullptr; LayerImpl* right_child_ = nullptr; - - private: - RenderSurfaceList render_surface_list_impl_; -}; - -class LayerTreeImplTestWithLayerLists : public LayerTreeImplTest { - public: - LayerTreeImplTestWithLayerLists() : LayerTreeImplTest(LayerListSettings()) {} }; TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { @@ -699,7 +687,6 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { intermediate_layer->SetBounds(gfx::Size(50, 50)); // Sanity check the intermediate layer should not clip. ASSERT_FALSE(intermediate_layer->masks_to_bounds()); - ASSERT_FALSE(intermediate_layer->test_properties()->mask_layer); CopyProperties(root, intermediate_layer); // this layer is positioned, and hit testing should correctly know where the // layer is located. @@ -973,13 +960,13 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { EXPECT_EQ(grand_child1, result_layer); } -TEST_F(LayerTreeImplTestWithLayerLists, HitTestingRespectsClipParents) { +TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) { LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); root->SetHitTestable(true); - LayerImpl* child = AddChildToRoot<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); child->SetHitTestable(true); @@ -987,14 +974,14 @@ TEST_F(LayerTreeImplTestWithLayerLists, HitTestingRespectsClipParents) { child->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); CreateClipNode(child); - LayerImpl* scroll_child = AddChildToRoot<LayerImpl>(); + LayerImpl* scroll_child = AddLayer<LayerImpl>(); scroll_child->SetBounds(gfx::Size(200, 200)); scroll_child->SetDrawsContent(true); scroll_child->SetHitTestable(true); CopyProperties(root, scroll_child); scroll_child->SetClipTreeIndex(child->clip_tree_index()); - LayerImpl* grand_child = AddChildToRoot<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); grand_child->SetBounds(gfx::Size(200, 200)); grand_child->SetDrawsContent(true); grand_child->SetHitTestable(true); @@ -1361,9 +1348,10 @@ TEST_F(LayerTreeImplTest, gfx::Rect(scaled_bounds_for_root)); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = page_scale_layer->id(); - host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); + LayerTreeImpl::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.page_scale_transform = + page_scale_layer->transform_tree_index(); + host_impl().active_tree()->SetViewportPropertyIds(viewport_property_ids); host_impl().active_tree()->PushPageScaleFromMainThread( page_scale_factor, page_scale_factor, max_page_scale_factor); host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); @@ -1445,7 +1433,8 @@ TEST_F(LayerTreeImplTest, // is also the root layer. page_scale_factor *= 1.5f; host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - EXPECT_EQ(page_scale_layer, host_impl().active_tree()->PageScaleLayer()); + EXPECT_EQ(page_scale_layer->transform_tree_index(), + host_impl().active_tree()->PageScaleTransformNode()->id); test_point = gfx::PointF(35.f, 35.f); test_point = @@ -1913,9 +1902,10 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize( root->bounds(), device_scale_factor * page_scale_factor); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = page_scale_layer->id(); - host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); + LayerTreeImpl::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.page_scale_transform = + page_scale_layer->transform_tree_index(); + host_impl().active_tree()->SetViewportPropertyIds(viewport_property_ids); host_impl().active_tree()->SetDeviceViewportRect( gfx::Rect(scaled_bounds_for_root)); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); @@ -2155,28 +2145,6 @@ TEST_F(LayerTreeImplTest, HitTestingCorrectLayerWheelListener) { EXPECT_EQ(left_child, result_layer); } -// When using layer lists, we may not have layers for the outer viewport. This -// test verifies that scroll size can be calculated using property tree nodes. -TEST_F(LayerTreeImplTest, ScrollSizeWithoutLayers) { - const gfx::Size inner_viewport_size(1000, 1000); - const gfx::Size outer_viewport_size(1000, 1000); - const gfx::Size scroll_layer_size(2000, 2000); - - auto* tree_impl = host_impl().active_tree(); - root_layer()->SetBounds(inner_viewport_size); - SetupViewport(root_layer(), outer_viewport_size, scroll_layer_size); - - // With viewport layers the scrollable size should be correct. - EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize()); - - // The scrollable size should be correct without non-outer viewport layers. - LayerTreeImpl::ViewportLayerIds updated_viewport_ids; - updated_viewport_ids.outer_viewport_scroll = - tree_impl->OuterViewportScrollLayer()->id(); - tree_impl->SetViewportLayersFromIds(updated_viewport_ids); - EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize()); -} - namespace { class PersistentSwapPromise @@ -2294,17 +2262,13 @@ TEST_F(LayerTreeImplTest, TrackPictureLayersWithPaintWorklets) { auto* root = EnsureRootLayerInPendingTree(); root->SetBounds(gfx::Size(100, 100)); - SetupRootProperties(root); // Add three layers; two with PaintWorklets and one without. - auto* child1 = - AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + auto* child1 = AddLayerInPendingTree<PictureLayerImpl>(); child1->SetBounds(gfx::Size(100, 100)); - auto* child2 = - AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + auto* child2 = AddLayerInPendingTree<PictureLayerImpl>(); child2->SetBounds(gfx::Size(100, 100)); - auto* child3 = - AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + auto* child3 = AddLayerInPendingTree<PictureLayerImpl>(); child3->SetBounds(gfx::Size(100, 100)); CopyProperties(root, child1); @@ -2336,8 +2300,7 @@ TEST_F(LayerTreeImplTest, TrackPictureLayersWithPaintWorklets) { EXPECT_EQ(layers.size(), 1u); EXPECT_FALSE(layers.contains(child1)); - // Deleting a layer should also cause it to be removed from the set. - root->test_properties()->RemoveChild(child3); + pending_tree->DetachLayers(); EXPECT_EQ(layers.size(), 0u); } @@ -2365,7 +2328,7 @@ TEST_F(CommitToPendingTreeLayerTreeImplTest, // active tree (as they are only used on the sync tree). LayerTreeImpl* active_tree = host_impl().active_tree(); UpdateDrawProperties(active_tree); - LayerImpl* active_root = active_tree->root_layer_for_testing(); + LayerImpl* active_root = active_tree->root_layer(); auto& active_opacity_map = active_tree->element_id_to_opacity_animations_for_testing(); @@ -2395,7 +2358,6 @@ TEST_F(CommitToPendingTreeLayerTreeImplTest, LayerImpl* child = AddLayerInPendingTree<LayerImpl>(); pending_tree->SetElementIdsForTesting(); - SetupRootProperties(pending_root); // A scale transform forces a TransformNode. gfx::Transform scale3d; scale3d.Scale3d(1, 1, 0.5); @@ -2458,7 +2420,7 @@ TEST_F(LayerTreeImplTest, ElementIdToAnimationMapsTrackOnlyOnSyncTree) { // they are used on the sync tree). LayerTreeImpl* active_tree = host_impl().active_tree(); UpdateDrawProperties(active_tree); - LayerImpl* root = active_tree->root_layer_for_testing(); + LayerImpl* root = active_tree->root_layer(); auto& opacity_map = active_tree->element_id_to_opacity_animations_for_testing(); diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index ce1e19e2915..182eb5f6873 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -43,6 +43,7 @@ class CC_EXPORT LayerTreeSettings { bool enable_latency_recovery = true; bool can_use_lcd_text = true; bool gpu_rasterization_forced = false; + bool gpu_rasterization_disabled = false; int gpu_rasterization_msaa_sample_count = 0; float gpu_rasterization_skewport_target_time_in_seconds = 0.2f; bool create_low_res_tiling = false; @@ -109,10 +110,6 @@ class CC_EXPORT LayerTreeSettings { LayerTreeDebugState initial_debug_state; - // Indicates that the LayerTreeHost should defer commits unless it has a valid - // viz::LocalSurfaceId set. - bool enable_surface_synchronization = true; - // Indicates the case when a sub-frame gets its own LayerTree because it's // rendered in a different process from its ancestor frames. bool is_layer_tree_for_subframe = false; @@ -128,6 +125,9 @@ class CC_EXPORT LayerTreeSettings { // deadlines. bool wait_for_all_pipeline_stages_before_draw = false; + // Determines whether the zoom needs to be applied to the device scale factor. + bool use_zoom_for_dsf = false; + // Determines whether mouse interactions on composited scrollbars are handled // on the compositor thread. bool compositor_threaded_scrollbar_scrolling = false; @@ -177,6 +177,11 @@ class CC_EXPORT LayerTreeSettings { bool allow_de_jelly_effect = false; }; +class CC_EXPORT LayerListSettings : public LayerTreeSettings { + public: + LayerListSettings() { use_layer_lists = true; } +}; + } // namespace cc #endif // CC_TREES_LAYER_TREE_SETTINGS_H_ diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h index c52ce403301..a77f8413551 100644 --- a/chromium/cc/trees/mutator_host.h +++ b/chromium/cc/trees/mutator_host.h @@ -158,6 +158,7 @@ class MutatorHost { virtual size_t CompositedAnimationsCount() const = 0; virtual size_t MainThreadAnimationsCount() const = 0; + virtual bool HasCustomPropertyAnimations() const = 0; virtual bool CurrentFrameHadRAF() const = 0; virtual bool NextFrameHasPendingRAF() const = 0; }; diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc index e4da0f3f7c4..363461feb19 100644 --- a/chromium/cc/trees/occlusion_tracker.cc +++ b/chromium/cc/trees/occlusion_tracker.cc @@ -196,8 +196,7 @@ void OcclusionTracker::FinishedRenderTarget( // If the occlusion within the surface can not be applied to things outside of // the surface's subtree, then clear the occlusion here so it won't be used. - if (finished_target_surface->HasMask() || - finished_target_surface->HasMaskingContributingSurface() || + if (finished_target_surface->HasMaskingContributingSurface() || finished_target_surface->draw_opacity() < 1 || !finished_target_surface->UsesDefaultBlendMode() || target_is_only_for_copy_request_or_force_render_surface || diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc index 41c812e1585..6fa6693d1f4 100644 --- a/chromium/cc/trees/occlusion_tracker_unittest.cc +++ b/chromium/cc/trees/occlusion_tracker_unittest.cc @@ -14,13 +14,15 @@ #include "cc/paint/filter_operations.h" #include "cc/test/animation_test_common.h" #include "cc/test/fake_impl_task_runner_provider.h" +#include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_test_common.h" +#include "cc/test/property_tree_test_utils.h" #include "cc/test/test_occlusion_tracker.h" #include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_host_common.h" +#include "cc/trees/draw_property_utils.h" #include "cc/trees/single_thread_proxy.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" @@ -90,35 +92,34 @@ class OcclusionTrackerTest : public testing::Test { protected: explicit OcclusionTrackerTest(bool opaque_layers) : opaque_layers_(opaque_layers), + layer_tree_frame_sink_(FakeLayerTreeFrameSink::Create3d()), animation_host_(AnimationHost::CreateForTesting(ThreadInstance::MAIN)), host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_, - animation_host_.get())), - next_layer_impl_id_(1) {} + animation_host_.get(), + LayerListSettings())), + next_layer_impl_id_(1) { + host_->host_impl()->InitializeFrameSink(layer_tree_frame_sink_.get()); + } virtual void RunMyTest() = 0; void TearDown() override { DestroyLayers(); } - TestContentLayerImpl* CreateRoot(const gfx::Transform& transform, - const gfx::PointF& position, - const gfx::Size& bounds) { + TestContentLayerImpl* CreateRoot(const gfx::Size& bounds) { LayerTreeImpl* tree = host_->host_impl()->active_tree(); int id = next_layer_impl_id_++; std::unique_ptr<TestContentLayerImpl> layer( new TestContentLayerImpl(tree, id)); TestContentLayerImpl* layer_ptr = layer.get(); - SetProperties(layer_ptr, transform, position, bounds); + layer_ptr->SetBounds(bounds); + SetupRootProperties(layer_ptr); host_->host_impl()->active_tree()->SetRootLayerForTesting(std::move(layer)); - - layer_ptr->test_properties()->force_render_surface = true; - SetRootLayerOnMainThread(layer_ptr); - return layer_ptr; } - LayerImpl* CreateLayer(LayerImpl* parent, + LayerImpl* CreateLayer(LayerImpl* property_parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds) { @@ -126,21 +127,30 @@ class OcclusionTrackerTest : public testing::Test { int id = next_layer_impl_id_++; std::unique_ptr<LayerImpl> layer = LayerImpl::Create(tree, id); LayerImpl* layer_ptr = layer.get(); - SetProperties(layer_ptr, transform, position, bounds); - parent->test_properties()->AddChild(std::move(layer)); + SetProperties(layer_ptr, property_parent, transform, position, bounds); + tree->AddLayer(std::move(layer)); return layer_ptr; } + void EnsureTransformNode(LayerImpl* layer) { + if (!layer->has_transform_node()) { + CreateTransformNode(layer).post_translation = + layer->offset_to_transform_parent(); + layer->SetOffsetToTransformParent(gfx::Vector2dF()); + } + } + LayerImpl* CreateSurface(LayerImpl* parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds) { LayerImpl* layer = CreateLayer(parent, transform, position, bounds); - layer->test_properties()->force_render_surface = true; + EnsureTransformNode(layer); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; return layer; } - TestContentLayerImpl* CreateDrawingLayer(LayerImpl* parent, + TestContentLayerImpl* CreateDrawingLayer(LayerImpl* property_parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds, @@ -150,7 +160,7 @@ class OcclusionTrackerTest : public testing::Test { std::unique_ptr<TestContentLayerImpl> layer( new TestContentLayerImpl(tree, id)); TestContentLayerImpl* layer_ptr = layer.get(); - SetProperties(layer_ptr, transform, position, bounds); + SetProperties(layer_ptr, property_parent, transform, position, bounds); if (opaque_layers_) { layer_ptr->SetContentsOpaque(opaque); @@ -162,64 +172,76 @@ class OcclusionTrackerTest : public testing::Test { layer_ptr->SetOpaqueContentsRect(gfx::Rect()); } - parent->test_properties()->AddChild(std::move(layer)); + tree->AddLayer(std::move(layer)); return layer_ptr; } - TestContentLayerImpl* CreateDrawingSurface(LayerImpl* parent, + TestContentLayerImpl* CreateDrawingSurface(LayerImpl* property_parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds, bool opaque) { - TestContentLayerImpl* layer = - CreateDrawingLayer(parent, transform, position, bounds, opaque); - layer->test_properties()->force_render_surface = true; + TestContentLayerImpl* layer = CreateDrawingLayer(property_parent, transform, + position, bounds, opaque); + EnsureTransformNode(layer); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; return layer; } - void DestroyLayers() { - host_->host_impl()->active_tree()->SetRootLayerForTesting(nullptr); - render_surface_list_impl_.clear(); - mask_layers_.clear(); - layer_iterator_.reset(); + void SetMasksToBounds(LayerImpl* layer) { + layer->SetMasksToBounds(true); + CreateClipNode(layer); } - void AddCopyRequest(Layer* layer) { - layer->RequestCopyOfOutput(viz::CopyOutputRequest::CreateStubForTesting()); + void DestroyLayers() { + auto* tree = host_->host_impl()->active_tree(); + tree->DetachLayers(); + tree->property_trees()->clear(); + layer_iterator_.reset(); } - void AddCopyRequest(LayerImpl* layer) { - layer->test_properties()->copy_requests.push_back( - viz::CopyOutputRequest::CreateStubForTesting()); + LayerImpl* CreateCopyLayer(LayerImpl* parent, + const gfx::Transform& transform, + const gfx::PointF& position, + const gfx::Size& bounds) { + LayerImpl* layer = CreateSurface(parent, transform, position, bounds); + auto* effect_node = GetEffectNode(layer); + effect_node->render_surface_reason = RenderSurfaceReason::kCopyRequest; + effect_node->has_copy_request = true; + effect_node->closest_ancestor_with_copy_request_id = effect_node->id; + auto& effect_tree = GetPropertyTrees(layer)->effect_tree; + effect_tree.AddCopyRequest(effect_node->id, + viz::CopyOutputRequest::CreateStubForTesting()); + // TODO(wangxianzhu): Let EffectTree::UpdateEffects() handle this. + do { + effect_node->subtree_has_copy_request = true; + effect_node = effect_tree.Node(effect_node->parent_id); + } while (effect_node && !effect_node->subtree_has_copy_request); + return layer; } - void CalcDrawEtc(TestContentLayerImpl* root) { - root->layer_tree_impl()->BuildLayerListForTesting(); - DCHECK(root == root->layer_tree_impl()->root_layer_for_testing()); - - // These occlusion tests attach and detach layers in multiple - // iterations, so rebuild property trees every time. - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Rect(root->bounds()), &render_surface_list_impl_); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + void CalcDrawEtc() { + LayerTreeImpl* tree = host_->host_impl()->active_tree(); + tree->SetDeviceViewportRect(gfx::Rect(tree->root_layer()->bounds())); + UpdateDrawProperties(tree); - layer_iterator_ = std::make_unique<EffectTreeLayerListIterator>( - host_->host_impl()->active_tree()); + layer_iterator_ = std::make_unique<EffectTreeLayerListIterator>(tree); } +#define ASSERT_EQ_WITH_IDS(a, b) \ + ASSERT_EQ(a, b) << " ids: " << (a)->id() << " vs " << (b)->id() + void EnterLayer(LayerImpl* layer, OcclusionTracker* occlusion) { - ASSERT_EQ(layer_iterator_->current_layer(), layer); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::LAYER); + ASSERT_EQ(EffectTreeLayerListIterator::State::LAYER, + layer_iterator_->state()); + ASSERT_EQ_WITH_IDS(layer, layer_iterator_->current_layer()); occlusion->EnterLayer(*layer_iterator_); } void LeaveLayer(LayerImpl* layer, OcclusionTracker* occlusion) { - ASSERT_EQ(layer_iterator_->current_layer(), layer); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::LAYER); + ASSERT_EQ(EffectTreeLayerListIterator::State::LAYER, + layer_iterator_->state()); + ASSERT_EQ_WITH_IDS(layer, layer_iterator_->current_layer()); occlusion->LeaveLayer(*layer_iterator_); ++(*layer_iterator_); } @@ -230,23 +252,23 @@ class OcclusionTrackerTest : public testing::Test { } void EnterContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) { - ASSERT_EQ(layer_iterator_->target_render_surface(), - GetRenderSurface(layer)); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::TARGET_SURFACE); + ASSERT_EQ(EffectTreeLayerListIterator::State::TARGET_SURFACE, + layer_iterator_->state()); + ASSERT_EQ_WITH_IDS(GetRenderSurface(layer), + layer_iterator_->target_render_surface()); occlusion->EnterLayer(*layer_iterator_); occlusion->LeaveLayer(*layer_iterator_); ++(*layer_iterator_); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE); + ASSERT_EQ(EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE, + layer_iterator_->state()); occlusion->EnterLayer(*layer_iterator_); } void LeaveContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) { - ASSERT_EQ(layer_iterator_->current_render_surface(), - GetRenderSurface(layer)); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE); + ASSERT_EQ(EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE, + layer_iterator_->state()); + ASSERT_EQ_WITH_IDS(GetRenderSurface(layer), + layer_iterator_->current_render_surface()); occlusion->LeaveLayer(*layer_iterator_); ++(*layer_iterator_); } @@ -268,30 +290,33 @@ class OcclusionTrackerTest : public testing::Test { host_->SetRootLayer(scoped_refptr<Layer>(root)); } - void SetRootLayerOnMainThread(LayerImpl* root) {} - void SetProperties(LayerImpl* layer, + LayerImpl* property_parent, const gfx::Transform& transform, - const gfx::PointF& position, + const gfx::PointF& offset_to_property_parent, const gfx::Size& bounds) { - layer->test_properties()->transform = transform; - layer->test_properties()->position = position; + layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); layer->SetBounds(bounds); - } - - void SetMask(LayerImpl* owning_layer, std::unique_ptr<LayerImpl> layer) { - owning_layer->test_properties()->SetMaskLayer(std::move(layer)); + CopyProperties(property_parent, layer); + gfx::Vector2dF offset_to_transform_parent = + property_parent->offset_to_transform_parent() + + offset_to_property_parent.OffsetFromOrigin(); + if (transform.IsIdentity()) { + layer->SetOffsetToTransformParent(offset_to_transform_parent); + } else { + auto& transform_node = CreateTransformNode(layer); + transform_node.local = transform; + transform_node.post_translation = offset_to_transform_parent; + } } bool opaque_layers_; FakeLayerTreeHostClient client_; TestTaskGraphRunner task_graph_runner_; + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink_; std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> host_; - // These hold ownership of the layers for the duration of the test. - RenderSurfaceList render_surface_list_impl_; std::unique_ptr<EffectTreeLayerListIterator> layer_iterator_; - LayerList mask_layers_; int next_layer_impl_id_; }; @@ -318,20 +343,19 @@ class OcclusionTrackerTestIdentityTransforms : public OcclusionTrackerTest { : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); + SetMasksToBounds(parent); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - parent->SetMasksToBounds(true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -352,20 +376,19 @@ class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest { layer_transform.Rotate(90.0); layer_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); + SetMasksToBounds(parent); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - parent->SetMasksToBounds(true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -384,20 +407,19 @@ class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest { gfx::Transform layer_transform; layer_transform.Translate(20.0, 20.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); + SetMasksToBounds(parent); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - parent->SetMasksToBounds(true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -418,29 +440,28 @@ class OcclusionTrackerTestChildInRotatedChild : public OcclusionTrackerTest { child_transform.Rotate(90.0); child_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - parent->SetMasksToBounds(true); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + SetMasksToBounds(parent); LayerImpl* child = this->CreateSurface( parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); - child->SetMasksToBounds(true); + SetMasksToBounds(child); TestContentLayerImpl* layer = this->CreateDrawingLayer( child, this->identity_matrix, gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer, &occlusion); - this->EnterContributingSurface(child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -505,14 +526,12 @@ class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest { : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(200, 200)); gfx::Transform layer1_matrix; layer1_matrix.Scale(2.0, 2.0); - TestContentLayerImpl* layer1 = this->CreateDrawingLayer( + TestContentLayerImpl* layer1 = this->CreateDrawingSurface( parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true); - layer1->test_properties()->force_render_surface = true; gfx::Transform layer2_matrix; layer2_matrix.Translate(25.0, 25.0); @@ -521,12 +540,12 @@ class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest { TestContentLayerImpl* occluder = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(100.f, 100.f), gfx::Size(500, 500), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(occluder, &occlusion); - this->EnterLayer(layer2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(occluder, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(layer2, &occlusion)); EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -542,8 +561,7 @@ class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest { explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); LayerImpl* surface = this->CreateSurface( root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size()); TestContentLayerImpl* surface_child = this->CreateDrawingLayer( @@ -556,25 +574,26 @@ class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest { TestContentLayerImpl* top_layer = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(40.f, 90.f), gfx::Size(50, 20), true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(top_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(top_layer, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(surface_child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface_child, &occlusion)); EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->EnterContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(surface, &occlusion)); EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -583,8 +602,9 @@ class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest { // Occlusion from |top_layer| already in the root target should get merged // with the occlusion from the |surface| we are leaving now. - this->LeaveContributingSurface(surface, &occlusion); - this->EnterLayer(root, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(root, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(), @@ -607,31 +627,30 @@ class OcclusionTrackerTestSurfaceRotatedOffAxis : public OcclusionTrackerTest { gfx::Transform layer_transform; layer_transform.Translate(10.0, 10.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(1000, 1000)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); LayerImpl* child = this->CreateSurface( parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); TestContentLayerImpl* layer = this->CreateDrawingLayer( child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect( layer_transform, layer->visible_layer_rect()); - this->VisitLayer(layer, &occlusion); - this->EnterContributingSurface(child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(clipped_layer_in_child.ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -653,37 +672,36 @@ class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren child_transform.Rotate(90.0); child_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(1000, 1000)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); - parent->SetMasksToBounds(true); + SetMasksToBounds(parent); TestContentLayerImpl* child = this->CreateDrawingSurface( parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), false); - child->SetMasksToBounds(true); + SetMasksToBounds(child); TestContentLayerImpl* layer1 = this->CreateDrawingLayer( child, this->identity_matrix, gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); TestContentLayerImpl* layer2 = this->CreateDrawingLayer( child, this->identity_matrix, gfx::PointF(10.f, 450.f), gfx::Size(500, 60), true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer2, &occlusion); - this->VisitLayer(layer1, &occlusion); - this->VisitLayer(child, &occlusion); - this->EnterContributingSurface(child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(child, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -725,9 +743,8 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - parent->SetMasksToBounds(true); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + SetMasksToBounds(parent); LayerImpl* child1 = this->CreateSurface( parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size()); LayerImpl* child2 = this->CreateSurface( @@ -737,12 +754,12 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings TestContentLayerImpl* layer2 = this->CreateDrawingLayer( child2, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size(40, 50), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer2, &occlusion); - this->EnterContributingSurface(child2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child2, &occlusion)); // layer2's occlusion. EXPECT_EQ(gfx::Rect().ToString(), @@ -750,9 +767,9 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child2, &occlusion); - this->VisitLayer(layer1, &occlusion); - this->EnterContributingSurface(child1, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child1, &occlusion)); // layer2's occlusion in the target space of layer1. EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(), @@ -761,8 +778,8 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child1, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); // The occlusion from from layer1 and layer2 is merged. EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); @@ -790,51 +807,50 @@ class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms child2_transform.Rotate(90.0); child2_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - parent->SetMasksToBounds(true); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + SetMasksToBounds(parent); LayerImpl* child1 = this->CreateSurface( parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10)); - LayerImpl* child2 = this->CreateDrawingSurface(parent, child2_transform, - gfx::PointF(20.f, 40.f), - gfx::Size(10, 10), false); TestContentLayerImpl* layer1 = this->CreateDrawingLayer( child1, this->identity_matrix, gfx::PointF(-10.f, -20.f), gfx::Size(510, 510), true); + LayerImpl* child2 = this->CreateDrawingSurface(parent, child2_transform, + gfx::PointF(20.f, 40.f), + gfx::Size(10, 10), false); TestContentLayerImpl* layer2 = this->CreateDrawingLayer( child2, this->identity_matrix, gfx::PointF(-10.f, -10.f), gfx::Size(510, 510), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer2, &occlusion); - this->EnterLayer(child2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(child2, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveLayer(child2, &occlusion); - this->EnterContributingSurface(child2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(child2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child2, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child2, &occlusion); - this->VisitLayer(layer1, &occlusion); - this->EnterContributingSurface(child1, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child1, &occlusion)); EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child1, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -880,16 +896,15 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest { layer_transform.Rotate(90.0); layer_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - parent->SetMasksToBounds(true); - TestContentLayerImpl* blur_layer = this->CreateDrawingLayer( + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + SetMasksToBounds(parent); + TestContentLayerImpl* blur_layer = this->CreateDrawingSurface( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - TestContentLayerImpl* opaque_layer = this->CreateDrawingLayer( + TestContentLayerImpl* opaque_layer = this->CreateDrawingSurface( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - TestContentLayerImpl* opacity_layer = this->CreateDrawingLayer( + TestContentLayerImpl* opacity_layer = this->CreateDrawingSurface( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); @@ -898,75 +913,82 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest { parent, rounded_corner_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - blur_layer->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(10.f)); - blur_layer->test_properties()->filters = filters; + GetEffectNode(blur_layer)->filters = filters; - opaque_layer->test_properties()->force_render_surface = true; filters.Clear(); filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); - opaque_layer->test_properties()->filters = filters; + GetEffectNode(opaque_layer)->filters = filters; - opacity_layer->test_properties()->force_render_surface = true; filters.Clear(); filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); - opacity_layer->test_properties()->filters = filters; + GetEffectNode(opacity_layer)->filters = filters; - rounded_corner_layer->test_properties()->rounded_corner_bounds = + CreateEffectNode(rounded_corner_layer).rounded_corner_bounds = gfx::RRectF(1, 2, 3, 4, 5, 6); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); + EXPECT_TRUE(rounded_corner_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(blur_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(opaque_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(opacity_layer->contributes_to_drawn_render_surface()); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); // Rounded corners won't contribute to occlusion. - this->EnterLayer(rounded_corner_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(rounded_corner_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); - this->LeaveLayer(rounded_corner_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(rounded_corner_layer, &occlusion)); // Opacity layer won't contribute to occlusion. - this->VisitLayer(opacity_layer, &occlusion); - this->EnterContributingSurface(opacity_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(opacity_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(opacity_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); // And has nothing to contribute to its parent surface. - this->LeaveContributingSurface(opacity_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(opacity_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); // Opaque layer will contribute to occlusion. - this->VisitLayer(opaque_layer, &occlusion); - this->EnterContributingSurface(opaque_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(opaque_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(opaque_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); // And it gets translated to the parent surface. - this->LeaveContributingSurface(opaque_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(opaque_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); // The blur layer needs to throw away any occlusion from outside its // subtree. - this->EnterLayer(blur_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(blur_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); // And it won't contribute to occlusion. - this->LeaveLayer(blur_layer, &occlusion); - this->EnterContributingSurface(blur_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(blur_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(blur_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); // But the opaque layer's occlusion is preserved on the parent. - this->LeaveContributingSurface(blur_layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(blur_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -981,22 +1003,21 @@ class OcclusionTrackerTestOpaqueContentsRegionEmpty explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 300)); TestContentLayerImpl* layer = this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200), false); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->EnterLayer(layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); - this->LeaveLayer(layer, &occlusion); - this->VisitContributingSurface(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitContributingSurface(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); @@ -1011,19 +1032,18 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 300)); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(100.f, 100.f), gfx::Size(200, 200), false); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); { TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100)); this->ResetLayerIterator(); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -1033,8 +1053,8 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180)); this->ResetLayerIterator(); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -1044,8 +1064,8 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100)); this->ResetLayerIterator(); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -1068,21 +1088,20 @@ class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude transform.Translate3d(0.0, 0.0, 110.0); transform.Translate(-50.0, -50.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, transform, gfx::PointF(), gfx::Size(100, 100), true); - parent->test_properties()->should_flatten_transform = false; - parent->test_properties()->sorting_context_id = 1; - layer->test_properties()->should_flatten_transform = false; - layer->test_properties()->sorting_context_id = 1; - this->CalcDrawEtc(parent); + GetTransformNode(parent)->flattens_inherited_transform = false; + GetTransformNode(parent)->sorting_context_id = 1; + GetTransformNode(layer)->flattens_inherited_transform = false; + GetTransformNode(layer)->sorting_context_id = 1; + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); // The |layer| is entirely behind the camera and should not occlude. - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); } @@ -1100,8 +1119,7 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent surface_transform.Scale(2.0, 2.0); surface_transform.Translate(-150.0, -150.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(500, 500)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(500, 500)); TestContentLayerImpl* surface = this->CreateDrawingSurface( parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false); TestContentLayerImpl* surface2 = this->CreateDrawingSurface( @@ -1109,12 +1127,13 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent gfx::Size(300, 300), false); surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(surface2, &occlusion); - this->VisitContributingSurface(surface2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface2, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(surface2, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1125,8 +1144,9 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); - this->VisitLayer(surface, &occlusion); - this->VisitContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(surface, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1145,19 +1165,19 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); - parent->SetMasksToBounds(true); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 300)); + SetMasksToBounds(parent); TestContentLayerImpl* surface = this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 300), false); surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200)); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(surface, &occlusion); - this->VisitContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(surface, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1177,8 +1197,7 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { // This test verifies that the surface cliprect does not end up empty and // clip away the entire unoccluded rect. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 200)); LayerImpl* surface = this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), false); @@ -1187,20 +1206,20 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { gfx::Size(100, 50), true); LayerImpl* topmost = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(-100, -100, 1000, 1000)); // |topmost| occludes everything partially so we know occlusion is happening // at all. - this->VisitLayer(topmost, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(topmost, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(surface_child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface_child, &occlusion)); // surface_child increases the occlusion in the screen by a narrow sliver. EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(), @@ -1215,7 +1234,8 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { // |surface_child| exercises different code paths as its parent does not // have a clip rect. - this->EnterContributingSurface(surface_child, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(surface_child, &occlusion)); // The |surface_child| can't occlude its own surface, but occlusion from // |topmost| can. EXPECT_EQ(gfx::Rect().ToString(), @@ -1224,18 +1244,20 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusion_on_contributing_surface_from_inside_target() .ToString()); - this->LeaveContributingSurface(surface_child, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(surface_child, &occlusion)); // When the surface_child's occlusion is transformed up to its parent, make // sure it is not clipped away inappropriately. - this->EnterLayer(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(surface, &occlusion)); EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveLayer(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(surface, &occlusion)); - this->EnterContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(surface, &occlusion)); // The occlusion from inside |surface| can't affect the surface, but // |topmost| can. EXPECT_EQ(gfx::Rect().ToString(), @@ -1245,8 +1267,9 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { occlusion.occlusion_on_contributing_surface_from_inside_target() .ToString()); - this->LeaveContributingSurface(surface, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); // The occlusion in |surface| and without are merged into the parent. EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1285,12 +1308,11 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter // which are above it in the z-order in various configurations. The // surface is scaled to test that the pixel moving is done in the target // space, where the backdrop filter is applied. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); - LayerImpl* filtered_surface = this->CreateDrawingLayer( + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(200, 200)); + LayerImpl* filtered_surface = this->CreateDrawingSurface( parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), false); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; gfx::Rect occlusion_rect; switch (i) { case LEFT: @@ -1312,21 +1334,20 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter LayerImpl* occluding_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), occlusion_rect.size(), true); - occluding_layer->test_properties()->force_render_surface = false; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); // This layer occludes pixels directly beside the filtered_surface. // Because filtered surface blends pixels in a radius, it will need to see // some of the pixels (up to radius far) underneath the occluding layers. - this->VisitLayer(occluding_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(occluding_layer, &occlusion)); EXPECT_EQ(occlusion_rect.ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - this->VisitLayer(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); // The occlusion is used fully inside the surface. gfx::Rect occlusion_inside_surface = @@ -1339,8 +1360,9 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter // currently considered occluded in order to be drawn. The pixels it // needs should be removed from the occluded area, so that they are drawn // when we get to the parent. - this->VisitContributingSurface(filtered_surface, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); // The spread due to a 10px blur is 30px. gfx::Rect expected_occlusion = occlusion_rect; @@ -1400,12 +1422,11 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter // which are above it in the z-order in various configurations. The // surface is scaled to test that the pixel moving is done in the target // space, where the backdrop filter is applied. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); - LayerImpl* filtered_surface = this->CreateDrawingLayer( + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(200, 200)); + LayerImpl* filtered_surface = this->CreateDrawingSurface( parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), false); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; gfx::Rect occlusion_rect; switch (i) { case LEFT: @@ -1427,21 +1448,20 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter LayerImpl* occluding_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), occlusion_rect.size(), true); - occluding_layer->test_properties()->force_render_surface = false; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); // This layer occludes pixels directly beside the filtered_surface. // Because filtered surface blends pixels in a radius, it will need to see // some of the pixels (up to radius far) underneath the occluding layers. - this->VisitLayer(occluding_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(occluding_layer, &occlusion)); EXPECT_EQ(occlusion_rect.ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - this->VisitLayer(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); // The occlusion is used fully inside the surface. gfx::Rect occlusion_inside_surface = @@ -1454,8 +1474,9 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter // currently considered occluded in order to be drawn. The pixels it // needs should be removed from the occluded area, so that they are drawn // when we get to the parent. - this->VisitContributingSurface(filtered_surface, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); gfx::Rect expected_occlusion; switch (i) { @@ -1504,41 +1525,41 @@ class OcclusionTrackerTestTwoBackdropFiltersReduceOcclusionTwice // Makes two surfaces that completely cover |parent|. The occlusion both // above and below the filters will be reduced by each of them. - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(75, 75)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(75, 75)); LayerImpl* parent = this->CreateSurface(root, scale_by_half, gfx::PointF(), gfx::Size(150, 150)); - parent->SetMasksToBounds(true); - LayerImpl* filtered_surface1 = this->CreateDrawingLayer( + SetMasksToBounds(parent); + LayerImpl* filtered_surface1 = this->CreateDrawingSurface( parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); - LayerImpl* filtered_surface2 = this->CreateDrawingLayer( + LayerImpl* filtered_surface2 = this->CreateDrawingSurface( parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); LayerImpl* occluding_layer_above = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(100.f, 100.f), gfx::Size(50, 50), true); // Filters make the layers own surfaces. - filtered_surface1->test_properties()->force_render_surface = true; - filtered_surface2->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(1.f)); - filtered_surface1->test_properties()->backdrop_filters = filters; - filtered_surface2->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface1)->backdrop_filters = filters; + GetEffectNode(filtered_surface2)->backdrop_filters = filters; - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(occluding_layer_above, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitLayer(occluding_layer_above, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(filtered_surface2, &occlusion); - this->VisitContributingSurface(filtered_surface2, &occlusion); - this->VisitLayer(filtered_surface1, &occlusion); - this->VisitContributingSurface(filtered_surface1, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface2, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface1, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface1, &occlusion)); // Test expectations in the target. int blur_outset = 3; @@ -1572,29 +1593,28 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackdropFilter // The surface is scaled to test that the pixel moving is done in the target // space, where the backdrop filter is applied, and the surface appears at // 50, 50. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 150)); LayerImpl* behind_surface_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(60.f, 60.f), gfx::Size(30, 30), true); - LayerImpl* filtered_surface = - this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f), - gfx::Size(100, 100), false); + LayerImpl* filtered_surface = this->CreateDrawingSurface( + parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), + false); // Filters make the layer own a surface. - filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); // The surface has a backdrop blur, so it blurs non-opaque pixels below // it. - this->VisitLayer(filtered_surface, &occlusion); - this->VisitContributingSurface(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); // The layers behind the surface are not blurred, and their occlusion does // not change, until we leave the surface. So it should not be modified by @@ -1605,7 +1625,7 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackdropFilter // without existing occlusion interfering. occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); - this->VisitLayer(behind_surface_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(behind_surface_layer, &occlusion)); // The layers behind the surface are not blurred, and their occlusion does // not change, until we leave the surface. So it should not be modified by @@ -1634,28 +1654,26 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackdropFilterIsOccluded // layer which is above it in the z-order. The surface is // scaled to test that the pixel moving is done in the target space, where // the backdrop filter is applied, and the surface appears at 50, 50. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 150)); - LayerImpl* filtered_surface = - this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f), - gfx::Size(100, 100), false); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(200, 150)); + LayerImpl* filtered_surface = this->CreateDrawingSurface( + parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), + false); LayerImpl* occluding_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size(50, 50), true); // Filters make the layer own a surface. - filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(occluding_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(occluding_layer, &occlusion)); - this->VisitLayer(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); { // The layers above the filtered surface occlude from outside. gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50); @@ -1668,7 +1686,8 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackdropFilterIsOccluded // The surface has a backdrop blur, so it blurs non-opaque pixels below // it. - this->VisitContributingSurface(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); { // The filter is completely occluded, so it should not blur anything and // reduce any occlusion. @@ -1699,11 +1718,10 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded // are above it in the z-order. The surface is scaled to test that the // pixel moving is done in the target space, where the backdrop filter is // applied, but the surface appears at 50, 50. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); - LayerImpl* filtered_surface = - this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f), - gfx::Size(100, 100), false); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 150)); + LayerImpl* filtered_surface = this->CreateDrawingSurface( + parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), + false); LayerImpl* above_surface_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(70.f, 50.f), gfx::Size(30, 50), true); @@ -1712,22 +1730,22 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded gfx::Size(10, 10), true); // Filters make the layer own a surface. - filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(beside_surface_layer, &occlusion); - this->VisitLayer(above_surface_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(beside_surface_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(above_surface_layer, &occlusion)); // The surface has a backdrop blur, so it blurs non-opaque pixels below // it. - this->VisitLayer(filtered_surface, &occlusion); - this->VisitContributingSurface(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); // The filter in the surface is partially unoccluded. Only the unoccluded // parts should reduce occlusion. This means it will push back the @@ -1766,9 +1784,8 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - LayerImpl* blend_mode_layer = this->CreateDrawingLayer( + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + LayerImpl* blend_mode_layer = this->CreateDrawingSurface( parent, this->identity_matrix, gfx::PointF(0.f, 0.f), gfx::Size(100, 100), true); LayerImpl* top_layer = this->CreateDrawingLayer( @@ -1776,20 +1793,19 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude gfx::Size(20, 22), true); // Blend mode makes the layer own a surface. - blend_mode_layer->test_properties()->force_render_surface = true; - blend_mode_layer->test_properties()->blend_mode = SkBlendMode::kMultiply; + GetEffectNode(blend_mode_layer)->blend_mode = SkBlendMode::kMultiply; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(top_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(top_layer, &occlusion)); // |top_layer| occludes. EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - this->VisitLayer(blend_mode_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(blend_mode_layer, &occlusion)); // |top_layer| and |blend_mode_layer| both occlude, since the blend mode // gets applied by blend_mode_layer's render surface, not when drawing the // layer itself. @@ -1798,7 +1814,8 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), occlusion.occlusion_from_outside_target().ToString()); - this->VisitContributingSurface(blend_mode_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(blend_mode_layer, &occlusion)); // |top_layer| occludes but not |blend_mode_layer|. EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -1816,20 +1833,19 @@ class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest { gfx::Size tracking_size(100, 100); gfx::Size below_tracking_size(99, 99); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(400, 400)); LayerImpl* large = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(), tracking_size, true); LayerImpl* small = this->CreateDrawingLayer(parent, this->identity_matrix, gfx::PointF(), below_tracking_size, true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); occlusion.set_minimum_tracking_size(tracking_size); // The small layer is not tracked because it is too small. - this->VisitLayer(small, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(small, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1837,7 +1853,7 @@ class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest { occlusion.occlusion_from_inside_target().ToString()); // The large layer is tracked as it is large enough. - this->VisitLayer(large, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(large, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1856,21 +1872,20 @@ class OcclusionTrackerTestScaledLayerIsClipped : public OcclusionTrackerTest { gfx::Transform scale_transform; scale_transform.Scale(512.0, 512.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(400, 400)); LayerImpl* clip = this->CreateLayer(parent, this->identity_matrix, gfx::PointF(10.f, 10.f), gfx::Size(50, 50)); - clip->SetMasksToBounds(true); + SetMasksToBounds(clip); LayerImpl* scale = this->CreateLayer(clip, scale_transform, gfx::PointF(), gfx::Size(1, 1)); LayerImpl* scaled = this->CreateDrawingLayer( scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(scaled, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(scaled, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1890,25 +1905,25 @@ class OcclusionTrackerTestScaledLayerInSurfaceIsClipped gfx::Transform scale_transform; scale_transform.Scale(512.0, 512.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(400, 400)); LayerImpl* clip = this->CreateLayer(parent, this->identity_matrix, gfx::PointF(10.f, 10.f), gfx::Size(50, 50)); - clip->SetMasksToBounds(true); + SetMasksToBounds(clip); LayerImpl* surface = this->CreateDrawingSurface( clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false); LayerImpl* scale = this->CreateLayer(surface, scale_transform, gfx::PointF(), gfx::Size(1, 1)); LayerImpl* scaled = this->CreateDrawingLayer( scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(scaled, &occlusion); - this->VisitLayer(surface, &occlusion); - this->VisitContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(scaled, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(surface, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1924,30 +1939,28 @@ class OcclusionTrackerTestCopyRequestDoesOcclude : public OcclusionTrackerTest { explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(400, 400)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(400, 400), true); LayerImpl* copy = - this->CreateLayer(parent, this->identity_matrix, gfx::PointF(100, 0), - gfx::Size(200, 400)); - this->AddCopyRequest(copy); + this->CreateCopyLayer(parent, this->identity_matrix, + gfx::PointF(100, 0), gfx::Size(200, 400)); LayerImpl* copy_child = this->CreateDrawingLayer( copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true); LayerImpl* top_layer = this->CreateDrawingLayer(root, this->identity_matrix, gfx::PointF(50, 0), gfx::Size(50, 400), true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(top_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(top_layer, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(copy_child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(copy_child, &occlusion)); // Layers outside the copy request do not occlude. EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1955,7 +1968,7 @@ class OcclusionTrackerTestCopyRequestDoesOcclude : public OcclusionTrackerTest { occlusion.occlusion_from_inside_target().ToString()); // CopyRequests cause the layer to own a surface. - this->VisitContributingSurface(copy, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitContributingSurface(copy, &occlusion)); // The occlusion from the copy should be kept. EXPECT_EQ(gfx::Rect().ToString(), @@ -1974,35 +1987,32 @@ class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(400, 400)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(400, 400), true); LayerImpl* hide = this->CreateLayer(parent, this->identity_matrix, gfx::PointF(), gfx::Size()); + // The |copy| layer is hidden but since it is being copied, it will be + // drawn. + CreateEffectNode(hide).opacity = 0.f; LayerImpl* copy = - this->CreateLayer(hide, this->identity_matrix, gfx::PointF(100.f, 0.f), - gfx::Size(200, 400)); - this->AddCopyRequest(copy); + this->CreateCopyLayer(hide, this->identity_matrix, + gfx::PointF(100.f, 0.f), gfx::Size(200, 400)); LayerImpl* copy_child = this->CreateDrawingLayer( copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true); - // The |copy| layer is hidden but since it is being copied, it will be - // drawn. - hide->test_properties()->hide_layer_and_subtree = true; - - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(copy_child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(copy_child, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(200, 400).ToString(), occlusion.occlusion_from_inside_target().ToString()); // CopyRequests cause the layer to own a surface. - this->VisitContributingSurface(copy, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitContributingSurface(copy, &occlusion)); // The occlusion from the copy should be dropped since it is hidden. EXPECT_EQ(gfx::Rect().ToString(), @@ -2021,19 +2031,18 @@ class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest { void RunMyTest() override { gfx::Transform translate; translate.Translate(10.0, 20.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); LayerImpl* surface = this->CreateSurface( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); LayerImpl* layer = this->CreateDrawingLayer( surface, translate, gfx::PointF(), gfx::Size(200, 200), false); TestContentLayerImpl* outside_layer = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200), false); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); - this->VisitLayer(outside_layer, &occlusion); - this->EnterLayer(layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(outside_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(layer, &occlusion)); // No occlusion, is not occluded. occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); @@ -2109,19 +2118,18 @@ class OcclusionTrackerTestUnoccludedLayerQuery : public OcclusionTrackerTest { void RunMyTest() override { gfx::Transform translate; translate.Translate(10.0, 20.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); LayerImpl* surface = this->CreateSurface( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); LayerImpl* layer = this->CreateDrawingLayer( surface, translate, gfx::PointF(), gfx::Size(200, 200), false); TestContentLayerImpl* outside_layer = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200), false); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); - this->VisitLayer(outside_layer, &occlusion); - this->EnterLayer(layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(outside_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(layer, &occlusion)); // No occlusion, is not occluded. occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); @@ -2272,8 +2280,7 @@ class OcclusionTrackerTestUnoccludedSurfaceQuery : public OcclusionTrackerTest { void RunMyTest() override { gfx::Transform translate; translate.Translate(10.0, 20.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); LayerImpl* surface = this->CreateSurface(root, translate, gfx::PointF(), gfx::Size(200, 200)); LayerImpl* layer = @@ -2281,12 +2288,13 @@ class OcclusionTrackerTestUnoccludedSurfaceQuery : public OcclusionTrackerTest { gfx::Size(200, 200), false); TestContentLayerImpl* outside_layer = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200), false); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); - this->VisitLayer(outside_layer, &occlusion); - this->VisitLayer(layer, &occlusion); - this->EnterContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(outside_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(surface, &occlusion)); // No occlusion, is not occluded. occlusion.set_occlusion_on_contributing_surface_from_outside_target( diff --git a/chromium/cc/trees/presentation_time_callback_buffer.cc b/chromium/cc/trees/presentation_time_callback_buffer.cc index 5274d5bdf1c..636f36ac351 100644 --- a/chromium/cc/trees/presentation_time_callback_buffer.cc +++ b/chromium/cc/trees/presentation_time_callback_buffer.cc @@ -49,6 +49,18 @@ void PresentationTimeCallbackBuffer::RegisterMainThreadPresentationCallbacks( DCHECK_LE(frame_token_infos_.size(), 25u); } +void PresentationTimeCallbackBuffer::RegisterCompositorPresentationCallbacks( + uint32_t frame_token, + std::vector<CallbackType> callbacks) { + // Splice the given |callbacks| onto the vector of existing callbacks. + std::vector<LayerTreeHost::PresentationTimeCallback>& sink = + GetOrMakeRegistration(frame_token).compositor_thread_callbacks; + sink.reserve(sink.size() + callbacks.size()); + std::move(callbacks.begin(), callbacks.end(), std::back_inserter(sink)); + + DCHECK_LE(frame_token_infos_.size(), 25u); +} + void PresentationTimeCallbackBuffer::RegisterFrameTime( uint32_t frame_token, base::TimeTicks frame_time) { @@ -93,6 +105,12 @@ PresentationTimeCallbackBuffer::PopPendingCallbacks(uint32_t frame_token) { info->main_thread_callbacks.end(), std::back_inserter(result.main_thread_callbacks)); + // Collect the compositor-thread callbacks. It's the caller's job to run + // them on the compositor thread. + std::move(info->compositor_thread_callbacks.begin(), + info->compositor_thread_callbacks.end(), + std::back_inserter(result.compositor_thread_callbacks)); + frame_token_infos_.erase(info); } diff --git a/chromium/cc/trees/presentation_time_callback_buffer.h b/chromium/cc/trees/presentation_time_callback_buffer.h index cdebf905c36..d5ccdc5e2fb 100644 --- a/chromium/cc/trees/presentation_time_callback_buffer.h +++ b/chromium/cc/trees/presentation_time_callback_buffer.h @@ -15,16 +15,19 @@ namespace cc { // Maintains a queue of callbacks and compositor frame times that we want to // buffer until a relevant frame is presented. // -// Callbacks are queued through |RegisterMainThreadPresentationCallbacks|. +// Callbacks are queued through |RegisterMainThreadPresentationCallbacks| and +// |RegisterCompositorPresentationCallbacks| if the callback is to be run on +// the main thread or compositor thread respectively. // // Once a frame is presented, users of this class can call // |PopPendingCallbacks| to get their callbacks back. This class never runs -// callbacks itself so it's up to calling code to |PostTask| as needed. +// callbacks itself so it's up to calling code to |PostTask| or call |Run()| as +// needed. // // This class is thread unsafe so concurrent access would require external // synchronization. In practice, however, instances of this class are only used -// on the compositor thread even though the buffered callbacks are intended to -// be run on the renderer main thread. +// on the compositor thread even though some of the buffered callbacks are +// intended to be run on the renderer main thread. // // CC_EXPORT is only needed for testing. class CC_EXPORT PresentationTimeCallbackBuffer { @@ -50,6 +53,13 @@ class CC_EXPORT PresentationTimeCallbackBuffer { uint32_t frame_token, std::vector<CallbackType> callbacks); + // Buffers the given |callbacks| in preparation for a GPU frame swap at or + // after the given |frame_token|. Calling code invokes these callbacks on the + // compositor thread once they're popped. + void RegisterCompositorPresentationCallbacks( + uint32_t frame_token, + std::vector<CallbackType> callbacks); + // The given |frame_time| is associated with the given |frame_token| and will // be exposed through |PopPendingCallbacks| if there is an exact frame token // match. Note that it is an error to register distinct |frame_time|s against @@ -73,6 +83,10 @@ class CC_EXPORT PresentationTimeCallbackBuffer { // |RegisterMainThreadPresentationCallbacks|. std::vector<CallbackType> main_thread_callbacks; + // Holds callbacks registered through + // |RegisterCompositorPresentationCallbacks|. + std::vector<CallbackType> compositor_thread_callbacks; + // Note: calling code needs to test against frame_time.is_null() because // frame_time is not always defined. See |PopPendingCallbacks|. base::TimeTicks frame_time; @@ -111,6 +125,9 @@ class CC_EXPORT PresentationTimeCallbackBuffer { // The callbacks to send back to the main thread. std::vector<CallbackType> main_thread_callbacks; + + // The callbacks to invoke on the compositor thread. + std::vector<CallbackType> compositor_thread_callbacks; }; // Returns a reference to a |FrameTokenInfo| with the given |frame_token|. diff --git a/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc b/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc index 2d6b36f1f54..f080d6d4a11 100644 --- a/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc +++ b/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc @@ -43,6 +43,7 @@ TEST(PresentationTimeCallbackBufferTest, TestNoCallbacks) { auto result = buffer.PopPendingCallbacks(kFrameToken1); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } @@ -57,12 +58,14 @@ TEST(PresentationTimeCallbackBufferTest, TestOneMainThreadCallback) { { auto result = buffer.PopPendingCallbacks(kFrameToken1); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } { auto result = buffer.PopPendingCallbacks(kFrameToken2); EXPECT_EQ(result.main_thread_callbacks.size(), 1ull); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } @@ -70,6 +73,38 @@ TEST(PresentationTimeCallbackBufferTest, TestOneMainThreadCallback) { { auto result = buffer.PopPendingCallbacks(kFrameToken2); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); + EXPECT_TRUE(result.frame_time.is_null()); + } +} + +TEST(PresentationTimeCallbackBufferTest, TestOneCompositorThreadCallback) { + PresentationTimeCallbackBuffer buffer; + + buffer.RegisterCompositorPresentationCallbacks(kFrameToken2, + GenerateCallbacks(1)); + + // Make sure that popping early frame tokens doesn't return irrelevant + // entries. + { + auto result = buffer.PopPendingCallbacks(kFrameToken1); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); + EXPECT_TRUE(result.frame_time.is_null()); + } + + { + auto result = buffer.PopPendingCallbacks(kFrameToken2); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_EQ(result.compositor_thread_callbacks.size(), 1ull); + EXPECT_TRUE(result.frame_time.is_null()); + } + + // Make sure that the buffer has removed the registration since the "pop". + { + auto result = buffer.PopPendingCallbacks(kFrameToken2); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } } @@ -85,12 +120,14 @@ TEST(PresentationTimeCallbackBufferTest, TestFrameTimeRegistration) { { auto result = buffer.PopPendingCallbacks(kFrameToken1); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } { auto result = buffer.PopPendingCallbacks(kFrameToken2); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_FALSE(result.frame_time.is_null()); EXPECT_EQ(result.frame_time, frame_time); } @@ -99,6 +136,43 @@ TEST(PresentationTimeCallbackBufferTest, TestFrameTimeRegistration) { { auto result = buffer.PopPendingCallbacks(kFrameToken2); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); + EXPECT_TRUE(result.frame_time.is_null()); + } +} + +TEST(PresentationTimeCallbackBufferTest, TestMixedCallbacks) { + PresentationTimeCallbackBuffer buffer; + + base::TimeTicks frame_time = MakeTicks(123); + buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2, + GenerateCallbacks(1)); + buffer.RegisterCompositorPresentationCallbacks(kFrameToken2, + GenerateCallbacks(1)); + buffer.RegisterFrameTime(kFrameToken2, frame_time); + + // Make sure that popping early frame tokens doesn't return irrelevant + // entries. + { + auto result = buffer.PopPendingCallbacks(kFrameToken1); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); + EXPECT_TRUE(result.frame_time.is_null()); + } + + { + auto result = buffer.PopPendingCallbacks(kFrameToken2); + EXPECT_EQ(result.main_thread_callbacks.size(), 1ull); + EXPECT_EQ(result.compositor_thread_callbacks.size(), 1ull); + EXPECT_FALSE(result.frame_time.is_null()); + EXPECT_EQ(result.frame_time, frame_time); + } + + // Make sure that the buffer has removed the registrations since the "pop". + { + auto result = buffer.PopPendingCallbacks(kFrameToken2); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } } @@ -127,6 +201,7 @@ TEST(PresentationTimeCallbackBufferTest, TestCallbackBatchingNoFrameTime) { { auto result = buffer.PopPendingCallbacks(kFrameToken3); EXPECT_EQ(result.main_thread_callbacks.size(), 3ull); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } } @@ -151,6 +226,7 @@ TEST(PresentationTimeCallbackBufferTest, TestCallbackBatchingWithFrameTime) { { auto result = buffer.PopPendingCallbacks(kFrameToken3); EXPECT_EQ(result.main_thread_callbacks.size(), 3ull); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_FALSE(result.frame_time.is_null()); EXPECT_EQ(result.frame_time, frame_time3); } diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc index f826436980d..6b306c718bd 100644 --- a/chromium/cc/trees/property_tree.cc +++ b/chromium/cc/trees/property_tree.cc @@ -12,12 +12,11 @@ #include "base/memory/ptr_util.h" #include "base/numerics/checked_math.h" #include "base/trace_event/traced_value.h" -#include "cc/layers/layer_impl.h" #include "cc/trees/clip_node.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/property_tree.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" #include "components/viz/common/frame_sinks/copy_output_request.h" @@ -132,47 +131,6 @@ void TransformTree::set_needs_update(bool needs_update) { PropertyTree<TransformNode>::set_needs_update(needs_update); } -bool TransformTree::ComputeTranslation(int source_id, - int dest_id, - gfx::Transform* transform) const { - transform->MakeIdentity(); - if (source_id == dest_id) - return true; - - const TransformNode* dest = Node(dest_id); - if (!dest->ancestors_are_invertible) - return false; - if (source_id != kInvalidNodeId) - transform->ConcatTransform(ToScreen(source_id)); - if (dest_id != kInvalidNodeId) { - if (dest->local.IsFlat() && (dest->node_and_ancestors_are_flat || - dest->flattens_inherited_transform)) { - // In this case, flattenning will not affect the result, so we can use the - // FromScreen transform of the dest node. - transform->ConcatTransform(FromScreen(dest_id)); - } else { - // In this case, some node between source and destination flattens - // inherited transform. Consider the tree R->A->B->C->D, where D is the - // source, A is the destination and C flattens inherited transform. The - // expected result is D * C * flattened(B). D's ToScreen will be D * C * - // flattened(B * A * R), but as the source to destination transform is - // at most translation, C and B cannot be non-flat and so flattened(B * A - // * R) = B * flattened(A * R). So, to get the expected result we have to - // multiply D's ToScreen transform with flattened(A * R)^{-1}, which is - // the inverse of flattened ToScreen of destination. - gfx::Transform to_screen = ToScreen(dest_id); - to_screen.FlattenTo2d(); - gfx::Transform from_screen; - bool success = to_screen.GetInverse(&from_screen); - if (!success) - return false; - transform->ConcatTransform(from_screen); - } - } - - return true; -} - TransformNode* TransformTree::FindNodeFromElementId(ElementId id) { auto iterator = property_trees()->element_id_to_transform_node_index.find(id); if (iterator == property_trees()->element_id_to_transform_node_index.end()) @@ -708,7 +666,6 @@ int EffectTree::Insert(const EffectNode& tree_node, int parent_id) { void EffectTree::clear() { PropertyTree<EffectNode>::clear(); - mask_layer_ids_.clear(); render_surfaces_.clear(); render_surfaces_.push_back(nullptr); @@ -1024,10 +981,6 @@ int EffectTree::LowestCommonAncestorWithRenderSurface(int id_1, return id_1; } -void EffectTree::AddMaskLayerId(int id) { - mask_layer_ids_.push_back(id); -} - bool EffectTree::ContributesToDrawnSurface(int id) { // All drawn nodes contribute to drawn surface. // Exception : Nodes that are hidden and are drawn only for the sake of @@ -1138,7 +1091,7 @@ bool EffectTree::HitTestMayBeAffectedByMask(int effect_id) const { for (; effect_node->id != kContentsRootNodeId; effect_node = Node(effect_node->parent_id)) { if (!effect_node->rounded_corner_bounds.IsEmpty() || - effect_node->has_masking_child || effect_node->is_masked) + effect_node->has_masking_child) return true; } return false; @@ -1176,7 +1129,6 @@ bool ClipTree::operator==(const ClipTree& other) const { EffectTree& EffectTree::operator=(const EffectTree& from) { PropertyTree::operator=(from); render_surfaces_.resize(size()); - mask_layer_ids_ = from.mask_layer_ids_; // copy_requests_ are omitted here, since these need to be moved rather // than copied or assigned. @@ -1184,8 +1136,7 @@ EffectTree& EffectTree::operator=(const EffectTree& from) { } bool EffectTree::operator==(const EffectTree& other) const { - return PropertyTree::operator==(other) && - mask_layer_ids_ == other.mask_layer_ids_; + return PropertyTree::operator==(other); } ScrollTree::ScrollTree() @@ -1478,10 +1429,7 @@ void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info, scroll_info->inner_viewport_scroll.element_id = id; scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta; } else { - LayerTreeHostCommon::ScrollUpdateInfo scroll; - scroll.element_id = id; - scroll.scroll_delta = scroll_delta; - scroll_info->scrolls.push_back(scroll); + scroll_info->scrolls.push_back({id, scroll_delta}); } } } @@ -1735,8 +1683,6 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) { from.inner_viewport_container_bounds_delta(); outer_viewport_container_bounds_delta_ = from.outer_viewport_container_bounds_delta(); - inner_viewport_scroll_bounds_delta_ = - from.inner_viewport_scroll_bounds_delta(); transform_tree.SetPropertyTrees(this); effect_tree.SetPropertyTrees(this); clip_tree.SetPropertyTrees(this); @@ -1910,11 +1856,6 @@ void PropertyTrees::AnimationScalesChanged(ElementId element_id, } } -void PropertyTrees::SetInnerViewportScrollBoundsDelta( - gfx::Vector2dF bounds_delta) { - inner_viewport_scroll_bounds_delta_ = bounds_delta; -} - void PropertyTrees::UpdateChangeTracking() { for (int id = EffectTree::kContentsRootNodeId; id < static_cast<int>(effect_tree.size()); ++id) { diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h index 214b9fca971..8370ad169cf 100644 --- a/chromium/cc/trees/property_tree.h +++ b/chromium/cc/trees/property_tree.h @@ -137,16 +137,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { TransformNode* FindNodeFromElementId(ElementId id); bool OnTransformAnimated(ElementId element_id, const gfx::Transform& transform); - // Computes the change of basis transform from node |source_id| to |dest_id|. - // This is used by scroll children to compute transform from their scroll - // parent space (source) to their parent space (destination) and it can atmost - // be a translation. This function assumes that the path from source to - // destination has only translations. So, it should not be called when there - // can be intermediate 3d transforms but the end result is a translation. - bool ComputeTranslation(int source_id, - int dest_id, - gfx::Transform* transform) const; - void ResetChangeTracking(); // Updates the parent, target, and screen space transforms and snapping. void UpdateTransforms(int id); @@ -325,9 +315,6 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { // surface. int LowestCommonAncestorWithRenderSurface(int id_1, int id_2) const; - void AddMaskLayerId(int id); - const std::vector<int>& mask_layer_ids() const { return mask_layer_ids_; } - RenderSurfaceImpl* GetRenderSurface(int id) { return render_surfaces_[id].get(); } @@ -371,9 +358,6 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { std::unordered_multimap<int, std::unique_ptr<viz::CopyOutputRequest>> copy_requests_; - // Unsorted list of all mask layer ids that effect nodes refer to. - std::vector<int> mask_layer_ids_; - // Indexed by node id. std::vector<std::unique_ptr<RenderSurfaceImpl>> render_surfaces_; }; @@ -644,7 +628,6 @@ class CC_EXPORT PropertyTrees final { float starting_scale); void SetInnerViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); void SetOuterViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); - void SetInnerViewportScrollBoundsDelta(gfx::Vector2dF bounds_delta); void UpdateChangeTracking(); void PushChangeTrackingTo(PropertyTrees* tree); void ResetAllChangeTracking(); @@ -652,13 +635,13 @@ class CC_EXPORT PropertyTrees final { gfx::Vector2dF inner_viewport_container_bounds_delta() const { return inner_viewport_container_bounds_delta_; } - - gfx::Vector2dF outer_viewport_container_bounds_delta() const { + gfx::Vector2dF inner_viewport_scroll_bounds_delta() const { + // Inner viewport scroll bounds are always the same as outer viewport + // container bounds. return outer_viewport_container_bounds_delta_; } - - gfx::Vector2dF inner_viewport_scroll_bounds_delta() const { - return inner_viewport_scroll_bounds_delta_; + gfx::Vector2dF outer_viewport_container_bounds_delta() const { + return outer_viewport_container_bounds_delta_; } std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const; @@ -690,7 +673,6 @@ class CC_EXPORT PropertyTrees final { private: gfx::Vector2dF inner_viewport_container_bounds_delta_; gfx::Vector2dF outer_viewport_container_bounds_delta_; - gfx::Vector2dF inner_viewport_scroll_bounds_delta_; // GetDrawTransforms may change the value of cached_data_. DrawTransforms& GetDrawTransforms(int transform_id, int effect_id) const; diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc index e962ff9a63c..0f04b6a6660 100644 --- a/chromium/cc/trees/property_tree_builder.cc +++ b/chromium/cc/trees/property_tree_builder.cc @@ -17,7 +17,7 @@ #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_impl.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "cc/trees/mutator_host.h" #include "cc/trees/scroll_node.h" @@ -37,71 +37,48 @@ struct DataForRecursion { int scroll_tree_parent; int closest_ancestor_with_cached_render_surface; int closest_ancestor_with_copy_request; - uint32_t main_thread_scrolling_reasons; SkColor safe_opaque_background_color; - bool in_subtree_of_page_scale_layer; - bool affected_by_outer_viewport_bounds_delta; - bool should_flatten; - bool scroll_tree_parent_created_by_uninheritable_criteria; bool animation_axis_aligned_since_render_target; bool not_axis_aligned_since_last_clip; gfx::Transform compound_transform_since_render_target; bool* subtree_has_rounded_corner; }; -template <typename LayerType> class PropertyTreeBuilderContext { public: - PropertyTreeBuilderContext(LayerType* root_layer, - const LayerType* page_scale_layer, - const LayerType* inner_viewport_scroll_layer, - const LayerType* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - const gfx::Transform& device_transform, - MutatorHost* mutator_host, - PropertyTrees* property_trees) - : root_layer_(root_layer), - page_scale_layer_(page_scale_layer), - inner_viewport_scroll_layer_(inner_viewport_scroll_layer), - outer_viewport_scroll_layer_(outer_viewport_scroll_layer), - overscroll_elasticity_element_id_(overscroll_elasticity_element_id), - elastic_overscroll_(elastic_overscroll), - page_scale_factor_(page_scale_factor), - device_transform_(device_transform), - mutator_host_(*mutator_host), - property_trees_(*property_trees), - transform_tree_(property_trees->transform_tree), - clip_tree_(property_trees->clip_tree), - effect_tree_(property_trees->effect_tree), - scroll_tree_(property_trees->scroll_tree) {} - - void BuildPropertyTrees(float device_scale_factor, - const gfx::Rect& viewport, - SkColor root_background_color) const; + explicit PropertyTreeBuilderContext(LayerTreeHost* layer_tree_host) + : layer_tree_host_(layer_tree_host), + root_layer_(layer_tree_host->root_layer()), + mutator_host_(*layer_tree_host->mutator_host()), + property_trees_(*layer_tree_host->property_trees()), + transform_tree_(property_trees_.transform_tree), + clip_tree_(property_trees_.clip_tree), + effect_tree_(property_trees_.effect_tree), + scroll_tree_(property_trees_.scroll_tree) {} + + void BuildPropertyTrees(); private: void BuildPropertyTreesInternal( - LayerType* layer, + Layer* layer, const DataForRecursion& data_from_parent) const; bool AddTransformNodeIfNeeded(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, bool created_render_surface, DataForRecursion* data_for_children) const; void AddClipNodeIfNeeded(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, bool created_transform_node, DataForRecursion* data_for_children) const; bool AddEffectNodeIfNeeded(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) const; void AddScrollNodeIfNeeded(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) const; bool UpdateRenderSurfaceIfNeeded(int parent_effect_tree_id, @@ -109,14 +86,8 @@ class PropertyTreeBuilderContext { bool subtree_has_rounded_corner, bool created_transform_node) const; - LayerType* root_layer_; - const LayerType* page_scale_layer_; - const LayerType* inner_viewport_scroll_layer_; - const LayerType* outer_viewport_scroll_layer_; - const ElementId overscroll_elasticity_element_id_; - const gfx::Vector2dF elastic_overscroll_; - float page_scale_factor_; - const gfx::Transform& device_transform_; + LayerTreeHost* layer_tree_host_; + Layer* root_layer_; MutatorHost& mutator_host_; PropertyTrees& property_trees_; TransformTree& transform_tree_; @@ -125,121 +96,47 @@ class PropertyTreeBuilderContext { ScrollTree& scroll_tree_; }; -static LayerImplList& LayerChildren(LayerImpl* layer) { - return layer->test_properties()->children; -} - -static const LayerList& LayerChildren(Layer* layer) { - return layer->children(); -} - -static LayerImpl* LayerChildAt(LayerImpl* layer, int index) { - return layer->test_properties()->children[index]; -} - -static Layer* LayerChildAt(Layer* layer, int index) { - return layer->children()[index].get(); -} - -static bool HasClipRect(Layer* layer) { - return !layer->clip_rect().IsEmpty(); -} - -static bool HasClipRect(LayerImpl* layer) { - return false; -} - -static inline const FilterOperations& Filters(Layer* layer) { - return layer->filters(); -} - -static inline const FilterOperations& Filters(LayerImpl* layer) { - return layer->test_properties()->filters; -} - -static bool IsFastRoundedCorner(Layer* layer) { - return layer->is_fast_rounded_corner(); -} - -static bool IsFastRoundedCorner(LayerImpl* layer) { - return false; -} - -static bool HasRoundedCorner(Layer* layer) { - return layer->HasRoundedCorner(); -} - -static bool HasRoundedCorner(LayerImpl* layer) { - return !layer->test_properties()->rounded_corner_bounds.IsEmpty(); -} - -static PictureLayer* MaskLayer(Layer* layer) { - return layer->mask_layer(); -} - -static LayerImpl* MaskLayer(LayerImpl* layer) { - return layer->test_properties()->mask_layer; -} - -static const gfx::Transform& Transform(Layer* layer) { - return layer->transform(); -} - -static const gfx::Transform& Transform(LayerImpl* layer) { - return layer->test_properties()->transform; -} - -static const gfx::PointF& Position(Layer* layer) { - return layer->position(); -} - -static const gfx::PointF& Position(LayerImpl* layer) { - return layer->test_properties()->position; -} - // Methods to query state from the AnimationHost ---------------------- -template <typename LayerType> -bool OpacityIsAnimating(const MutatorHost& host, LayerType* layer) { +bool OpacityIsAnimating(const MutatorHost& host, Layer* layer) { return host.IsAnimatingOpacityProperty(layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> bool HasPotentiallyRunningOpacityAnimation(const MutatorHost& host, - LayerType* layer) { + Layer* layer) { return host.HasPotentiallyRunningOpacityAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> -bool FilterIsAnimating(const MutatorHost& host, LayerType* layer) { +bool HasPotentialOpacityAnimation(const MutatorHost& host, Layer* layer) { + return HasPotentiallyRunningOpacityAnimation(host, layer) || + layer->OpacityCanAnimateOnImplThread(); +} + +bool FilterIsAnimating(const MutatorHost& host, Layer* layer) { return host.IsAnimatingFilterProperty(layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> bool HasPotentiallyRunningFilterAnimation(const MutatorHost& host, - LayerType* layer) { + Layer* layer) { return host.HasPotentiallyRunningFilterAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> -bool TransformIsAnimating(const MutatorHost& host, LayerType* layer) { +bool TransformIsAnimating(const MutatorHost& host, Layer* layer) { return host.IsAnimatingTransformProperty(layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> bool HasPotentiallyRunningTransformAnimation(const MutatorHost& host, - LayerType* layer) { + Layer* layer) { return host.HasPotentiallyRunningTransformAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> void GetAnimationScales(const MutatorHost& host, - LayerType* layer, + Layer* layer, float* maximum_scale, float* starting_scale) { return host.GetAnimationScales(layer->element_id(), @@ -247,94 +144,46 @@ void GetAnimationScales(const MutatorHost& host, maximum_scale, starting_scale); } -template <typename LayerType> -bool AnimationsPreserveAxisAlignment(const MutatorHost& host, - LayerType* layer) { +bool AnimationsPreserveAxisAlignment(const MutatorHost& host, Layer* layer) { return host.AnimationsPreserveAxisAlignment(layer->element_id()); } -template <typename LayerType> bool HasAnyAnimationTargetingProperty(const MutatorHost& host, - LayerType* layer, + Layer* layer, TargetProperty::Type property) { return host.HasAnyAnimationTargetingProperty(layer->element_id(), property); } // ------------------------------------------------------------------- -template <typename LayerType> -static bool LayerClipsSubtreeToItsBounds(LayerType* layer) { - return layer->masks_to_bounds() || MaskLayer(layer); -} - -template <typename LayerType> -static bool LayerClipsSubtree(LayerType* layer) { - return LayerClipsSubtreeToItsBounds(layer) || HasRoundedCorner(layer) || - HasClipRect(layer); -} - -gfx::RectF EffectiveClipRect(Layer* layer) { - return layer->EffectiveClipRect(); -} - -gfx::RectF EffectiveClipRect(LayerImpl* layer) { - return gfx::RectF(gfx::PointF(), gfx::SizeF(layer->bounds())); -} - -static gfx::RRectF RoundedCornerBounds(Layer* layer) { - return gfx::RRectF(EffectiveClipRect(layer), layer->corner_radii()); -} - -static gfx::RRectF RoundedCornerBounds(LayerImpl* layer) { - return layer->test_properties()->rounded_corner_bounds; -} - -static Layer* LayerParent(Layer* layer) { - return layer->parent(); -} - -static LayerImpl* LayerParent(LayerImpl* layer) { - return layer->test_properties()->parent; -} - -static inline int SortingContextId(Layer* layer) { - return layer->sorting_context_id(); -} - -static inline int SortingContextId(LayerImpl* layer) { - return layer->test_properties()->sorting_context_id; +bool LayerClipsSubtreeToItsBounds(Layer* layer) { + return layer->masks_to_bounds() || layer->IsMaskedByChild(); } -static inline bool Is3dSorted(Layer* layer) { - return layer->sorting_context_id() != 0; +bool LayerClipsSubtree(Layer* layer) { + return LayerClipsSubtreeToItsBounds(layer) || layer->HasRoundedCorner() || + !layer->clip_rect().IsEmpty(); } -static inline bool Is3dSorted(LayerImpl* layer) { - return layer->test_properties()->sorting_context_id != 0; +gfx::RRectF RoundedCornerBounds(Layer* layer) { + return gfx::RRectF(layer->EffectiveClipRect(), layer->corner_radii()); } -static inline void SetHasClipNode(Layer* layer, bool val) { - layer->SetHasClipNode(val); -} - -static inline void SetHasClipNode(LayerImpl* layer, bool val) {} - -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded( +void PropertyTreeBuilderContext::AddClipNodeIfNeeded( const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, bool created_transform_node, DataForRecursion* data_for_children) const { const int parent_id = data_from_ancestor.clip_tree_parent; bool layer_clips_subtree = LayerClipsSubtree(layer); bool requires_node = - layer_clips_subtree || Filters(layer).HasFilterThatMovesPixels(); + layer_clips_subtree || layer->filters().HasFilterThatMovesPixels(); if (!requires_node) { data_for_children->clip_tree_parent = parent_id; } else { ClipNode node; - node.clip = EffectiveClipRect(layer); + node.clip = layer->EffectiveClipRect(); // Move the clip bounds so that it is relative to the transform parent. node.clip += layer->offset_to_transform_parent(); @@ -345,51 +194,23 @@ void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded( if (layer_clips_subtree) { node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; } else { - DCHECK(Filters(layer).HasFilterThatMovesPixels()); + DCHECK(layer->filters().HasFilterThatMovesPixels()); node.clip_type = ClipNode::ClipType::EXPANDS_CLIP; node.clip_expander = ClipExpander(layer->effect_tree_index()); } data_for_children->clip_tree_parent = clip_tree_.Insert(node, parent_id); } - SetHasClipNode(layer, requires_node); + layer->SetHasClipNode(requires_node); layer->SetClipTreeIndex(data_for_children->clip_tree_parent); } -template <typename LayerType> -static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { - return LayerParent(layer) - ? SortingContextId(LayerParent(layer)) != SortingContextId(layer) - : Is3dSorted(layer); -} - -static inline gfx::Point3F TransformOrigin(Layer* layer) { - return layer->transform_origin(); -} - -static inline gfx::Point3F TransformOrigin(LayerImpl* layer) { - return layer->test_properties()->transform_origin; -} - -static inline bool ShouldFlattenTransform(Layer* layer) { - return layer->should_flatten_transform(); -} - -static inline bool ShouldFlattenTransform(LayerImpl* layer) { - return layer->test_properties()->should_flatten_transform; -} - -template <typename LayerType> -bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( +bool PropertyTreeBuilderContext::AddTransformNodeIfNeeded( const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, bool created_render_surface, DataForRecursion* data_for_children) const { - const bool is_root = !LayerParent(layer); - const bool is_page_scale_layer = layer == page_scale_layer_; - const bool is_overscroll_elasticity_layer = - overscroll_elasticity_element_id_ && - layer->element_id() == overscroll_elasticity_element_id_; + const bool is_root = !layer->parent(); const bool is_scrollable = layer->scrollable(); // Scrolling a layer should not move it from being pixel-aligned to moving off // the pixel grid and becoming fuzzy. So always snap scrollable things to the @@ -398,7 +219,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( is_scrollable || layer->IsSnappedToPixelGridInTarget(); const bool has_significant_transform = - !Transform(layer).IsIdentityOr2DTranslation(); + !layer->transform().IsIdentityOr2DTranslation(); const bool has_potentially_animated_transform = HasPotentiallyRunningTransformAnimation(mutator_host_, layer); @@ -412,15 +233,10 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( const bool has_surface = created_render_surface; - const bool is_at_boundary_of_3d_rendering_context = - IsAtBoundaryOf3dRenderingContext(layer); - DCHECK(!is_scrollable || is_snapped); bool requires_node = is_root || is_snapped || has_significant_transform || has_any_transform_animation || has_surface || - is_page_scale_layer || is_overscroll_elasticity_layer || - is_at_boundary_of_3d_rendering_context || - HasRoundedCorner(layer); + layer->HasRoundedCorner(); int parent_index = TransformTree::kRootNodeId; gfx::Vector2dF parent_offset; @@ -428,17 +244,14 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( parent_index = data_from_ancestor.transform_tree_parent; // Now layer tree mode (IsUsingLayerLists is false) is for ui compositor // only. The transform tree hierarchy is always the same as layer hierarchy. - DCHECK_EQ(parent_index, LayerParent(layer)->transform_tree_index()); - parent_offset = LayerParent(layer)->offset_to_transform_parent(); + DCHECK_EQ(parent_index, layer->parent()->transform_tree_index()); + parent_offset = layer->parent()->offset_to_transform_parent(); } if (!requires_node) { - data_for_children->should_flatten |= ShouldFlattenTransform(layer); - gfx::Vector2dF local_offset = - Position(layer).OffsetFromOrigin() + Transform(layer).To2dTranslation(); + gfx::Vector2dF local_offset = layer->position().OffsetFromOrigin() + + layer->transform().To2dTranslation(); layer->SetOffsetToTransformParent(parent_offset + local_offset); - layer->SetShouldFlattenScreenSpaceTransformFromPropertyTree( - data_from_ancestor.should_flatten); layer->SetTransformTreeIndex(parent_index); return false; } @@ -458,272 +271,60 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( node->scrolls = is_scrollable; node->should_be_snapped = is_snapped; - node->flattens_inherited_transform = data_for_children->should_flatten; - node->sorting_context_id = SortingContextId(layer); - if (is_root || is_page_scale_layer) { + if (is_root) { // Root layer and page scale layer should not have transform or offset. - DCHECK(Position(layer).IsOrigin()); + DCHECK(layer->position().IsOrigin()); DCHECK(parent_offset.IsZero()); - DCHECK(Transform(layer).IsIdentity()); + DCHECK(layer->transform().IsIdentity()); - if (is_root) { - DCHECK(!is_page_scale_layer); - transform_tree_.SetRootScaleAndTransform( - transform_tree_.device_scale_factor(), device_transform_); - } else { - DCHECK(is_page_scale_layer); - transform_tree_.set_page_scale_factor(page_scale_factor_); - node->local.Scale(page_scale_factor_, page_scale_factor_); - data_for_children->in_subtree_of_page_scale_layer = true; - } + transform_tree_.SetRootScaleAndTransform( + transform_tree_.device_scale_factor(), gfx::Transform()); } else { - node->local = Transform(layer); - node->origin = TransformOrigin(layer); - node->post_translation = parent_offset + Position(layer).OffsetFromOrigin(); + node->local = layer->transform(); + node->origin = layer->transform_origin(); + node->post_translation = + parent_offset + layer->position().OffsetFromOrigin(); } - node->in_subtree_of_page_scale_layer = - data_for_children->in_subtree_of_page_scale_layer; - - // Surfaces inherently flatten transforms. - data_for_children->should_flatten = - ShouldFlattenTransform(layer) || has_surface; - node->has_potential_animation = has_potentially_animated_transform; node->is_currently_animating = TransformIsAnimating(mutator_host_, layer); GetAnimationScales(mutator_host_, layer, &node->maximum_animation_scale, &node->starting_animation_scale); - if (is_overscroll_elasticity_layer) { - DCHECK(!is_scrollable); - node->scroll_offset = gfx::ScrollOffset(elastic_overscroll_); - } else { - node->scroll_offset = layer->CurrentScrollOffset(); - } + node->scroll_offset = layer->CurrentScrollOffset(); node->needs_local_transform_update = true; transform_tree_.UpdateTransforms(node->id); layer->SetOffsetToTransformParent(gfx::Vector2dF()); - // Flattening (if needed) will be handled by |node|. - layer->SetShouldFlattenScreenSpaceTransformFromPropertyTree(false); - return true; } -static inline bool HasPotentialOpacityAnimation(const MutatorHost& host, - Layer* layer) { - return HasPotentiallyRunningOpacityAnimation(host, layer) || - layer->OpacityCanAnimateOnImplThread(); -} - -static inline bool HasPotentialOpacityAnimation(const MutatorHost& host, - LayerImpl* layer) { - return HasPotentiallyRunningOpacityAnimation(host, layer) || - layer->test_properties()->opacity_can_animate; -} - -static inline bool DoubleSided(Layer* layer) { - return layer->double_sided(); -} - -static inline bool DoubleSided(LayerImpl* layer) { - return layer->test_properties()->double_sided; -} - -static inline bool TrilinearFiltering(Layer* layer) { - return layer->trilinear_filtering(); -} - -static inline bool TrilinearFiltering(LayerImpl* layer) { - return layer->test_properties()->trilinear_filtering; -} - -static inline bool CacheRenderSurface(Layer* layer) { - return layer->cache_render_surface(); -} - -static inline bool CacheRenderSurface(LayerImpl* layer) { - return layer->test_properties()->cache_render_surface; -} - -static inline bool ForceRenderSurfaceForTesting(Layer* layer) { - return layer->force_render_surface_for_testing(); -} - -static inline bool ForceRenderSurfaceForTesting(LayerImpl* layer) { - return layer->test_properties()->force_render_surface; -} - -template <typename LayerType> -static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) { - return Is3dSorted(layer) && LayerParent(layer) && - Is3dSorted(LayerParent(layer)) && - (SortingContextId(LayerParent(layer)) == SortingContextId(layer)); -} - -static inline bool IsRootForIsolatedGroup(Layer* layer) { - return layer->is_root_for_isolated_group(); -} - -static inline bool IsRootForIsolatedGroup(LayerImpl* layer) { - return false; -} - -static inline int NumDescendantsThatDrawContent(Layer* layer) { - return layer->NumDescendantsThatDrawContent(); -} - -static inline int NumLayerOrDescendantsThatDrawContentRecursive( - LayerImpl* layer) { - int num = layer->DrawsContent() ? 1 : 0; - for (size_t i = 0; i < layer->test_properties()->children.size(); ++i) { - LayerImpl* child_layer = layer->test_properties()->children[i]; - num += NumLayerOrDescendantsThatDrawContentRecursive(child_layer); - } - return num; -} - -static inline int NumDescendantsThatDrawContent(LayerImpl* layer) { - int num_descendants_that_draw_content = 0; - for (size_t i = 0; i < layer->test_properties()->children.size(); ++i) { - LayerImpl* child_layer = layer->test_properties()->children[i]; - num_descendants_that_draw_content += - NumLayerOrDescendantsThatDrawContentRecursive(child_layer); - } - return num_descendants_that_draw_content; -} - -static inline float EffectiveOpacity(Layer* layer) { - return layer->EffectiveOpacity(); -} - -static inline float EffectiveOpacity(LayerImpl* layer) { - return layer->test_properties()->hide_layer_and_subtree - ? 0.f - : layer->test_properties()->opacity; -} - -static inline float Opacity(Layer* layer) { - return layer->opacity(); -} - -static inline float Opacity(LayerImpl* layer) { - return layer->test_properties()->opacity; -} - -static inline SkBlendMode BlendMode(Layer* layer) { - return layer->blend_mode(); -} - -static inline SkBlendMode BlendMode(LayerImpl* layer) { - return layer->test_properties()->blend_mode; -} - -static inline const gfx::PointF FiltersOrigin(Layer* layer) { - return layer->filters_origin(); -} - -static inline const gfx::PointF FiltersOrigin(LayerImpl* layer) { - return layer->test_properties()->filters_origin; -} - -static inline const FilterOperations& BackdropFilters(Layer* layer) { - return layer->backdrop_filters(); -} - -static inline const FilterOperations& BackdropFilters(LayerImpl* layer) { - return layer->test_properties()->backdrop_filters; -} - -static inline const base::Optional<gfx::RRectF>& BackdropFilterBounds( - Layer* layer) { - return layer->backdrop_filter_bounds(); -} - -static inline const base::Optional<gfx::RRectF>& BackdropFilterBounds( - LayerImpl* layer) { - return layer->test_properties()->backdrop_filter_bounds; -} - -static inline ElementId BackdropMaskElementId(Layer* layer) { - return layer->backdrop_mask_element_id(); -} - -static inline ElementId BackdropMaskElementId(LayerImpl* layer) { - return layer->test_properties()->backdrop_mask_element_id; -} - -static inline float BackdropFilterQuality(Layer* layer) { - return layer->backdrop_filter_quality(); -} - -static inline float BackdropFilterQuality(LayerImpl* layer) { - return layer->test_properties()->backdrop_filter_quality; -} - -static inline bool HideLayerAndSubtree(Layer* layer) { - return layer->hide_layer_and_subtree(); -} - -static inline bool HideLayerAndSubtree(LayerImpl* layer) { - return layer->test_properties()->hide_layer_and_subtree; -} - -static inline bool HasCopyRequest(Layer* layer) { - return layer->HasCopyRequest(); -} - -static inline bool HasCopyRequest(LayerImpl* layer) { - return !layer->test_properties()->copy_requests.empty(); -} - -static inline int MirrorCount(Layer* layer) { - return layer->mirror_count(); -} - -static inline int MirrorCount(LayerImpl* layer) { - return 0; -} - -static inline bool PropertyChanged(Layer* layer) { - return layer->subtree_property_changed(); -} - -static inline bool PropertyChanged(LayerImpl* layer) { - return false; -} - -template <typename LayerType> RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host, - LayerType* layer, + Layer* layer, gfx::Transform current_transform, bool animation_axis_aligned) { const bool preserves_2d_axis_alignment = current_transform.Preserves2dAxisAlignment() && animation_axis_aligned; - const bool is_root = !LayerParent(layer); + const bool is_root = !layer->parent(); if (is_root) return RenderSurfaceReason::kRoot; - // If the layer uses a mask. - if (MaskLayer(layer)) { + if (layer->IsMaskedByChild()) { return RenderSurfaceReason::kMask; } - // If the layer uses trilinear filtering. - if (TrilinearFiltering(layer)) { + if (layer->trilinear_filtering()) { return RenderSurfaceReason::kTrilinearFiltering; } - // If the layer uses a CSS filter. - if (!Filters(layer).IsEmpty()) { + if (!layer->filters().IsEmpty()) { return RenderSurfaceReason::kFilter; } - // If the layer uses a CSS backdrop-filter. - if (!BackdropFilters(layer).IsEmpty()) { + if (!layer->backdrop_filters().IsEmpty()) { return RenderSurfaceReason::kBackdropFilter; } @@ -733,16 +334,10 @@ RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host, return RenderSurfaceReason::kFilterAnimation; } - int num_descendants_that_draw_content = NumDescendantsThatDrawContent(layer); - - // If the layer flattens its subtree, but it is treated as a 3D object by its - // parent (i.e. parent participates in a 3D rendering context). - if (LayerIsInExisting3DRenderingContext(layer) && - ShouldFlattenTransform(layer) && num_descendants_that_draw_content > 0) { - return RenderSurfaceReason::k3dTransformFlattening; - } + int num_descendants_that_draw_content = + layer->NumDescendantsThatDrawContent(); - if (!IsFastRoundedCorner(layer) && HasRoundedCorner(layer) && + if (!layer->is_fast_rounded_corner() && layer->HasRoundedCorner() && num_descendants_that_draw_content > 1) { return RenderSurfaceReason::kRoundedCorner; } @@ -751,7 +346,7 @@ RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host, // TODO(rosca): this is temporary, until blending is implemented for other // types of quads than viz::RenderPassDrawQuad. Layers having descendants that // draw content will still create a separate rendering surface. - if (BlendMode(layer) != SkBlendMode::kSrcOver) { + if (layer->blend_mode() != SkBlendMode::kSrcOver) { return RenderSurfaceReason::kBlendMode; } // If the layer clips its descendants but it is not axis-aligned with respect @@ -772,94 +367,50 @@ RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host, (layer->DrawsContent() || num_descendants_that_draw_content > 1); bool may_have_transparency = - EffectiveOpacity(layer) != 1.f || + layer->EffectiveOpacity() != 1.f || HasPotentiallyRunningOpacityAnimation(mutator_host, layer); - if (may_have_transparency && ShouldFlattenTransform(layer) && - at_least_two_layers_in_subtree_draw_content) { + if (may_have_transparency && at_least_two_layers_in_subtree_draw_content) { DCHECK(!is_root); return RenderSurfaceReason::kOpacity; } - // If the layer has isolation. - // TODO(rosca): to be optimized - create separate rendering surface only when - // the blending descendants might have access to the content behind this layer - // (layer has transparent background or descendants overflow). - // https://code.google.com/p/chromium/issues/detail?id=301738 - if (IsRootForIsolatedGroup(layer)) { - return RenderSurfaceReason::kRootOrIsolatedGroup; - } // If we force it. - if (ForceRenderSurfaceForTesting(layer)) + if (layer->force_render_surface_for_testing()) return RenderSurfaceReason::kTest; // If we cache it. - if (CacheRenderSurface(layer)) + if (layer->cache_render_surface()) return RenderSurfaceReason::kCache; // If we'll make a copy of the layer's contents. - if (HasCopyRequest(layer)) + if (layer->HasCopyRequest()) return RenderSurfaceReason::kCopyRequest; // If the layer is mirrored. - if (MirrorCount(layer)) + if (layer->mirror_count()) return RenderSurfaceReason::kMirrored; return RenderSurfaceReason::kNone; } -static void TakeCopyRequests( - Layer* layer, - std::vector<std::unique_ptr<viz::CopyOutputRequest>>* copy_requests) { - layer->TakeCopyRequests(copy_requests); -} - -static void TakeCopyRequests( - LayerImpl* layer, - std::vector<std::unique_ptr<viz::CopyOutputRequest>>* copy_requests) { - for (auto& request : layer->test_properties()->copy_requests) - copy_requests->push_back(std::move(request)); - layer->test_properties()->copy_requests.clear(); -} - -static void SetSubtreeHasCopyRequest(Layer* layer, - bool subtree_has_copy_request) { - layer->SetSubtreeHasCopyRequest(subtree_has_copy_request); -} - -static void SetSubtreeHasCopyRequest(LayerImpl* layer, - bool subtree_has_copy_request) { - layer->test_properties()->subtree_has_copy_request = subtree_has_copy_request; -} - -static bool SubtreeHasCopyRequest(Layer* layer) { - return layer->SubtreeHasCopyRequest(); -} - -static bool SubtreeHasCopyRequest(LayerImpl* layer) { - return layer->test_properties()->subtree_has_copy_request; -} - -template <typename LayerType> -bool UpdateSubtreeHasCopyRequestRecursive(LayerType* layer) { +bool UpdateSubtreeHasCopyRequestRecursive(Layer* layer) { bool subtree_has_copy_request = false; - if (HasCopyRequest(layer)) + if (layer->HasCopyRequest()) subtree_has_copy_request = true; - for (size_t i = 0; i < LayerChildren(layer).size(); ++i) { - LayerType* current_child = LayerChildAt(layer, i); + for (const scoped_refptr<Layer>& child : layer->children()) { subtree_has_copy_request |= - UpdateSubtreeHasCopyRequestRecursive(current_child); + UpdateSubtreeHasCopyRequestRecursive(child.get()); } - SetSubtreeHasCopyRequest(layer, subtree_has_copy_request); + layer->SetSubtreeHasCopyRequest(subtree_has_copy_request); return subtree_has_copy_request; } -template <typename LayerType> -bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( +bool PropertyTreeBuilderContext::AddEffectNodeIfNeeded( const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) const { - const bool is_root = !LayerParent(layer); - const bool has_transparency = EffectiveOpacity(layer) != 1.f; + const bool is_root = !layer->parent(); + const bool has_transparency = layer->EffectiveOpacity() != 1.f; const bool has_potential_opacity_animation = HasPotentialOpacityAnimation(mutator_host_, layer); const bool has_potential_filter_animation = @@ -867,7 +418,8 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( data_for_children->animation_axis_aligned_since_render_target &= AnimationsPreserveAxisAlignment(mutator_host_, layer); - data_for_children->compound_transform_since_render_target *= Transform(layer); + data_for_children->compound_transform_since_render_target *= + layer->transform(); auto render_surface_reason = ComputeRenderSurfaceReason( mutator_host_, layer, data_for_children->compound_transform_since_render_target, @@ -879,7 +431,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( data_from_ancestor.not_axis_aligned_since_last_clip ? true : !AnimationsPreserveAxisAlignment(mutator_host_, layer) || - !Transform(layer).Preserves2dAxisAlignment(); + !layer->transform().Preserves2dAxisAlignment(); // A non-axis aligned clip may need a render surface. So, we create an effect // node. bool has_non_axis_aligned_clip = @@ -888,7 +440,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( bool requires_node = is_root || has_transparency || has_potential_opacity_animation || has_potential_filter_animation || has_non_axis_aligned_clip || - should_create_render_surface || HasRoundedCorner(layer); + should_create_render_surface || layer->HasRoundedCorner(); int parent_id = data_from_ancestor.effect_tree_parent; @@ -902,55 +454,47 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( EffectNode* node = effect_tree_.back(); node->stable_id = layer->id(); - node->opacity = Opacity(layer); - node->blend_mode = BlendMode(layer); - node->unscaled_mask_target_size = layer->bounds(); - node->cache_render_surface = CacheRenderSurface(layer); - node->has_copy_request = HasCopyRequest(layer); - node->filters = Filters(layer); - node->backdrop_filters = BackdropFilters(layer); - node->backdrop_filter_bounds = BackdropFilterBounds(layer); - node->backdrop_filter_quality = BackdropFilterQuality(layer); - node->backdrop_mask_element_id = BackdropMaskElementId(layer); - node->filters_origin = FiltersOrigin(layer); - node->trilinear_filtering = TrilinearFiltering(layer); + node->opacity = layer->opacity(); + node->blend_mode = layer->blend_mode(); + node->cache_render_surface = layer->cache_render_surface(); + node->has_copy_request = layer->HasCopyRequest(); + node->filters = layer->filters(); + node->backdrop_filters = layer->backdrop_filters(); + node->backdrop_filter_bounds = layer->backdrop_filter_bounds(); + node->backdrop_filter_quality = layer->backdrop_filter_quality(); + node->filters_origin = layer->filters_origin(); + node->trilinear_filtering = layer->trilinear_filtering(); node->has_potential_opacity_animation = has_potential_opacity_animation; node->has_potential_filter_animation = has_potential_filter_animation; - node->double_sided = DoubleSided(layer); - node->subtree_hidden = HideLayerAndSubtree(layer); + node->double_sided = layer->double_sided(); + node->subtree_hidden = layer->hide_layer_and_subtree(); node->is_currently_animating_opacity = OpacityIsAnimating(mutator_host_, layer); node->is_currently_animating_filter = FilterIsAnimating(mutator_host_, layer); - node->effect_changed = PropertyChanged(layer); - node->subtree_has_copy_request = SubtreeHasCopyRequest(layer); + node->effect_changed = layer->subtree_property_changed(); + node->subtree_has_copy_request = layer->SubtreeHasCopyRequest(); node->render_surface_reason = render_surface_reason; node->closest_ancestor_with_cached_render_surface_id = - CacheRenderSurface(layer) + layer->cache_render_surface() ? node_id : data_from_ancestor.closest_ancestor_with_cached_render_surface; node->closest_ancestor_with_copy_request_id = - HasCopyRequest(layer) + layer->HasCopyRequest() ? node_id : data_from_ancestor.closest_ancestor_with_copy_request; - if (MaskLayer(layer)) { - node->mask_layer_id = MaskLayer(layer)->id(); - effect_tree_.AddMaskLayerId(node->mask_layer_id); - node->is_masked = true; - } - - if (HasRoundedCorner(layer)) { + if (layer->HasRoundedCorner()) { // This is currently in the local space of the layer and hence in an invalid // space. Once we have the associated transform node for this effect node, // we will update this to the transform node's coordinate space. node->rounded_corner_bounds = RoundedCornerBounds(layer); - node->is_fast_rounded_corner = IsFastRoundedCorner(layer); + node->is_fast_rounded_corner = layer->is_fast_rounded_corner(); } if (!is_root) { // Having a rounded corner or a render surface, both trigger the creation // of a transform node. - if (should_create_render_surface || HasRoundedCorner(layer)) { + if (should_create_render_surface || layer->HasRoundedCorner()) { // In this case, we will create a transform node, so it's safe to use the // next available id from the transform tree as this effect node's // transform id. @@ -958,12 +502,11 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( } node->clip_id = data_from_ancestor.clip_tree_parent; } else { - // The root render surface acts as the unbounded and untransformed - // surface into which content is drawn. The transform node created - // from the root layer (which includes device scale factor) and - // the clip node created from the root layer (which includes - // viewports) apply to the root render surface's content, but not - // to the root render surface itself. + // The root render surface acts as the unbounded and untransformed surface + // into which content is drawn. The transform node created from the root + // layer (which includes device scale factor) and the clip node created from + // the root layer apply to the root render surface's content, but not to the + // root render surface itself. node->transform_id = TransformTree::kRootNodeId; node->clip_id = ClipTree::kViewportNodeId; } @@ -983,7 +526,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( } std::vector<std::unique_ptr<viz::CopyOutputRequest>> layer_copy_requests; - TakeCopyRequests(layer, &layer_copy_requests); + layer->TakeCopyRequests(&layer_copy_requests); for (auto& it : layer_copy_requests) { effect_tree_.AddCopyRequest(node_id, std::move(it)); } @@ -997,8 +540,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( return should_create_render_surface; } -template <typename LayerType> -bool PropertyTreeBuilderContext<LayerType>::UpdateRenderSurfaceIfNeeded( +bool PropertyTreeBuilderContext::UpdateRenderSurfaceIfNeeded( int parent_effect_tree_id, DataForRecursion* data_for_children, bool subtree_has_rounded_corner, @@ -1039,70 +581,19 @@ bool PropertyTreeBuilderContext<LayerType>::UpdateRenderSurfaceIfNeeded( return effect_node->HasRenderSurface(); } -static inline bool UserScrollableHorizontal(Layer* layer) { - return layer->GetUserScrollableHorizontal(); -} - -static inline bool UserScrollableHorizontal(LayerImpl* layer) { - return layer->test_properties()->user_scrollable_horizontal; -} - -static inline bool UserScrollableVertical(Layer* layer) { - return layer->GetUserScrollableVertical(); -} - -static inline bool UserScrollableVertical(LayerImpl* layer) { - return layer->test_properties()->user_scrollable_vertical; -} - -static inline const base::Optional<SnapContainerData>& GetSnapContainerData( - Layer* layer) { - return layer->snap_container_data(); -} - -static inline const base::Optional<SnapContainerData>& GetSnapContainerData( - LayerImpl* layer) { - return layer->test_properties()->snap_container_data; -} - -static inline uint32_t MainThreadScrollingReasons(Layer* layer) { - return layer->GetMainThreadScrollingReasons(); -} - -static inline uint32_t MainThreadScrollingReasons(LayerImpl* layer) { - return layer->test_properties()->main_thread_scrolling_reasons; -} - -template <typename LayerType> -void SetHasTransformNode(LayerType* layer, bool val) { - layer->SetHasTransformNode(val); -} - -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded( +void PropertyTreeBuilderContext::AddScrollNodeIfNeeded( const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) const { int parent_id = data_from_ancestor.scroll_tree_parent; - bool is_root = !LayerParent(layer); + bool is_root = !layer->parent(); bool scrollable = layer->scrollable(); bool contains_non_fast_scrollable_region = !layer->non_fast_scrollable_region().IsEmpty(); - uint32_t main_thread_scrolling_reasons = MainThreadScrollingReasons(layer); - bool scroll_node_uninheritable_criteria = - is_root || scrollable || contains_non_fast_scrollable_region; - bool has_different_main_thread_scrolling_reasons = - main_thread_scrolling_reasons != - data_from_ancestor.main_thread_scrolling_reasons; bool requires_node = - scroll_node_uninheritable_criteria || - (main_thread_scrolling_reasons != - MainThreadScrollingReason::kNotScrollingOnMain && - (has_different_main_thread_scrolling_reasons || - data_from_ancestor - .scroll_tree_parent_created_by_uninheritable_criteria)); + is_root || scrollable || contains_non_fast_scrollable_region; int node_id; if (!requires_node) { @@ -1111,32 +602,17 @@ void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded( } else { ScrollNode node; node.scrollable = scrollable; - node.main_thread_scrolling_reasons = main_thread_scrolling_reasons; - node.scrolls_inner_viewport = layer == inner_viewport_scroll_layer_; - node.scrolls_outer_viewport = layer == outer_viewport_scroll_layer_; - - if (node.scrolls_inner_viewport && - data_from_ancestor.in_subtree_of_page_scale_layer) { - node.max_scroll_offset_affected_by_page_scale = true; - } - node.bounds = layer->bounds(); node.container_bounds = layer->scroll_container_bounds(); node.offset_to_transform_parent = layer->offset_to_transform_parent(); - node.should_flatten = - layer->should_flatten_screen_space_transform_from_property_tree(); - node.user_scrollable_horizontal = UserScrollableHorizontal(layer); - node.user_scrollable_vertical = UserScrollableVertical(layer); + node.user_scrollable_horizontal = layer->GetUserScrollableHorizontal(); + node.user_scrollable_vertical = layer->GetUserScrollableVertical(); node.element_id = layer->element_id(); node.transform_id = data_for_children->transform_tree_parent; - node.snap_container_data = GetSnapContainerData(layer); node_id = scroll_tree_.Insert(node, parent_id); data_for_children->scroll_tree_parent = node_id; - data_for_children->main_thread_scrolling_reasons = - node.main_thread_scrolling_reasons; - data_for_children->scroll_tree_parent_created_by_uninheritable_criteria = - scroll_node_uninheritable_criteria; + // For animation subsystem purposes, if this layer has a compositor element // id, we build a map from that id to this scroll node. if (layer->element_id()) { @@ -1153,28 +629,24 @@ void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded( layer->SetScrollTreeIndex(node_id); } -template <typename LayerType> -void SetBackfaceVisibilityTransform(LayerType* layer, - bool created_transform_node) { +void SetBackfaceVisibilityTransform(Layer* layer, bool created_transform_node) { if (layer->use_parent_backface_visibility()) { - DCHECK(LayerParent(layer)); - DCHECK(!LayerParent(layer)->use_parent_backface_visibility()); + DCHECK(layer->parent()); + DCHECK(!layer->parent()->use_parent_backface_visibility()); layer->SetShouldCheckBackfaceVisibility( - LayerParent(layer)->should_check_backface_visibility()); + layer->parent()->should_check_backface_visibility()); } else { // A double-sided layer's backface can been shown when its visible. // In addition, we need to check if (1) there might be a local 3D transform // on the layer that might turn it to the backface, or (2) it is not drawn // into a flattened space. - layer->SetShouldCheckBackfaceVisibility( - !DoubleSided(layer) && (created_transform_node || - !ShouldFlattenTransform(LayerParent(layer)))); + layer->SetShouldCheckBackfaceVisibility(!layer->double_sided() && + created_transform_node); } } -template <typename LayerType> void SetSafeOpaqueBackgroundColor(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) { SkColor background_color = layer->background_color(); data_for_children->safe_opaque_background_color = @@ -1185,17 +657,8 @@ void SetSafeOpaqueBackgroundColor(const DataForRecursion& data_from_ancestor, data_for_children->safe_opaque_background_color); } -static void SetLayerPropertyChangedForChild(Layer* parent, Layer* child) { - if (parent->subtree_property_changed()) - child->SetSubtreePropertyChanged(); -} - -static void SetLayerPropertyChangedForChild(LayerImpl* parent, - LayerImpl* child) {} - -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal( - LayerType* layer, +void PropertyTreeBuilderContext::BuildPropertyTreesInternal( + Layer* layer, const DataForRecursion& data_from_parent) const { layer->set_property_tree_sequence_number(property_trees_.sequence_number); @@ -1207,7 +670,7 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal( bool created_transform_node = AddTransformNodeIfNeeded( data_from_parent, layer, created_render_surface, &data_for_children); - SetHasTransformNode(layer, created_transform_node); + layer->SetHasTransformNode(created_transform_node); AddClipNodeIfNeeded(data_from_parent, layer, created_transform_node, &data_for_children); @@ -1220,78 +683,40 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal( data_from_parent.not_axis_aligned_since_last_clip ? true : !AnimationsPreserveAxisAlignment(mutator_host_, layer) || - !Transform(layer).Preserves2dAxisAlignment(); + !layer->transform().Preserves2dAxisAlignment(); bool has_non_axis_aligned_clip = not_axis_aligned_since_last_clip && LayerClipsSubtree(layer); data_for_children.not_axis_aligned_since_last_clip = !has_non_axis_aligned_clip; bool subtree_has_rounded_corner = false; - for (size_t i = 0; i < LayerChildren(layer).size(); ++i) { - LayerType* current_child = LayerChildAt(layer, i); - SetLayerPropertyChangedForChild(layer, current_child); - BuildPropertyTreesInternal(current_child, data_for_children); + for (const scoped_refptr<Layer>& child : layer->children()) { + if (layer->subtree_property_changed()) + child->SetSubtreePropertyChanged(); + BuildPropertyTreesInternal(child.get(), data_for_children); subtree_has_rounded_corner |= *data_for_children.subtree_has_rounded_corner; } created_render_surface = UpdateRenderSurfaceIfNeeded( data_from_parent.effect_tree_parent, &data_for_children, subtree_has_rounded_corner, created_transform_node); - - if (MaskLayer(layer)) { - MaskLayer(layer)->set_property_tree_sequence_number( - property_trees_.sequence_number); - MaskLayer(layer)->SetOffsetToTransformParent( - layer->offset_to_transform_parent()); - MaskLayer(layer)->SetTransformTreeIndex(layer->transform_tree_index()); - MaskLayer(layer)->SetClipTreeIndex(layer->clip_tree_index()); - MaskLayer(layer)->SetEffectTreeIndex(layer->effect_tree_index()); - MaskLayer(layer)->SetScrollTreeIndex(layer->scroll_tree_index()); - } } -} // namespace - -Layer* PropertyTreeBuilder::FindFirstScrollableLayer(Layer* layer) { - if (!layer) - return nullptr; - - if (layer->scrollable()) - return layer; +void PropertyTreeBuilderContext::BuildPropertyTrees() { + property_trees_.is_main_thread = true; + property_trees_.is_active = false; - for (size_t i = 0; i < layer->children().size(); ++i) { - Layer* found = FindFirstScrollableLayer(layer->children()[i].get()); - if (found) - return found; - } - - return nullptr; -} + if (layer_tree_host_->has_copy_request()) + UpdateSubtreeHasCopyRequestRecursive(root_layer_); -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( - float device_scale_factor, - const gfx::Rect& viewport, - SkColor root_background_color) const { if (!property_trees_.needs_rebuild) { - DCHECK_NE(page_scale_layer_, root_layer_); - if (page_scale_layer_) { - DCHECK_GE(page_scale_layer_->transform_tree_index(), - TransformTree::kRootNodeId); - TransformNode* node = property_trees_.transform_tree.Node( - page_scale_layer_->transform_tree_index()); - draw_property_utils::UpdatePageScaleFactor(&property_trees_, node, - page_scale_factor_); - } - draw_property_utils::UpdateElasticOverscroll( - &property_trees_, overscroll_elasticity_element_id_, - elastic_overscroll_); - clip_tree_.SetViewportClip(gfx::RectF(viewport)); + clip_tree_.SetViewportClip( + gfx::RectF(layer_tree_host_->device_viewport_rect())); // SetRootScaleAndTransform will be incorrect if the root layer has // non-zero position, so ensure it is zero. - DCHECK(Position(root_layer_).IsOrigin()); - transform_tree_.SetRootScaleAndTransform(device_scale_factor, - device_transform_); + DCHECK(root_layer_->position().IsOrigin()); + transform_tree_.SetRootScaleAndTransform( + layer_tree_host_->device_scale_factor(), gfx::Transform()); return; } @@ -1304,23 +729,21 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( EffectTree::kInvalidNodeId; data_for_recursion.closest_ancestor_with_copy_request = EffectTree::kInvalidNodeId; - data_for_recursion.in_subtree_of_page_scale_layer = false; - data_for_recursion.affected_by_outer_viewport_bounds_delta = false; - data_for_recursion.should_flatten = false; - data_for_recursion.main_thread_scrolling_reasons = - MainThreadScrollingReason::kNotScrollingOnMain; - data_for_recursion.scroll_tree_parent_created_by_uninheritable_criteria = - true; data_for_recursion.compound_transform_since_render_target = gfx::Transform(); data_for_recursion.animation_axis_aligned_since_render_target = true; data_for_recursion.not_axis_aligned_since_last_clip = false; + + SkColor root_background_color = layer_tree_host_->background_color(); + if (SkColorGetA(root_background_color) != 255) + root_background_color = SkColorSetA(root_background_color, 255); data_for_recursion.safe_opaque_background_color = root_background_color; property_trees_.clear(); - transform_tree_.set_device_scale_factor(device_scale_factor); + transform_tree_.set_device_scale_factor( + layer_tree_host_->device_scale_factor()); ClipNode root_clip; root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; - root_clip.clip = gfx::RectF(viewport); + root_clip.clip = gfx::RectF(layer_tree_host_->device_viewport_rect()); root_clip.transform_id = TransformTree::kRootNodeId; data_for_recursion.clip_tree_parent = clip_tree_.Insert(root_clip, ClipTree::kRootNodeId); @@ -1340,70 +763,17 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( scroll_tree_.set_needs_update(false); } -void PropertyTreeBuilder::BuildPropertyTrees( - Layer* root_layer, - const Layer* page_scale_layer, - const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - float device_scale_factor, - const gfx::Rect& viewport, - const gfx::Transform& device_transform, - PropertyTrees* property_trees) { - property_trees->is_main_thread = true; - property_trees->is_active = false; - SkColor color = root_layer->layer_tree_host()->background_color(); - if (SkColorGetA(color) != 255) - color = SkColorSetA(color, 255); - if (root_layer->layer_tree_host()->has_copy_request()) - UpdateSubtreeHasCopyRequestRecursive(root_layer); - PropertyTreeBuilderContext<Layer>( - root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, overscroll_elasticity_element_id, - elastic_overscroll, page_scale_factor, device_transform, - root_layer->layer_tree_host()->mutator_host(), property_trees) - .BuildPropertyTrees(device_scale_factor, viewport, color); - property_trees->ResetCachedData(); +} // namespace + +void PropertyTreeBuilder::BuildPropertyTrees(LayerTreeHost* layer_tree_host) { + PropertyTreeBuilderContext(layer_tree_host).BuildPropertyTrees(); + + layer_tree_host->property_trees()->ResetCachedData(); // During building property trees, all copy requests are moved from layers to // effect tree, which are then pushed at commit to compositor thread and // handled there. LayerTreeHost::has_copy_request is only required to // decide if we want to create a effect node. So, it can be reset now. - root_layer->layer_tree_host()->SetHasCopyRequest(false); -} - -void PropertyTreeBuilder::BuildPropertyTrees( - LayerImpl* root_layer, - const LayerImpl* page_scale_layer, - const LayerImpl* inner_viewport_scroll_layer, - const LayerImpl* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - float device_scale_factor, - const gfx::Rect& viewport, - const gfx::Transform& device_transform, - PropertyTrees* property_trees) { - // Preserve render surfaces when rebuilding. - std::vector<std::unique_ptr<RenderSurfaceImpl>> render_surfaces; - property_trees->effect_tree.TakeRenderSurfaces(&render_surfaces); - property_trees->is_main_thread = false; - property_trees->is_active = root_layer->IsActive(); - SkColor color = root_layer->layer_tree_impl()->background_color(); - if (SkColorGetA(color) != 255) - color = SkColorSetA(color, 255); - UpdateSubtreeHasCopyRequestRecursive(root_layer); - - PropertyTreeBuilderContext<LayerImpl>( - root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, overscroll_elasticity_element_id, - elastic_overscroll, page_scale_factor, device_transform, - root_layer->layer_tree_impl()->mutator_host(), property_trees) - .BuildPropertyTrees(device_scale_factor, viewport, color); - property_trees->effect_tree.CreateOrReuseRenderSurfaces( - &render_surfaces, root_layer->layer_tree_impl()); - property_trees->ResetCachedData(); + layer_tree_host->SetHasCopyRequest(false); } } // namespace cc diff --git a/chromium/cc/trees/property_tree_builder.h b/chromium/cc/trees/property_tree_builder.h index c22bf43378e..8103a91e88e 100644 --- a/chromium/cc/trees/property_tree_builder.h +++ b/chromium/cc/trees/property_tree_builder.h @@ -7,39 +7,15 @@ #include <vector> -#include "cc/trees/layer_tree_host_common.h" -#include "cc/trees/property_tree.h" +#include "cc/cc_export.h" namespace cc { +class LayerTreeHost; + class PropertyTreeBuilder { public: - static Layer* FindFirstScrollableLayer(Layer* root_layer); - - static void CC_EXPORT - BuildPropertyTrees(Layer* root_layer, - const Layer* page_scale_layer, - const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - float device_scale_factor, - const gfx::Rect& viewport, - const gfx::Transform& device_transform, - PropertyTrees* property_trees); - static void CC_EXPORT - BuildPropertyTrees(LayerImpl* root_layer, - const LayerImpl* page_scale_layer, - const LayerImpl* inner_viewport_scroll_layer, - const LayerImpl* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - float device_scale_factor, - const gfx::Rect& viewport, - const gfx::Transform& device_transform, - PropertyTrees* property_trees); + static void CC_EXPORT BuildPropertyTrees(LayerTreeHost*); }; } // namespace cc diff --git a/chromium/cc/trees/property_tree_builder_unittest.cc b/chromium/cc/trees/property_tree_builder_unittest.cc new file mode 100644 index 00000000000..9b4a5f348b0 --- /dev/null +++ b/chromium/cc/trees/property_tree_builder_unittest.cc @@ -0,0 +1,1954 @@ +// Copyright 2011 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 "cc/trees/property_tree_builder.h" + +#include "cc/animation/keyframed_animation_curve.h" +#include "cc/layers/layer.h" +#include "cc/layers/layer_impl.h" +#include "cc/layers/picture_layer.h" +#include "cc/layers/render_surface_impl.h" +#include "cc/layers/texture_layer.h" +#include "cc/test/animation_test_common.h" +#include "cc/test/fake_content_layer_client.h" +#include "cc/test/layer_tree_impl_test_base.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/vector2d_conversions.h" +#include "ui/gfx/transform.h" + +namespace cc { +namespace { + +class PropertyTreeBuilderTest : public LayerTreeImplTestBase, + public testing::Test { + public: + PropertyTreeBuilderTest() : LayerTreeImplTestBase(LayerTreeSettings()) {} + + void UpdateMainDrawProperties(float device_scale_factor = 1.0f) { + SetDeviceScaleAndUpdateViewportRect(host(), device_scale_factor); + UpdateDrawProperties(host()); + } + + LayerImpl* ImplOf(const scoped_refptr<Layer>& layer) { + return layer ? host_impl()->active_tree()->LayerById(layer->id()) : nullptr; + } + RenderSurfaceImpl* GetRenderSurfaceImpl(const scoped_refptr<Layer>& layer) { + return GetRenderSurface(ImplOf(layer)); + } + + // Updates main thread draw properties, commits main thread tree to + // impl-side pending tree, and updates pending tree draw properties. + void Commit(float device_scale_factor = 1.0f) { + UpdateMainDrawProperties(device_scale_factor); + if (!host_impl()->pending_tree()) + host_impl()->CreatePendingTree(); + host()->CommitAndCreatePendingTree(); + // TODO(https://crbug.com/939968) This call should be handled by + // FakeLayerTreeHost instead of manually pushing the properties from the + // layer tree host to the pending tree. + host()->PushLayerTreePropertiesTo(host_impl()->pending_tree()); + + UpdateDrawProperties(host_impl()->pending_tree()); + } + + // Calls Commit(), then activates the pending tree, and updates active tree + // draw properties. + void CommitAndActivate(float device_scale_factor = 1.0f) { + Commit(device_scale_factor); + host_impl()->ActivateSyncTree(); + DCHECK_EQ(device_scale_factor, + host_impl()->active_tree()->device_scale_factor()); + UpdateActiveTreeDrawProperties(device_scale_factor); + } + + const RenderSurfaceList& GetRenderSurfaceList() { + return host_impl()->active_tree()->GetRenderSurfaceList(); + } +}; + +TEST_F(PropertyTreeBuilderTest, EffectTreeTransformIdTest) { + // Tests that effect tree node gets a valid transform id when a layer + // has opacity but doesn't create a render surface. + auto parent = Layer::Create(); + host()->SetRootLayer(parent); + auto child = Layer::Create(); + parent->AddChild(child); + child->SetIsDrawable(true); + + parent->SetBounds(gfx::Size(100, 100)); + child->SetPosition(gfx::PointF(10, 10)); + child->SetBounds(gfx::Size(100, 100)); + child->SetOpacity(0.f); + UpdateMainDrawProperties(); + EffectNode* node = GetEffectNode(child.get()); + const int transform_tree_size = + GetPropertyTrees(parent.get())->transform_tree.next_available_id(); + EXPECT_LT(node->transform_id, transform_tree_size); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceForNonAxisAlignedClipping) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto rotated_and_transparent = Layer::Create(); + root->AddChild(rotated_and_transparent); + auto clips_subtree = Layer::Create(); + rotated_and_transparent->AddChild(clips_subtree); + auto draws_content = Layer::Create(); + clips_subtree->AddChild(draws_content); + + root->SetBounds(gfx::Size(10, 10)); + rotated_and_transparent->SetBounds(gfx::Size(10, 10)); + rotated_and_transparent->SetOpacity(0.5f); + gfx::Transform rotate; + rotate.Rotate(2); + rotated_and_transparent->SetTransform(rotate); + clips_subtree->SetBounds(gfx::Size(10, 10)); + clips_subtree->SetMasksToBounds(true); + draws_content->SetBounds(gfx::Size(10, 10)); + draws_content->SetIsDrawable(true); + + UpdateMainDrawProperties(); + EXPECT_TRUE(GetEffectNode(clips_subtree.get())->HasRenderSurface()); +} + +TEST_F(PropertyTreeBuilderTest, EffectNodesForNonAxisAlignedClips) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto rotate_and_clip = Layer::Create(); + root->AddChild(rotate_and_clip); + auto only_clip = Layer::Create(); + rotate_and_clip->AddChild(only_clip); + auto rotate_and_clip2 = Layer::Create(); + only_clip->AddChild(rotate_and_clip2); + + gfx::Transform rotate; + rotate.Rotate(2); + root->SetBounds(gfx::Size(10, 10)); + rotate_and_clip->SetBounds(gfx::Size(10, 10)); + rotate_and_clip->SetTransform(rotate); + rotate_and_clip->SetMasksToBounds(true); + only_clip->SetBounds(gfx::Size(10, 10)); + only_clip->SetMasksToBounds(true); + rotate_and_clip2->SetBounds(gfx::Size(10, 10)); + rotate_and_clip2->SetTransform(rotate); + rotate_and_clip2->SetMasksToBounds(true); + + UpdateMainDrawProperties(); + // non-axis aligned clip should create an effect node + EXPECT_NE(root->effect_tree_index(), rotate_and_clip->effect_tree_index()); + // Since only_clip's clip is in the same non-axis aligned space as + // rotate_and_clip's clip, no new effect node should be created. + EXPECT_EQ(rotate_and_clip->effect_tree_index(), + only_clip->effect_tree_index()); + // rotate_and_clip2's clip and only_clip's clip are in different non-axis + // aligned spaces. So, new effect node should be created. + EXPECT_NE(rotate_and_clip2->effect_tree_index(), + only_clip->effect_tree_index()); +} + +TEST_F(PropertyTreeBuilderTest, + RenderSurfaceListForRenderSurfaceWithClippedLayer) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + + root->SetBounds(gfx::Size(10, 10)); + root->SetMasksToBounds(true); + render_surface1->SetBounds(gfx::Size(10, 10)); + render_surface1->SetForceRenderSurfaceForTesting(true); + child->SetIsDrawable(true); + child->SetPosition(gfx::PointF(30.f, 30.f)); + child->SetBounds(gfx::Size(10, 10)); + + CommitAndActivate(); + + // The child layer's content is entirely outside the root's clip rect, so + // the intermediate render surface should not be listed here, even if it was + // forced to be created. Render surfaces without children or visible content + // are unexpected at draw time (e.g. we might try to create a content texture + // of size 0). + ASSERT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(1U, GetRenderSurfaceList().size()); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForTransparentChild) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + + root->SetBounds(gfx::Size(10, 10)); + render_surface1->SetBounds(gfx::Size(10, 10)); + render_surface1->SetForceRenderSurfaceForTesting(true); + render_surface1->SetOpacity(0.f); + child->SetBounds(gfx::Size(10, 10)); + child->SetIsDrawable(true); + + CommitAndActivate(); + + // Since the layer is transparent, render_surface1_impl->GetRenderSurface() + // should not have gotten added anywhere. Also, the drawable content rect + // should not have been extended by the children. + ASSERT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(0, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_EQ(1U, GetRenderSurfaceList().size()); + EXPECT_EQ(static_cast<viz::RenderPassId>(root->id()), + GetRenderSurfaceList().at(0)->id()); + EXPECT_EQ(gfx::Rect(), ImplOf(root)->drawable_content_rect()); +} + +TEST_F(PropertyTreeBuilderTest, + RenderSurfaceListForTransparentChildWithBackdropFilter) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + + root->SetBounds(gfx::Size(10, 10)); + render_surface1->SetBounds(gfx::Size(10, 10)); + render_surface1->SetForceRenderSurfaceForTesting(true); + render_surface1->SetOpacity(0.f); + render_surface1->SetIsDrawable(true); + FilterOperations filters; + filters.Append(FilterOperation::CreateBlurFilter(1.5f)); + render_surface1->SetBackdropFilters(filters); + child->SetBounds(gfx::Size(10, 10)); + child->SetIsDrawable(true); + host()->SetElementIdsForTesting(); + + CommitAndActivate(); + EXPECT_EQ(2U, GetRenderSurfaceList().size()); + + // The layer is fully transparent, but has a backdrop filter, so it + // shouldn't be skipped and should be drawn. + ASSERT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_EQ(gfx::RectF(0, 0, 10, 10), + GetRenderSurfaceImpl(root)->DrawableContentRect()); + EXPECT_TRUE(GetEffectNode(ImplOf(render_surface1))->is_drawn); + + // When root is transparent, the layer should not be drawn. + host_impl()->active_tree()->SetOpacityMutated(root->element_id(), 0.f); + host_impl()->active_tree()->SetOpacityMutated(render_surface1->element_id(), + 1.f); + ImplOf(render_surface1)->set_visible_layer_rect(gfx::Rect()); + UpdateActiveTreeDrawProperties(); + + EXPECT_FALSE(GetEffectNode(ImplOf(render_surface1))->is_drawn); + EXPECT_EQ(gfx::Rect(), ImplOf(render_surface1)->visible_layer_rect()); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForFilter) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto parent = Layer::Create(); + root->AddChild(parent); + auto child1 = Layer::Create(); + parent->AddChild(child1); + auto child2 = Layer::Create(); + parent->AddChild(child2); + + gfx::Transform scale_matrix; + scale_matrix.Scale(2.0f, 2.0f); + + root->SetBounds(gfx::Size(100, 100)); + parent->SetTransform(scale_matrix); + FilterOperations filters; + filters.Append(FilterOperation::CreateBlurFilter(10.0f)); + parent->SetFilters(filters); + parent->SetForceRenderSurfaceForTesting(true); + child1->SetBounds(gfx::Size(25, 25)); + child1->SetIsDrawable(true); + child1->SetForceRenderSurfaceForTesting(true); + child2->SetPosition(gfx::PointF(25, 25)); + child2->SetBounds(gfx::Size(25, 25)); + child2->SetIsDrawable(true); + child2->SetForceRenderSurfaceForTesting(true); + + CommitAndActivate(); + + ASSERT_TRUE(GetRenderSurfaceImpl(parent)); + EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); + EXPECT_EQ(4U, GetRenderSurfaceList().size()); + + // The rectangle enclosing child1 and child2 (0,0 50x50), expanded for the + // blur (-30,-30 110x110), and then scaled by the scale matrix + // (-60,-60 220x220). + EXPECT_EQ(gfx::RectF(-60, -60, 220, 220), + GetRenderSurfaceImpl(parent)->DrawableContentRect()); +} + +TEST_F(PropertyTreeBuilderTest, ForceRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + + root->SetBounds(gfx::Size(10, 10)); + render_surface1->SetBounds(gfx::Size(10, 10)); + render_surface1->SetForceRenderSurfaceForTesting(true); + child->SetBounds(gfx::Size(10, 10)); + child->SetIsDrawable(true); + + CommitAndActivate(); + + // The root layer always creates a render surface + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); + + render_surface1->SetForceRenderSurfaceForTesting(false); + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); +} + +TEST_F(PropertyTreeBuilderTest, VisibleRectWithClippingAndFilters) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto clip = Layer::Create(); + root->AddChild(clip); + auto filter = Layer::Create(); + clip->AddChild(filter); + auto filter_child = Layer::Create(); + filter->AddChild(filter_child); + + root->SetBounds(gfx::Size(100, 100)); + clip->SetBounds(gfx::Size(10, 10)); + filter->SetForceRenderSurfaceForTesting(true); + filter_child->SetBounds(gfx::Size(2000, 2000)); + filter_child->SetPosition(gfx::PointF(-50, -50)); + filter_child->SetIsDrawable(true); + + clip->SetMasksToBounds(true); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(50, 50, 10, 10), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurfaceImpl(filter)->content_rect()); + + FilterOperations blur_filter; + blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); + filter->SetFilters(blur_filter); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(38, 38, 34, 34), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(-12, -12, 34, 34), + GetRenderSurfaceImpl(filter)->content_rect()); + + gfx::Transform vertical_flip; + vertical_flip.Scale(1, -1); + sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>( + vertical_flip.matrix(), kLow_SkFilterQuality, nullptr); + FilterOperations reflection_filter; + reflection_filter.Append( + FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( + SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); + filter->SetFilters(reflection_filter); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(49, 39, 12, 21), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(-1, -11, 12, 21), + GetRenderSurfaceImpl(filter)->content_rect()); +} + +TEST_F(PropertyTreeBuilderTest, VisibleRectWithScalingClippingAndFilters) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto scale = Layer::Create(); + root->AddChild(scale); + auto clip = Layer::Create(); + scale->AddChild(clip); + auto filter = Layer::Create(); + clip->AddChild(filter); + auto filter_child = Layer::Create(); + filter->AddChild(filter_child); + + root->SetBounds(gfx::Size(100, 100)); + clip->SetBounds(gfx::Size(10, 10)); + filter->SetForceRenderSurfaceForTesting(true); + filter_child->SetBounds(gfx::Size(2000, 2000)); + filter_child->SetPosition(gfx::PointF(-50, -50)); + filter_child->SetIsDrawable(true); + + clip->SetMasksToBounds(true); + + gfx::Transform scale_transform; + scale_transform.Scale(3, 3); + scale->SetTransform(scale_transform); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(50, 50, 10, 10), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(30, 30), GetRenderSurfaceImpl(filter)->content_rect()); + + FilterOperations blur_filter; + blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); + filter->SetFilters(blur_filter); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(38, 38, 34, 34), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(-36, -36, 102, 102), + GetRenderSurfaceImpl(filter)->content_rect()); + + gfx::Transform vertical_flip; + vertical_flip.Scale(1, -1); + sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>( + vertical_flip.matrix(), kLow_SkFilterQuality, nullptr); + FilterOperations reflection_filter; + reflection_filter.Append( + FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( + SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); + filter->SetFilters(reflection_filter); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(49, 39, 12, 21), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(-1, -31, 32, 61), + GetRenderSurfaceImpl(filter)->content_rect()); +} + +TEST_F(PropertyTreeBuilderTest, TextureLayerSnapping) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = TextureLayer::CreateForMailbox(nullptr); + root->AddChild(child); + + root->SetBounds(gfx::Size(100, 100)); + child->SetBounds(gfx::Size(100, 100)); + child->SetIsDrawable(true); + gfx::Transform fractional_translate; + fractional_translate.Translate(10.5f, 20.3f); + child->SetTransform(fractional_translate); + + CommitAndActivate(); + + auto child_screen_space_transform = ImplOf(child)->ScreenSpaceTransform(); + EXPECT_NE(child_screen_space_transform, fractional_translate); + fractional_translate.RoundTranslationComponents(); + EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform, + fractional_translate); + gfx::RectF layer_bounds_in_screen_space = MathUtil::MapClippedRect( + child_screen_space_transform, gfx::RectF(gfx::SizeF(child->bounds()))); + EXPECT_EQ(layer_bounds_in_screen_space, gfx::RectF(11.f, 20.f, 100.f, 100.f)); +} + +// Verify the behavior of back-face culling when there are no preserve-3d +// layers. Note that 3d transforms still apply in this case, but they are +// "flattened" to each parent layer according to current W3C spec. +TEST_F(PropertyTreeBuilderTest, BackFaceCullingWithoutPreserves3d) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto front_facing_child = Layer::Create(); + root->AddChild(front_facing_child); + auto back_facing_child = Layer::Create(); + root->AddChild(back_facing_child); + auto front_facing_surface = Layer::Create(); + root->AddChild(front_facing_surface); + auto back_facing_surface = Layer::Create(); + root->AddChild(back_facing_surface); + auto front_facing_child_of_front_facing_surface = Layer::Create(); + front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); + auto back_facing_child_of_front_facing_surface = Layer::Create(); + front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); + auto front_facing_child_of_back_facing_surface = Layer::Create(); + back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); + auto back_facing_child_of_back_facing_surface = Layer::Create(); + back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); + + // Nothing is double-sided + front_facing_child->SetDoubleSided(false); + back_facing_child->SetDoubleSided(false); + front_facing_surface->SetDoubleSided(false); + back_facing_surface->SetDoubleSided(false); + front_facing_child_of_front_facing_surface->SetDoubleSided(false); + back_facing_child_of_front_facing_surface->SetDoubleSided(false); + front_facing_child_of_back_facing_surface->SetDoubleSided(false); + back_facing_child_of_back_facing_surface->SetDoubleSided(false); + + // Everything draws content. + front_facing_child->SetIsDrawable(true); + back_facing_child->SetIsDrawable(true); + front_facing_surface->SetIsDrawable(true); + back_facing_surface->SetIsDrawable(true); + front_facing_child_of_front_facing_surface->SetIsDrawable(true); + back_facing_child_of_front_facing_surface->SetIsDrawable(true); + front_facing_child_of_back_facing_surface->SetIsDrawable(true); + back_facing_child_of_back_facing_surface->SetIsDrawable(true); + + gfx::Transform backface_matrix; + backface_matrix.Translate(50.0, 50.0); + backface_matrix.RotateAboutYAxis(180.0); + backface_matrix.Translate(-50.0, -50.0); + + root->SetBounds(gfx::Size(100, 100)); + front_facing_child->SetBounds(gfx::Size(100, 100)); + back_facing_child->SetBounds(gfx::Size(100, 100)); + front_facing_surface->SetBounds(gfx::Size(100, 100)); + back_facing_surface->SetBounds(gfx::Size(100, 100)); + front_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); + back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); + front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); + back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); + + front_facing_surface->SetForceRenderSurfaceForTesting(true); + back_facing_surface->SetForceRenderSurfaceForTesting(true); + + back_facing_child->SetTransform(backface_matrix); + back_facing_surface->SetTransform(backface_matrix); + back_facing_child_of_front_facing_surface->SetTransform(backface_matrix); + back_facing_child_of_back_facing_surface->SetTransform(backface_matrix); + + // Note: No layers preserve 3d. According to current W3C CSS gfx::Transforms + // spec, these layers should blindly use their own local transforms to + // determine back-face culling. + CommitAndActivate(); + + // Verify which render surfaces were created. + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child), + GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface), + GetRenderSurfaceImpl(back_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), + GetRenderSurfaceImpl(back_facing_surface)); + + EXPECT_EQ(3u, update_layer_impl_list().size()); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerImplListContains( + front_facing_child_of_front_facing_surface->id())); +} + +// Verify that layers are appropriately culled when their back face is showing +// and they are not double sided, while animations are going on. +// Even layers that are animating get culled if their back face is showing and +// they are not double sided. +TEST_F(PropertyTreeBuilderTest, BackFaceCullingWithAnimatingTransforms) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto animating_surface = Layer::Create(); + root->AddChild(animating_surface); + auto child_of_animating_surface = Layer::Create(); + animating_surface->AddChild(child_of_animating_surface); + auto animating_child = Layer::Create(); + root->AddChild(animating_child); + auto child2 = Layer::Create(); + root->AddChild(child2); + + // Nothing is double-sided + child->SetDoubleSided(false); + child2->SetDoubleSided(false); + animating_surface->SetDoubleSided(false); + child_of_animating_surface->SetDoubleSided(false); + animating_child->SetDoubleSided(false); + + // Everything draws content. + child->SetIsDrawable(true); + child2->SetIsDrawable(true); + animating_surface->SetIsDrawable(true); + child_of_animating_surface->SetIsDrawable(true); + animating_child->SetIsDrawable(true); + + gfx::Transform backface_matrix; + backface_matrix.Translate(50.0, 50.0); + backface_matrix.RotateAboutYAxis(180.0); + backface_matrix.Translate(-50.0, -50.0); + + host()->SetElementIdsForTesting(); + + // Animate the transform on the render surface. + AddAnimatedTransformToElementWithAnimation(animating_surface->element_id(), + timeline(), 10.0, 30, 0); + // This is just an animating layer, not a surface. + AddAnimatedTransformToElementWithAnimation(animating_child->element_id(), + timeline(), 10.0, 30, 0); + + root->SetBounds(gfx::Size(100, 100)); + child->SetBounds(gfx::Size(100, 100)); + child->SetTransform(backface_matrix); + animating_surface->SetBounds(gfx::Size(100, 100)); + animating_surface->SetTransform(backface_matrix); + animating_surface->SetForceRenderSurfaceForTesting(true); + child_of_animating_surface->SetBounds(gfx::Size(100, 100)); + child_of_animating_surface->SetTransform(backface_matrix); + animating_child->SetBounds(gfx::Size(100, 100)); + animating_child->SetTransform(backface_matrix); + child2->SetBounds(gfx::Size(100, 100)); + + CommitAndActivate(); + + EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_TRUE(GetRenderSurfaceImpl(animating_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(child_of_animating_surface), + GetRenderSurfaceImpl(animating_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(animating_child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root)); + + EXPECT_EQ(1u, update_layer_impl_list().size()); + + // The back facing layers are culled from the layer list, and have an empty + // visible rect. + EXPECT_TRUE(UpdateLayerImplListContains(child2->id())); + EXPECT_TRUE(ImplOf(child)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(ImplOf(animating_surface)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE( + ImplOf(child_of_animating_surface)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(ImplOf(animating_child)->visible_layer_rect().IsEmpty()); + + EXPECT_EQ(gfx::Rect(100, 100), ImplOf(child2)->visible_layer_rect()); +} + +// Verify that having animated opacity but current opacity 1 still creates +// a render surface. +TEST_F(PropertyTreeBuilderTest, AnimatedOpacityCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); + + root->SetBounds(gfx::Size(50, 50)); + child->SetBounds(gfx::Size(50, 50)); + child->SetIsDrawable(true); + grandchild->SetBounds(gfx::Size(50, 50)); + grandchild->SetIsDrawable(true); + + host()->SetElementIdsForTesting(); + AddOpacityTransitionToElementWithAnimation(child->element_id(), timeline(), + 10.0, 1.f, 0.2f, false); + CommitAndActivate(); + + EXPECT_EQ(1.f, ImplOf(child)->Opacity()); + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); +} + +static bool FilterIsAnimating(LayerImpl* layer) { + MutatorHost* host = layer->layer_tree_impl()->mutator_host(); + return host->IsAnimatingFilterProperty(layer->element_id(), + layer->GetElementTypeForAnimation()); +} + +// Verify that having an animated filter (but no current filter, as these +// are mutually exclusive) correctly creates a render surface. +TEST_F(PropertyTreeBuilderTest, AnimatedFilterCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); + + root->SetBounds(gfx::Size(50, 50)); + child->SetBounds(gfx::Size(50, 50)); + grandchild->SetBounds(gfx::Size(50, 50)); + + host()->SetElementIdsForTesting(); + AddAnimatedFilterToElementWithAnimation(child->element_id(), timeline(), 10.0, + 0.1f, 0.2f); + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); + + EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); + EXPECT_TRUE(FilterIsAnimating(ImplOf(child))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); +} + +bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) { + MutatorHost* host = layer.layer_tree_impl()->mutator_host(); + return host->HasPotentiallyRunningFilterAnimation( + layer.element_id(), layer.GetElementTypeForAnimation()); +} + +// Verify that having a filter animation with a delayed start time creates a +// render surface. +TEST_F(PropertyTreeBuilderTest, DelayedFilterAnimationCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); + + root->SetBounds(gfx::Size(50, 50)); + child->SetBounds(gfx::Size(50, 50)); + grandchild->SetBounds(gfx::Size(50, 50)); + + host()->SetElementIdsForTesting(); + + std::unique_ptr<KeyframedFilterAnimationCurve> curve( + KeyframedFilterAnimationCurve::Create()); + FilterOperations start_filters; + start_filters.Append(FilterOperation::CreateBrightnessFilter(0.1f)); + FilterOperations end_filters; + end_filters.Append(FilterOperation::CreateBrightnessFilter(0.3f)); + curve->AddKeyframe( + FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr)); + curve->AddKeyframe(FilterKeyframe::Create( + base::TimeDelta::FromMilliseconds(100), end_filters, nullptr)); + std::unique_ptr<KeyframeModel> keyframe_model = + KeyframeModel::Create(std::move(curve), 0, 1, TargetProperty::FILTER); + keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE); + keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); + + AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(), + std::move(keyframe_model)); + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); + + EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); + EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(root))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(child))); + EXPECT_TRUE(HasPotentiallyRunningFilterAnimation(*ImplOf(child))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); + EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(grandchild))); +} + +TEST_F(PropertyTreeBuilderTest, ChangingAxisAlignmentTriggersRebuild) { + gfx::Transform translate; + gfx::Transform rotate; + + translate.Translate(10, 10); + rotate.Rotate(45); + + scoped_refptr<Layer> root = Layer::Create(); + root->SetBounds(gfx::Size(800, 800)); + + host()->SetRootLayer(root); + + UpdateMainDrawProperties(); + EXPECT_FALSE(host()->property_trees()->needs_rebuild); + + root->SetTransform(translate); + EXPECT_FALSE(host()->property_trees()->needs_rebuild); + + root->SetTransform(rotate); + EXPECT_TRUE(host()->property_trees()->needs_rebuild); +} + +TEST_F(PropertyTreeBuilderTest, ResetPropertyTreeIndices) { + scoped_refptr<Layer> root = Layer::Create(); + root->SetBounds(gfx::Size(800, 800)); + + gfx::Transform translate_z; + translate_z.Translate3d(0, 0, 10); + + scoped_refptr<Layer> child = Layer::Create(); + child->SetTransform(translate_z); + child->SetBounds(gfx::Size(100, 100)); + + root->AddChild(child); + + host()->SetRootLayer(root); + + UpdateMainDrawProperties(); + EXPECT_NE(-1, child->transform_tree_index()); + + child->RemoveFromParent(); + + UpdateMainDrawProperties(); + EXPECT_EQ(-1, child->transform_tree_index()); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceClipsSubtree) { + // Ensure that a Clip Node is added when a render surface applies clip. + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto significant_transform = Layer::Create(); + root->AddChild(significant_transform); + auto layer_clips_subtree = Layer::Create(); + significant_transform->AddChild(layer_clips_subtree); + auto render_surface = Layer::Create(); + layer_clips_subtree->AddChild(render_surface); + auto test_layer = Layer::Create(); + render_surface->AddChild(test_layer); + + // This transform should be a significant one so that a transform node is + // formed for it. + gfx::Transform transform1; + transform1.RotateAboutYAxis(45); + transform1.RotateAboutXAxis(30); + // This transform should be a 3d transform as we want the render surface + // to flatten the transform + gfx::Transform transform2; + transform2.Translate3d(10, 10, 10); + + root->SetBounds(gfx::Size(30, 30)); + significant_transform->SetTransform(transform1); + significant_transform->SetBounds(gfx::Size(30, 30)); + layer_clips_subtree->SetBounds(gfx::Size(30, 30)); + layer_clips_subtree->SetMasksToBounds(true); + layer_clips_subtree->SetForceRenderSurfaceForTesting(true); + render_surface->SetTransform(transform2); + render_surface->SetBounds(gfx::Size(30, 30)); + render_surface->SetForceRenderSurfaceForTesting(true); + test_layer->SetBounds(gfx::Size(30, 30)); + test_layer->SetIsDrawable(true); + + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(significant_transform), + GetRenderSurfaceImpl(root)); + EXPECT_TRUE(GetRenderSurfaceImpl(layer_clips_subtree)); + EXPECT_NE(GetRenderSurfaceImpl(render_surface), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(test_layer), + GetRenderSurfaceImpl(render_surface)); + + EXPECT_EQ(gfx::Rect(30, 20), ImplOf(test_layer)->visible_layer_rect()); +} + +TEST_F(PropertyTreeBuilderTest, PropertyTreesRebuildWithOpacityChanges) { + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> child = Layer::Create(); + child->SetIsDrawable(true); + root->AddChild(child); + host()->SetRootLayer(root); + + root->SetBounds(gfx::Size(100, 100)); + child->SetBounds(gfx::Size(20, 20)); + UpdateMainDrawProperties(); + + // Changing the opacity from 1 to non-1 value should trigger rebuild of + // property trees as a new effect node will be created. + child->SetOpacity(0.5f); + PropertyTrees* property_trees = host()->property_trees(); + EXPECT_TRUE(property_trees->needs_rebuild); + + UpdateMainDrawProperties(); + EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); + + // child already has an effect node. Changing its opacity shouldn't trigger + // a property trees rebuild. + child->SetOpacity(0.8f); + property_trees = host()->property_trees(); + EXPECT_FALSE(property_trees->needs_rebuild); + + UpdateMainDrawProperties(); + EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); + + // Changing the opacity from non-1 value to 1 should trigger a rebuild of + // property trees as the effect node may no longer be needed. + child->SetOpacity(1.f); + property_trees = host()->property_trees(); + EXPECT_TRUE(property_trees->needs_rebuild); + + UpdateMainDrawProperties(); + EXPECT_EQ(child->effect_tree_index(), root->effect_tree_index()); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForTrilinearFiltering) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto parent = Layer::Create(); + root->AddChild(parent); + auto child1 = Layer::Create(); + parent->AddChild(child1); + auto child2 = Layer::Create(); + parent->AddChild(child2); + + gfx::Transform scale_matrix; + scale_matrix.Scale(.25f, .25f); + + root->SetBounds(gfx::Size(200, 200)); + parent->SetTransform(scale_matrix); + parent->SetTrilinearFiltering(true); + child1->SetBounds(gfx::Size(50, 50)); + child1->SetIsDrawable(true); + child1->SetForceRenderSurfaceForTesting(true); + child2->SetPosition(gfx::PointF(50, 50)); + child2->SetBounds(gfx::Size(50, 50)); + child2->SetIsDrawable(true); + child2->SetForceRenderSurfaceForTesting(true); + + CommitAndActivate(); + + ASSERT_TRUE(GetRenderSurfaceImpl(parent)); + EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); + EXPECT_EQ(4U, GetRenderSurfaceList().size()); + + // The rectangle enclosing child1 and child2 (0,0 100x100), scaled by the + // scale matrix to (0,0 25x25). + EXPECT_EQ(gfx::RectF(0, 0, 25, 25), + GetRenderSurfaceImpl(parent)->DrawableContentRect()); +} + +TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) { + // Layer Tree: + // +root + // +--render surface + // +----rounded corner layer 1 [should trigger render surface] + // +----layer 1 + // +--rounded corner layer 2 [should trigger render surface] + // +----layer 2 + // +------rounded corner layer 3 [should trigger render surface] + // +--------rounded corner layer 4 [should trigger render surface] + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + constexpr int kRoundedCorner3Radius = 1; + constexpr int kRoundedCorner4Radius = 1; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(15.f, 15.f, 20.f, 20.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f); + constexpr gfx::RectF kRoundedCornerLayer3Bound(0.f, 15.f, 5.f, 5.f); + constexpr gfx::RectF kRoundedCornerLayer4Bound(1.f, 1.f, 3.f, 3.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> render_surface = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); + scoped_refptr<Layer> layer_2 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create(); + + // Set up layer tree + root->AddChild(render_surface); + root->AddChild(rounded_corner_layer_2); + + render_surface->AddChild(rounded_corner_layer_1); + render_surface->AddChild(layer_1); + + rounded_corner_layer_2->AddChild(layer_2); + + layer_2->AddChild(rounded_corner_layer_3); + + rounded_corner_layer_3->AddChild(rounded_corner_layer_4); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + render_surface->SetPosition(gfx::PointF(0, 0)); + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + layer_1->SetPosition(gfx::PointF(10.f, 10.f)); + rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); + layer_2->SetPosition(gfx::PointF(30.f, 30.f)); + rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin()); + rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + render_surface->SetBounds(gfx::Size(50, 50)); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + layer_1->SetBounds(gfx::Size(10, 10)); + rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + layer_2->SetBounds(gfx::Size(25, 25)); + rounded_corner_layer_3->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); + rounded_corner_layer_4->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); + + // Add Layer transforms. + gfx::Transform layer_2_transform; + constexpr gfx::Vector2dF kLayer2Translation(10.f, 10.f); + layer_2_transform.Translate(kLayer2Translation); + layer_2->SetTransform(layer_2_transform); + + gfx::Transform rounded_corner_layer_3_transform; + constexpr float kRoundedCorner3Scale = 2.f; + rounded_corner_layer_3_transform.Scale(kRoundedCorner3Scale, + kRoundedCorner3Scale); + rounded_corner_layer_3->SetTransform(rounded_corner_layer_3_transform); + + // Set the layer properties + render_surface->SetForceRenderSurfaceForTesting(true); + + root->SetIsDrawable(true); + render_surface->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + layer_1->SetIsDrawable(true); + rounded_corner_layer_2->SetIsDrawable(true); + layer_2->SetIsDrawable(true); + rounded_corner_layer_3->SetIsDrawable(true); + rounded_corner_layer_4->SetIsDrawable(true); + + // Set Rounded corners + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + rounded_corner_layer_3->SetRoundedCorner( + {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, + kRoundedCorner3Radius}); + rounded_corner_layer_4->SetRoundedCorner( + {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, + kRoundedCorner4Radius}); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this effect node has no descendants that draw and no descendant that + // has a rounded corner, it does not need a render surface. + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this node has descendants with roudned corners, it needs a render + // surface. It also has 2 descendants that draw. + effect_node = GetEffectNode(rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + // Since this node has a descendant that has a rounded corner, it will trigger + // the creation of a render surface. + effect_node = GetEffectNode(rounded_corner_layer_3.get()); + gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), + kRoundedCorner3Radius); + EXPECT_EQ(rounded_corner_bounds_3.rect(), + gfx::RectF(kRoundedCornerLayer3Bound.size())); + + // Since this node has no descendants that draw nor any descendant that has a + // rounded corner, it does not need a render surface. + effect_node = GetEffectNode(rounded_corner_layer_4.get()); + gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), + kRoundedCorner4Radius); + EXPECT_EQ(rounded_corner_bounds_4.rect(), + gfx::RectF(kRoundedCornerLayer4Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* rounded_corner_layer_1_impl = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_2_impl = + layer_tree_impl->LayerById(rounded_corner_layer_2->id()); + LayerImpl* rounded_corner_layer_3_impl = + layer_tree_impl->LayerById(rounded_corner_layer_3->id()); + LayerImpl* rounded_corner_layer_4_impl = + layer_tree_impl->LayerById(rounded_corner_layer_4->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Rounded corner layer 1 + // The render target for this layer is |render_surface|, hence its target + // bounds are relative to |render_surface|. + // The offset from the origin of the render target is [15, 15] and the device + // scale factor is 1.6 thus giving the target space origin of [24, 24]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_rrect_1 = + rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Rounded corner layer 2 + // The render target for this layer is |root|. + // The offset from the origin of the render target is [40, 40] and the device + // scale factor is 1.6 thus giving the target space origin of [64, 64]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_2 = + rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_2 = + rounded_corner_layer_2_impl->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); + + // Rounded corner layer 3 + // The render target for this layer is |rounded_corner_2|. + // The net offset from the origin of the render target is [40, 55] and the + // device scale factor is 1.6 thus giving the target space origin of [64, 88]. + // The corner radius is also scaled by a factor of 1.6 * transform scale. + const gfx::RRectF actual_self_rrect_3 = + rounded_corner_layer_3_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer3Bound; + bounds_in_target_space += + layer_2->position().OffsetFromOrigin() + kLayer2Translation; + bounds_in_target_space.Scale(kDeviceScale); + gfx::SizeF transformed_size = bounds_in_target_space.size(); + transformed_size.Scale(kRoundedCorner3Scale); + bounds_in_target_space.set_size(transformed_size); + + const gfx::RRectF actual_render_target_rrect_3 = + rounded_corner_layer_3_impl->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), + kRoundedCorner3Radius * kDeviceScale * kRoundedCorner3Scale); + + // Rounded corner layer 4 + // The render target for this layer is |rounded_corner_3|. + // The net offset from the origin of the render target is [1, 1] and the + // net scale is 1.6 * transform scale = 3.2 thus giving the target space o + // rigin of [3.2, 3.2]. + // The corner radius is also scaled by a factor of 3.2. + const gfx::RRectF actual_rrect_4 = + rounded_corner_layer_4_impl->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer4Bound; + bounds_in_target_space.Scale(kDeviceScale * kRoundedCorner3Scale); + EXPECT_EQ(actual_rrect_4.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_4.GetSimpleRadius(), + kRoundedCorner4Radius * kDeviceScale * kRoundedCorner3Scale); +} + +TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsInterveningRenderTarget) { + // Layer Tree: + // +root + // +--rounded corner layer 1 [should not trigger render surface] + // +----render surface [Does not draw] + // +------rounded corner layer 2 [should not trigger render surface] + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(60.f, 0.f, 40.f, 30.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 30.f, 20.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> render_surface = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); + + // Set up layer tree + root->AddChild(rounded_corner_layer_1); + rounded_corner_layer_1->AddChild(render_surface); + render_surface->AddChild(rounded_corner_layer_2); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + render_surface->SetPosition(gfx::PointF(0, 0)); + rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + render_surface->SetBounds(gfx::Size(30, 30)); + rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + + // Set the layer properties + render_surface->SetForceRenderSurfaceForTesting(true); + + root->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + rounded_corner_layer_2->SetIsDrawable(true); + + // Set Rounded corners + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this effect node has only 1 descendant that draws and no descendant + // that has a rounded corner before the render surface, it does not need a + // render surface. + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this effect node has no descendants that draw and no descendant that + // has a rounded corner, it does not need a render surface. + effect_node = GetEffectNode(rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* rounded_corner_layer_1_impl = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_2_impl = + layer_tree_impl->LayerById(rounded_corner_layer_2->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Rounded corner layer 1 + // The render target for this layer is |root|, hence its target + // bounds are relative to |root|. + // The offset from the origin of the render target is [60, 0] and the device + // scale factor is 1.6 thus giving the target space origin of [96, 0]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_rrect_1 = + rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Rounded corner layer 2 + // The render target for this layer is |render_surface|. + // The offset from the origin of the render target is [0, 0]. + const gfx::RRectF actual_rrect_2 = + rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); +} + +TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsSiblingRenderTarget) { + // Layer Tree: + // +root + // +--rounded corner layer 1 [should trigger render surface] + // +----render surface [Does not draw] + // +----rounded corner layer 2 [should not trigger render surface] + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 60.f, 30.f, 40.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 20.f, 30.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> render_surface = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); + + // Set up layer tree + root->AddChild(rounded_corner_layer_1); + rounded_corner_layer_1->AddChild(render_surface); + rounded_corner_layer_1->AddChild(rounded_corner_layer_2); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + render_surface->SetPosition(gfx::PointF(0, 0)); + rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + render_surface->SetBounds(gfx::Size(30, 30)); + rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + + // Set the layer properties + render_surface->SetForceRenderSurfaceForTesting(true); + + root->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + rounded_corner_layer_2->SetIsDrawable(true); + + // Set Rounded corners + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this effect node has 1 descendant with a rounded corner without a + // render surface along the chain, it need a render surface. + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this effect node has no descendants that draw and no descendant that + // has a rounded corner, it does not need a render surface. + effect_node = GetEffectNode(rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* rounded_corner_layer_1_impl = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_2_impl = + layer_tree_impl->LayerById(rounded_corner_layer_2->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Rounded corner layer 1 + // The render target for this layer is |root|, hence its target + // bounds are relative to |root|. + // The offset from the origin of the render target is [0, 60] and the device + // scale factor is 1.6 thus giving the target space origin of [0, 96]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_1 = + rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); + + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_1 = + rounded_corner_layer_1_impl->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Rounded corner layer 2 + // The render target for this layer is |render_surface|. + // The offset from the origin of the render target is [0, 0]. + const gfx::RRectF actual_rrect_2 = + rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); +} + +TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) { + // Layer Tree: + // +root + // +--fast rounded corner layer [should not trigger render surface] + // +----layer 1 + // +----layer 2 + // +--rounded corner layer [should trigger render surface] + // +----layer 3 + // +----layer 4 + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 0.f, 50.f, 50.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> fast_rounded_corner_layer = Layer::Create(); + scoped_refptr<Layer> layer_1 = Layer::Create(); + scoped_refptr<Layer> layer_2 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer = Layer::Create(); + scoped_refptr<Layer> layer_3 = Layer::Create(); + scoped_refptr<Layer> layer_4 = Layer::Create(); + + // Set up layer tree + root->AddChild(fast_rounded_corner_layer); + root->AddChild(rounded_corner_layer); + + fast_rounded_corner_layer->AddChild(layer_1); + fast_rounded_corner_layer->AddChild(layer_2); + + rounded_corner_layer->AddChild(layer_3); + rounded_corner_layer->AddChild(layer_4); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + fast_rounded_corner_layer->SetPosition(kRoundedCornerLayer1Bound.origin()); + layer_1->SetPosition(gfx::PointF(0.f, 0.f)); + layer_2->SetPosition(gfx::PointF(25.f, 0.f)); + rounded_corner_layer->SetPosition(kRoundedCornerLayer2Bound.origin()); + layer_3->SetPosition(gfx::PointF(0.f, 0.f)); + layer_4->SetPosition(gfx::PointF(30.f, 0.f)); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + fast_rounded_corner_layer->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + layer_1->SetBounds(gfx::Size(25, 25)); + layer_2->SetBounds(gfx::Size(25, 25)); + rounded_corner_layer->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + layer_3->SetBounds(gfx::Size(30, 60)); + layer_4->SetBounds(gfx::Size(30, 60)); + + root->SetIsDrawable(true); + fast_rounded_corner_layer->SetIsDrawable(true); + layer_1->SetIsDrawable(true); + layer_2->SetIsDrawable(true); + rounded_corner_layer->SetIsDrawable(true); + layer_3->SetIsDrawable(true); + layer_4->SetIsDrawable(true); + + // Set Rounded corners + fast_rounded_corner_layer->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + + fast_rounded_corner_layer->SetIsFastRoundedCorner(true); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this layer has a fast rounded corner, it should not have a render + // surface even though it has 2 layers in the subtree that draws content. + const EffectNode* effect_node = + GetEffectNode(fast_rounded_corner_layer.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this node has 2 descendants that draw, it will have a rounded corner. + effect_node = GetEffectNode(rounded_corner_layer.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* fast_rounded_corner_layer_impl = + layer_tree_impl->LayerById(fast_rounded_corner_layer->id()); + LayerImpl* layer_1_impl = layer_tree_impl->LayerById(layer_1->id()); + LayerImpl* layer_2_impl = layer_tree_impl->LayerById(layer_2->id()); + LayerImpl* rounded_corner_layer_impl = + layer_tree_impl->LayerById(rounded_corner_layer->id()); + LayerImpl* layer_3_impl = layer_tree_impl->LayerById(layer_3->id()); + LayerImpl* layer_4_impl = layer_tree_impl->LayerById(layer_4->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Fast rounded corner layer. + // The render target for this layer is |root|, hence its target bounds are + // relative to |root|. + // The offset from the origin of the render target is [0, 0] and the device + // scale factor is 1.6. + const gfx::RRectF actual_rrect_1 = + fast_rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Layer 1 and layer 2 rounded corner bounds + // This should have the same rounded corner boudns as fast rounded corner + // layer. + const gfx::RRectF layer_1_rrect = + layer_1_impl->draw_properties().rounded_corner_bounds; + const gfx::RRectF layer_2_rrect = + layer_2_impl->draw_properties().rounded_corner_bounds; + EXPECT_EQ(actual_rrect_1, layer_1_rrect); + EXPECT_EQ(actual_rrect_1, layer_2_rrect); + + // Rounded corner layer + // The render target for this layer is |root|. + // The offset from the origin of the render target is [40, 40] and the device + // scale factor is 1.6 thus giving the target space origin of [64, 64]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_2 = + rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_2 = + rounded_corner_layer_impl->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); + + // Layer 3 and layer 4 should have no rounded corner bounds set as their + // parent is a render surface. + const gfx::RRectF layer_3_rrect = + layer_3_impl->draw_properties().rounded_corner_bounds; + const gfx::RRectF layer_4_rrect = + layer_4_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(layer_3_rrect.IsEmpty()); + EXPECT_TRUE(layer_4_rrect.IsEmpty()); +} + +TEST_F(PropertyTreeBuilderTest, + FastRoundedCornerTriggersRenderSurfaceInAncestor) { + // Layer Tree: + // +root + // +--rounded corner layer [1] [should trigger render surface] + // +----fast rounded corner layer [2] [should not trigger render surface] + // +--rounded corner layer [3] [should trigger render surface] + // +----rounded corner layer [4] [should not trigger render surface] + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + constexpr int kRoundedCorner3Radius = 1; + constexpr int kRoundedCorner4Radius = 3; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(5.f, 5.f, 50.f, 50.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 25.f, 25.f); + constexpr gfx::RectF kRoundedCornerLayer3Bound(40.f, 40.f, 60.f, 60.f); + constexpr gfx::RectF kRoundedCornerLayer4Bound(30.f, 0.f, 30.f, 60.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> fast_rounded_corner_layer_2 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create(); + + // Set up layer tree + root->AddChild(rounded_corner_layer_1); + root->AddChild(rounded_corner_layer_3); + + rounded_corner_layer_1->AddChild(fast_rounded_corner_layer_2); + + rounded_corner_layer_3->AddChild(rounded_corner_layer_4); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + fast_rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); + rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin()); + rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + fast_rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + rounded_corner_layer_3->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); + rounded_corner_layer_4->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); + + root->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + fast_rounded_corner_layer_2->SetIsDrawable(true); + rounded_corner_layer_3->SetIsDrawable(true); + rounded_corner_layer_4->SetIsDrawable(true); + + // Set Rounded corners + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + fast_rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + rounded_corner_layer_3->SetRoundedCorner( + {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, + kRoundedCorner3Radius}); + rounded_corner_layer_4->SetRoundedCorner( + {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, + kRoundedCorner4Radius}); + + fast_rounded_corner_layer_2->SetIsFastRoundedCorner(true); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this layer has a descendant that has rounded corner, this node will + // require a render surface. + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this layer has no descendant with rounded corner or drawable, it will + // not have a render surface. + effect_node = GetEffectNode(fast_rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + // Since this layer has 1 descendant with a rounded corner, it should have a + // render surface. + effect_node = GetEffectNode(rounded_corner_layer_3.get()); + gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), + kRoundedCorner3Radius); + EXPECT_EQ(rounded_corner_bounds_3.rect(), + gfx::RectF(kRoundedCornerLayer3Bound.size())); + + // Since this layer no descendants, it would no thave a render pass. + effect_node = GetEffectNode(rounded_corner_layer_4.get()); + gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), + kRoundedCorner4Radius); + EXPECT_EQ(rounded_corner_bounds_4.rect(), + gfx::RectF(kRoundedCornerLayer4Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* rounded_corner_layer_impl_1 = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* fast_rounded_corner_layer_impl_2 = + layer_tree_impl->LayerById(fast_rounded_corner_layer_2->id()); + LayerImpl* rounded_corner_layer_impl_3 = + layer_tree_impl->LayerById(rounded_corner_layer_3->id()); + LayerImpl* rounded_corner_layer_impl_4 = + layer_tree_impl->LayerById(rounded_corner_layer_4->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Rounded corner layer 1. + // The render target for this layer is |root|, hence its target bounds are + // relative to |root|. + // The offset from the origin of the render target is [5, 5] and the device + // scale factor is 1.6 giving a total offset of [8, 8]. + const gfx::RRectF actual_self_rrect_1 = + rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); + + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_1 = + rounded_corner_layer_impl_1->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Fast rounded corner layer 2 + // The render target for this layer is |rounded_corner_layer_1|. + // The offset from the origin of the render target is [0, 0] and the device + // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_2 = + fast_rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); + + // Rounded corner layer 3 + // The render target for this layer is |root|. + // The offset from the origin of the render target is [40, 40] and the device + // scale factor is 1.6 thus giving the target space origin of [64, 64]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_3 = + rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer3Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_3 = + rounded_corner_layer_impl_3->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), + kRoundedCorner3Radius * kDeviceScale); + + // Rounded corner layer 4 + // The render target for this layer is |rounded_corner_layer_3|. + // The offset from the origin of the render target is [30, 0] and the device + // scale factor is 1.6 thus giving the target space origin of [48, 0]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_4 = + rounded_corner_layer_impl_4->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer4Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(), + kRoundedCorner4Radius * kDeviceScale); +} + +TEST_F(PropertyTreeBuilderTest, + FastRoundedCornerDoesNotTriggerRenderSurfaceFromSubtree) { + // Layer Tree: + // +root + // +--fast rounded corner layer 1 [should trigger render surface] + // +----rounded corner layer 1 [should not trigger render surface] + // +--rounded corner layer 2 [should trigger render surface] + // +----rounded corner layer 3 [should not trigger render surface] + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + constexpr int kRoundedCorner3Radius = 4; + constexpr int kRoundedCorner4Radius = 5; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(10.f, 5.f, 45.f, 50.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(5.f, 5.f, 20.f, 20.f); + constexpr gfx::RectF kRoundedCornerLayer3Bound(60.f, 5.f, 40.f, 25.f); + constexpr gfx::RectF kRoundedCornerLayer4Bound(0.f, 10.f, 10.f, 20.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> fast_rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); + + // Set up layer tree + root->AddChild(fast_rounded_corner_layer_1); + root->AddChild(rounded_corner_layer_2); + + fast_rounded_corner_layer_1->AddChild(rounded_corner_layer_1); + rounded_corner_layer_2->AddChild(rounded_corner_layer_3); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + fast_rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer2Bound.origin()); + rounded_corner_layer_2->SetPosition(kRoundedCornerLayer3Bound.origin()); + rounded_corner_layer_3->SetPosition(kRoundedCornerLayer4Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + fast_rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); + rounded_corner_layer_3->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); + + root->SetIsDrawable(true); + fast_rounded_corner_layer_1->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + rounded_corner_layer_2->SetIsDrawable(true); + rounded_corner_layer_3->SetIsDrawable(true); + + // Set Rounded corners + fast_rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, + kRoundedCorner3Radius}); + rounded_corner_layer_3->SetRoundedCorner( + {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, + kRoundedCorner4Radius}); + + fast_rounded_corner_layer_1->SetIsFastRoundedCorner(true); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this layer has a descendant with rounded corner, it needs a render + // surface. + const EffectNode* effect_node = + GetEffectNode(fast_rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this layer has no descendant with rounded corner or drawable, it will + // not have a render surface. + effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + // Since this layer has a descendant with rounded corner, it should have a + // render surface. + effect_node = GetEffectNode(rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), + kRoundedCorner3Radius); + EXPECT_EQ(rounded_corner_bounds_3.rect(), + gfx::RectF(kRoundedCornerLayer3Bound.size())); + + // Since this layer has no descendant, it does not need a render surface. + effect_node = GetEffectNode(rounded_corner_layer_3.get()); + gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), + kRoundedCorner4Radius); + EXPECT_EQ(rounded_corner_bounds_4.rect(), + gfx::RectF(kRoundedCornerLayer4Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* fast_rounded_corner_layer_impl_1 = + layer_tree_impl->LayerById(fast_rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_impl_1 = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_impl_2 = + layer_tree_impl->LayerById(rounded_corner_layer_2->id()); + LayerImpl* rounded_corner_layer_impl_3 = + layer_tree_impl->LayerById(rounded_corner_layer_3->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Fast rounded corner layer 1. + // The render target for this layer is |root|, hence its target bounds are + // relative to |root|. + // The offset from the origin of the render target is [5, 5] and the device + // scale factor is 1.6. + const gfx::RRectF actual_self_rrect_1 = + fast_rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); + + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_1 = + fast_rounded_corner_layer_impl_1->render_target() + ->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Rounded corner layer 1 + // The render target for this layer is |fast_rounded_corner_layer_1|. + // The offset from the origin of the render target is [0, 0] and the device + // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_2 = + rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); + + // Rounded corner layer 3 + // The render target for this layer is |root|. + // The offset from the origin of the render target is [5, 5] and the device + // scale factor is 1.6 thus giving the target space origin of [8, 8]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_3 = + rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer3Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_3 = + rounded_corner_layer_impl_2->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), + kRoundedCorner3Radius * kDeviceScale); + + // Rounded corner layer 4 + // The render target for this layer is |rounded_corner_layer_2|. + // The offset from the origin of the render target is [0, 5] and the device + // scale factor is 1.6 thus giving the target space origin of [0, 8]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_4 = + rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer4Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(), + kRoundedCorner4Radius * kDeviceScale); +} + +} // namespace +} // namespace cc diff --git a/chromium/cc/trees/proxy_common.cc b/chromium/cc/trees/proxy_common.cc index f80fd3553fb..a04796a3aa0 100644 --- a/chromium/cc/trees/proxy_common.cc +++ b/chromium/cc/trees/proxy_common.cc @@ -5,6 +5,7 @@ #include "cc/trees/proxy_common.h" #include "cc/trees/layer_tree_host.h" +#include "cc/trees/scroll_and_scale_set.h" namespace cc { diff --git a/chromium/cc/trees/proxy_common.h b/chromium/cc/trees/proxy_common.h index e4de8308fa4..3d363b26a8a 100644 --- a/chromium/cc/trees/proxy_common.h +++ b/chromium/cc/trees/proxy_common.h @@ -9,11 +9,12 @@ #include "base/callback_forward.h" #include "cc/cc_export.h" -#include "cc/trees/layer_tree_host_common.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" namespace cc { +struct ScrollAndScaleSet; + struct CC_EXPORT BeginMainFrameAndCommitState { BeginMainFrameAndCommitState(); ~BeginMainFrameAndCommitState(); diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc index ed8eb19667d..a43c4b40b7d 100644 --- a/chromium/cc/trees/proxy_impl.cc +++ b/chromium/cc/trees/proxy_impl.cc @@ -24,12 +24,13 @@ #include "cc/trees/mutator_host.h" #include "cc/trees/proxy_main.h" #include "cc/trees/render_frame_metadata_observer.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/task_runner_provider.h" #include "components/viz/common/frame_sinks/delay_based_time_source.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "services/metrics/public/cpp/ukm_recorder.h" -#include "ui/gfx/presentation_feedback.h" namespace cc { @@ -378,6 +379,10 @@ size_t ProxyImpl::MainThreadAnimationsCount() const { return host_impl_->mutator_host()->MainThreadAnimationsCount(); } +bool ProxyImpl::HasCustomPropertyAnimations() const { + return host_impl_->mutator_host()->HasCustomPropertyAnimations(); +} + bool ProxyImpl::CurrentFrameHadRAF() const { return host_impl_->mutator_host()->CurrentFrameHadRAF(); } @@ -500,13 +505,14 @@ void ProxyImpl::NotifyImageDecodeRequestFinished() { void ProxyImpl::DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) { + const viz::FrameTimingDetails& details) { MainThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyMain::DidPresentCompositorFrame, - proxy_main_weak_ptr_, frame_token, - std::move(callbacks), feedback)); + FROM_HERE, + base::BindOnce(&ProxyMain::DidPresentCompositorFrame, + proxy_main_weak_ptr_, frame_token, std::move(callbacks), + details.presentation_feedback)); if (scheduler_) - scheduler_->DidPresentCompositorFrame(frame_token, feedback.timestamp); + scheduler_->DidPresentCompositorFrame(frame_token, details); } void ProxyImpl::NotifyAnimationWorkletStateChange( diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h index d8222df2013..b245b60c0f5 100644 --- a/chromium/cc/trees/proxy_impl.h +++ b/chromium/cc/trees/proxy_impl.h @@ -14,6 +14,10 @@ #include "cc/scheduler/scheduler.h" #include "cc/trees/layer_tree_host_impl.h" +namespace viz { +struct FrameTimingDetails; +} + namespace cc { class LayerTreeHost; class ProxyMain; @@ -109,7 +113,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, void DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) override; + const viz::FrameTimingDetails& details) override; void NotifyAnimationWorkletStateChange( AnimationWorkletMutationState state, ElementListType element_list_type) override; @@ -137,6 +141,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, void FrameIntervalUpdated(base::TimeDelta interval) override {} size_t CompositedAnimationsCount() const override; size_t MainThreadAnimationsCount() const override; + bool HasCustomPropertyAnimations() const override; bool CurrentFrameHadRAF() const override; bool NextFrameHasPendingRAF() const override; diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc index 7e9e5b66b2f..f5b1875c8b0 100644 --- a/chromium/cc/trees/proxy_main.cc +++ b/chromium/cc/trees/proxy_main.cc @@ -132,6 +132,10 @@ void ProxyMain::BeginMainFrame( benchmark_instrumentation::kDoBeginFrame, begin_main_frame_state->begin_frame_id); + // This needs to run unconditionally, so do it before any early-returns. + if (layer_tree_host_->scheduling_client()) + layer_tree_host_->scheduling_client()->DidRunBeginMainFrame(); + // If the commit finishes, LayerTreeHost will transfer its swap promises to // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the // remaining swap promises. @@ -217,6 +221,13 @@ void ProxyMain::BeginMainFrame( } layer_tree_host_->WillBeginMainFrame(); + + // This call winds through to the LocalFrameView to mark the beginning + // of a main frame for metrics purposes. Some metrics are only gathered + // between calls to RecordStartOfFrameMetrics and RecordEndOfFrameMetrics. + // This is not wrapped into layer_tree_host_->WillBeginMainFrame because + // it should only be called from the multi-threaded proxy (we do not want + // metrics gathering in tests). layer_tree_host_->RecordStartOfFrameMetrics(); // See LayerTreeHostClient::BeginMainFrame for more documentation on @@ -236,7 +247,7 @@ void ProxyMain::BeginMainFrame( // See LayerTreeHostClient::MainFrameUpdate for more documentation on // what this does. - layer_tree_host_->RequestMainFrameUpdate(); + layer_tree_host_->RequestMainFrameUpdate(true /* report_cc_metrics */); // At this point the main frame may have deferred main frame updates to // avoid committing right now, or we may be deferring commits but not @@ -313,16 +324,6 @@ void ProxyMain::BeginMainFrame( return; } - // Queue the LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT swap promise only - // once we know we will commit since QueueSwapPromise itself requests a - // commit. - ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME); - new_latency_info.AddLatencyNumberWithTimestamp( - ui::LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT, - begin_main_frame_state->begin_frame_args.frame_time); - layer_tree_host_->QueueSwapPromise( - std::make_unique<LatencyInfoSwapPromise>(new_latency_info)); - current_pipeline_stage_ = NO_PIPELINE_STAGE; // Notify the impl thread that the main thread is ready to commit. This will diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h index 515f1e10de9..cfef4ce6031 100644 --- a/chromium/cc/trees/proxy_main.h +++ b/chromium/cc/trees/proxy_main.h @@ -7,6 +7,7 @@ #include "cc/cc_export.h" #include "cc/input/browser_controls_state.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/proxy.h" #include "cc/trees/proxy_common.h" diff --git a/chromium/cc/trees/scroll_and_scale_set.cc b/chromium/cc/trees/scroll_and_scale_set.cc new file mode 100644 index 00000000000..e2d08c839c1 --- /dev/null +++ b/chromium/cc/trees/scroll_and_scale_set.cc @@ -0,0 +1,22 @@ +// Copyright 2011 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 "cc/trees/scroll_and_scale_set.h" + +#include "cc/trees/swap_promise.h" + +namespace cc { + +ScrollAndScaleSet::ScrollAndScaleSet() + : page_scale_delta(1.f), + is_pinch_gesture_active(false), + top_controls_delta(0.f), + browser_controls_constraint(BrowserControlsState::kBoth), + browser_controls_constraint_changed(false), + scroll_gesture_did_end(false), + manipulation_info(kManipulationInfoNone) {} + +ScrollAndScaleSet::~ScrollAndScaleSet() = default; + +} // namespace cc diff --git a/chromium/cc/trees/scroll_and_scale_set.h b/chromium/cc/trees/scroll_and_scale_set.h new file mode 100644 index 00000000000..41687918fb2 --- /dev/null +++ b/chromium/cc/trees/scroll_and_scale_set.h @@ -0,0 +1,93 @@ +// Copyright 2011 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. + +#ifndef CC_TREES_SCROLL_AND_SCALE_SET_H_ +#define CC_TREES_SCROLL_AND_SCALE_SET_H_ + +#include <vector> + +#include "cc/cc_export.h" +#include "cc/input/browser_controls_state.h" +#include "cc/paint/element_id.h" +#include "cc/trees/layer_tree_host_client.h" +#include "ui/gfx/geometry/scroll_offset.h" +#include "ui/gfx/geometry/vector2d.h" +#include "ui/gfx/transform.h" + +namespace cc { + +class SwapPromise; + +struct CC_EXPORT ScrollAndScaleSet { + ScrollAndScaleSet(); + ScrollAndScaleSet(const ScrollAndScaleSet&) = delete; + ~ScrollAndScaleSet(); + + ScrollAndScaleSet& operator=(const ScrollAndScaleSet&) = delete; + + struct CC_EXPORT ScrollUpdateInfo { + ElementId element_id; + gfx::ScrollOffset scroll_delta; + + bool operator==(const ScrollUpdateInfo& other) const { + return element_id == other.element_id && + scroll_delta == other.scroll_delta; + } + }; + + // The inner viewport scroll delta is kept separate since it's special. + // Because the inner (visual) viewport's maximum offset depends on the + // current page scale, the two must be committed at the same time to prevent + // clamping. + ScrollUpdateInfo inner_viewport_scroll; + + std::vector<ScrollUpdateInfo> scrolls; + float page_scale_delta; + bool is_pinch_gesture_active; + + // Elastic overscroll effect offset delta. This is used only on Mac and shows + // the pixels that the page is rubber-banned/stretched by. + gfx::Vector2dF elastic_overscroll_delta; + + // Unconsumed scroll delta used to send overscroll events to the latched + // element on the main thread; + gfx::Vector2dF overscroll_delta; + + // The element id of the node to which scrolling is latched. This is used to + // send overscroll/scrollend DOM events to proper targets whenever needed. + ElementId scroll_latched_element_id; + + float top_controls_delta; + + // Used to communicate scrollbar visibility from Impl thread to Blink. + // Scrollbar input is handled by Blink but the compositor thread animates + // opacity on scrollbars to fade them out when they're overlay. Blink needs + // to be told when they're faded out so it can stop handling input for + // invisible scrollbars. + struct CC_EXPORT ScrollbarsUpdateInfo { + ElementId element_id; + bool hidden = true; + + bool operator==(const ScrollbarsUpdateInfo& other) const { + return element_id == other.element_id && hidden == other.hidden; + } + }; + std::vector<ScrollbarsUpdateInfo> scrollbars; + + std::vector<std::unique_ptr<SwapPromise>> swap_promises; + BrowserControlsState browser_controls_constraint; + bool browser_controls_constraint_changed; + + // Set to true when a scroll gesture being handled on the compositor has + // ended. + bool scroll_gesture_did_end; + + // Tracks different methods of scrolling (e.g. wheel, touch, precision + // touchpad, etc.). + ManipulationInfo manipulation_info; +}; + +} // namespace cc + +#endif // CC_TREES_SCROLL_AND_SCALE_SET_H_ diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index 962b023a9a2..64cf02bdbf2 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -19,15 +19,15 @@ #include "cc/trees/latency_info_swap_promise.h" #include "cc/trees/layer_tree_frame_sink.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_single_thread_client.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/render_frame_metadata_observer.h" #include "cc/trees/scoped_abort_remaining_swap_promises.h" +#include "cc/trees/scroll_and_scale_set.h" #include "components/viz/common/frame_sinks/delay_based_time_source.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/gpu/context_provider.h" -#include "ui/gfx/presentation_feedback.h" namespace cc { @@ -427,6 +427,10 @@ size_t SingleThreadProxy::MainThreadAnimationsCount() const { return 0; } +bool SingleThreadProxy::HasCustomPropertyAnimations() const { + return false; +} + bool SingleThreadProxy::CurrentFrameHadRAF() const { return false; } @@ -529,13 +533,12 @@ void SingleThreadProxy::NotifyImageDecodeRequestFinished() { void SingleThreadProxy::DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) { + const viz::FrameTimingDetails& details) { layer_tree_host_->DidPresentCompositorFrame(frame_token, std::move(callbacks), - feedback); + details.presentation_feedback); if (scheduler_on_impl_thread_) { - scheduler_on_impl_thread_->DidPresentCompositorFrame(frame_token, - feedback.timestamp); + scheduler_on_impl_thread_->DidPresentCompositorFrame(frame_token, details); } } @@ -576,8 +579,8 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time, } viz::BeginFrameArgs begin_frame_args(viz::BeginFrameArgs::Create( - BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1, - frame_begin_time, base::TimeTicks(), + BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, + begin_frame_sequence_number_++, frame_begin_time, base::TimeTicks(), viz::BeginFrameArgs::DefaultInterval(), viz::BeginFrameArgs::NORMAL)); // Start the impl frame. @@ -841,14 +844,6 @@ void SingleThreadProxy::BeginMainFrame( return; } - // Queue the LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT swap promise only once we - // know we will commit since QueueSwapPromise itself requests a commit. - ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME); - new_latency_info.AddLatencyNumberWithTimestamp( - ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, begin_frame_args.frame_time); - layer_tree_host_->QueueSwapPromise( - std::make_unique<LatencyInfoSwapPromise>(new_latency_info)); - DoPainting(); } @@ -868,7 +863,7 @@ void SingleThreadProxy::DoBeginMainFrame( layer_tree_host_->WillBeginMainFrame(); layer_tree_host_->BeginMainFrame(begin_frame_args); layer_tree_host_->AnimateLayers(begin_frame_args.frame_time); - layer_tree_host_->RequestMainFrameUpdate(); + layer_tree_host_->RequestMainFrameUpdate(false /* record_cc_metrics */); } void SingleThreadProxy::DoPainting() { diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h index 320688ea79b..3cde647963d 100644 --- a/chromium/cc/trees/single_thread_proxy.h +++ b/chromium/cc/trees/single_thread_proxy.h @@ -17,6 +17,7 @@ namespace viz { class BeginFrameSource; +struct FrameTimingDetails; } namespace cc { @@ -96,6 +97,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void FrameIntervalUpdated(base::TimeDelta interval) override; size_t CompositedAnimationsCount() const override; size_t MainThreadAnimationsCount() const override; + bool HasCustomPropertyAnimations() const override; bool CurrentFrameHadRAF() const override; bool NextFrameHasPendingRAF() const override; @@ -130,7 +132,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) override; + const viz::FrameTimingDetails& details) override; void NotifyAnimationWorkletStateChange( AnimationWorkletMutationState state, ElementListType element_list_type) override; @@ -201,6 +203,10 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // initialized. bool layer_tree_frame_sink_lost_; + // A number that kept incrementing in CompositeImmediately, which indicates a + // new impl frame. + uint64_t begin_frame_sequence_number_ = 1u; + // This is the callback for the scheduled RequestNewLayerTreeFrameSink. base::CancelableOnceClosure layer_tree_frame_sink_creation_callback_; diff --git a/chromium/cc/trees/swap_promise_manager_unittest.cc b/chromium/cc/trees/swap_promise_manager_unittest.cc index 154feb117f0..5bf0c072971 100644 --- a/chromium/cc/trees/swap_promise_manager_unittest.cc +++ b/chromium/cc/trees/swap_promise_manager_unittest.cc @@ -21,7 +21,6 @@ class MockSwapPromiseMonitor : public SwapPromiseMonitor { MOCK_METHOD0(OnSetNeedsCommitOnMain, void()); void OnSetNeedsRedrawOnImpl() override {} - void OnForwardScrollUpdateToMainThreadOnImpl() override {} }; class MockSwapPromise : public SwapPromise { diff --git a/chromium/cc/trees/swap_promise_monitor.h b/chromium/cc/trees/swap_promise_monitor.h index 7efe2e281a5..3350ca1ffd9 100644 --- a/chromium/cc/trees/swap_promise_monitor.h +++ b/chromium/cc/trees/swap_promise_monitor.h @@ -33,7 +33,6 @@ class CC_EXPORT SwapPromiseMonitor { virtual void OnSetNeedsCommitOnMain() = 0; virtual void OnSetNeedsRedrawOnImpl() = 0; - virtual void OnForwardScrollUpdateToMainThreadOnImpl() = 0; protected: SwapPromiseManager* swap_promise_manager_; diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc index 33c32cbb52c..0419820ba5d 100644 --- a/chromium/cc/trees/tree_synchronizer.cc +++ b/chromium/cc/trees/tree_synchronizer.cc @@ -68,7 +68,7 @@ template <typename LayerTreeType> void PushLayerList(OwnedLayerImplMap* old_layers, LayerTreeType* host, LayerTreeImpl* tree_impl) { - tree_impl->ClearLayerList(); + DCHECK(tree_impl->LayerListIsEmpty()); for (auto* layer : *host) { std::unique_ptr<LayerImpl> layer_impl( ReuseOrCreateLayerImpl(old_layers, layer, tree_impl)); @@ -82,7 +82,6 @@ void PushLayerList(OwnedLayerImplMap* old_layers, LayerWillPushProperties(host, layer)); #endif - tree_impl->AddToLayerList(layer_impl.get()); tree_impl->AddLayer(std::move(layer_impl)); } tree_impl->OnCanDrawStateChangedForTree(); @@ -95,21 +94,15 @@ void SynchronizeTreesInternal(LayerTreeType* source_tree, DCHECK(tree_impl); TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees"); - std::unique_ptr<OwnedLayerImplList> old_layers(tree_impl->DetachLayers()); + OwnedLayerImplList old_layers = tree_impl->DetachLayers(); OwnedLayerImplMap old_layer_map; - for (auto& it : *old_layers) { + for (auto& it : old_layers) { DCHECK(it); old_layer_map[it->id()] = std::move(it); } PushLayerList(&old_layer_map, source_tree, tree_impl); - - for (int id : property_trees->effect_tree.mask_layer_ids()) { - std::unique_ptr<LayerImpl> layer_impl(ReuseOrCreateLayerImpl( - &old_layer_map, source_tree->LayerById(id), tree_impl)); - tree_impl->AddLayer(std::move(layer_impl)); - } } } // namespace diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc index 08690725e5f..5f1a8f09d31 100644 --- a/chromium/cc/trees/tree_synchronizer_unittest.cc +++ b/chromium/cc/trees/tree_synchronizer_unittest.cc @@ -27,7 +27,7 @@ #include "cc/test/stub_layer_tree_host_single_thread_client.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/task_runner_provider.h" @@ -109,16 +109,6 @@ void ExpectTreesAreIdentical(Layer* root_layer, EXPECT_EQ(layer->non_fast_scrollable_region(), layer_impl->non_fast_scrollable_region()); - - const EffectTree& effect_tree = tree_impl->property_trees()->effect_tree; - if (layer->mask_layer()) { - SCOPED_TRACE("mask_layer"); - int mask_layer_id = layer->mask_layer()->id(); - EXPECT_TRUE(tree_impl->LayerById(mask_layer_id)); - EXPECT_EQ( - mask_layer_id, - effect_tree.Node(layer_impl->effect_tree_index())->mask_layer_id); - } } } @@ -150,7 +140,7 @@ class TreeSynchronizerTest : public testing::Test { host_impl->ActivateSyncTree(); ExpectTreesAreIdentical(layer_tree_root.get(), - host_impl->active_tree()->root_layer_for_testing(), + host_impl->active_tree()->root_layer(), host_impl->active_tree()); return scroll_layer; @@ -175,7 +165,7 @@ class TreeSynchronizerTest : public testing::Test { TEST_F(TreeSynchronizerTest, SyncNullTree) { TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(nullptr), host_->pending_tree()); - EXPECT_TRUE(!host_->pending_tree()->root_layer_for_testing()); + EXPECT_TRUE(!host_->pending_tree()->root_layer()); } // Constructs a very simple tree and synchronizes it without trying to reuse any @@ -191,12 +181,12 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) { TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->pending_tree()); - LayerImpl* root = host_->pending_tree()->root_layer_for_testing(); + LayerImpl* root = host_->pending_tree()->root_layer(); EXPECT_TRUE(base::Contains( host_->pending_tree()->LayersThatShouldPushProperties(), root)); ExpectTreesAreIdentical(layer_tree_root.get(), - host_->pending_tree()->root_layer_for_testing(), + host_->pending_tree()->root_layer(), host_->pending_tree()); } @@ -217,12 +207,12 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndPushPropertiesFromEmpty) { // First time the main thread layers are synced to pending tree, and all the // layers are created on pending tree and they all need to push properties to // active tree. - LayerImpl* root = host_->pending_tree()->root_layer_for_testing(); + LayerImpl* root = host_->pending_tree()->root_layer(); EXPECT_TRUE(base::Contains( host_->pending_tree()->LayersThatShouldPushProperties(), root)); ExpectTreesAreIdentical(layer_tree_root.get(), - host_->pending_tree()->root_layer_for_testing(), + host_->pending_tree()->root_layer(), host_->pending_tree()); // Push properties to make pending tree have valid property tree index. @@ -267,8 +257,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->pending_tree()); - LayerImpl* layer_impl_tree_root = - host_->pending_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->pending_tree()->root_layer(); EXPECT_TRUE( base::Contains(host_->pending_tree()->LayersThatShouldPushProperties(), layer_impl_tree_root)); @@ -291,7 +280,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->pending_tree()); - layer_impl_tree_root = host_->pending_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->pending_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->pending_tree()); @@ -322,8 +311,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -339,7 +327,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -382,8 +370,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -430,8 +417,7 @@ TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -458,7 +444,7 @@ TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -488,8 +474,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(), host_->active_tree()); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(old_layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -508,7 +493,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(), host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(new_layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -538,8 +523,7 @@ TEST_F(TreeSynchronizerTest, SyncMaskLayer) { host_->BuildPropertyTreesForTesting(); host_->CommitAndCreateLayerImplTree(); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -548,15 +532,15 @@ TEST_F(TreeSynchronizerTest, SyncMaskLayer) { host_->BuildPropertyTreesForTesting(); host_->CommitAndCreateLayerImplTree(); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -589,7 +573,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) { host_impl->ActivateSyncTree(); ExpectTreesAreIdentical(layer_tree_root.get(), - host_impl->active_tree()->root_layer_for_testing(), + host_impl->active_tree()->root_layer(), host_impl->active_tree()); ScrollNode* scroll_node = @@ -641,7 +625,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) { host_impl->ActivateSyncTree(); ExpectTreesAreIdentical(layer_tree_root.get(), - host_impl->active_tree()->root_layer_for_testing(), + host_impl->active_tree()->root_layer(), host_impl->active_tree()); // After the initial commit, scroll_offset_map in scroll_tree is expected to |