diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-17 13:57:45 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-19 13:44:40 +0000 |
commit | 6ec7b8da05d21a3878bd21c691b41e675d74bb1c (patch) | |
tree | b87f250bc19413750b9bb9cdbf2da20ef5014820 /chromium/cc/trees | |
parent | ec02ee4181c49b61fce1c8fb99292dbb8139cc90 (diff) | |
download | qtwebengine-chromium-6ec7b8da05d21a3878bd21c691b41e675d74bb1c.tar.gz |
BASELINE: Update Chromium to 60.0.3112.70
Change-Id: I9911c2280a014d4632f254857876a395d4baed2d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/cc/trees')
56 files changed, 4010 insertions, 3696 deletions
diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc index aa4a6236801..d740521408d 100644 --- a/chromium/cc/trees/damage_tracker.cc +++ b/chromium/cc/trees/damage_tracker.cc @@ -14,6 +14,7 @@ #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer_impl.h" #include "cc/layers/render_surface_impl.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" @@ -29,18 +30,14 @@ DamageTracker::DamageTracker() DamageTracker::~DamageTracker() {} -void DamageTracker::UpdateDamageTrackingState( - const LayerImplList& layer_list, - const RenderSurfaceImpl* target_surface, - bool target_surface_property_changed_only_from_descendant, - const gfx::Rect& target_surface_content_rect, - LayerImpl* target_surface_mask_layer, - const FilterOperations& filters) { +void DamageTracker::UpdateDamageTracking( + LayerTreeImpl* layer_tree_impl, + const RenderSurfaceList& render_surface_list) { // - // This function computes the "damage rect" of a target surface, and updates - // the state that is used to correctly track damage across frames. The damage - // rect is the region of the surface that may have changed and needs to be - // redrawn. This can be used to scissor what is actually drawn, to save GPU + // This function computes the "damage rect" of each target surface, and + // updates the state that is used to correctly track damage across frames. The + // damage rect is the region of the surface that may have changed and needs to + // be redrawn. This can be used to scissor what is actually drawn, to save GPU // computation and bandwidth. // // The surface's damage rect is computed as the union of all possible changes @@ -52,25 +49,30 @@ void DamageTracker::UpdateDamageTrackingState( // // The basic algorithm for computing the damage region is as follows: // - // 1. compute damage caused by changes in active/new layers - // for each layer in the layer_list: - // if the layer is actually a render_surface: - // add the surface's damage to our target surface. - // else - // add the layer's damage to the target surface. + // 1. compute damage caused by changes in contributing layers or surfaces + // for each contributing layer or render surface: + // add the layer's or surface's damage to the target surface. // // 2. compute damage caused by the target surface's mask, if it exists. // // 3. compute damage caused by old layers/surfaces that no longer exist - // for each leftover layer: + // for each leftover layer or render surface: // add the old layer/surface bounds to the target surface damage. // // 4. combine all partial damage rects to get the full damage rect. // // Additional important points: // - // - This algorithm is implicitly recursive; it assumes that descendant - // surfaces have already computed their damage. + // - This algorithm requires that descendant surfaces compute their damage + // before ancestor surfaces. Further, since contributing surfaces with + // background filters can expand the damage caused by contributors + // underneath them (that is, before them in draw order), the exact damage + // caused by these contributors must be computed before computing the damage + // caused by the contributing surface. This is implemented by visiting + // layers in draw order, computing the damage caused by each one to their + // target; during this walk, as soon as all of a surface's contributors have + // been visited, the surface's own damage is computed and then added to its + // target's accumulated damage. // // - Changes to layers/surfaces indicate "damage" to the target surface; If a // layer is not changed, it does NOT mean that the layer can skip drawing. @@ -104,40 +106,98 @@ void DamageTracker::UpdateDamageTrackingState( // erased from map. // - PrepareRectHistoryForUpdate(); + for (RenderSurfaceImpl* render_surface : render_surface_list) { + render_surface->damage_tracker()->PrepareForUpdate(); + } + + EffectTree& effect_tree = layer_tree_impl->property_trees()->effect_tree; + int current_target_effect_id = EffectTree::kContentsRootNodeId; + DCHECK(effect_tree.GetRenderSurface(current_target_effect_id)); + for (LayerImpl* layer : *layer_tree_impl) { + if (!layer->contributes_to_drawn_render_surface()) + continue; + + int next_target_effect_id = layer->render_target_effect_tree_index(); + if (next_target_effect_id != current_target_effect_id) { + int lowest_common_ancestor_id = + effect_tree.LowestCommonAncestorWithRenderSurface( + current_target_effect_id, next_target_effect_id); + while (current_target_effect_id != lowest_common_ancestor_id) { + // Moving to a non-descendant target surface. This implies that the + // current target doesn't have any more contributors, since only + // descendants can contribute to a target, and the each's target's + // content (including content contributed by descendants) is contiguous + // in draw order. + RenderSurfaceImpl* current_target = + effect_tree.GetRenderSurface(current_target_effect_id); + current_target->damage_tracker()->ComputeSurfaceDamage(current_target); + RenderSurfaceImpl* parent_target = current_target->render_target(); + parent_target->damage_tracker()->AccumulateDamageFromRenderSurface( + current_target); + current_target_effect_id = + effect_tree.Node(current_target_effect_id)->target_id; + } + current_target_effect_id = next_target_effect_id; + } + + RenderSurfaceImpl* target_surface = layer->render_target(); + + // We skip damage from the HUD layer because (a) the HUD layer damages the + // whole frame and (b) we don't want HUD layer damage to be shown by the + // HUD damage rect visualization. + if (layer != layer_tree_impl->hud_layer()) { + target_surface->damage_tracker()->AccumulateDamageFromLayer(layer); + } + } + + DCHECK_GE(current_target_effect_id, EffectTree::kContentsRootNodeId); + RenderSurfaceImpl* current_target = + effect_tree.GetRenderSurface(current_target_effect_id); + while (true) { + current_target->damage_tracker()->ComputeSurfaceDamage(current_target); + if (current_target->EffectTreeIndex() == EffectTree::kContentsRootNodeId) + break; + RenderSurfaceImpl* next_target = current_target->render_target(); + next_target->damage_tracker()->AccumulateDamageFromRenderSurface( + current_target); + current_target = next_target; + } +} + +void DamageTracker::ComputeSurfaceDamage(RenderSurfaceImpl* render_surface) { + // All damage from contributing layers and surfaces must already have been + // added to damage_for_this_update_ through calls to AccumulateDamageFromLayer + // and AccumulateDamageFromRenderSurface. + // 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_active_layers = - TrackDamageFromActiveLayers(layer_list, target_surface); DamageAccumulator damage_from_surface_mask = - TrackDamageFromSurfaceMask(target_surface_mask_layer); + TrackDamageFromSurfaceMask(render_surface->MaskLayer()); DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects(); - DamageAccumulator damage_for_this_update; - - if (target_surface_property_changed_only_from_descendant) { - damage_for_this_update.Union(target_surface_content_rect); + if (render_surface->SurfacePropertyChangedOnlyFromDescendant()) { + damage_for_this_update_ = DamageAccumulator(); + damage_for_this_update_.Union(render_surface->content_rect()); } 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_active_layers); - damage_for_this_update.Union(damage_from_surface_mask); - damage_for_this_update.Union(damage_from_leftover_rects); + damage_for_this_update_.Union(damage_from_surface_mask); + damage_for_this_update_.Union(damage_from_leftover_rects); gfx::Rect damage_rect; - bool is_rect_valid = damage_for_this_update.GetAsRect(&damage_rect); + bool is_rect_valid = damage_for_this_update_.GetAsRect(&damage_rect); if (is_rect_valid) { - damage_rect = - filters.MapRect(damage_rect, target_surface->SurfaceScale().matrix()); - damage_for_this_update = DamageAccumulator(); - damage_for_this_update.Union(damage_rect); + damage_rect = render_surface->Filters().MapRect( + damage_rect, render_surface->SurfaceScale().matrix()); + damage_for_this_update_ = DamageAccumulator(); + damage_for_this_update_.Union(damage_rect); } } // Damage accumulates until we are notified that we actually did draw on that // frame. - current_damage_.Union(damage_for_this_update); + current_damage_.Union(damage_for_this_update_); } bool DamageTracker::GetDamageRectIfValid(gfx::Rect* rect) { @@ -177,31 +237,6 @@ DamageTracker::SurfaceRectMapData& DamageTracker::RectDataForSurface( return *it; } -DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromActiveLayers( - const LayerImplList& layer_list, - const RenderSurfaceImpl* target_surface) { - DamageAccumulator damage; - - for (size_t layer_index = 0; layer_index < layer_list.size(); ++layer_index) { - // Visit layers in back-to-front order. - LayerImpl* layer = layer_list[layer_index]; - - // We skip damage from the HUD layer because (a) the HUD layer damages the - // whole frame and (b) we don't want HUD layer damage to be shown by the - // HUD damage rect visualization. - if (layer == layer->layer_tree_impl()->hud_layer()) - continue; - - RenderSurfaceImpl* render_surface = layer->GetRenderSurface(); - if (render_surface && render_surface != target_surface) - ExtendDamageForRenderSurface(render_surface, &damage); - else - ExtendDamageForLayer(layer, &damage); - } - - return damage; -} - DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask( LayerImpl* target_surface_mask_layer) { DamageAccumulator damage; @@ -220,8 +255,9 @@ DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask( return damage; } -void DamageTracker::PrepareRectHistoryForUpdate() { +void DamageTracker::PrepareForUpdate() { mailboxId_++; + damage_for_this_update_ = DamageAccumulator(); } DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() { @@ -292,12 +328,11 @@ DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() { void DamageTracker::ExpandDamageInsideRectWithFilters( const gfx::Rect& pre_filter_rect, - const FilterOperations& filters, - DamageAccumulator* damage) { + const FilterOperations& filters) { gfx::Rect damage_rect; - bool is_valid_rect = damage->GetAsRect(&damage_rect); - // If the input isn't a valid rect, then there is no point in trying to make - // it bigger. + bool is_valid_rect = damage_for_this_update_.GetAsRect(&damage_rect); + // If the damage accumulated so far isn't a valid rect, then there is no point + // in trying to make it bigger. if (!is_valid_rect) return; @@ -308,11 +343,10 @@ void DamageTracker::ExpandDamageInsideRectWithFilters( // Restrict it to the rectangle in which the background filter is shown. expanded_damage_rect.Intersect(pre_filter_rect); - damage->Union(expanded_damage_rect); + damage_for_this_update_.Union(expanded_damage_rect); } -void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, - DamageAccumulator* target_damage) { +void DamageTracker::AccumulateDamageFromLayer(LayerImpl* layer) { // There are two ways that a layer can damage a region of the target surface: // 1. Property change (e.g. opacity, position, transforms): // - the entire region of the layer itself damages the surface. @@ -341,11 +375,11 @@ void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, if (layer_is_new || layer->LayerPropertyChanged()) { // If a layer is new or has changed, then its entire layer rect affects the // target surface. - target_damage->Union(rect_in_target_space); + damage_for_this_update_.Union(rect_in_target_space); // The layer's old region is now exposed on the target surface, too. // Note old_rect_in_target_space is already in target space. - target_damage->Union(old_rect_in_target_space); + damage_for_this_update_.Union(old_rect_in_target_space); return; } @@ -357,13 +391,12 @@ void DamageTracker::ExtendDamageForLayer(LayerImpl* layer, if (!damage_rect.IsEmpty()) { gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect); - target_damage->Union(damage_rect_in_target_space); + damage_for_this_update_.Union(damage_rect_in_target_space); } } -void DamageTracker::ExtendDamageForRenderSurface( - RenderSurfaceImpl* render_surface, - DamageAccumulator* target_damage) { +void DamageTracker::AccumulateDamageFromRenderSurface( + RenderSurfaceImpl* render_surface) { // There are two ways a "descendant surface" can damage regions of the "target // surface": // 1. Property change: @@ -390,10 +423,10 @@ void DamageTracker::ExtendDamageForRenderSurface( if (surface_is_new || render_surface->SurfacePropertyChanged()) { // The entire surface contributes damage. - target_damage->Union(surface_rect_in_target_space); + damage_for_this_update_.Union(surface_rect_in_target_space); // The surface's old region is now exposed on the target surface, too. - target_damage->Union(old_surface_rect); + damage_for_this_update_.Union(old_surface_rect); } else { // Only the surface's damage_rect will damage the target surface. gfx::Rect damage_rect_in_local_space; @@ -405,9 +438,9 @@ void DamageTracker::ExtendDamageForRenderSurface( const gfx::Transform& draw_transform = render_surface->draw_transform(); gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( draw_transform, damage_rect_in_local_space); - target_damage->Union(damage_rect_in_target_space); + damage_for_this_update_.Union(damage_rect_in_target_space); } else if (!is_valid_rect) { - target_damage->Union(surface_rect_in_target_space); + damage_for_this_update_.Union(surface_rect_in_target_space); } } @@ -421,7 +454,7 @@ void DamageTracker::ExtendDamageForRenderSurface( render_surface->BackgroundFilters(); if (background_filters.HasFilterThatMovesPixels()) { ExpandDamageInsideRectWithFilters(surface_rect_in_target_space, - background_filters, target_damage); + background_filters); } } diff --git a/chromium/cc/trees/damage_tracker.h b/chromium/cc/trees/damage_tracker.h index 6ddc504dafa..751eeb977e5 100644 --- a/chromium/cc/trees/damage_tracker.h +++ b/chromium/cc/trees/damage_tracker.h @@ -21,6 +21,7 @@ namespace cc { class FilterOperations; class LayerImpl; +class LayerTreeImpl; class RenderSurfaceImpl; // Computes the region where pixels have actually changed on a @@ -31,15 +32,12 @@ class CC_EXPORT DamageTracker { static std::unique_ptr<DamageTracker> Create(); ~DamageTracker(); + static void UpdateDamageTracking( + LayerTreeImpl* layer_tree_impl, + const RenderSurfaceList& render_surface_list); + void DidDrawDamagedArea() { current_damage_ = DamageAccumulator(); } void AddDamageNextUpdate(const gfx::Rect& dmg) { current_damage_.Union(dmg); } - void UpdateDamageTrackingState( - const LayerImplList& layer_list, - const RenderSurfaceImpl* target_surface, - bool target_surface_property_changed_only_from_descendant, - const gfx::Rect& target_surface_content_rect, - LayerImpl* target_surface_mask_layer, - const FilterOperations& filters); bool GetDamageRectIfValid(gfx::Rect* rect); @@ -84,21 +82,17 @@ class CC_EXPORT DamageTracker { int bottom_ = 0; }; - DamageAccumulator TrackDamageFromActiveLayers( - const LayerImplList& layer_list, - const RenderSurfaceImpl* target_surface); DamageAccumulator TrackDamageFromSurfaceMask( LayerImpl* target_surface_mask_layer); DamageAccumulator TrackDamageFromLeftoverRects(); - void PrepareRectHistoryForUpdate(); - // These helper functions are used only in TrackDamageFromActiveLayers(). - void ExtendDamageForLayer(LayerImpl* layer, DamageAccumulator* target_damage); - void ExtendDamageForRenderSurface(RenderSurfaceImpl* render_surface, - DamageAccumulator* target_damage); + // These helper functions are used only during UpdateDamageTracking(). + void PrepareForUpdate(); + void AccumulateDamageFromLayer(LayerImpl* layer); + void AccumulateDamageFromRenderSurface(RenderSurfaceImpl* render_surface); + void ComputeSurfaceDamage(RenderSurfaceImpl* render_surface); void ExpandDamageInsideRectWithFilters(const gfx::Rect& pre_filter_rect, - const FilterOperations& filters, - DamageAccumulator* damage); + const FilterOperations& filters); struct LayerRectMapData { LayerRectMapData() : layer_id_(0), mailboxId_(0) {} @@ -147,6 +141,9 @@ class CC_EXPORT DamageTracker { unsigned int mailboxId_; DamageAccumulator current_damage_; + // Damage accumulated since the last call to PrepareForUpdate(). + DamageAccumulator damage_for_this_update_; + DISALLOW_COPY_AND_ASSIGN(DamageTracker); }; diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc index 91cec6dc030..d036723038e 100644 --- a/chromium/cc/trees/damage_tracker_unittest.cc +++ b/chromium/cc/trees/damage_tracker_unittest.cc @@ -13,6 +13,7 @@ #include "cc/test/fake_impl_task_runner_provider.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/test_task_graph_runner.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" @@ -27,22 +28,22 @@ namespace { void ExecuteCalculateDrawProperties(LayerImpl* root, float device_scale_factor, - LayerImplList* render_surface_layer_list) { + 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_layer_list->size()); + ASSERT_FALSE(render_surface_list->size()); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), device_scale_factor, render_surface_layer_list); + root, root->bounds(), device_scale_factor, render_surface_list); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - ASSERT_TRUE(root->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(root)); } void ClearDamageForAllSurfaces(LayerImpl* root) { for (auto* layer : *root->layer_tree_impl()) { - if (layer->GetRenderSurface()) - layer->GetRenderSurface()->damage_tracker()->DidDrawDamagedArea(); + if (GetRenderSurface(layer)) + GetRenderSurface(layer)->damage_tracker()->DidDrawDamagedArea(); } } @@ -53,23 +54,12 @@ void EmulateDrawingOneFrame(LayerImpl* root, float device_scale_factor = 1.f) { // 3. resetting all update_rects and property_changed flags for all layers // and surfaces. - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_layer_list); - - // Iterate back-to-front, so that damage correctly propagates from descendant - // surfaces to ancestors. - size_t render_surface_layer_list_size = render_surface_layer_list.size(); - for (size_t i = 0; i < render_surface_layer_list_size; ++i) { - size_t index = render_surface_layer_list_size - 1 - i; - RenderSurfaceImpl* target_surface = - render_surface_layer_list[index]->GetRenderSurface(); - target_surface->damage_tracker()->UpdateDamageTrackingState( - target_surface->layer_list(), target_surface, - target_surface->SurfacePropertyChangedOnlyFromDescendant(), - target_surface->content_rect(), target_surface->MaskLayer(), - target_surface->Filters()); - } + &render_surface_list); + + DamageTracker::UpdateDamageTracking(root->layer_tree_impl(), + render_surface_list); root->layer_tree_impl()->ResetAllChangeTracking(); } @@ -185,16 +175,17 @@ class DamageTrackerTest : public testing::Test { TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { // Sanity check that the simple test tree will actually produce the expected - // render surfaces and layer lists. + // render surfaces. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); + LayerImpl* child = root->test_properties()->children[0]; - EXPECT_EQ(2u, root->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(1, root->GetRenderSurface()->layer_list()[0]->id()); - EXPECT_EQ(2, root->GetRenderSurface()->layer_list()[1]->id()); + EXPECT_EQ(2, GetRenderSurface(root)->num_contributors()); + EXPECT_TRUE(root->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child->contributes_to_drawn_render_surface()); gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); @@ -202,7 +193,7 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { // Sanity check that the complex test tree will actually produce the expected - // render surfaces and layer lists. + // render surfaces. LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); @@ -210,17 +201,16 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { LayerImpl* child2 = root->test_properties()->children[1]; gfx::Rect child_damage_rect; - EXPECT_TRUE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - ASSERT_TRUE(child1->GetRenderSurface()); - EXPECT_FALSE(child2->GetRenderSurface()); - EXPECT_EQ(3u, root->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(2u, child1->GetRenderSurface()->layer_list().size()); + 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()); // The render surface for child1 only has a content_rect that encloses // grand_child1 and grand_child2, because child1 does not draw content. @@ -243,7 +233,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // Damage position on the surface should be: position of update_rect (10, 11) // relative to the child (100, 100). gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(), root_damage_rect.ToString()); @@ -254,7 +244,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(110, 111, 12, 13).ToString(), root_damage_rect.ToString()); @@ -268,7 +258,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // Damage position on the surface should be: position of update_rect (20, 25) // relative to the child (100, 100). - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(120, 125, 1, 2).ToString(), root_damage_rect.ToString()); } @@ -287,7 +277,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { // Damage position on the surface should be: position of layer damage_rect // (10, 11) relative to the child (100, 100). gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13))); @@ -297,7 +287,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { child->AddDamageRect(gfx::Rect(10, 11, 12, 13)); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13))); @@ -310,7 +300,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { // Damage position on the surface should be: position of layer damage_rect // (20, 25) relative to the child (100, 100). - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2))); @@ -324,7 +314,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { // Damage position on the surface should be: position of layer damage_rect // (20, 25) relative to the child (100, 100). - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2))); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 115, 3, 4))); @@ -346,7 +336,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { // damage_rect and update rect (5, 6) // relative to the child (100, 100). gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 106, 24, 20))); @@ -357,7 +347,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { child->SetUpdateRect(gfx::Rect(10, 11, 14, 15)); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 14, 15))); @@ -371,7 +361,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { // Damage position on the surface should be: position of unified layer damage // rect and update rect (5, 10) relative to the child (100, 100). - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 110, 17, 18))); } @@ -390,12 +380,12 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { root->layer_tree_impl()->SetOpacityMutated(child->element_id(), 0.5f); EmulateDrawingOneFrame(root); - ASSERT_EQ(2u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(2, GetRenderSurface(root)->num_contributors()); // Damage should be the entire child layer in target_surface space. gfx::Rect expected_rect = gfx::Rect(100, 100, 30, 30); gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString()); @@ -408,7 +398,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { ClearDamageForAllSurfaces(root); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); @@ -422,7 +412,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { // Expect damage to be the combination of the previous one and the new one. expected_rect.Union(gfx::Rect(200, 230, 30, 30)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect); } @@ -440,7 +430,7 @@ TEST_F(DamageTrackerTest, VerifyDamageWhenSurfaceRemoved) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), root_damage_rect.ToString()); @@ -468,7 +458,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { // Sanity check that the layer actually moved to (85, 85), damaging its old // location and new location. gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(85, 85, 45, 45).ToString(), root_damage_rect.ToString()); @@ -486,7 +476,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { float expected_position = 100.f - 0.5f * expected_width; gfx::Rect expected_rect = gfx::ToEnclosingRect(gfx::RectF( expected_position, expected_position, expected_width, expected_width)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString()); } @@ -539,7 +529,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { // don't care whether the damage rect was clamped or is larger than the // surface for this test. gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); gfx::Rect damage_we_care_about = gfx::Rect(gfx::Size(500, 500)); EXPECT_TRUE(root_damage_rect.Contains(damage_we_care_about)); @@ -570,7 +560,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { // relative to the child (300, 300), but expanded by the blur outsets // (15, since the blur radius is 5). gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(286, 287, 33, 34), root_damage_rect); } @@ -594,9 +584,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { EmulateDrawingOneFrame(root); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); // gfx::Rect(100, 100, 30, 30), expanded by 6px for the 2px blur filter. @@ -610,9 +600,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { child->SetUpdateRect(gfx::Rect(1, 1)); EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); // gfx::Rect(100, 100, 1, 1), expanded by 6px for the 2px blur filter. @@ -644,9 +634,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { EmulateDrawingOneFrame(root); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); // Blur outset is 6px for a 2px blur. @@ -666,9 +656,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { child->SetUpdateRect(gfx::Rect(30, 30)); EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); int expect_width = 30 + 2 * blur_outset; @@ -699,9 +689,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { EmulateDrawingOneFrame(root, device_scale_factor); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); EmulateDrawingOneFrame(root, device_scale_factor); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); // Blur outset is 9px for a 3px blur, scaled up by DSF. @@ -722,9 +712,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { child->SetUpdateRect(gfx::Rect(30, 30)); EmulateDrawingOneFrame(root, device_scale_factor); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_EQ(expected_root_damage_rect, root_damage_rect); @@ -759,7 +749,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + 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 @@ -779,7 +769,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + 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 @@ -797,7 +787,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // Damage on the root should be: position of update_rect (30, 30), not // expanded. @@ -813,7 +803,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // Damage on the root should be: the originally damaged rect (99,99 1x1) // plus the rect that can influence with a 2px blur (93,93 13x13) intersected @@ -830,7 +820,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // Damage on child2 should be: position of update_rect offset by the child's // position (11, 11), and not expanded by anything. @@ -846,7 +836,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // Damage on child1 should be: position of update_rect offset by the child's // position (100, 100), and expanded by the damage. @@ -879,10 +869,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { // Sanity check - all 3 layers should be on the same render surface; render // surfaces are tested elsewhere. - ASSERT_EQ(3u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(3, GetRenderSurface(root)->num_contributors()); gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString()); @@ -895,7 +885,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); @@ -905,7 +895,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), root_damage_rect.ToString()); @@ -939,10 +929,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { // Sanity check - all 3 layers should be on the same render surface; render // surfaces are tested elsewhere. - ASSERT_EQ(3u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(3, GetRenderSurface(root)->num_contributors()); gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString()); } @@ -975,7 +965,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(100, 100, 303, 284).ToString(), root_damage_rect.ToString()); @@ -999,10 +989,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { ClearDamageForAllSurfaces(root); root->layer_tree_impl()->SetOpacityMutated(grand_child1->element_id(), 0.5f); EmulateDrawingOneFrame(root); - EXPECT_TRUE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString()); EXPECT_EQ(gfx::Rect(300, 300, 6, 8).ToString(), root_damage_rect.ToString()); @@ -1017,10 +1006,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { 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( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString()); EXPECT_EQ(gfx::Rect(11, 11, 295, 297).ToString(), @@ -1046,10 +1034,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { grand_child1->SetPosition(gfx::PointF(195.f, 205.f)); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // The new surface bounds should be damaged entirely, even though only one of @@ -1087,10 +1074,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { root->layer_tree_impl()->SetTransformMutated(child1->element_id(), translation); EmulateDrawingOneFrame(root); - EXPECT_TRUE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // The new surface bounds should be damaged entirely. @@ -1119,10 +1105,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { EmulateDrawingOneFrame(root); // Sanity check that there is only one surface now. - ASSERT_FALSE(child1->GetRenderSurface()); - ASSERT_EQ(4u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(GetRenderSurface(child1), GetRenderSurface(root)); + ASSERT_EQ(4, GetRenderSurface(root)->num_contributors()); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), root_damage_rect.ToString()); @@ -1135,7 +1121,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { ClearDamageForAllSurfaces(root); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); @@ -1147,14 +1133,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { EmulateDrawingOneFrame(root); // Sanity check that there is a new surface now. - ASSERT_TRUE(child1->GetRenderSurface()); - EXPECT_EQ(3u, root->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(2u, child1->GetRenderSurface()->layer_list().size()); + ASSERT_TRUE(GetRenderSurface(child1)); + EXPECT_EQ(3, GetRenderSurface(root)->num_contributors()); + EXPECT_EQ(2, GetRenderSurface(child1)->num_contributors()); - EXPECT_TRUE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), child_damage_rect.ToString()); @@ -1173,10 +1158,9 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { ClearDamageForAllSurfaces(root); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(child_damage_rect.IsEmpty()); EXPECT_TRUE(root_damage_rect.IsEmpty()); @@ -1187,10 +1171,9 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { ClearDamageForAllSurfaces(root); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(child_damage_rect.IsEmpty()); EXPECT_TRUE(root_damage_rect.IsEmpty()); @@ -1208,10 +1191,9 @@ TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { child1->SetUpdateRect(gfx::Rect(1, 2)); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &child_damage_rect)); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(child_damage_rect.IsEmpty()); EXPECT_TRUE(root_damage_rect.IsEmpty()); @@ -1257,7 +1239,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); @@ -1269,7 +1251,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { ClearDamageForAllSurfaces(root); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(child_damage_rect.IsEmpty()); @@ -1279,7 +1261,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); @@ -1291,7 +1273,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { ClearDamageForAllSurfaces(root); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(child_damage_rect.IsEmpty()); @@ -1304,9 +1286,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { EmulateDrawingOneFrame(root); // Sanity check that a render surface still exists. - ASSERT_TRUE(child->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(child)); - EXPECT_TRUE(child->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); } @@ -1320,12 +1302,12 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { // ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); - root->GetRenderSurface()->damage_tracker()->AddDamageNextUpdate( + 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(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::UnionRects(gfx::Rect(15, 16, 32, 33), gfx::Rect(100 + 10, 100 + 11, 12, 13)).ToString(), @@ -1335,19 +1317,16 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { // nothing on the layer tree changed. // ClearDamageForAllSurfaces(root); - root->GetRenderSurface()->damage_tracker()->AddDamageNextUpdate( + GetRenderSurface(root)->damage_tracker()->AddDamageNextUpdate( gfx::Rect(30, 31, 14, 15)); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString()); } -TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) { - // Though it should never happen, its a good idea to verify that the damage - // tracker does not crash when it receives an empty layer_list. - +TEST_F(DamageTrackerTest, VerifyDamageWithNoContributingLayers) { std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_.active_tree(), 1); root->test_properties()->force_render_surface = true; @@ -1356,13 +1335,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) { root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root_ptr); - DCHECK_EQ(root_ptr->GetRenderSurface(), root_ptr->render_target()); - RenderSurfaceImpl* target_surface = root_ptr->GetRenderSurface(); - - LayerImplList empty_list; - target_surface->damage_tracker()->UpdateDamageTrackingState( - empty_list, target_surface, false, gfx::Rect(), NULL, FilterOperations()); - + DCHECK_EQ(GetRenderSurface(root_ptr), root_ptr->render_target()); + RenderSurfaceImpl* target_surface = GetRenderSurface(root_ptr); gfx::Rect damage_rect; EXPECT_TRUE( target_surface->damage_tracker()->GetDamageRectIfValid(&damage_rect)); @@ -1382,7 +1356,7 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // Sanity check damage after the first frame; this isnt the actual test yet. gfx::Rect root_damage_rect; - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(110, 111, 1, 2).ToString(), root_damage_rect.ToString()); @@ -1391,15 +1365,15 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { child->SetUpdateRect(gfx::Rect(20, 25, 1, 2)); root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(110, 111, 11, 16).ToString(), root_damage_rect.ToString()); // If we notify the damage tracker that we drew the damaged area, then damage // should be emptied. - root->GetRenderSurface()->damage_tracker()->DidDrawDamagedArea(); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + GetRenderSurface(root)->damage_tracker()->DidDrawDamagedArea(); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); @@ -1407,7 +1381,7 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // damage. root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); } @@ -1441,9 +1415,8 @@ TEST_F(DamageTrackerTest, HugeDamageRect) { // The expected damage should cover the visible part of the child layer, // which is (0, 0, i, i) in the viewport. gfx::Rect root_damage_rect; - EXPECT_TRUE( - root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &root_damage_rect)); + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( + &root_damage_rect)); gfx::Rect damage_we_care_about = gfx::Rect(i, i); EXPECT_LE(damage_we_care_about.right(), root_damage_rect.right()); EXPECT_LE(damage_we_care_about.bottom(), root_damage_rect.bottom()); @@ -1470,10 +1443,10 @@ TEST_F(DamageTrackerTest, DamageRectTooBig) { // The expected damage would be too large to store in a gfx::Rect, so we // should damage everything (ie, we don't have a valid rect). gfx::Rect damage_rect; - EXPECT_FALSE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_FALSE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); - EXPECT_EQ(root->GetRenderSurface()->content_rect(), - root->GetRenderSurface()->GetDamageRect()); + EXPECT_EQ(GetRenderSurface(root)->content_rect(), + GetRenderSurface(root)->GetDamageRect()); } TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) { @@ -1501,10 +1474,10 @@ TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) { // The expected damage would be too large to store in a gfx::Rect, so we // should damage everything (ie, we don't have a valid rect). gfx::Rect damage_rect; - EXPECT_FALSE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + EXPECT_FALSE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); - EXPECT_EQ(root->GetRenderSurface()->content_rect(), - root->GetRenderSurface()->GetDamageRect()); + EXPECT_EQ(GetRenderSurface(root)->content_rect(), + GetRenderSurface(root)->GetDamageRect()); } TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) { @@ -1527,36 +1500,31 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; float device_scale_factor = 1.f; - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_layer_list); - - auto* surface = child1->GetRenderSurface(); - surface->damage_tracker()->UpdateDamageTrackingState( - surface->layer_list(), surface, false, surface->content_rect(), - surface->MaskLayer(), surface->Filters()); - surface = root->GetRenderSurface(); - surface->damage_tracker()->UpdateDamageTrackingState( - surface->layer_list(), surface, false, surface->content_rect(), - surface->MaskLayer(), surface->Filters()); + &render_surface_list); + // 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); // The expected damage would be too large to store in a gfx::Rect, so we // should damage everything on child1. gfx::Rect damage_rect; - EXPECT_FALSE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(child1->GetRenderSurface()->content_rect(), - child1->GetRenderSurface()->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 // as damage. - ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); - EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); + EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); - EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); + gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); // Add new damage, without changing properties, which goes down a different // path in the damage tracker. @@ -1565,34 +1533,27 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) { grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); // Recompute all damage / properties. - render_surface_layer_list.clear(); + render_surface_list.clear(); ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_layer_list); - surface = child1->GetRenderSurface(); - surface->damage_tracker()->UpdateDamageTrackingState( - surface->layer_list(), surface, false, surface->content_rect(), - surface->MaskLayer(), surface->Filters()); - surface = root->GetRenderSurface(); - surface->damage_tracker()->UpdateDamageTrackingState( - surface->layer_list(), surface, false, surface->content_rect(), - surface->MaskLayer(), surface->Filters()); + &render_surface_list); + DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), + render_surface_list); // 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( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(child1->GetRenderSurface()->content_rect(), - child1->GetRenderSurface()->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. - ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); - EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); + EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); - EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); + gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); } TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) { @@ -1621,36 +1582,31 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; float device_scale_factor = 1.f; - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_layer_list); - - auto* surface = child1->GetRenderSurface(); - surface->damage_tracker()->UpdateDamageTrackingState( - surface->layer_list(), surface, false, surface->content_rect(), - surface->MaskLayer(), surface->Filters()); - surface = root->GetRenderSurface(); - surface->damage_tracker()->UpdateDamageTrackingState( - surface->layer_list(), surface, false, surface->content_rect(), - surface->MaskLayer(), surface->Filters()); + &render_surface_list); + // 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); // The expected damage would be too large to store in a gfx::Rect, so we // should damage everything on child1. gfx::Rect damage_rect; - EXPECT_FALSE( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(child1->GetRenderSurface()->content_rect(), - child1->GetRenderSurface()->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 // as damage. - ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); - EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); + EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); - EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); + gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); // Add new damage, without changing properties, which goes down a different // path in the damage tracker. @@ -1659,34 +1615,27 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) { grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); // Recompute all damage / properties. - render_surface_layer_list.clear(); + render_surface_list.clear(); ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_layer_list); - surface = child1->GetRenderSurface(); - surface->damage_tracker()->UpdateDamageTrackingState( - surface->layer_list(), surface, false, surface->content_rect(), - surface->MaskLayer(), surface->Filters()); - surface = root->GetRenderSurface(); - surface->damage_tracker()->UpdateDamageTrackingState( - surface->layer_list(), surface, false, surface->content_rect(), - surface->MaskLayer(), surface->Filters()); + &render_surface_list); + DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), + render_surface_list); // 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( - child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(child1->GetRenderSurface()->content_rect(), - child1->GetRenderSurface()->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. - ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( + ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); - EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); + EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); - EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); + gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); } } // namespace diff --git a/chromium/cc/trees/debug_rect_history.cc b/chromium/cc/trees/debug_rect_history.cc index 243c610214c..35c8db1073d 100644 --- a/chromium/cc/trees/debug_rect_history.cc +++ b/chromium/cc/trees/debug_rect_history.cc @@ -32,7 +32,7 @@ DebugRectHistory::~DebugRectHistory() {} void DebugRectHistory::SaveDebugRectsForCurrentFrame( LayerTreeImpl* tree_impl, LayerImpl* hud_layer, - const LayerImplList& render_surface_layer_list, + const RenderSurfaceList& render_surface_list, const LayerTreeDebugState& debug_state) { // For now, clear all rects from previous frames. In the future we may want to // store all debug rects for a history of many frames. @@ -54,13 +54,13 @@ void DebugRectHistory::SaveDebugRectsForCurrentFrame( SavePaintRects(tree_impl); if (debug_state.show_property_changed_rects) - SavePropertyChangedRects(render_surface_layer_list, hud_layer); + SavePropertyChangedRects(tree_impl, hud_layer); if (debug_state.show_surface_damage_rects) - SaveSurfaceDamageRects(render_surface_layer_list); + SaveSurfaceDamageRects(render_surface_list); if (debug_state.show_screen_space_rects) - SaveScreenSpaceRects(render_surface_layer_list); + SaveScreenSpaceRects(render_surface_list); if (debug_state.show_layer_animation_bounds_rects) SaveLayerAnimationBoundsRects(tree_impl); @@ -84,46 +84,27 @@ void DebugRectHistory::SavePaintRects(LayerTreeImpl* tree_impl) { } } -void DebugRectHistory::SavePropertyChangedRects( - const LayerImplList& render_surface_layer_list, - LayerImpl* hud_layer) { - for (size_t i = 0; i < render_surface_layer_list.size(); ++i) { - size_t surface_index = render_surface_layer_list.size() - 1 - i; - LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; - RenderSurfaceImpl* render_surface = - render_surface_layer->GetRenderSurface(); - DCHECK(render_surface); - - const LayerImplList& layer_list = render_surface->layer_list(); - for (unsigned layer_index = 0; layer_index < layer_list.size(); - ++layer_index) { - LayerImpl* layer = layer_list[layer_index]; - - if (layer->GetRenderSurface() && - layer->GetRenderSurface() != render_surface) - continue; - - if (layer == hud_layer) - continue; +void DebugRectHistory::SavePropertyChangedRects(LayerTreeImpl* tree_impl, + LayerImpl* hud_layer) { + for (LayerImpl* layer : *tree_impl) { + if (layer == hud_layer) + continue; - if (!layer->LayerPropertyChanged()) - continue; + if (!layer->LayerPropertyChanged()) + continue; - debug_rects_.push_back(DebugRect( - PROPERTY_CHANGED_RECT_TYPE, - MathUtil::MapEnclosingClippedRect(layer->ScreenSpaceTransform(), - gfx::Rect(layer->bounds())))); - } + debug_rects_.push_back(DebugRect( + PROPERTY_CHANGED_RECT_TYPE, + MathUtil::MapEnclosingClippedRect(layer->ScreenSpaceTransform(), + gfx::Rect(layer->bounds())))); } } void DebugRectHistory::SaveSurfaceDamageRects( - const LayerImplList& render_surface_layer_list) { - for (size_t i = 0; i < render_surface_layer_list.size(); ++i) { - size_t surface_index = render_surface_layer_list.size() - 1 - i; - LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; - RenderSurfaceImpl* render_surface = - render_surface_layer->GetRenderSurface(); + const RenderSurfaceList& render_surface_list) { + for (size_t i = 0; i < render_surface_list.size(); ++i) { + size_t surface_index = render_surface_list.size() - 1 - i; + RenderSurfaceImpl* render_surface = render_surface_list[surface_index]; DCHECK(render_surface); debug_rects_.push_back(DebugRect( @@ -134,12 +115,10 @@ void DebugRectHistory::SaveSurfaceDamageRects( } void DebugRectHistory::SaveScreenSpaceRects( - const LayerImplList& render_surface_layer_list) { - for (size_t i = 0; i < render_surface_layer_list.size(); ++i) { - size_t surface_index = render_surface_layer_list.size() - 1 - i; - LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; - RenderSurfaceImpl* render_surface = - render_surface_layer->GetRenderSurface(); + const RenderSurfaceList& render_surface_list) { + for (size_t i = 0; i < render_surface_list.size(); ++i) { + size_t surface_index = render_surface_list.size() - 1 - i; + RenderSurfaceImpl* render_surface = render_surface_list[surface_index]; DCHECK(render_surface); debug_rects_.push_back(DebugRect( @@ -218,7 +197,7 @@ void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) { void DebugRectHistory::SaveLayerAnimationBoundsRects(LayerTreeImpl* tree_impl) { for (auto it = tree_impl->rbegin(); it != tree_impl->rend(); ++it) { - if (!(*it)->is_drawn_render_surface_layer_list_member()) + if (!(*it)->contributes_to_drawn_render_surface()) continue; // TODO(avallee): Figure out if we should show something for a layer who's diff --git a/chromium/cc/trees/debug_rect_history.h b/chromium/cc/trees/debug_rect_history.h index 183cddeb775..7728237eb54 100644 --- a/chromium/cc/trees/debug_rect_history.h +++ b/chromium/cc/trees/debug_rect_history.h @@ -67,7 +67,7 @@ class DebugRectHistory { void SaveDebugRectsForCurrentFrame( LayerTreeImpl* tree_impl, LayerImpl* hud_layer, - const LayerImplList& render_surface_layer_list, + const RenderSurfaceList& render_surface_list, const LayerTreeDebugState& debug_state); const std::vector<DebugRect>& debug_rects() { return debug_rects_; } @@ -76,10 +76,9 @@ class DebugRectHistory { DebugRectHistory(); void SavePaintRects(LayerTreeImpl* tree_impl); - void SavePropertyChangedRects(const LayerImplList& render_surface_layer_list, - LayerImpl* hud_layer); - void SaveSurfaceDamageRects(const LayerImplList& render_surface_layer_list); - void SaveScreenSpaceRects(const LayerImplList& render_surface_layer_list); + void SavePropertyChangedRects(LayerTreeImpl* tree_impl, LayerImpl* hud_layer); + void SaveSurfaceDamageRects(const RenderSurfaceList& render_surface_list); + void SaveScreenSpaceRects(const RenderSurfaceList& render_surface_list); void SaveTouchEventHandlerRects(LayerTreeImpl* layer); void SaveTouchEventHandlerRectsCallback(LayerImpl* layer); void SaveWheelEventHandlerRects(LayerTreeImpl* tree_impl); diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index 5af6686aa61..43120259e3d 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -458,14 +458,11 @@ static inline bool LayerShouldBeSkippedInternal( transform_tree.Node(layer->transform_tree_index()); const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); - if (effect_node->has_render_surface && - effect_node->num_copy_requests_in_subtree > 0) + if (effect_node->has_render_surface && effect_node->subtree_has_copy_request) return false; - // If the layer transform is not invertible, it should be skipped. - // TODO(ajuma): Correctly process subtrees with singular transform for the - // case where we may animate to a non-singular transform and wish to - // pre-raster. + // If the layer transform is not invertible, it should be skipped. In case the + // transform is animating and singular, we should not skip it. return !transform_node->node_and_ancestors_are_animated_or_invertible || effect_node->hidden_by_backface_visibility || !effect_node->is_drawn; } @@ -672,9 +669,10 @@ static void SetSurfaceDrawTransform(const PropertyTrees* property_trees, static 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_copy_request = - property_trees->effect_tree.ClosestAncestorWithCopyRequest( - layer->effect_tree_index()); + effect_node->closest_ancestor_with_copy_request_id; bool non_root_copy_request = effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId; gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); @@ -722,27 +720,18 @@ static ConditionalClip LayerClipRect(PropertyTrees* property_trees, effect_node->has_render_surface ? effect_node : effect_tree->Node(effect_node->target_id); - // TODO(weiliangc): When effect node has up to date render surface info on - // compositor thread, no need to check for resourceless draw mode - if (!property_trees->non_root_surfaces_enabled) { - target_node = effect_tree->Node(1); - } - bool include_expanding_clips = false; return ComputeAccumulatedClip(property_trees, include_expanding_clips, layer->clip_tree_index(), target_node->id); } -static void UpdateRenderTarget(EffectTree* effect_tree, - bool can_render_to_separate_surface) { +static void UpdateRenderTarget(EffectTree* effect_tree) { for (int i = EffectTree::kContentsRootNodeId; i < static_cast<int>(effect_tree->size()); ++i) { EffectNode* node = effect_tree->Node(i); if (i == EffectTree::kContentsRootNodeId) { // Render target of the node corresponding to root is itself. node->target_id = EffectTree::kContentsRootNodeId; - } else if (!can_render_to_separate_surface) { - node->target_id = EffectTree::kContentsRootNodeId; } else if (effect_tree->parent(node)->has_render_surface) { node->target_id = node->parent_id; } else { @@ -809,15 +798,17 @@ void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, 1.0 / effect_node->surface_contents_scale.y()); } -bool LayerShouldBeSkipped(LayerImpl* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree) { +bool LayerShouldBeSkippedForDrawPropertiesComputation( + LayerImpl* layer, + const TransformTree& transform_tree, + const EffectTree& effect_tree) { return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); } -bool LayerShouldBeSkipped(Layer* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree) { +bool LayerShouldBeSkippedForDrawPropertiesComputation( + Layer* layer, + const TransformTree& transform_tree, + const EffectTree& effect_tree) { return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); } @@ -827,8 +818,8 @@ void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, const TransformTree& transform_tree = property_trees->transform_tree; const EffectTree& effect_tree = property_trees->effect_tree; for (auto* layer : *layer_tree_host) { - if (!IsRootLayer(layer) && - LayerShouldBeSkipped(layer, transform_tree, effect_tree)) + if (!IsRootLayer(layer) && LayerShouldBeSkippedForDrawPropertiesComputation( + layer, transform_tree, effect_tree)) continue; bool layer_is_drawn = @@ -852,16 +843,9 @@ void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, const EffectTree& effect_tree = property_trees->effect_tree; for (auto* layer_impl : *layer_tree_impl) { - DCHECK(layer_impl); - DCHECK(layer_impl->layer_tree_impl()); - // TODO(crbug.com/726423) : This is a workaround for crbug.com/725851 to - // avoid crashing when layer_impl is nullptr. This workaround should be - // removed as layer_impl should not be nullptr here. - if (!layer_impl || !layer_impl->HasValidPropertyTreeIndices()) - continue; - if (!IsRootLayer(layer_impl) && - LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree)) + LayerShouldBeSkippedForDrawPropertiesComputation( + layer_impl, transform_tree, effect_tree)) continue; bool layer_is_drawn = @@ -891,16 +875,10 @@ void ComputeEffects(EffectTree* effect_tree) { } void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, - PropertyTrees* property_trees, - bool can_render_to_separate_surface) { + PropertyTrees* property_trees) { DCHECK(layer_tree_host); DCHECK(property_trees); DCHECK_EQ(layer_tree_host->property_trees(), property_trees); - if (property_trees->non_root_surfaces_enabled != - can_render_to_separate_surface) { - property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; - property_trees->transform_tree.set_needs_update(true); - } if (property_trees->transform_tree.needs_update()) { property_trees->clip_tree.set_needs_update(true); property_trees->effect_tree.set_needs_update(true); @@ -915,15 +893,8 @@ void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, PropertyTrees* property_trees, - bool can_render_to_separate_surface, bool can_adjust_raster_scales) { bool render_surfaces_need_update = false; - if (property_trees->non_root_surfaces_enabled != - can_render_to_separate_surface) { - property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; - property_trees->transform_tree.set_needs_update(true); - render_surfaces_need_update = true; - } if (property_trees->can_adjust_raster_scales != can_adjust_raster_scales) { property_trees->can_adjust_raster_scales = can_adjust_raster_scales; property_trees->transform_tree.set_needs_update(true); @@ -935,11 +906,9 @@ void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, } if (render_surfaces_need_update) { property_trees->effect_tree.UpdateRenderSurfaces( - root_layer->layer_tree_impl(), - property_trees->non_root_surfaces_enabled); + root_layer->layer_tree_impl()); } - UpdateRenderTarget(&property_trees->effect_tree, - property_trees->non_root_surfaces_enabled); + UpdateRenderTarget(&property_trees->effect_tree); ComputeTransforms(&property_trees->transform_tree); ComputeEffects(&property_trees->effect_tree); @@ -967,12 +936,9 @@ gfx::Transform DrawTransform(const LayerImpl* layer, // node and surface's transform node and scales it by the surface's content // scale. gfx::Transform xform; - if (transform_tree.property_trees()->non_root_surfaces_enabled) - transform_tree.property_trees()->GetToTarget( - layer->transform_tree_index(), layer->render_target_effect_tree_index(), - &xform); - else - xform = transform_tree.ToScreen(layer->transform_tree_index()); + transform_tree.property_trees()->GetToTarget( + layer->transform_tree_index(), layer->render_target_effect_tree_index(), + &xform); if (layer->should_flatten_transform_from_property_tree()) xform.FlattenTo2d(); xform.Translate(layer->offset_to_transform_parent().x(), @@ -1060,8 +1026,7 @@ void ComputeMaskDrawProperties(LayerImpl* mask_layer, } void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface, - const bool use_layer_lists) { + RenderSurfaceImpl* render_surface) { SetSurfaceIsClipped(property_trees->clip_tree, render_surface); SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); SetSurfaceDrawTransform(property_trees, render_surface); diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h index b5ff981c579..45ed01f6e88 100644 --- a/chromium/cc/trees/draw_property_utils.h +++ b/chromium/cc/trees/draw_property_utils.h @@ -37,15 +37,12 @@ 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, - bool can_render_to_separate_surface); + PropertyTrees* property_trees); void CC_EXPORT UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, PropertyTrees* property_trees, - bool can_render_to_separate_surface, bool can_adjust_raster_scales); void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, @@ -65,12 +62,12 @@ void CC_EXPORT ComputeMaskDrawProperties(LayerImpl* mask_layer, const PropertyTrees* property_trees); void CC_EXPORT ComputeSurfaceDrawProperties(PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface, - const bool use_layer_lists); + RenderSurfaceImpl* render_surface); -bool CC_EXPORT LayerShouldBeSkipped(LayerImpl* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree); +bool CC_EXPORT LayerShouldBeSkippedForDrawPropertiesComputation( + LayerImpl* layer, + const TransformTree& transform_tree, + const EffectTree& effect_tree); bool CC_EXPORT LayerNeedsUpdate(Layer* layer, bool layer_is_drawn, diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc index 142cb08db41..7a556277530 100644 --- a/chromium/cc/trees/effect_node.cc +++ b/chromium/cc/trees/effect_node.cc @@ -27,11 +27,12 @@ EffectNode::EffectNode() is_currently_animating_filter(false), is_currently_animating_opacity(false), effect_changed(false), - num_copy_requests_in_subtree(0), + subtree_has_copy_request(false), transform_id(0), clip_id(0), target_id(1), - mask_layer_id(-1) {} + mask_layer_id(Layer::INVALID_ID), + closest_ancestor_with_copy_request_id(-1) {} EffectNode::EffectNode(const EffectNode& other) = default; @@ -58,9 +59,11 @@ bool EffectNode::operator==(const EffectNode& other) const { is_currently_animating_opacity == other.is_currently_animating_opacity && effect_changed == other.effect_changed && - num_copy_requests_in_subtree == other.num_copy_requests_in_subtree && + 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 && mask_layer_id == other.mask_layer_id && + closest_ancestor_with_copy_request_id == + other.closest_ancestor_with_copy_request_id; } void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { @@ -77,12 +80,13 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetBoolean("has_potential_opacity_animation", has_potential_opacity_animation); value->SetBoolean("effect_changed", effect_changed); - value->SetInteger("num_copy_requests_in_subtree", - num_copy_requests_in_subtree); + value->SetInteger("subtree_has_copy_request", subtree_has_copy_request); 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_copy_request_id", + closest_ancestor_with_copy_request_id); } } // namespace cc diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h index 48997c03823..8079f898283 100644 --- a/chromium/cc/trees/effect_node.h +++ b/chromium/cc/trees/effect_node.h @@ -43,27 +43,42 @@ struct CC_EXPORT EffectNode { gfx::Size unscaled_mask_target_size; - bool has_render_surface; - bool has_copy_request; - bool hidden_by_backface_visibility; - bool double_sided; - bool is_drawn; + bool has_render_surface : 1; + bool has_copy_request : 1; + bool hidden_by_backface_visibility : 1; + bool double_sided : 1; + bool is_drawn : 1; // TODO(jaydasika) : Delete this after implementation of // SetHideLayerAndSubtree is cleaned up. (crbug.com/595843) - bool subtree_hidden; - bool has_potential_filter_animation; - bool has_potential_opacity_animation; - bool is_currently_animating_filter; - bool is_currently_animating_opacity; - // We need to track changes to effects on the compositor to compute damage - // rect. - bool effect_changed; - int num_copy_requests_in_subtree; + bool subtree_hidden : 1; + // Whether this node has a potentially running (i.e., irrespective + // of exact timeline) filter animation. + bool has_potential_filter_animation : 1; + // Whether this node has a potentially running (i.e., irrespective + // of exact timeline) opacity animation. + bool has_potential_opacity_animation : 1; + // Whether this node has a currently running filter animation. + bool is_currently_animating_filter : 1; + // Whether this node has a currently running opacity animation. + bool is_currently_animating_opacity : 1; + // Whether this node's effect has been changed since the last + // frame. Needed in order to compute damage rect. + bool effect_changed : 1; + bool subtree_has_copy_request : 1; + // The transform node index of the transform to apply to this effect + // node's content when rendering to a surface. int transform_id; + // The clip node index of the clip to apply to this effect node's + // content when rendering to a surface. int clip_id; - // Effect node id of which this effect contributes to. + + // 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_copy_request_id; bool operator==(const EffectNode& other) const; diff --git a/chromium/cc/trees/element_id.cc b/chromium/cc/trees/element_id.cc index 45913303c10..6e32b660aa5 100644 --- a/chromium/cc/trees/element_id.cc +++ b/chromium/cc/trees/element_id.cc @@ -13,7 +13,7 @@ namespace cc { bool ElementId::operator==(const ElementId& o) const { - return primaryId == o.primaryId && secondaryId == o.secondaryId; + return id_ == o.id_; } bool ElementId::operator!=(const ElementId& o) const { @@ -21,36 +21,33 @@ bool ElementId::operator!=(const ElementId& o) const { } bool ElementId::operator<(const ElementId& o) const { - return std::tie(primaryId, secondaryId) < - std::tie(o.primaryId, o.secondaryId); + return id_ < o.id_; } ElementId::operator bool() const { - return !!primaryId; + return !!id_; } ElementId LayerIdToElementIdForTesting(int layer_id) { - return ElementId(std::numeric_limits<int>::max() - layer_id, 0); + return ElementId(std::numeric_limits<int>::max() - layer_id); } void ElementId::AddToTracedValue(base::trace_event::TracedValue* res) const { - res->SetInteger("primaryId", primaryId); - res->SetInteger("secondaryId", secondaryId); + res->SetInteger("id_", id_); } std::unique_ptr<base::Value> ElementId::AsValue() const { std::unique_ptr<base::DictionaryValue> res(new base::DictionaryValue()); - res->SetInteger("primaryId", primaryId); - res->SetInteger("secondaryId", secondaryId); + res->SetInteger("id_", id_); return std::move(res); } size_t ElementIdHash::operator()(ElementId key) const { - return base::HashInts(key.primaryId, key.secondaryId); + return std::hash<int>()(key.id_); } std::ostream& operator<<(std::ostream& out, const ElementId& id) { - return out << "(" << id.primaryId << ", " << id.secondaryId << ")"; + return out << "(" << id.id_ << ")"; } } // namespace cc diff --git a/chromium/cc/trees/element_id.h b/chromium/cc/trees/element_id.h index 74de4c9995f..059cf2b36d7 100644 --- a/chromium/cc/trees/element_id.h +++ b/chromium/cc/trees/element_id.h @@ -24,20 +24,32 @@ class TracedValue; namespace cc { -// An "element" is really an animation target. It retains the name element to be -// symmetric with ElementAnimations and blink::ElementAnimations, but is not -// in fact tied to the notion of a blink element. It is also not associated with -// the notion of a Layer. Ultimately, these ids will be used to look up the -// property tree node associated with the given animation. +using ElementIdType = uint64_t; + +static const ElementIdType kInvalidElementId = 0; + +// Element ids are chosen by cc's clients and can be used as a stable identifier +// across updates. +// +// Historically, the layer tree stored all compositing data but this has been +// refactored over time into auxilliary structures such as property trees. +// +// In composited scrolling, Layers directly reference scroll tree nodes +// (Layer::scroll_tree_index) but scroll tree nodes are being refactored to +// reference stable element ids instead of layers. Scroll property nodes have +// unique element ids that blink creates from scrollable areas (though this is +// opaque to the compositor). This refactoring of scroll nodes keeping a +// scrolling element id instead of a scrolling layer id allows for more general +// compositing where, for example, multiple layers scroll with one scroll node. // -// These ids are chosen by cc's clients to permit the destruction and -// restoration of cc entities (when visuals are hidden and shown) but maintain -// stable identifiers. There will be a single layer for an ElementId, but -// not every layer will have an id. +// The animation system (see: ElementAnimations and blink::ElementAnimations) is +// another auxilliary structure to the layer tree and uses element ids as a +// stable identifier for animation targets. A Layer's element id can change over +// the Layer's lifetime because non-default ElementIds are only set during an +// animation's lifetime. struct CC_EXPORT ElementId { - ElementId(int primaryId, int secondaryId) - : primaryId(primaryId), secondaryId(secondaryId) {} - ElementId() : ElementId(0, 0) {} + explicit ElementId(int id) : id_(id) {} + ElementId() : ElementId(kInvalidElementId) {} bool operator==(const ElementId& o) const; bool operator!=(const ElementId& o) const; @@ -52,11 +64,10 @@ struct CC_EXPORT ElementId { // The compositor treats this as an opaque handle and should not know how to // interpret these bits. Non-blink cc clients typically operate in terms of // layers and may set this value to match the client's layer id. - int primaryId; - int secondaryId; + ElementIdType id_; }; -CC_EXPORT ElementId LayerIdToElementIdForTesting(int layer_id); +ElementId CC_EXPORT LayerIdToElementIdForTesting(int layer_id); struct CC_EXPORT ElementIdHash { size_t operator()(ElementId key) const; diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc index e8a6f4b0c07..8db96130c74 100644 --- a/chromium/cc/trees/layer_tree_host.cc +++ b/chromium/cc/trees/layer_tree_host.cc @@ -46,7 +46,6 @@ #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" @@ -108,8 +107,6 @@ LayerTreeHost::LayerTreeHost(InitParams* params, CompositorMode mode) mutator_host_(params->mutator_host) { DCHECK(task_graph_runner_); DCHECK(!settings_.enable_checker_imaging || image_worker_task_runner_); - DCHECK(!settings_.enable_checker_imaging || - settings_.image_decode_tasks_enabled); mutator_host_->SetMutatorHostClient(this); @@ -168,14 +165,14 @@ void LayerTreeHost::InitializeProxy(std::unique_ptr<Proxy> proxy) { LayerTreeHost::~LayerTreeHost() { // Track when we're inside a main frame to see if compositor is being // destroyed midway which causes a crash. crbug.com/654672 - CHECK(!inside_main_frame_); + DCHECK(!inside_main_frame_); TRACE_EVENT0("cc", "LayerTreeHostInProcess::~LayerTreeHostInProcess"); // Clear any references into the LayerTreeHost. mutator_host_->SetMutatorHostClient(nullptr); // We must clear any pointers into the layer tree prior to destroying it. - RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr); + RegisterViewportLayers(ViewportLayers()); if (root_layer_) { root_layer_->SetLayerTreeHost(nullptr); @@ -249,6 +246,10 @@ void LayerTreeHost::BeginMainFrameNotExpectedSoon() { client_->BeginMainFrameNotExpectedSoon(); } +void LayerTreeHost::BeginMainFrameNotExpectedUntil(base::TimeTicks time) { + client_->BeginMainFrameNotExpectedUntil(time); +} + void LayerTreeHost::BeginMainFrame(const BeginFrameArgs& args) { client_->BeginMainFrame(args); } @@ -288,6 +289,7 @@ void LayerTreeHost::FinishCommitOnImplThread( } LayerTreeImpl* sync_tree = host_impl->sync_tree(); + sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kBeginningSync); if (next_commit_forces_redraw_) { sync_tree->ForceRedrawNextActivation(); @@ -303,34 +305,37 @@ void LayerTreeHost::FinishCommitOnImplThread( if (needs_full_tree_sync_) TreeSynchronizer::SynchronizeTrees(root_layer(), sync_tree); - PushPropertiesTo(sync_tree); + // Track the navigation state before pushing properties since it overwrites + // the |content_source_id_| on the sync tree. + bool did_navigate = content_source_id_ != sync_tree->content_source_id(); + if (did_navigate) + host_impl->ClearImageCacheOnNavigation(); - sync_tree->PassSwapPromises(swap_promise_manager_.TakeSwapPromises()); + { + TRACE_EVENT0("cc", "LayerTreeHostInProcess::PushProperties"); - host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); - host_impl->SetContentIsSuitableForGpuRasterization( - content_is_suitable_for_gpu_rasterization_); - RecordGpuRasterizationHistogram(host_impl); + PushPropertyTreesTo(sync_tree); + sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kSyncedPropertyTrees); - host_impl->SetViewportSize(device_viewport_size_); - sync_tree->SetDeviceScaleFactor(device_scale_factor_); - host_impl->SetDebugState(debug_state_); + TreeSynchronizer::PushLayerProperties(this, sync_tree); + sync_tree->lifecycle().AdvanceTo( + LayerTreeLifecycle::kSyncedLayerProperties); - if (did_navigate_) { - did_navigate_ = false; - host_impl->ClearImageCacheOnNavigation(); - } + PushLayerTreePropertiesTo(sync_tree); + PushLayerTreeHostPropertiesTo(host_impl); - sync_tree->set_ui_resource_request_queue( - ui_resource_manager_->TakeUIResourcesRequests()); + sync_tree->PassSwapPromises(swap_promise_manager_.TakeSwapPromises()); - { - TRACE_EVENT0("cc", "LayerTreeHostInProcess::PushProperties"); + // TODO(pdr): Move this into PushPropertyTreesTo or introduce a lifecycle + // state for it. + sync_tree->SetDeviceScaleFactor(device_scale_factor_); - TreeSynchronizer::PushLayerProperties(this, sync_tree); + sync_tree->set_ui_resource_request_queue( + ui_resource_manager_->TakeUIResourcesRequests()); // This must happen after synchronizing property trees and after pushing // properties, which updates the clobber_active_value flag. + // TODO(pdr): Enforce this comment with DCHECKS and a lifecycle state. sync_tree->property_trees()->scroll_tree.PushScrollUpdatesFromMainThread( property_trees(), sync_tree); @@ -339,11 +344,16 @@ void LayerTreeHost::FinishCommitOnImplThread( // host pushes properties as animation host push properties can change // Animation::InEffect and we want the old InEffect value for updating // property tree scrolling and animation. - sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread(); + // TODO(pdr): Enforce this comment with DCHECKS and a lifecycle state. + bool is_impl_side_update = false; + sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread( + is_impl_side_update); TRACE_EVENT0("cc", "LayerTreeHostInProcess::AnimationHost::PushProperties"); DCHECK(host_impl->mutator_host()); mutator_host_->PushPropertiesTo(host_impl->mutator_host()); + + sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kNotSyncing); } // Transfer image decode requests to the impl thread. @@ -355,6 +365,23 @@ void LayerTreeHost::FinishCommitOnImplThread( property_trees_.ResetAllChangeTracking(); } +void LayerTreeHost::PushPropertyTreesTo(LayerTreeImpl* tree_impl) { + bool property_trees_changed_on_active_tree = + tree_impl->IsActiveTree() && tree_impl->property_trees()->changed; + // 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_ && property_trees_changed_on_active_tree) { + if (property_trees_.sequence_number == + tree_impl->property_trees()->sequence_number) + tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_); + else + tree_impl->MoveChangeTrackingToLayers(); + } + + tree_impl->SetPropertyTrees(&property_trees_); +} + void LayerTreeHost::WillCommit() { swap_promise_manager_.WillCommit(); client_->WillCommit(); @@ -652,7 +679,7 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { Layer* root_scroll = PropertyTreeBuilder::FindFirstScrollableLayer(root_layer); - Layer* page_scale_layer = page_scale_layer_.get(); + Layer* page_scale_layer = viewport_layers_.page_scale.get(); if (!page_scale_layer && root_scroll) page_scale_layer = root_scroll->parent(); @@ -682,7 +709,6 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { TRACE_EVENT0( TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), "LayerTreeHostInProcessCommon::ComputeVisibleRectsWithPropertyTrees"); - bool can_render_to_separate_surface = true; PropertyTrees* property_trees = &property_trees_; if (!settings_.use_layer_lists) { // If use_layer_lists is set, then the property trees should have been @@ -702,15 +728,11 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { TRACE_EVENT_SCOPE_THREAD, "property_trees", property_trees->AsTracedValue()); } - draw_property_utils::UpdatePropertyTrees(this, property_trees, - can_render_to_separate_surface); + draw_property_utils::UpdatePropertyTrees(this, property_trees); draw_property_utils::FindLayersThatNeedUpdates(this, property_trees, &update_layer_list); } - for (const auto& layer : update_layer_list) - layer->SavePaintProperties(); - bool content_is_suitable_for_gpu = true; bool did_paint_content = PaintContent(update_layer_list, &content_is_suitable_for_gpu); @@ -740,10 +762,10 @@ void LayerTreeHost::ApplyViewportDeltas(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 (inner_viewport_scroll_layer_) { - inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide( + if (viewport_layers_.inner_viewport_scroll) { + viewport_layers_.inner_viewport_scroll->SetScrollOffsetFromImplSide( gfx::ScrollOffsetWithDelta( - inner_viewport_scroll_layer_->scroll_offset(), + viewport_layers_.inner_viewport_scroll->scroll_offset(), inner_viewport_scroll_delta)); } @@ -788,7 +810,7 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) { SetNeedsUpdateLayers(); } for (size_t i = 0; i < info->scrollbars.size(); ++i) { - Layer* layer = LayerById(info->scrollbars[i].layer_id); + Layer* layer = LayerByElementId(info->scrollbars[i].element_id); if (!layer) continue; layer->SetScrollbarsHiddenFromImplSide(info->scrollbars[i].hidden); @@ -878,20 +900,21 @@ void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) { ResetGpuRasterizationTracking(); SetNeedsFullTreeSync(); - did_navigate_ = true; } -void LayerTreeHost::RegisterViewportLayers( - scoped_refptr<Layer> overscroll_elasticity_layer, - scoped_refptr<Layer> page_scale_layer, - scoped_refptr<Layer> inner_viewport_scroll_layer, - scoped_refptr<Layer> outer_viewport_scroll_layer) { - DCHECK(!inner_viewport_scroll_layer || - inner_viewport_scroll_layer != outer_viewport_scroll_layer); - overscroll_elasticity_layer_ = overscroll_elasticity_layer; - page_scale_layer_ = page_scale_layer; - inner_viewport_scroll_layer_ = inner_viewport_scroll_layer; - outer_viewport_scroll_layer_ = outer_viewport_scroll_layer; +LayerTreeHost::ViewportLayers::ViewportLayers() {} + +LayerTreeHost::ViewportLayers::~ViewportLayers() {} + +void LayerTreeHost::RegisterViewportLayers(const ViewportLayers& layers) { + DCHECK(!layers.inner_viewport_scroll || + layers.inner_viewport_scroll != layers.outer_viewport_scroll); + viewport_layers_.overscroll_elasticity = layers.overscroll_elasticity; + 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::RegisterSelection(const LayerSelection& selection) { @@ -1123,7 +1146,7 @@ void LayerTreeHost::SetPropertyTreesNeedRebuild() { SetNeedsUpdateLayers(); } -void LayerTreeHost::PushPropertiesTo(LayerTreeImpl* tree_impl) { +void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) { tree_impl->set_needs_full_tree_sync(needs_full_tree_sync_); needs_full_tree_sync_ = false; @@ -1147,35 +1170,29 @@ void LayerTreeHost::PushPropertiesTo(LayerTreeImpl* tree_impl) { EventListenerClass::kTouchEndOrCancel, event_listener_properties(EventListenerClass::kTouchEndOrCancel)); - if (page_scale_layer_ && inner_viewport_scroll_layer_) { - tree_impl->SetViewportLayersFromIds( - overscroll_elasticity_layer_ ? overscroll_elasticity_layer_->id() - : Layer::INVALID_ID, - page_scale_layer_->id(), inner_viewport_scroll_layer_->id(), - outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id() - : Layer::INVALID_ID); - DCHECK(inner_viewport_scroll_layer_->IsContainerForFixedPositionLayers()); + if (viewport_layers_.page_scale && viewport_layers_.inner_viewport_scroll) { + LayerTreeImpl::ViewportLayerIds ids; + if (viewport_layers_.overscroll_elasticity) + ids.overscroll_elasticity = viewport_layers_.overscroll_elasticity->id(); + 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); + DCHECK(viewport_layers_.inner_viewport_scroll + ->IsContainerForFixedPositionLayers()); } else { tree_impl->ClearViewportLayers(); } tree_impl->RegisterSelection(selection_); - bool property_trees_changed_on_active_tree = - tree_impl->IsActiveTree() && tree_impl->property_trees()->changed; - // 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_ && property_trees_changed_on_active_tree) { - if (property_trees_.sequence_number == - tree_impl->property_trees()->sequence_number) - tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_); - else - tree_impl->MoveChangeTrackingToLayers(); - } - // Setting property trees must happen before pushing the page scale. - tree_impl->SetPropertyTrees(&property_trees_); - tree_impl->PushPageScaleFromMainThread( page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_); @@ -1206,6 +1223,17 @@ void LayerTreeHost::PushPropertiesTo(LayerTreeImpl* tree_impl) { tree_impl->set_has_ever_been_drawn(false); } +void LayerTreeHost::PushLayerTreeHostPropertiesTo( + LayerTreeHostImpl* host_impl) { + host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); + host_impl->SetContentIsSuitableForGpuRasterization( + content_is_suitable_for_gpu_rasterization_); + RecordGpuRasterizationHistogram(host_impl); + + host_impl->SetViewportSize(device_viewport_size_); + host_impl->SetDebugState(debug_state_); +} + Layer* LayerTreeHost::LayerByElementId(ElementId element_id) const { auto iter = element_layers_map_.find(element_id); return iter != element_layers_map_.end() ? iter->second : nullptr; @@ -1264,6 +1292,13 @@ void LayerTreeHost::SetMutatorsNeedRebuildPropertyTrees() { void LayerTreeHost::SetElementFilterMutated(ElementId element_id, ElementListType list_type, const FilterOperations& filters) { + if (settings_.use_layer_lists) { + // In SPv2 we always have property trees and can set the filter + // directly on the effect node. + property_trees_.effect_tree.OnFilterAnimated(element_id, filters); + return; + } + Layer* layer = LayerByElementId(element_id); DCHECK(layer); layer->OnFilterAnimated(filters); @@ -1272,10 +1307,16 @@ void LayerTreeHost::SetElementFilterMutated(ElementId element_id, void LayerTreeHost::SetElementOpacityMutated(ElementId element_id, ElementListType list_type, float opacity) { - Layer* layer = LayerByElementId(element_id); - DCHECK(layer); DCHECK_GE(opacity, 0.f); DCHECK_LE(opacity, 1.f); + + if (settings_.use_layer_lists) { + property_trees_.effect_tree.OnOpacityAnimated(element_id, opacity); + return; + } + + Layer* layer = LayerByElementId(element_id); + DCHECK(layer); layer->OnOpacityAnimated(opacity); if (EffectNode* node = @@ -1296,6 +1337,11 @@ void LayerTreeHost::SetElementTransformMutated( ElementId element_id, ElementListType list_type, const gfx::Transform& transform) { + if (settings_.use_layer_lists) { + property_trees_.transform_tree.OnTransformAnimated(element_id, transform); + return; + } + Layer* layer = LayerByElementId(element_id); DCHECK(layer); layer->OnTransformAnimated(transform); @@ -1441,4 +1487,8 @@ void LayerTreeHost::SetNeedsDisplayOnAllLayers() { layer->SetNeedsDisplay(); } +void LayerTreeHost::SetHasCopyRequest(bool has_copy_request) { + has_copy_request_ = has_copy_request; +} + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index bf5520e2a39..51622245b1e 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -19,6 +19,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "cc/benchmarks/micro_benchmark.h" #include "cc/benchmarks/micro_benchmark_controller.h" @@ -67,8 +68,6 @@ struct ScrollAndScaleSet; class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), public NON_EXPORTED_BASE(MutatorHostClient) { public: - // TODO(sad): InitParams should be a movable type so that it can be - // std::move()d to the Create* functions. struct CC_EXPORT InitParams { LayerTreeHostClient* client = nullptr; TaskGraphRunner* task_graph_runner = nullptr; @@ -242,20 +241,32 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), Layer* root_layer() { return root_layer_.get(); } const Layer* root_layer() const { return root_layer_.get(); } - void RegisterViewportLayers(scoped_refptr<Layer> overscroll_elasticity_layer, - scoped_refptr<Layer> page_scale_layer, - scoped_refptr<Layer> inner_viewport_scroll_layer, - scoped_refptr<Layer> outer_viewport_scroll_layer); - + struct CC_EXPORT ViewportLayers { + ViewportLayers(); + ~ViewportLayers(); + scoped_refptr<Layer> overscroll_elasticity; + scoped_refptr<Layer> page_scale; + scoped_refptr<Layer> inner_viewport_container; + scoped_refptr<Layer> outer_viewport_container; + scoped_refptr<Layer> inner_viewport_scroll; + scoped_refptr<Layer> outer_viewport_scroll; + }; + void RegisterViewportLayers(const ViewportLayers& viewport_layers); Layer* overscroll_elasticity_layer() const { - return overscroll_elasticity_layer_.get(); + return viewport_layers_.overscroll_elasticity.get(); + } + 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* page_scale_layer() const { return page_scale_layer_.get(); } Layer* inner_viewport_scroll_layer() const { - return inner_viewport_scroll_layer_.get(); + return viewport_layers_.inner_viewport_scroll.get(); } Layer* outer_viewport_scroll_layer() const { - return outer_viewport_scroll_layer_.get(); + return viewport_layers_.outer_viewport_scroll.get(); } void RegisterSelection(const LayerSelection& selection); @@ -341,6 +352,9 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), bool* content_is_suitable_for_gpu); bool in_paint_layer_contents() const { return in_paint_layer_contents_; } + void SetHasCopyRequest(bool has_copy_request); + bool has_copy_request() const { return has_copy_request_; } + void AddLayerShouldPushProperties(Layer* layer); void RemoveLayerShouldPushProperties(Layer* layer); std::unordered_set<Layer*>& LayersThatShouldPushProperties(); @@ -358,7 +372,9 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), void SetPropertyTreesNeedRebuild(); - void PushPropertiesTo(LayerTreeImpl* tree_impl); + void PushPropertyTreesTo(LayerTreeImpl* tree_impl); + void PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl); + void PushLayerTreeHostPropertiesTo(LayerTreeHostImpl* host_impl); MutatorHost* mutator_host() const { return mutator_host_; } @@ -384,6 +400,7 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), void DidBeginMainFrame(); void BeginMainFrame(const BeginFrameArgs& args); void BeginMainFrameNotExpectedSoon(); + void BeginMainFrameNotExpectedUntil(base::TimeTicks time); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); void RequestMainFrameUpdate(); void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); @@ -557,10 +574,7 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), scoped_refptr<Layer> root_layer_; - scoped_refptr<Layer> overscroll_elasticity_layer_; - scoped_refptr<Layer> page_scale_layer_; - scoped_refptr<Layer> inner_viewport_scroll_layer_; - scoped_refptr<Layer> outer_viewport_scroll_layer_; + ViewportLayers viewport_layers_; float top_controls_height_ = 0.f; float top_controls_shown_ratio_ = 0.f; @@ -611,13 +625,16 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), bool in_paint_layer_contents_ = false; bool in_update_property_trees_ = false; + // This is true if atleast one layer in the layer tree has a copy request. We + // use this bool to decide whether we need to compute subtree has copy request + // for every layer during property tree building. + bool has_copy_request_ = false; + MutatorHost* mutator_host_; std::vector<std::pair<sk_sp<const SkImage>, base::Callback<void(bool)>>> queued_image_decodes_; - bool did_navigate_ = false; - DISALLOW_COPY_AND_ASSIGN(LayerTreeHost); }; diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h index 84416d60ef0..f54a69b0217 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -8,6 +8,7 @@ #include <memory> #include "base/memory/ref_counted.h" +#include "base/time/time.h" namespace gfx { class Vector2dF; @@ -24,6 +25,7 @@ class LayerTreeHostClient { // mode, this corresponds to DidCommit(). virtual void BeginMainFrame(const BeginFrameArgs& args) = 0; virtual void BeginMainFrameNotExpectedSoon() = 0; + virtual void BeginMainFrameNotExpectedUntil(base::TimeTicks time) = 0; virtual void DidBeginMainFrame() = 0; // A LayerTreeHost is bound to a LayerTreeHostClient. Visual frame-based // updates to the state of the LayerTreeHost are expected to happen only in diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc index 8d09c07ec1d..e289a34db08 100644 --- a/chromium/cc/trees/layer_tree_host_common.cc +++ b/chromium/cc/trees/layer_tree_host_common.cc @@ -20,6 +20,7 @@ #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" @@ -77,10 +78,8 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( const gfx::Vector2dF& elastic_overscroll, const LayerImpl* elastic_overscroll_application_layer, int max_texture_size, - bool can_render_to_separate_surface, bool can_adjust_raster_scales, - bool use_layer_lists, - LayerImplList* render_surface_layer_list, + RenderSurfaceList* render_surface_list, PropertyTrees* property_trees) : root_layer(root_layer), device_viewport_size(device_viewport_size), @@ -94,10 +93,8 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( elastic_overscroll_application_layer( elastic_overscroll_application_layer), max_texture_size(max_texture_size), - can_render_to_separate_surface(can_render_to_separate_surface), can_adjust_raster_scales(can_adjust_raster_scales), - use_layer_lists(use_layer_lists), - render_surface_layer_list(render_surface_layer_list), + render_surface_list(render_surface_list), property_trees(property_trees) {} LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: @@ -105,7 +102,7 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, float device_scale_factor, - LayerImplList* render_surface_layer_list) + RenderSurfaceList* render_surface_list) : CalcDrawPropsImplInputs(root_layer, device_viewport_size, device_transform, @@ -117,46 +114,44 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: gfx::Vector2dF(), NULL, std::numeric_limits<int>::max() / 2, - true, false, - false, - render_surface_layer_list, + render_surface_list, GetPropertyTrees(root_layer)) { DCHECK(root_layer); - DCHECK(render_surface_layer_list); + DCHECK(render_surface_list); } LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, - LayerImplList* render_surface_layer_list) + RenderSurfaceList* render_surface_list) : CalcDrawPropsImplInputsForTesting(root_layer, device_viewport_size, device_transform, 1.f, - render_surface_layer_list) {} + render_surface_list) {} LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, - LayerImplList* render_surface_layer_list) + RenderSurfaceList* render_surface_list) : CalcDrawPropsImplInputsForTesting(root_layer, device_viewport_size, gfx::Transform(), 1.f, - render_surface_layer_list) {} + render_surface_list) {} LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, float device_scale_factor, - LayerImplList* render_surface_layer_list) + RenderSurfaceList* render_surface_list) : CalcDrawPropsImplInputsForTesting(root_layer, device_viewport_size, gfx::Transform(), device_scale_factor, - render_surface_layer_list) {} + render_surface_list) {} LayerTreeHostCommon::ScrollUpdateInfo::ScrollUpdateInfo() : layer_id(Layer::INVALID_ID) {} @@ -167,15 +162,15 @@ bool LayerTreeHostCommon::ScrollUpdateInfo::operator==( } LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo() - : layer_id(Layer::INVALID_ID), hidden(true) {} + : element_id(), hidden(true) {} -LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo(int layer_id, +LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo(ElementId id, bool hidden) - : layer_id(layer_id), hidden(hidden) {} + : element_id(id), hidden(hidden) {} bool LayerTreeHostCommon::ScrollbarsUpdateInfo::operator==( const LayerTreeHostCommon::ScrollbarsUpdateInfo& other) const { - return layer_id == other.layer_id && hidden == other.hidden; + return element_id == other.element_id && hidden == other.hidden; } ScrollAndScaleSet::ScrollAndScaleSet() @@ -186,28 +181,21 @@ ScrollAndScaleSet::ScrollAndScaleSet() ScrollAndScaleSet::~ScrollAndScaleSet() {} -static inline void SetMaskLayersAreDrawnRenderSurfaceLayerListMembers( +static inline void SetMaskLayersContributeToDrawnRenderSurface( RenderSurfaceImpl* surface, PropertyTrees* property_trees) { LayerImpl* mask_layer = surface->MaskLayer(); if (mask_layer) { - mask_layer->set_is_drawn_render_surface_layer_list_member(true); + mask_layer->set_contributes_to_drawn_render_surface(true); draw_property_utils::ComputeMaskDrawProperties(mask_layer, property_trees); } } -static inline void ClearMaskLayersAreDrawnRenderSurfaceLayerListMembers( +static inline void ClearMaskLayersContributeToDrawnRenderSurface( RenderSurfaceImpl* surface) { LayerImpl* mask_layer = surface->MaskLayer(); if (mask_layer) - mask_layer->set_is_drawn_render_surface_layer_list_member(false); -} - -static inline void ClearIsDrawnRenderSurfaceLayerListMember( - LayerImplList* layer_list, - ScrollTree* scroll_tree) { - for (LayerImpl* layer : *layer_list) - layer->set_is_drawn_render_surface_layer_list_member(false); + mask_layer->set_contributes_to_drawn_render_surface(false); } static bool CdpPerfTracingEnabled() { @@ -280,86 +268,120 @@ enum PropertyTreeOption { DONT_BUILD_PROPERTY_TREES }; -static void ComputeInitialRenderSurfaceLayerList( +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() || + 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, - LayerImplList* render_surface_layer_list, - bool can_render_to_separate_surface, - bool use_layer_lists) { - // Add all non-skipped surfaces to the initial render surface layer list. Add - // all non-skipped layers to the layer list of their target surface, and - // add their content rect to their target surface's accumulated content rect. + 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->set_contributes_to_drawn_render_surface(false); - // TODO(crbug.com/726423): LayerImpls should never have invalid PropertyTree - // indices. - if (!layer) - continue; + bool is_root = layer_tree_impl->IsRootLayer(layer); - layer->set_is_drawn_render_surface_layer_list_member(false); - if (!layer->HasValidPropertyTreeIndices()) - continue; + bool skip_draw_properties_computation = + draw_property_utils::LayerShouldBeSkippedForDrawPropertiesComputation( + layer, property_trees->transform_tree, property_trees->effect_tree); - RenderSurfaceImpl* render_surface = layer->GetRenderSurface(); - if (render_surface) { - render_surface->ClearLayerLists(); - ClearMaskLayersAreDrawnRenderSurfaceLayerListMembers(render_surface); - } - layer->set_is_drawn_render_surface_layer_list_member(false); + bool skip_for_invertibility = SkipForInvertibility(layer, property_trees); - bool is_root = layer_tree_impl->IsRootLayer(layer); - bool skip_layer = !is_root && draw_property_utils::LayerShouldBeSkipped( - layer, property_trees->transform_tree, - property_trees->effect_tree); + bool skip_layer = !is_root && (skip_draw_properties_computation || + skip_for_invertibility); + + layer->set_raster_even_if_not_in_rsll(skip_for_invertibility && + !skip_draw_properties_computation); if (skip_layer) continue; - bool render_to_separate_surface = - is_root || (can_render_to_separate_surface && render_surface); - - if (render_to_separate_surface) { - DCHECK(render_surface); - DCHECK(layer->render_target() == render_surface); - render_surface->ClearAccumulatedContentRect(); - render_surface_layer_list->push_back(layer); - 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 { - render_surface->render_target()->layer_list().push_back(layer); - bool contributes_to_drawn_surface = - property_trees->effect_tree.ContributesToDrawnSurface( - layer->effect_tree_index()); - render_surface->set_contributes_to_drawn_surface( - contributes_to_drawn_surface); - } - - draw_property_utils::ComputeSurfaceDrawProperties( - property_trees, render_surface, use_layer_lists); - - // 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() || - 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 layer_is_drawn = property_trees->effect_tree.Node(layer->effect_tree_index())->is_drawn; bool layer_should_be_drawn = draw_property_utils::LayerNeedsUpdate( @@ -367,24 +389,30 @@ static void ComputeInitialRenderSurfaceLayerList( if (!layer_should_be_drawn) continue; - layer->set_is_drawn_render_surface_layer_list_member(true); - layer->render_target()->layer_list().push_back(layer); + 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. - layer->render_target()->AccumulateContentRectFromContributingLayer(layer); + render_target->AccumulateContentRectFromContributingLayer(layer); + render_target->increment_num_contributors(); } } static void ComputeSurfaceContentRects(LayerTreeImpl* layer_tree_impl, PropertyTrees* property_trees, - LayerImplList* render_surface_layer_list, + 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 (LayerImpl* layer : base::Reversed(*render_surface_layer_list)) { - RenderSurfaceImpl* render_surface = layer->GetRenderSurface(); - if (layer_tree_impl->IsRootLayer(layer)) { - // The root layer's surface content rect is always the entire viewport. + 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; } @@ -396,82 +424,74 @@ static void ComputeSurfaceContentRects(LayerTreeImpl* layer_tree_impl, // Now the render surface's content rect is calculated correctly, it could // contribute to its render target. - render_surface->render_target() - ->AccumulateContentRectFromContributingRenderSurface(render_surface); + 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, - LayerImplList* initial_surface_list, - LayerImplList* final_surface_list) { +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. - for (LayerImpl* layer : *initial_surface_list) { - bool is_root = layer_tree_impl->IsRootLayer(layer); - RenderSurfaceImpl* surface = layer->GetRenderSurface(); + 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->layer_list().empty())) { - ClearIsDrawnRenderSurfaceLayerListMember(&surface->layer_list(), - &property_trees->scroll_tree); - surface->ClearLayerLists(); - if (!is_root) { - LayerImplList& target_list = target_surface->layer_list(); - auto it = std::find(target_list.begin(), target_list.end(), layer); - if (it != target_list.end()) { - target_list.erase(it); - // This surface has an empty content rect. If its target's layer list - // had no other layers, then its target would also have had an empty - // content rect, meaning it would have been removed and had its layer - // list cleared when we visited it, unless the target surface is the - // root surface. - DCHECK(!target_surface->layer_list().empty() || - target_surface->render_target() == target_surface); - } else { - // This layer was removed when the target itself was cleared. - DCHECK(target_surface->layer_list().empty()); + !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(); } } - continue; } - SetMaskLayersAreDrawnRenderSurfaceLayerListMembers(surface, property_trees); - final_surface_list->push_back(layer); } } static void CalculateRenderSurfaceLayerList( LayerTreeImpl* layer_tree_impl, PropertyTrees* property_trees, - LayerImplList* render_surface_layer_list, - const bool can_render_to_separate_surface, - const bool use_layer_lists, + RenderSurfaceList* render_surface_list, const int max_texture_size) { - // This calculates top level Render Surface Layer List, and Layer List for all - // Render Surfaces. - // |render_surface_layer_list| is the top level RenderSurfaceLayerList. + RenderSurfaceList initial_render_surface_list; - LayerImplList initial_render_surface_list; - - // First compute an RSLL that might include surfaces that later turn out to + // 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 RSLL that omits empty surfaces. - ComputeInitialRenderSurfaceLayerList( - layer_tree_impl, property_trees, &initial_render_surface_list, - can_render_to_separate_surface, use_layer_lists); + // produce a final list that omits empty surfaces. + ComputeInitialRenderSurfaceList(layer_tree_impl, property_trees, + &initial_render_surface_list); ComputeSurfaceContentRects(layer_tree_impl, property_trees, &initial_render_surface_list, max_texture_size); ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, &initial_render_surface_list, - render_surface_layer_list); + render_surface_list); } void CalculateDrawPropertiesInternal( LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs, PropertyTreeOption property_tree_option) { - inputs->render_surface_layer_list->clear(); + inputs->render_surface_list->clear(); const bool should_measure_property_tree_performance = property_tree_option == BUILD_PROPERTY_TREES_IF_NEEDED; @@ -498,7 +518,6 @@ void CalculateDrawPropertiesInternal( inputs->device_transform, inputs->property_trees); draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( inputs->root_layer, inputs->property_trees, - inputs->can_render_to_separate_surface, inputs->can_adjust_raster_scales); // Property trees are normally constructed on the main thread and @@ -545,7 +564,6 @@ void CalculateDrawPropertiesInternal( inputs->device_transform, inputs->root_layer->position()); draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( inputs->root_layer, inputs->property_trees, - inputs->can_render_to_separate_surface, inputs->can_adjust_raster_scales); break; } @@ -559,15 +577,12 @@ void CalculateDrawPropertiesInternal( draw_property_utils::FindLayersThatNeedUpdates( inputs->root_layer->layer_tree_impl(), inputs->property_trees, &visible_layer_list); - DCHECK(inputs->can_render_to_separate_surface == - inputs->property_trees->non_root_surfaces_enabled); draw_property_utils::ComputeDrawPropertiesOfVisibleLayers( &visible_layer_list, inputs->property_trees); CalculateRenderSurfaceLayerList( inputs->root_layer->layer_tree_impl(), inputs->property_trees, - inputs->render_surface_layer_list, inputs->can_render_to_separate_surface, - inputs->use_layer_lists, inputs->max_texture_size); + inputs->render_surface_list, inputs->max_texture_size); if (should_measure_property_tree_performance) { TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), @@ -576,13 +591,13 @@ void CalculateDrawPropertiesInternal( // A root layer render_surface should always exist after // CalculateDrawProperties. - DCHECK(inputs->root_layer->GetRenderSurface()); + DCHECK(inputs->property_trees->effect_tree.GetRenderSurface( + EffectTree::kContentsRootNodeId)); } void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( CalcDrawPropsMainInputsForTesting* inputs) { LayerList update_layer_list; - bool can_render_to_separate_surface = true; PropertyTrees* property_trees = inputs->root_layer->layer_tree_host()->property_trees(); Layer* overscroll_elasticity_layer = nullptr; @@ -595,8 +610,7 @@ void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( gfx::Rect(inputs->device_viewport_size), inputs->device_transform, property_trees); draw_property_utils::UpdatePropertyTrees( - inputs->root_layer->layer_tree_host(), property_trees, - can_render_to_separate_surface); + inputs->root_layer->layer_tree_host(), property_trees); draw_property_utils::FindLayersThatNeedUpdates( inputs->root_layer->layer_tree_host(), property_trees, &update_layer_list); diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h index dd668caa88e..522ef93c050 100644 --- a/chromium/cc/trees/layer_tree_host_common.h +++ b/chromium/cc/trees/layer_tree_host_common.h @@ -72,10 +72,8 @@ class CC_EXPORT LayerTreeHostCommon { const gfx::Vector2dF& elastic_overscroll, const LayerImpl* elastic_overscroll_application_layer, int max_texture_size, - bool can_render_to_separate_surface, bool can_adjust_raster_scales, - bool use_layer_lists, - LayerImplList* render_surface_layer_list, + RenderSurfaceList* render_surface_list, PropertyTrees* property_trees); LayerImpl* root_layer; @@ -89,10 +87,8 @@ class CC_EXPORT LayerTreeHostCommon { gfx::Vector2dF elastic_overscroll; const LayerImpl* elastic_overscroll_application_layer; int max_texture_size; - bool can_render_to_separate_surface; bool can_adjust_raster_scales; - bool use_layer_lists; - LayerImplList* render_surface_layer_list; + RenderSurfaceList* render_surface_list; PropertyTrees* property_trees; }; @@ -102,18 +98,18 @@ class CC_EXPORT LayerTreeHostCommon { const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, float device_scale_factor, - LayerImplList* render_surface_layer_list); + RenderSurfaceList* render_surface_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, - LayerImplList* render_surface_layer_list); + RenderSurfaceList* render_surface_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, - LayerImplList* render_surface_layer_list); + RenderSurfaceList* render_surface_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, float device_scale_factor, - LayerImplList* render_surface_layer_list); + RenderSurfaceList* render_surface_list); }; static int CalculateLayerJitter(LayerImpl* scrolling_layer); @@ -149,11 +145,11 @@ class CC_EXPORT LayerTreeHostCommon { // to be told when they're faded out so it can stop handling input for // invisible scrollbars. struct CC_EXPORT ScrollbarsUpdateInfo { - int layer_id; + ElementId element_id; bool hidden; ScrollbarsUpdateInfo(); - ScrollbarsUpdateInfo(int layer_id, bool hidden); + ScrollbarsUpdateInfo(ElementId element_id, bool hidden); bool operator==(const ScrollbarsUpdateInfo& other) const; }; diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc index 89946eea48a..c0b1e3254d2 100644 --- a/chromium/cc/trees/layer_tree_host_common_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc @@ -86,12 +86,8 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { LayerTreeImpl* active_tree = host_impl->active_tree(); do { - bool can_render_to_separate_surface = true; int max_texture_size = 8096; - DoCalcDrawPropertiesImpl(can_render_to_separate_surface, - max_texture_size, - active_tree, - host_impl); + DoCalcDrawPropertiesImpl(max_texture_size, active_tree, host_impl); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); @@ -99,22 +95,20 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { EndTest(); } - void DoCalcDrawPropertiesImpl(bool can_render_to_separate_surface, - int max_texture_size, + void DoCalcDrawPropertiesImpl(int max_texture_size, LayerTreeImpl* active_tree, LayerTreeHostImpl* host_impl) { - LayerImplList update_list; + RenderSurfaceList update_list; LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - active_tree->root_layer_for_testing(), active_tree->DrawViewportSize(), - host_impl->DrawTransform(), active_tree->device_scale_factor(), + active_tree->root_layer_for_testing(), + active_tree->DeviceViewport().size(), 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->OverscrollElasticityLayer(), max_texture_size, - can_render_to_separate_surface, - false, // don't use layer lists for perf tests host_impl->settings().layer_transforms_should_scale_layer_contents, &update_list, active_tree->property_trees()); LayerTreeHostCommon::CalculateDrawProperties(&inputs); diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc index e6f69f6dd99..a26ee7f4559 100644 --- a/chromium/cc/trees/layer_tree_host_common_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc @@ -42,7 +42,6 @@ #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/property_tree_builder.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" @@ -139,14 +138,13 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { gfx::Size(root_layer->bounds().width() * device_scale_factor, root_layer->bounds().height() * device_scale_factor); - render_surface_layer_list_impl_.reset(new LayerImplList); + render_surface_list_impl_.reset(new RenderSurfaceList); // We are probably not testing what is intended if the root_layer bounds are // empty. DCHECK(!root_layer->bounds().IsEmpty()); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, - render_surface_layer_list_impl_.get()); + root_layer, device_viewport_size, render_surface_list_impl_.get()); inputs.device_scale_factor = device_scale_factor; inputs.page_scale_factor = page_scale_factor; inputs.page_scale_layer = page_scale_layer; @@ -182,8 +180,6 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(Layer* root_layer) { DCHECK(root_layer->layer_tree_host()); - bool can_render_to_separate_surface = true; - const Layer* page_scale_layer = root_layer->layer_tree_host()->page_scale_layer(); Layer* inner_viewport_scroll_layer = @@ -208,8 +204,7 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { elastic_overscroll, page_scale_factor, device_scale_factor, gfx::Rect(device_viewport_size), gfx::Transform(), property_trees); draw_property_utils::UpdatePropertyTrees(root_layer->layer_tree_host(), - property_trees, - can_render_to_separate_surface); + property_trees); draw_property_utils::FindLayersThatNeedUpdates( root_layer->layer_tree_host(), property_trees, &update_layer_list_); } @@ -217,7 +212,6 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList( LayerImpl* root_layer) { DCHECK(root_layer->layer_tree_impl()); - bool can_render_to_separate_surface = true; bool can_adjust_raster_scales = true; const LayerImpl* page_scale_layer = nullptr; @@ -245,8 +239,7 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { elastic_overscroll, page_scale_factor, device_scale_factor, gfx::Rect(device_viewport_size), gfx::Transform(), property_trees); draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( - root_layer, property_trees, can_render_to_separate_surface, - can_adjust_raster_scales); + root_layer, property_trees, can_adjust_raster_scales); draw_property_utils::FindLayersThatNeedUpdates( root_layer->layer_tree_impl(), property_trees, update_layer_list_impl_.get()); @@ -258,14 +251,12 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { LayerImpl* root_layer) { gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width(), root_layer->bounds().height()); - render_surface_layer_list_impl_.reset(new LayerImplList); + render_surface_list_impl_.reset(new RenderSurfaceList); DCHECK(!root_layer->bounds().IsEmpty()); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, - render_surface_layer_list_impl_.get()); + root_layer, device_viewport_size, render_surface_list_impl_.get()); inputs.can_adjust_raster_scales = true; - inputs.can_render_to_separate_surface = false; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); } @@ -274,13 +265,11 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { LayerImpl* root_layer) { gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width(), root_layer->bounds().height()); - render_surface_layer_list_impl_.reset(new LayerImplList); + render_surface_list_impl_.reset(new RenderSurfaceList); DCHECK(!root_layer->bounds().IsEmpty()); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, - render_surface_layer_list_impl_.get()); - inputs.can_render_to_separate_surface = true; + root_layer, device_viewport_size, render_surface_list_impl_.get()); inputs.can_adjust_raster_scales = false; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); @@ -302,8 +291,8 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { return false; } - const LayerImplList* render_surface_layer_list_impl() const { - return render_surface_layer_list_impl_.get(); + const RenderSurfaceList* render_surface_list_impl() const { + return render_surface_list_impl_.get(); } const LayerImplList* update_layer_list_impl() const { return update_layer_list_impl_.get(); @@ -317,7 +306,7 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { } private: - std::unique_ptr<std::vector<LayerImpl*>> render_surface_layer_list_impl_; + std::unique_ptr<RenderSurfaceList> render_surface_list_impl_; LayerList update_layer_list_; std::unique_ptr<LayerImplList> update_layer_list_impl_; }; @@ -613,9 +602,10 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { // Test that page scale is updated even when we don't rebuild property trees. page_scale = 1.888f; - root_layer->layer_tree_impl()->SetViewportLayersFromIds( - Layer::INVALID_ID, scroll_layer->test_properties()->parent->id(), - Layer::INVALID_ID, Layer::INVALID_ID); + + LayerTreeImpl::ViewportLayerIds viewport_ids; + viewport_ids.page_scale = scroll_layer->test_properties()->parent->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, page_scale, @@ -750,8 +740,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { ExecuteCalculateDrawProperties(root); // Render surface should have been created now. - ASSERT_TRUE(child->GetRenderSurface()); - ASSERT_EQ(child->GetRenderSurface(), child->render_target()); + ASSERT_TRUE(GetRenderSurface(child)); + ASSERT_EQ(GetRenderSurface(child), child->render_target()); // The child layer's draw transform should refer to its new render surface. // The screen-space transform, however, should still refer to the root. @@ -773,54 +763,6 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { child->render_target()->screen_space_transform()); } -TEST_F(LayerTreeHostCommonTest, TransformsWhenCannotRenderToSeparateSurface) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChildToRoot<LayerImpl>(); - LayerImpl* child = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child); - - gfx::Transform parent_transform; - parent_transform.Translate(10.0, 10.0); - - gfx::Transform child_transform; - child_transform.Rotate(45.0); - - root->SetBounds(gfx::Size(100, 100)); - parent->test_properties()->transform = parent_transform; - parent->SetBounds(gfx::Size(10, 10)); - child->test_properties()->transform = child_transform; - child->SetBounds(gfx::Size(10, 10)); - child->test_properties()->force_render_surface = true; - grand_child->SetPosition(gfx::PointF(2.f, 2.f)); - grand_child->SetBounds(gfx::Size(20, 20)); - grand_child->SetDrawsContent(true); - - gfx::Transform expected_grand_child_screen_space_transform; - expected_grand_child_screen_space_transform.Translate(10.0, 10.0); - expected_grand_child_screen_space_transform.Rotate(45.0); - expected_grand_child_screen_space_transform.Translate(2.0, 2.0); - - // First compute draw properties with separate surfaces enabled. - ExecuteCalculateDrawProperties(root); - - // The grand child's draw transform should be its offset wrt the child. - gfx::Transform expected_grand_child_draw_transform; - expected_grand_child_draw_transform.Translate(2.0, 2.0); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform, - grand_child->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform, - grand_child->ScreenSpaceTransform()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - - // With separate surfaces disabled, the grand child's draw transform should be - // the same as its screen space transform. - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform, - grand_child->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform, - grand_child->ScreenSpaceTransform()); -} - TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { // This test creates a more complex tree and verifies it all at once. This // covers the following cases: @@ -935,33 +877,37 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { // Only layers that are associated with render surfaces should have an actual // RenderSurface() value. - ASSERT_TRUE(root->GetRenderSurface()); - ASSERT_FALSE(child_of_root->GetRenderSurface()); - ASSERT_FALSE(grand_child_of_root->GetRenderSurface()); - - ASSERT_TRUE(render_surface1->GetRenderSurface()); - ASSERT_FALSE(child_of_rs1->GetRenderSurface()); - ASSERT_FALSE(grand_child_of_rs1->GetRenderSurface()); - - ASSERT_TRUE(render_surface2->GetRenderSurface()); - ASSERT_FALSE(child_of_rs2->GetRenderSurface()); - ASSERT_FALSE(grand_child_of_rs2->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(child_of_root), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(grand_child_of_root), GetRenderSurface(root)); + + ASSERT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(child_of_rs1), GetRenderSurface(render_surface1)); + ASSERT_EQ(GetRenderSurface(grand_child_of_rs1), + GetRenderSurface(render_surface1)); + + ASSERT_NE(GetRenderSurface(render_surface2), GetRenderSurface(root)); + ASSERT_NE(GetRenderSurface(render_surface2), + GetRenderSurface(render_surface1)); + ASSERT_EQ(GetRenderSurface(child_of_rs2), GetRenderSurface(render_surface2)); + ASSERT_EQ(GetRenderSurface(grand_child_of_rs2), + GetRenderSurface(render_surface2)); // Verify all render target accessors - EXPECT_EQ(root->GetRenderSurface(), parent->render_target()); - EXPECT_EQ(root->GetRenderSurface(), child_of_root->render_target()); - EXPECT_EQ(root->GetRenderSurface(), grand_child_of_root->render_target()); + EXPECT_EQ(GetRenderSurface(root), parent->render_target()); + EXPECT_EQ(GetRenderSurface(root), child_of_root->render_target()); + EXPECT_EQ(GetRenderSurface(root), grand_child_of_root->render_target()); - EXPECT_EQ(render_surface1->GetRenderSurface(), + EXPECT_EQ(GetRenderSurface(render_surface1), render_surface1->render_target()); - EXPECT_EQ(render_surface1->GetRenderSurface(), child_of_rs1->render_target()); - EXPECT_EQ(render_surface1->GetRenderSurface(), + EXPECT_EQ(GetRenderSurface(render_surface1), child_of_rs1->render_target()); + EXPECT_EQ(GetRenderSurface(render_surface1), grand_child_of_rs1->render_target()); - EXPECT_EQ(render_surface2->GetRenderSurface(), + EXPECT_EQ(GetRenderSurface(render_surface2), render_surface2->render_target()); - EXPECT_EQ(render_surface2->GetRenderSurface(), child_of_rs2->render_target()); - EXPECT_EQ(render_surface2->GetRenderSurface(), + EXPECT_EQ(GetRenderSurface(render_surface2), child_of_rs2->render_target()); + EXPECT_EQ(GetRenderSurface(render_surface2), grand_child_of_rs2->render_target()); // Verify layer draw transforms note that draw transforms are described with @@ -1007,17 +953,16 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { // // Draw transform of render surface 1 is described with respect to root. EXPECT_TRANSFORMATION_MATRIX_EQ( - A * A * S1, render_surface1->GetRenderSurface()->draw_transform()); + A * A * S1, GetRenderSurface(render_surface1)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ( - A * A * S1, - render_surface1->GetRenderSurface()->screen_space_transform()); + A * A * S1, GetRenderSurface(render_surface1)->screen_space_transform()); // Draw transform of render surface 2 is described with respect to render // surface 1. EXPECT_TRANSFORMATION_MATRIX_EQ( - SS1 * A * S2, render_surface2->GetRenderSurface()->draw_transform()); + SS1 * A * S2, GetRenderSurface(render_surface2)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ( A * A * A * S2, - render_surface2->GetRenderSurface()->screen_space_transform()); + GetRenderSurface(render_surface2)->screen_space_transform()); // Sanity check. If these fail there is probably a bug in the test itself. It // is expected that we correctly set up transforms so that the y-component of @@ -1088,12 +1033,12 @@ TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) { ExecuteCalculateDrawProperties(root); // The child's draw transform should have been taken by its surface. - ASSERT_TRUE(child->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(child)); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_draw_transform, - child->GetRenderSurface()->draw_transform()); + GetRenderSurface(child)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_child_screen_space_transform, - child->GetRenderSurface()->screen_space_transform()); + GetRenderSurface(child)->screen_space_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_screen_space_transform, child->ScreenSpaceTransform()); @@ -1169,10 +1114,10 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { grand_child->SetBounds(gfx::Size(10, 10)); ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(child->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(child)); // This is the real test, the rest are sanity checks. EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - child->GetRenderSurface()->draw_transform()); + GetRenderSurface(child)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), grand_child->DrawTransform()); @@ -1199,9 +1144,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { // render_surface will have a sublayer scale because of device scale factor. float device_scale_factor = 2.0f; - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl); + root, root->bounds(), translate, &render_surface_list_impl); inputs.device_scale_factor = device_scale_factor; inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); @@ -1229,9 +1174,9 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform translate; translate.Translate(50, 50); { - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl); + root, root->bounds(), translate, &render_surface_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1239,7 +1184,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_TRANSFORMATION_MATRIX_EQ( translate, child->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - root->GetRenderSurface()->draw_transform()); + GetRenderSurface(root)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(translate, child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(50, 50, 100, 100), child->clip_rect()); } @@ -1247,9 +1192,9 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform scale; scale.Scale(2, 2); { - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), scale, &render_surface_layer_list_impl); + root, root->bounds(), scale, &render_surface_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1257,7 +1202,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_TRANSFORMATION_MATRIX_EQ( scale, child->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - root->GetRenderSurface()->draw_transform()); + GetRenderSurface(root)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(scale, child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(0, 0, 200, 200), child->clip_rect()); } @@ -1265,9 +1210,9 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform rotate; rotate.Rotate(2); { - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), rotate, &render_surface_layer_list_impl); + root, root->bounds(), rotate, &render_surface_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1275,7 +1220,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_TRANSFORMATION_MATRIX_EQ( rotate, child->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - root->GetRenderSurface()->draw_transform()); + GetRenderSurface(root)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(rotate, child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(-4, 0, 104, 104), child->clip_rect()); } @@ -1285,9 +1230,9 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { composite.ConcatTransform(scale); composite.ConcatTransform(rotate); { - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), composite, &render_surface_layer_list_impl); + root, root->bounds(), composite, &render_surface_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1295,7 +1240,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_TRANSFORMATION_MATRIX_EQ( composite, child->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - root->GetRenderSurface()->draw_transform()); + GetRenderSurface(root)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(composite, child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(89, 103, 208, 208), child->clip_rect()); } @@ -1304,9 +1249,9 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { float device_scale_factor = 1.5f; { - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl); + root, root->bounds(), translate, &render_surface_list_impl); inputs.device_scale_factor = device_scale_factor; inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); @@ -1319,7 +1264,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { device_scaled_translate, child->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - root->GetRenderSurface()->draw_transform()); + GetRenderSurface(root)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(device_scaled_translate, child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(50, 50, 150, 150), child->clip_rect()); @@ -1329,9 +1274,9 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { float page_scale_factor = 2.f; { - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), translate, &render_surface_layer_list_impl); + root, root->bounds(), translate, &render_surface_list_impl); inputs.page_scale_factor = page_scale_factor; inputs.page_scale_layer = root; inputs.property_trees->needs_rebuild = true; @@ -1343,7 +1288,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_TRANSFORMATION_MATRIX_EQ( page_scaled_translate, child->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - root->GetRenderSurface()->draw_transform()); + GetRenderSurface(root)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(page_scaled_translate, child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(50, 50, 200, 200), child->clip_rect()); @@ -1353,9 +1298,9 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { root->test_properties()->transform = composite; { - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), composite, &render_surface_layer_list_impl); + root, root->bounds(), composite, &render_surface_list_impl); inputs.property_trees->needs_rebuild = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); gfx::Transform compositeSquared = composite; @@ -1365,13 +1310,68 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_TRANSFORMATION_MATRIX_EQ( compositeSquared, child->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - root->GetRenderSurface()->draw_transform()); + GetRenderSurface(root)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(compositeSquared, child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(254, 316, 428, 428), child->clip_rect()); } } +TEST_F(LayerTreeHostCommonTest, RenderSurfaceForNonAxisAlignedClipping) { + LayerImpl* root = root_layer_for_testing(); + LayerImpl* rotated_and_transparent = AddChildToRoot<LayerImpl>(); + LayerImpl* clips_subtree = AddChild<LayerImpl>(rotated_and_transparent); + LayerImpl* draws_content = AddChild<LayerImpl>(clips_subtree); + + root->SetBounds(gfx::Size(10, 10)); + rotated_and_transparent->SetBounds(gfx::Size(10, 10)); + rotated_and_transparent->test_properties()->opacity = 0.5f; + gfx::Transform rotate; + rotate.Rotate(2); + rotated_and_transparent->test_properties()->transform = rotate; + clips_subtree->SetBounds(gfx::Size(10, 10)); + clips_subtree->SetMasksToBounds(true); + draws_content->SetBounds(gfx::Size(10, 10)); + draws_content->SetDrawsContent(true); + + ExecuteCalculateDrawProperties(root); + EffectTree& effect_tree = + root->layer_tree_impl()->property_trees()->effect_tree; + EffectNode* node = effect_tree.Node(clips_subtree->effect_tree_index()); + EXPECT_TRUE(node->has_render_surface); +} + +TEST_F(LayerTreeHostCommonTest, EffectNodesForNonAxisAlignedClips) { + LayerImpl* root = root_layer_for_testing(); + LayerImpl* rotate_and_clip = AddChildToRoot<LayerImpl>(); + LayerImpl* only_clip = AddChild<LayerImpl>(rotate_and_clip); + LayerImpl* rotate_and_clip2 = AddChild<LayerImpl>(only_clip); + + gfx::Transform rotate; + rotate.Rotate(2); + root->SetBounds(gfx::Size(10, 10)); + rotate_and_clip->SetBounds(gfx::Size(10, 10)); + rotate_and_clip->test_properties()->transform = 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->test_properties()->transform = rotate; + rotate_and_clip2->SetMasksToBounds(true); + + ExecuteCalculateDrawProperties(root); + // 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(LayerTreeHostCommonTest, RenderSurfaceListForRenderSurfaceWithClippedLayer) { LayerImpl* root = root_layer_for_testing(); @@ -1392,8 +1392,8 @@ TEST_F(LayerTreeHostCommonTest, // 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(root->GetRenderSurface()); - EXPECT_EQ(1U, render_surface_layer_list_impl()->size()); + ASSERT_TRUE(GetRenderSurface(root)); + EXPECT_EQ(1U, render_surface_list_impl()->size()); } TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) { @@ -1407,19 +1407,19 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) { child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list); + root, root->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // Since the layer is transparent, render_surface1->GetRenderSurface() should // not have gotten added anywhere. Also, the drawable content rect should not // have been extended by the children. - ASSERT_TRUE(root->GetRenderSurface()); - EXPECT_EQ(0U, root->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(1U, render_surface_layer_list.size()); - EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id()); + ASSERT_TRUE(GetRenderSurface(root)); + EXPECT_EQ(0, GetRenderSurface(root)->num_contributors()); + EXPECT_EQ(1U, render_surface_list.size()); + EXPECT_EQ(root->id(), render_surface_list.at(0)->id()); EXPECT_EQ(gfx::Rect(), root->drawable_content_rect()); } @@ -1442,19 +1442,19 @@ TEST_F(LayerTreeHostCommonTest, root->layer_tree_impl()->SetElementIdsForTesting(); { - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list); + root, root->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - EXPECT_EQ(2U, render_surface_layer_list.size()); + EXPECT_EQ(2U, render_surface_list.size()); } // The layer is fully transparent, but has a background filter, so it // shouldn't be skipped and should be drawn. - ASSERT_TRUE(root->GetRenderSurface()); - EXPECT_EQ(1U, root->GetRenderSurface()->layer_list().size()); + ASSERT_TRUE(GetRenderSurface(root)); + EXPECT_EQ(1, GetRenderSurface(root)->num_contributors()); EXPECT_EQ(gfx::RectF(0, 0, 10, 10), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); EffectTree& effect_tree = root->layer_tree_impl()->property_trees()->effect_tree; EffectNode* node = effect_tree.Node(render_surface1->effect_tree_index()); @@ -1466,9 +1466,9 @@ TEST_F(LayerTreeHostCommonTest, 1.f); render_surface1->set_visible_layer_rect(gfx::Rect()); { - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list); + root, root->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); } @@ -1501,21 +1501,21 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForFilter) { child2->SetDrawsContent(true); child2->test_properties()->force_render_surface = true; - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list); + root, root->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - ASSERT_TRUE(parent->GetRenderSurface()); - EXPECT_EQ(2U, parent->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(4U, render_surface_layer_list.size()); + ASSERT_TRUE(GetRenderSurface(parent)); + EXPECT_EQ(2, GetRenderSurface(parent)->num_contributors()); + EXPECT_EQ(4U, render_surface_list.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), - parent->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(parent)->DrawableContentRect()); } TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { @@ -1535,9 +1535,9 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { // 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 // contents (at the new offset). - ASSERT_TRUE(child->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(child)); EXPECT_EQ(gfx::RectF(50, 50, 25, 25), - child->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(child)->DrawableContentRect()); } TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { @@ -1562,9 +1562,9 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { // it need only have a drawable content rect large enough to contain the // contents (at the new offset). All coordinates should be scaled by 2, // corresponding to the device scale factor. - ASSERT_TRUE(child->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(child)); EXPECT_EQ(gfx::RectF(100, 100, 50, 50), - child->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(child)->DrawableContentRect()); } TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { @@ -1581,10 +1581,10 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { // Since the child layer has a blend mode other than normal, it should get // its own render surface. - ASSERT_TRUE(child->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(child)); EXPECT_EQ(1.0f, child->draw_opacity()); - EXPECT_EQ(0.5f, child->GetRenderSurface()->draw_opacity()); - EXPECT_EQ(SkBlendMode::kMultiply, child->GetRenderSurface()->BlendMode()); + EXPECT_EQ(0.5f, GetRenderSurface(child)->draw_opacity()); + EXPECT_EQ(SkBlendMode::kMultiply, GetRenderSurface(child)->BlendMode()); } TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { @@ -1606,73 +1606,13 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { surface2->test_properties()->force_render_surface = true; ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(surface1->GetRenderSurface()); - ASSERT_FALSE(not_surface->GetRenderSurface()); - ASSERT_TRUE(surface2->GetRenderSurface()); - EXPECT_EQ(0.5f, surface1->GetRenderSurface()->draw_opacity()); + ASSERT_TRUE(GetRenderSurface(surface1)); + ASSERT_EQ(GetRenderSurface(not_surface), GetRenderSurface(surface1)); + ASSERT_TRUE(GetRenderSurface(surface2)); + EXPECT_EQ(0.5f, GetRenderSurface(surface1)->draw_opacity()); // surface2's draw opacity should include the opacity of not-surface and // itself, but not the opacity of surface1. - EXPECT_EQ(0.25f, surface2->GetRenderSurface()->draw_opacity()); -} - -TEST_F(LayerTreeHostCommonTest, DrawOpacityWhenCannotRenderToSeparateSurface) { - // Tests that when separate surfaces are disabled, a layer's draw opacity is - // the product of all ancestor layer opacties and the layer's own opacity. - // (Rendering will still be incorrect in situations where we really do need - // surfaces to apply opacity, such as when we have overlapping layers with an - // ancestor whose opacity is <1.) - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child1 = AddChild<LayerImpl>(parent); - LayerImpl* child2 = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child1); - LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child); - LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2); - - root->SetBounds(gfx::Size(100, 100)); - root->SetDrawsContent(true); - parent->SetBounds(gfx::Size(100, 100)); - parent->SetDrawsContent(true); - child1->SetBounds(gfx::Size(100, 100)); - child1->SetDrawsContent(true); - child1->test_properties()->opacity = 0.5f; - child1->test_properties()->force_render_surface = true; - child2->SetBounds(gfx::Size(100, 100)); - child2->SetDrawsContent(true); - grand_child->SetBounds(gfx::Size(100, 100)); - grand_child->SetDrawsContent(true); - grand_child->test_properties()->opacity = 0.5f; - grand_child->test_properties()->force_render_surface = true; - leaf_node1->SetBounds(gfx::Size(100, 100)); - leaf_node1->SetDrawsContent(true); - leaf_node1->test_properties()->opacity = 0.5f; - leaf_node2->SetBounds(gfx::Size(100, 100)); - leaf_node2->SetDrawsContent(true); - leaf_node2->test_properties()->opacity = 0.5f; - - // With surfaces enabled, each layer's draw opacity is the product of layer - // opacities on the path from the layer to its render target, not including - // the opacity of the layer that owns the target surface (since that opacity - // is applied by the surface). - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(1.f, root->draw_opacity()); - EXPECT_EQ(1.f, parent->draw_opacity()); - EXPECT_EQ(1.f, child1->draw_opacity()); - EXPECT_EQ(1.f, child2->draw_opacity()); - EXPECT_EQ(1.f, grand_child->draw_opacity()); - EXPECT_EQ(0.5f, leaf_node1->draw_opacity()); - EXPECT_EQ(0.5f, leaf_node2->draw_opacity()); - - // With surfaces disabled, each layer's draw opacity is the product of layer - // opacities on the path from the layer to the root. - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_EQ(1.f, root->draw_opacity()); - EXPECT_EQ(1.f, parent->draw_opacity()); - EXPECT_EQ(0.5f, child1->draw_opacity()); - EXPECT_EQ(1.f, child2->draw_opacity()); - EXPECT_EQ(0.25f, grand_child->draw_opacity()); - EXPECT_EQ(0.125f, leaf_node1->draw_opacity()); - EXPECT_EQ(0.5f, leaf_node2->draw_opacity()); + EXPECT_EQ(0.25f, GetRenderSurface(surface2)->draw_opacity()); } TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { @@ -1690,16 +1630,16 @@ TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); // The root layer always creates a render surface - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_TRUE(render_surface1->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root)); } { render_surface1->test_properties()->force_render_surface = false; render_surface1->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_FALSE(render_surface1->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(render_surface1), GetRenderSurface(root)); } } @@ -1725,9 +1665,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfacesFlattenScreenSpaceTransform) { grand_child->test_properties()->should_flatten_transform = false; ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(parent->GetRenderSurface()); - EXPECT_FALSE(child->GetRenderSurface()); - EXPECT_FALSE(grand_child->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(parent)); + EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(parent)); + EXPECT_EQ(GetRenderSurface(grand_child), GetRenderSurface(parent)); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), @@ -1746,7 +1686,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfacesFlattenScreenSpaceTransform) { TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { // The entire subtree of layers that are outside the clip rect should be - // culled away, and should not affect the render_surface_layer_list. + // culled away, and should not affect the render_surface_list. // // The test tree is set up as follows: // - all layers except the leaf_nodes are forced to be a new render surface @@ -1765,9 +1705,8 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { LayerImpl* grand_child = AddChild<LayerImpl>(child); LayerImpl* great_grand_child = AddChild<LayerImpl>(grand_child); - // leaf_node1 ensures that root and child are kept on the - // render_surface_layer_list, even though grand_child and great_grand_child - // should be clipped. + // 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. LayerImpl* leaf_node1 = AddChild<LayerImpl>(child); LayerImpl* leaf_node2 = AddChild<LayerImpl>(great_grand_child); @@ -1784,9 +1723,9 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { leaf_node2->SetDrawsContent(true); ExecuteCalculateDrawProperties(root); - ASSERT_EQ(2U, render_surface_layer_list_impl()->size()); - EXPECT_EQ(root->id(), render_surface_layer_list_impl()->at(0)->id()); - EXPECT_EQ(child->id(), render_surface_layer_list_impl()->at(1)->id()); + ASSERT_EQ(2U, render_surface_list_impl()->size()); + EXPECT_EQ(root->id(), render_surface_list_impl()->at(0)->id()); + EXPECT_EQ(child->id(), render_surface_list_impl()->at(1)->id()); } TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { @@ -1802,7 +1741,7 @@ 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_layer_list. + // render_surface_list. LayerImpl* root = root_layer_for_testing(); LayerImpl* child = AddChildToRoot<LayerImpl>(); @@ -1821,9 +1760,9 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { ExecuteCalculateDrawProperties(root); // We should cull child and grand_child from the - // render_surface_layer_list. - ASSERT_EQ(1U, render_surface_layer_list_impl()->size()); - EXPECT_EQ(root->id(), render_surface_layer_list_impl()->at(0)->id()); + // render_surface_list. + ASSERT_EQ(1U, render_surface_list_impl()->size()); + EXPECT_EQ(root->id(), render_surface_list_impl()->at(0)->id()); } TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { @@ -1866,15 +1805,15 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { // Case 1: nothing is clipped except the root render surface. ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(root->GetRenderSurface()); - ASSERT_TRUE(child2->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(root)); + ASSERT_TRUE(GetRenderSurface(child2)); EXPECT_FALSE(root->is_clipped()); - EXPECT_TRUE(root->GetRenderSurface()->is_clipped()); + EXPECT_TRUE(GetRenderSurface(root)->is_clipped()); EXPECT_FALSE(parent->is_clipped()); EXPECT_FALSE(child1->is_clipped()); EXPECT_FALSE(child2->is_clipped()); - EXPECT_FALSE(child2->GetRenderSurface()->is_clipped()); + EXPECT_FALSE(GetRenderSurface(child2)->is_clipped()); EXPECT_FALSE(grand_child->is_clipped()); EXPECT_FALSE(leaf_node1->is_clipped()); EXPECT_FALSE(leaf_node2->is_clipped()); @@ -1888,15 +1827,15 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(root->GetRenderSurface()); - ASSERT_TRUE(child2->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(root)); + ASSERT_TRUE(GetRenderSurface(child2)); EXPECT_FALSE(root->is_clipped()); - EXPECT_TRUE(root->GetRenderSurface()->is_clipped()); + EXPECT_TRUE(GetRenderSurface(root)->is_clipped()); EXPECT_TRUE(parent->is_clipped()); EXPECT_TRUE(child1->is_clipped()); EXPECT_FALSE(child2->is_clipped()); - EXPECT_TRUE(child2->GetRenderSurface()->is_clipped()); + EXPECT_TRUE(GetRenderSurface(child2)->is_clipped()); EXPECT_TRUE(grand_child->is_clipped()); EXPECT_TRUE(leaf_node1->is_clipped()); EXPECT_FALSE(leaf_node2->is_clipped()); @@ -1910,15 +1849,15 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(root->GetRenderSurface()); - ASSERT_TRUE(child2->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(root)); + ASSERT_TRUE(GetRenderSurface(child2)); EXPECT_FALSE(root->is_clipped()); - EXPECT_TRUE(root->GetRenderSurface()->is_clipped()); + EXPECT_TRUE(GetRenderSurface(root)->is_clipped()); EXPECT_FALSE(parent->is_clipped()); EXPECT_FALSE(child1->is_clipped()); EXPECT_TRUE(child2->is_clipped()); - EXPECT_FALSE(child2->GetRenderSurface()->is_clipped()); + EXPECT_FALSE(GetRenderSurface(child2)->is_clipped()); EXPECT_FALSE(grand_child->is_clipped()); EXPECT_FALSE(leaf_node1->is_clipped()); EXPECT_TRUE(leaf_node2->is_clipped()); @@ -1958,154 +1897,6 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { EXPECT_EQ(gfx::Rect(), child->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, IsClippedWhenCannotRenderToSeparateSurface) { - // Tests that when separate surfaces are disabled, is_clipped is true exactly - // when a layer or its ancestor has a clip; in particular, if a layer - // is_clipped, so is its entire subtree (since there are no render surfaces - // that can reset is_clipped). - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child1 = AddChild<LayerImpl>(parent); - LayerImpl* child2 = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child1); - LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child); - LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2); - - root->SetBounds(gfx::Size(100, 100)); - root->SetDrawsContent(true); - parent->SetBounds(gfx::Size(100, 100)); - parent->SetDrawsContent(true); - child1->SetBounds(gfx::Size(100, 100)); - child1->SetDrawsContent(true); - child1->test_properties()->force_render_surface = true; - child2->SetBounds(gfx::Size(100, 100)); - child2->SetDrawsContent(true); - grand_child->SetBounds(gfx::Size(100, 100)); - grand_child->SetDrawsContent(true); - grand_child->test_properties()->force_render_surface = true; - leaf_node1->SetBounds(gfx::Size(100, 100)); - leaf_node1->SetDrawsContent(true); - leaf_node2->SetBounds(gfx::Size(100, 100)); - leaf_node2->SetDrawsContent(true); - - // Case 1: Nothing is clipped. In this case, is_clipped is always false, with - // or without surfaces. - ExecuteCalculateDrawProperties(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_FALSE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_FALSE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_FALSE(leaf_node2->is_clipped()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_FALSE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_FALSE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_FALSE(leaf_node2->is_clipped()); - - // Case 2: The root is clipped. With surfaces, this only persists until the - // next render surface. Without surfaces, the entire tree is clipped. - root->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->is_clipped()); - EXPECT_TRUE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_TRUE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_TRUE(root->is_clipped()); - EXPECT_TRUE(parent->is_clipped()); - EXPECT_TRUE(child1->is_clipped()); - EXPECT_TRUE(child2->is_clipped()); - EXPECT_TRUE(grand_child->is_clipped()); - EXPECT_TRUE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - - root->SetMasksToBounds(false); - - // Case 3: The parent is clipped. Again, with surfaces, this only persists - // until the next render surface. Without surfaces, parent's entire subtree is - // clipped. - parent->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_TRUE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_TRUE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_TRUE(parent->is_clipped()); - EXPECT_TRUE(child1->is_clipped()); - EXPECT_TRUE(child2->is_clipped()); - EXPECT_TRUE(grand_child->is_clipped()); - EXPECT_TRUE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - - parent->SetMasksToBounds(false); - - // Case 4: child1 is clipped. With surfaces, only child1 is_clipped, since it - // has no non-surface children. Without surfaces, child1's entire subtree is - // clipped. - child1->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_FALSE(parent->is_clipped()); - EXPECT_TRUE(child1->is_clipped()); - EXPECT_FALSE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_FALSE(leaf_node2->is_clipped()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_FALSE(parent->is_clipped()); - EXPECT_TRUE(child1->is_clipped()); - EXPECT_FALSE(child2->is_clipped()); - EXPECT_TRUE(grand_child->is_clipped()); - EXPECT_TRUE(leaf_node1->is_clipped()); - EXPECT_FALSE(leaf_node2->is_clipped()); - - child1->SetMasksToBounds(false); - - // Case 5: Only the leaf nodes are clipped. The behavior with and without - // surfaces is the same. - leaf_node1->SetMasksToBounds(true); - leaf_node2->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_FALSE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_FALSE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_TRUE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_FALSE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_FALSE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_TRUE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); -} - TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { // Verify that layers get the appropriate DrawableContentRect when their // parent MasksToBounds is true. @@ -2201,286 +1992,18 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { leaf_node4->SetDrawsContent(true); ExecuteCalculateDrawProperties(parent); - ASSERT_TRUE(grand_child1->GetRenderSurface()); - ASSERT_TRUE(grand_child2->GetRenderSurface()); - ASSERT_TRUE(grand_child3->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(grand_child1)); + ASSERT_TRUE(GetRenderSurface(grand_child2)); + ASSERT_TRUE(GetRenderSurface(grand_child3)); // Surfaces are clipped by their parent, but un-affected by the owning layer's // MasksToBounds. EXPECT_EQ(gfx::Rect(0, 0, 20, 20), - grand_child1->GetRenderSurface()->clip_rect()); + GetRenderSurface(grand_child1)->clip_rect()); EXPECT_EQ(gfx::Rect(0, 0, 20, 20), - grand_child2->GetRenderSurface()->clip_rect()); + GetRenderSurface(grand_child2)->clip_rect()); EXPECT_EQ(gfx::Rect(0, 0, 20, 20), - grand_child3->GetRenderSurface()->clip_rect()); -} - -TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) { - // Tests that when separate surfaces are disabled, a layer's clip_rect is the - // intersection of all ancestor clips in screen space; in particular, if a - // layer masks to bounds, it contributes to the clip_rect of all layers in its - // subtree (since there are no render surfaces that can reset the clip_rect). - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child1 = AddChild<LayerImpl>(parent); - LayerImpl* child2 = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child1); - LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child); - LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetPosition(gfx::PointF(2.f, 2.f)); - parent->SetBounds(gfx::Size(400, 400)); - child1->SetPosition(gfx::PointF(4.f, 4.f)); - child1->SetBounds(gfx::Size(800, 800)); - child2->SetPosition(gfx::PointF(3.f, 3.f)); - child2->SetBounds(gfx::Size(800, 800)); - grand_child->SetPosition(gfx::PointF(8.f, 8.f)); - grand_child->SetBounds(gfx::Size(1500, 1500)); - leaf_node1->SetPosition(gfx::PointF(16.f, 16.f)); - leaf_node1->SetBounds(gfx::Size(2000, 2000)); - leaf_node2->SetPosition(gfx::PointF(9.f, 9.f)); - leaf_node2->SetBounds(gfx::Size(2000, 2000)); - - root->SetDrawsContent(true); - parent->SetDrawsContent(true); - child1->SetDrawsContent(true); - child2->SetDrawsContent(true); - grand_child->SetDrawsContent(true); - leaf_node1->SetDrawsContent(true); - leaf_node2->SetDrawsContent(true); - - root->test_properties()->force_render_surface = true; - child1->test_properties()->force_render_surface = true; - grand_child->test_properties()->force_render_surface = true; - - // Case 1: Nothing is clipped. In this case, each layer's clip rect is its - // bounds in target space. The only thing that changes when surfaces are - // disabled is that target space is always screen space. - ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_FALSE(parent->GetRenderSurface()); - EXPECT_TRUE(child1->GetRenderSurface()); - EXPECT_FALSE(child2->GetRenderSurface()); - EXPECT_TRUE(grand_child->GetRenderSurface()); - EXPECT_FALSE(leaf_node1->GetRenderSurface()); - EXPECT_FALSE(leaf_node2->GetRenderSurface()); - EXPECT_FALSE(root->is_clipped()); - EXPECT_FALSE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_FALSE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_FALSE(leaf_node2->is_clipped()); - EXPECT_TRUE(root->GetRenderSurface()->is_clipped()); - EXPECT_FALSE(child1->GetRenderSurface()->is_clipped()); - EXPECT_FALSE(grand_child->GetRenderSurface()->is_clipped()); - EXPECT_EQ(gfx::Rect(100, 100), root->GetRenderSurface()->clip_rect()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_FALSE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_FALSE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_FALSE(leaf_node2->is_clipped()); - EXPECT_TRUE(root->GetRenderSurface()->is_clipped()); - EXPECT_EQ(gfx::Rect(100, 100), root->GetRenderSurface()->clip_rect()); - - // Case 2: The root is clipped. In this case, layers that draw into the root - // render surface are clipped by the root's bounds. - root->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; - root->test_properties()->force_render_surface = true; - child1->test_properties()->force_render_surface = true; - grand_child->test_properties()->force_render_surface = true; - ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_FALSE(parent->GetRenderSurface()); - EXPECT_TRUE(child1->GetRenderSurface()); - EXPECT_FALSE(child2->GetRenderSurface()); - EXPECT_TRUE(grand_child->GetRenderSurface()); - EXPECT_FALSE(leaf_node1->GetRenderSurface()); - EXPECT_FALSE(leaf_node2->GetRenderSurface()); - EXPECT_TRUE(root->is_clipped()); - EXPECT_TRUE(parent->is_clipped()); - EXPECT_FALSE(child1->is_clipped()); - EXPECT_TRUE(child1->GetRenderSurface()->is_clipped()); - EXPECT_TRUE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_FALSE(grand_child->GetRenderSurface()->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), parent->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), child1->GetRenderSurface()->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), child2->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), leaf_node2->clip_rect()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_TRUE(root->is_clipped()); - EXPECT_TRUE(parent->is_clipped()); - EXPECT_TRUE(child1->is_clipped()); - EXPECT_TRUE(child2->is_clipped()); - EXPECT_TRUE(grand_child->is_clipped()); - EXPECT_TRUE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), parent->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), child1->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), child2->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), grand_child->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), leaf_node1->clip_rect()); - EXPECT_EQ(gfx::Rect(100, 100), leaf_node2->clip_rect()); - - root->SetMasksToBounds(false); - - // Case 3: The parent and child1 are clipped. When surfaces are enabled, the - // parent clip rect only contributes to the subtree rooted at child2, since - // the subtree rooted at child1 renders into a separate surface. Similarly, - // child1's clip rect doesn't contribute to its descendants, since its only - // child is a render surface. However, without surfaces, these clip rects - // contribute to all descendants. - parent->SetMasksToBounds(true); - child1->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; - root->test_properties()->force_render_surface = true; - child1->test_properties()->force_render_surface = true; - grand_child->test_properties()->force_render_surface = true; - ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_FALSE(parent->GetRenderSurface()); - EXPECT_TRUE(child1->GetRenderSurface()); - EXPECT_FALSE(child2->GetRenderSurface()); - EXPECT_TRUE(grand_child->GetRenderSurface()); - EXPECT_FALSE(leaf_node1->GetRenderSurface()); - EXPECT_FALSE(leaf_node2->GetRenderSurface()); - EXPECT_FALSE(root->is_clipped()); - EXPECT_TRUE(root->GetRenderSurface()->is_clipped()); - EXPECT_TRUE(parent->is_clipped()); - EXPECT_TRUE(child1->is_clipped()); - EXPECT_TRUE(child2->is_clipped()); - EXPECT_FALSE(grand_child->is_clipped()); - EXPECT_TRUE(grand_child->GetRenderSurface()->is_clipped()); - EXPECT_FALSE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - EXPECT_EQ(gfx::Rect(100, 100), root->GetRenderSurface()->clip_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect()); - EXPECT_EQ(gfx::Rect(800, 800), child1->clip_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), child2->clip_rect()); - EXPECT_EQ(gfx::Rect(800, 800), grand_child->GetRenderSurface()->clip_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), leaf_node2->clip_rect()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_FALSE(root->is_clipped()); - EXPECT_TRUE(root->GetRenderSurface()->is_clipped()); - EXPECT_TRUE(parent->is_clipped()); - EXPECT_TRUE(child1->is_clipped()); - EXPECT_TRUE(child2->is_clipped()); - EXPECT_TRUE(grand_child->is_clipped()); - EXPECT_TRUE(leaf_node1->is_clipped()); - EXPECT_TRUE(leaf_node2->is_clipped()); - EXPECT_EQ(gfx::Rect(100, 100), root->GetRenderSurface()->clip_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect()); - EXPECT_EQ(gfx::Rect(6, 6, 396, 396), child1->clip_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), child2->clip_rect()); - EXPECT_EQ(gfx::Rect(6, 6, 396, 396), grand_child->clip_rect()); - EXPECT_EQ(gfx::Rect(6, 6, 396, 396), leaf_node1->clip_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), leaf_node2->clip_rect()); -} - -TEST_F(LayerTreeHostCommonTest, HitTestingWhenSurfacesDisabled) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child); - LayerImpl* leaf_node = AddChild<LayerImpl>(grand_child); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetPosition(gfx::PointF(2.f, 2.f)); - parent->SetBounds(gfx::Size(400, 400)); - parent->SetMasksToBounds(true); - child->SetPosition(gfx::PointF(4.f, 4.f)); - child->SetBounds(gfx::Size(800, 800)); - child->SetMasksToBounds(true); - child->test_properties()->force_render_surface = true; - grand_child->SetPosition(gfx::PointF(8.f, 8.f)); - grand_child->SetBounds(gfx::Size(1500, 1500)); - grand_child->test_properties()->force_render_surface = true; - leaf_node->SetPosition(gfx::PointF(16.f, 16.f)); - leaf_node->SetBounds(gfx::Size(2000, 2000)); - - root->SetDrawsContent(true); - parent->SetDrawsContent(true); - child->SetDrawsContent(true); - grand_child->SetDrawsContent(true); - leaf_node->SetDrawsContent(true); - - host_impl()->set_resourceless_software_draw_for_testing(); - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - gfx::PointF test_point(90.f, 90.f); - LayerImpl* result_layer = - root->layer_tree_impl()->FindLayerThatIsHitByPoint(test_point); - ASSERT_TRUE(result_layer); - EXPECT_EQ(leaf_node, result_layer); -} - -TEST_F(LayerTreeHostCommonTest, SurfacesDisabledAndReEnabled) { - // Tests that draw properties are computed correctly when we disable and then - // re-enable separate surfaces. - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child = AddChild<LayerImpl>(parent); - LayerImpl* grand_child = AddChild<LayerImpl>(child); - LayerImpl* leaf_node = AddChild<LayerImpl>(grand_child); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetPosition(gfx::PointF(2.f, 2.f)); - parent->SetBounds(gfx::Size(400, 400)); - parent->SetMasksToBounds(true); - child->SetPosition(gfx::PointF(4.f, 4.f)); - child->SetBounds(gfx::Size(800, 800)); - child->SetMasksToBounds(true); - child->test_properties()->force_render_surface = true; - grand_child->SetPosition(gfx::PointF(8.f, 8.f)); - grand_child->SetBounds(gfx::Size(1500, 1500)); - grand_child->test_properties()->force_render_surface = true; - leaf_node->SetPosition(gfx::PointF(16.f, 16.f)); - leaf_node->SetBounds(gfx::Size(2000, 2000)); - - root->SetDrawsContent(true); - parent->SetDrawsContent(true); - child->SetDrawsContent(true); - grand_child->SetDrawsContent(true); - leaf_node->SetDrawsContent(true); - - gfx::Transform expected_leaf_draw_transform_with_surfaces; - expected_leaf_draw_transform_with_surfaces.Translate(16.0, 16.0); - - gfx::Transform expected_leaf_draw_transform_without_surfaces; - expected_leaf_draw_transform_without_surfaces.Translate(30.0, 30.0); - - ExecuteCalculateDrawProperties(root); - EXPECT_FALSE(leaf_node->is_clipped()); - EXPECT_TRUE(leaf_node->render_target()->is_clipped()); - EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_leaf_draw_transform_with_surfaces, - leaf_node->DrawTransform()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_TRUE(leaf_node->is_clipped()); - EXPECT_EQ(gfx::Rect(6, 6, 396, 396), leaf_node->clip_rect()); - EXPECT_EQ(gfx::Rect(30, 30, 372, 372), leaf_node->drawable_content_rect()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_leaf_draw_transform_without_surfaces, - leaf_node->DrawTransform()); - - ExecuteCalculateDrawProperties(root); - EXPECT_FALSE(leaf_node->is_clipped()); - EXPECT_TRUE(leaf_node->render_target()->is_clipped()); - EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_leaf_draw_transform_with_surfaces, - leaf_node->DrawTransform()); + GetRenderSurface(grand_child3)->clip_rect()); } TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { @@ -2581,33 +2104,37 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { // Only layers that are associated with render surfaces should have an actual // RenderSurface() value. - ASSERT_TRUE(root->GetRenderSurface()); - ASSERT_FALSE(child_of_root->GetRenderSurface()); - ASSERT_FALSE(grand_child_of_root->GetRenderSurface()); - - ASSERT_TRUE(render_surface1->GetRenderSurface()); - ASSERT_FALSE(child_of_rs1->GetRenderSurface()); - ASSERT_FALSE(grand_child_of_rs1->GetRenderSurface()); - - ASSERT_TRUE(render_surface2->GetRenderSurface()); - ASSERT_FALSE(child_of_rs2->GetRenderSurface()); - ASSERT_FALSE(grand_child_of_rs2->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(child_of_root), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(grand_child_of_root), GetRenderSurface(root)); + + ASSERT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(child_of_rs1), GetRenderSurface(render_surface1)); + ASSERT_EQ(GetRenderSurface(grand_child_of_rs1), + GetRenderSurface(render_surface1)); + + ASSERT_NE(GetRenderSurface(render_surface2), GetRenderSurface(root)); + ASSERT_NE(GetRenderSurface(render_surface2), + GetRenderSurface(render_surface1)); + ASSERT_EQ(GetRenderSurface(child_of_rs2), GetRenderSurface(render_surface2)); + ASSERT_EQ(GetRenderSurface(grand_child_of_rs2), + GetRenderSurface(render_surface2)); // Verify all render target accessors - EXPECT_EQ(root->GetRenderSurface(), root->render_target()); - EXPECT_EQ(root->GetRenderSurface(), child_of_root->render_target()); - EXPECT_EQ(root->GetRenderSurface(), grand_child_of_root->render_target()); + EXPECT_EQ(GetRenderSurface(root), root->render_target()); + EXPECT_EQ(GetRenderSurface(root), child_of_root->render_target()); + EXPECT_EQ(GetRenderSurface(root), grand_child_of_root->render_target()); - EXPECT_EQ(render_surface1->GetRenderSurface(), + EXPECT_EQ(GetRenderSurface(render_surface1), render_surface1->render_target()); - EXPECT_EQ(render_surface1->GetRenderSurface(), child_of_rs1->render_target()); - EXPECT_EQ(render_surface1->GetRenderSurface(), + EXPECT_EQ(GetRenderSurface(render_surface1), child_of_rs1->render_target()); + EXPECT_EQ(GetRenderSurface(render_surface1), grand_child_of_rs1->render_target()); - EXPECT_EQ(render_surface2->GetRenderSurface(), + EXPECT_EQ(GetRenderSurface(render_surface2), render_surface2->render_target()); - EXPECT_EQ(render_surface2->GetRenderSurface(), child_of_rs2->render_target()); - EXPECT_EQ(render_surface2->GetRenderSurface(), + EXPECT_EQ(GetRenderSurface(render_surface2), child_of_rs2->render_target()); + EXPECT_EQ(GetRenderSurface(render_surface2), grand_child_of_rs2->render_target()); // Verify screen_space_transform_is_animating values @@ -2662,6 +2189,11 @@ TEST_F(LayerTreeHostCommonTest, LargeTransforms) { EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect()); } +static bool TransformIsAnimating(LayerImpl* layer) { + return layer->GetMutatorHost()->IsAnimatingTransformProperty( + layer->element_id(), layer->GetElementTypeForAnimation()); +} + TEST_F(LayerTreeHostCommonTest, ScreenSpaceTransformIsAnimatingWithDelayedAnimation) { LayerImpl* root = root_layer_for_testing(); @@ -2694,7 +2226,7 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_FALSE(root->screen_space_transform_is_animating()); EXPECT_FALSE(child->screen_space_transform_is_animating()); - EXPECT_FALSE(grand_child->TransformIsAnimating()); + EXPECT_FALSE(TransformIsAnimating(grand_child)); EXPECT_TRUE(grand_child->HasPotentiallyRunningTransformAnimation()); EXPECT_TRUE(grand_child->screen_space_transform_is_animating()); EXPECT_TRUE(great_grand_child->screen_space_transform_is_animating()); @@ -3031,7 +2563,7 @@ TEST_F(LayerTreeHostCommonTest, ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::RectF(100.f, 100.f), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); // In target space, not clipped. EXPECT_EQ(gfx::Rect(60, 70, 100, 100), root->drawable_content_rect()); // In layer space, clipped. @@ -3056,7 +2588,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::RectF(100.f, 100.f), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); // Layers that do not draw content should have empty visible_layer_rects. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect()); @@ -3095,7 +2627,7 @@ TEST_F(LayerTreeHostCommonTest, ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::RectF(100.f, 100.f), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); // Layers that do not draw content should have empty visible content rects. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect()); @@ -3152,7 +2684,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithClippingAndFilters) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(50, 50, 10, 10), filter_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), filter->GetRenderSurface()->content_rect()); + EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurface(filter)->content_rect()); FilterOperations blur_filter; blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); @@ -3163,7 +2695,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithClippingAndFilters) { EXPECT_EQ(gfx::Rect(38, 38, 34, 34), filter_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(-12, -12, 34, 34), - filter->GetRenderSurface()->content_rect()); + GetRenderSurface(filter)->content_rect()); gfx::Transform vertical_flip; vertical_flip.Scale(1, -1); @@ -3180,7 +2712,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithClippingAndFilters) { EXPECT_EQ(gfx::Rect(50, 40, 10, 20), filter_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(0, -10, 10, 20), - filter->GetRenderSurface()->content_rect()); + GetRenderSurface(filter)->content_rect()); } TEST_F(LayerTreeHostCommonTest, VisibleRectWithScalingClippingAndFilters) { @@ -3205,7 +2737,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithScalingClippingAndFilters) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(50, 50, 10, 10), filter_child->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(30, 30), filter->GetRenderSurface()->content_rect()); + EXPECT_EQ(gfx::Rect(30, 30), GetRenderSurface(filter)->content_rect()); FilterOperations blur_filter; blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); @@ -3216,7 +2748,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithScalingClippingAndFilters) { EXPECT_EQ(gfx::Rect(38, 38, 34, 34), filter_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(-36, -36, 102, 102), - filter->GetRenderSurface()->content_rect()); + GetRenderSurface(filter)->content_rect()); gfx::Transform vertical_flip; vertical_flip.Scale(1, -1); @@ -3233,7 +2765,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectWithScalingClippingAndFilters) { EXPECT_EQ(gfx::Rect(50, 40, 10, 20), filter_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(0, -30, 30, 60), - filter->GetRenderSurface()->content_rect()); + GetRenderSurface(filter)->content_rect()); } TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParentAndFilters) { @@ -3331,10 +2863,10 @@ TEST_F(LayerTreeHostCommonTest, child3->SetDrawsContent(true); ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(render_surface->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(render_surface)); EXPECT_EQ(gfx::RectF(100.f, 100.f), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); // Layers that do not draw content should have empty visible content rects. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect()); @@ -3343,7 +2875,7 @@ TEST_F(LayerTreeHostCommonTest, // An unclipped surface grows its DrawableContentRect to include all drawable // regions of the subtree. EXPECT_EQ(gfx::RectF(5.f, 5.f, 170.f, 170.f), - render_surface->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface)->DrawableContentRect()); // All layers that draw content into the unclipped surface are also unclipped. // Only the viewport clip should apply @@ -3357,184 +2889,6 @@ TEST_F(LayerTreeHostCommonTest, } TEST_F(LayerTreeHostCommonTest, - DrawableAndVisibleRectsWhenCannotRenderToSeparateSurface) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* parent = AddChild<LayerImpl>(root); - LayerImpl* child1 = AddChild<LayerImpl>(parent); - LayerImpl* child2 = AddChild<LayerImpl>(parent); - LayerImpl* grand_child1 = AddChild<LayerImpl>(child1); - LayerImpl* grand_child2 = AddChild<LayerImpl>(child2); - LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child1); - LayerImpl* leaf_node2 = AddChild<LayerImpl>(grand_child2); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetPosition(gfx::PointF(2.f, 2.f)); - parent->SetBounds(gfx::Size(400, 400)); - child1->SetPosition(gfx::PointF(4.f, 4.f)); - child1->SetBounds(gfx::Size(800, 800)); - child1->test_properties()->force_render_surface = true; - child2->SetPosition(gfx::PointF(3.f, 3.f)); - child2->SetBounds(gfx::Size(800, 800)); - child2->test_properties()->force_render_surface = true; - grand_child1->SetPosition(gfx::PointF(8.f, 8.f)); - grand_child1->SetBounds(gfx::Size(1500, 1500)); - grand_child2->SetPosition(gfx::PointF(7.f, 7.f)); - grand_child2->SetBounds(gfx::Size(1500, 1500)); - leaf_node1->SetPosition(gfx::PointF(16.f, 16.f)); - leaf_node1->SetBounds(gfx::Size(2000, 2000)); - leaf_node2->SetPosition(gfx::PointF(9.f, 9.f)); - leaf_node2->SetBounds(gfx::Size(2000, 2000)); - - root->SetDrawsContent(true); - parent->SetDrawsContent(true); - child1->SetDrawsContent(true); - child2->SetDrawsContent(true); - grand_child1->SetDrawsContent(true); - grand_child2->SetDrawsContent(true); - leaf_node1->SetDrawsContent(true); - leaf_node2->SetDrawsContent(true); - - // Case 1: No layers clip. Visible rects are clipped by the viewport. - // Each layer's drawable content rect is its bounds in target space; the only - // thing that changes with surfaces disabled is that target space is always - // screen space. - child1->test_properties()->force_render_surface = true; - child2->test_properties()->force_render_surface = true; - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(0, 0, 98, 98), parent->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect()); - - EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(8, 8, 1500, 1500), grand_child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(24, 24, 2000, 2000), leaf_node1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node2->drawable_content_rect()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect()); - - EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(6, 6, 800, 800), child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(5, 5, 800, 800), child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(14, 14, 1500, 1500), - grand_child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(12, 12, 1500, 1500), - grand_child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(30, 30, 2000, 2000), leaf_node1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(21, 21, 2000, 2000), leaf_node2->drawable_content_rect()); - - // Case 2: The parent clips. In this case, neither surface is unclipped, so - // all visible layer rects are clipped by the intersection of all ancestor - // clips, whether or not surfaces are disabled. However, drawable content - // rects are clipped only until the next render surface is reached, so - // descendants of parent have their drawable content rects clipped only when - // surfaces are disabled. - parent->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect()); - - EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(8, 8, 1500, 1500), grand_child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(24, 24, 2000, 2000), leaf_node1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node2->drawable_content_rect()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect()); - - EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(6, 6, 396, 396), child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(5, 5, 397, 397), child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(14, 14, 388, 388), grand_child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(12, 12, 390, 390), grand_child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(30, 30, 372, 372), leaf_node1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(21, 21, 381, 381), leaf_node2->drawable_content_rect()); - - parent->SetMasksToBounds(false); - - // Case 3: child1 and grand_child2 clip. In this case, descendants of these - // layers have their visible rects clipped by them; Similarly, descendants of - // these layers have their drawable content rects clipped by them. - child1->SetMasksToBounds(true); - grand_child2->SetMasksToBounds(true); - host_impl()->active_tree()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect()); - - EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(8, 8, 792, 792), grand_child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(24, 24, 776, 776), leaf_node1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(16, 16, 1491, 1491), leaf_node2->drawable_content_rect()); - - ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root); - EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect()); - - EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(6, 6, 800, 800), child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(5, 5, 800, 800), child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(14, 14, 792, 792), grand_child1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(12, 12, 1500, 1500), - grand_child2->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(30, 30, 776, 776), leaf_node1->drawable_content_rect()); - EXPECT_EQ(gfx::Rect(21, 21, 1491, 1491), leaf_node2->drawable_content_rect()); -} - -TEST_F(LayerTreeHostCommonTest, VisibleContentRectsForClippedSurfaceWithEmptyClip) { LayerImpl* root = root_layer_for_testing(); LayerImpl* child1 = AddChild<LayerImpl>(root); @@ -3552,18 +2906,18 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; // Now set the root render surface an empty clip. LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Size(), &render_surface_layer_list_impl); + root, gfx::Size(), &render_surface_list_impl); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - ASSERT_TRUE(root->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(root)); EXPECT_FALSE(root->is_clipped()); gfx::Rect empty; - EXPECT_EQ(empty, root->GetRenderSurface()->clip_rect()); - EXPECT_TRUE(root->GetRenderSurface()->is_clipped()); + EXPECT_EQ(empty, GetRenderSurface(root)->clip_rect()); + EXPECT_TRUE(GetRenderSurface(root)->is_clipped()); // Visible content rect calculation will check if the target surface is // clipped or not. An empty clip rect does not indicate the render surface @@ -3717,11 +3071,11 @@ TEST_F(LayerTreeHostCommonTest, OcclusionBySiblingOfTarget) { host_impl.active_tree()->UpdateDrawProperties(update_lcd_text); EXPECT_TRANSFORMATION_MATRIX_EQ( - surface_ptr->GetRenderSurface()->draw_transform(), translate); + GetRenderSurface(surface_ptr)->draw_transform(), translate); // surface_sibling draws into the root render surface and occludes // surface_child's contents. Occlusion actual_occlusion = - surface_child_ptr->GetRenderSurface()->occlusion_in_content_space(); + GetRenderSurface(surface_child_ptr)->occlusion_in_content_space(); Occlusion expected_occlusion(translate, SimpleEnclosedRegion(gfx::Rect()), SimpleEnclosedRegion(gfx::Rect(200, 200))); EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); @@ -3874,10 +3228,10 @@ TEST_F(LayerTreeHostCommonTest, child3->SetDrawsContent(true); ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(render_surface->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(render_surface)); EXPECT_EQ(gfx::RectF(100.f, 100.f), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); // Layers that do not draw content should have empty visible content rects. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect()); @@ -3886,7 +3240,7 @@ TEST_F(LayerTreeHostCommonTest, // A clipped surface grows its DrawableContentRect to include all drawable // regions of the subtree, but also gets clamped by the ancestor's clip. EXPECT_EQ(gfx::RectF(5.f, 5.f, 95.f, 95.f), - render_surface->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface)->DrawableContentRect()); // All layers that draw content into the surface have their visible content // rect clipped by the surface clip rect. @@ -3927,11 +3281,11 @@ TEST_F(LayerTreeHostCommonTest, child3->SetDrawsContent(true); ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(render_surface1->GetRenderSurface()); - ASSERT_TRUE(render_surface2->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(render_surface1)); + ASSERT_TRUE(GetRenderSurface(render_surface2)); EXPECT_EQ(gfx::RectF(100.f, 100.f), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); // Layers that do not draw content should have empty visible content rects. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect()); @@ -3941,13 +3295,13 @@ TEST_F(LayerTreeHostCommonTest, // A clipped surface grows its DrawableContentRect to include all drawable // regions of the subtree, but also gets clamped by the ancestor's clip. EXPECT_EQ(gfx::RectF(5.f, 5.f, 95.f, 95.f), - render_surface1->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface1)->DrawableContentRect()); // render_surface1 lives in the "unclipped universe" of render_surface1, and // is only implicitly clipped by render_surface1's content rect. So, // render_surface2 grows to enclose all drawable content of its subtree. EXPECT_EQ(gfx::RectF(5.f, 5.f, 170.f, 170.f), - render_surface2->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface2)->DrawableContentRect()); // All layers that draw content into render_surface2 think they are unclipped // by the surface. So, only the viewport clip applies. @@ -4058,12 +3412,11 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { float device_scale_factor = 1.f; ExecuteCalculateDrawProperties(root, device_scale_factor); - EXPECT_EQ(gfx::Rect(50, 50), - render_surface2->GetRenderSurface()->clip_rect()); + EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(render_surface2)->clip_rect()); device_scale_factor = 2.f; ExecuteCalculateDrawProperties(root, device_scale_factor); EXPECT_EQ(gfx::Rect(100, 100), - render_surface2->GetRenderSurface()->clip_rect()); + GetRenderSurface(render_surface2)->clip_rect()); } TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { @@ -4079,11 +3432,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { test_layer->SetBounds(gfx::Size(150, 150)); ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(100, 100), surface->GetRenderSurface()->content_rect()); + EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(surface)->content_rect()); test_layer->SetDrawsContent(true); ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(150, 150), surface->GetRenderSurface()->content_rect()); + EXPECT_EQ(gfx::Rect(150, 150), GetRenderSurface(surface)->content_rect()); } TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { @@ -4191,10 +3544,10 @@ TEST_F(LayerTreeHostCommonTest, child1->test_properties()->transform_origin = gfx::Point3F(25.f, 25.f, 0.f); ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(render_surface->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(render_surface)); EXPECT_EQ(gfx::RectF(100.f, 100.f), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); // Layers that do not draw content should have empty visible content rects. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect()); @@ -4209,7 +3562,7 @@ TEST_F(LayerTreeHostCommonTest, diagonal_radius * 2, diagonal_radius * 2); EXPECT_EQ(gfx::RectF(expected_surface_drawable_content), - render_surface->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface)->DrawableContentRect()); // All layers that draw content into the unclipped surface are also unclipped. EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect()); @@ -4238,7 +3591,7 @@ TEST_F(LayerTreeHostCommonTest, child1->test_properties()->transform_origin = gfx::Point3F(25.f, 25.f, 0.f); ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(render_surface->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(render_surface)); // The clipped surface clamps the DrawableContentRect that encloses the // rotated layer. @@ -4250,7 +3603,7 @@ TEST_F(LayerTreeHostCommonTest, gfx::RectF expected_surface_drawable_content( gfx::IntersectRects(unclipped_surface_content, gfx::Rect(50, 50))); EXPECT_EQ(expected_surface_drawable_content, - render_surface->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface)->DrawableContentRect()); // On the clipped surface, only a quarter of the child1 is visible, but when // rotating it back to child1's content space, the actual enclosing rect ends @@ -4296,20 +3649,20 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { float device_scale_factor = 2.f; ExecuteCalculateDrawProperties(root, device_scale_factor); - ASSERT_TRUE(render_surface1->GetRenderSurface()); - ASSERT_TRUE(render_surface2->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(render_surface1)); + ASSERT_TRUE(GetRenderSurface(render_surface2)); // drawable_content_rects for all layers and surfaces are scaled by // device_scale_factor. EXPECT_EQ(gfx::RectF(200.f, 200.f), - root->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(root)->DrawableContentRect()); EXPECT_EQ(gfx::RectF(10.f, 10.f, 190.f, 190.f), - render_surface1->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface1)->DrawableContentRect()); // render_surface2 lives in the "unclipped universe" of render_surface1, and // is only implicitly clipped by render_surface1. EXPECT_EQ(gfx::RectF(10.f, 10.f, 350.f, 350.f), - render_surface2->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface2)->DrawableContentRect()); EXPECT_EQ(gfx::Rect(10, 10, 100, 100), child1->drawable_content_rect()); EXPECT_EQ(gfx::Rect(150, 150, 100, 100), child2->drawable_content_rect()); @@ -4401,14 +3754,20 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); // Verify which render surfaces were created. - EXPECT_FALSE(front_facing_child->GetRenderSurface()); - EXPECT_FALSE(back_facing_child->GetRenderSurface()); - EXPECT_TRUE(front_facing_surface->GetRenderSurface()); - EXPECT_TRUE(back_facing_surface->GetRenderSurface()); - EXPECT_FALSE(front_facing_child_of_front_facing_surface->GetRenderSurface()); - EXPECT_FALSE(back_facing_child_of_front_facing_surface->GetRenderSurface()); - EXPECT_FALSE(front_facing_child_of_back_facing_surface->GetRenderSurface()); - EXPECT_FALSE(back_facing_child_of_back_facing_surface->GetRenderSurface()); + EXPECT_EQ(GetRenderSurface(front_facing_child), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(back_facing_child), GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(front_facing_surface), GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(back_facing_surface), GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(back_facing_surface), + GetRenderSurface(front_facing_surface)); + EXPECT_EQ(GetRenderSurface(front_facing_child_of_front_facing_surface), + GetRenderSurface(front_facing_surface)); + EXPECT_EQ(GetRenderSurface(back_facing_child_of_front_facing_surface), + GetRenderSurface(front_facing_surface)); + EXPECT_EQ(GetRenderSurface(front_facing_child_of_back_facing_surface), + GetRenderSurface(back_facing_surface)); + EXPECT_EQ(GetRenderSurface(back_facing_child_of_back_facing_surface), + GetRenderSurface(back_facing_surface)); EXPECT_EQ(3u, update_layer_list_impl()->size()); EXPECT_TRUE(UpdateLayerListImplContains(front_facing_child->id())); @@ -4509,15 +3868,21 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); // Verify which render surfaces were created and used. - EXPECT_FALSE(front_facing_child->GetRenderSurface()); - EXPECT_FALSE(back_facing_child->GetRenderSurface()); - EXPECT_TRUE(front_facing_surface->GetRenderSurface()); + EXPECT_EQ(GetRenderSurface(front_facing_child), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(back_facing_child), GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(front_facing_surface), GetRenderSurface(root)); // We expect that a has_render_surface was created but not used. - EXPECT_TRUE(back_facing_surface->GetRenderSurface()); - EXPECT_FALSE(front_facing_child_of_front_facing_surface->GetRenderSurface()); - EXPECT_FALSE(back_facing_child_of_front_facing_surface->GetRenderSurface()); - EXPECT_FALSE(front_facing_child_of_back_facing_surface->GetRenderSurface()); - EXPECT_FALSE(back_facing_child_of_back_facing_surface->GetRenderSurface()); + EXPECT_NE(GetRenderSurface(back_facing_surface), GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(back_facing_surface), + GetRenderSurface(front_facing_surface)); + EXPECT_EQ(GetRenderSurface(front_facing_child_of_front_facing_surface), + GetRenderSurface(front_facing_surface)); + EXPECT_EQ(GetRenderSurface(back_facing_child_of_front_facing_surface), + GetRenderSurface(front_facing_surface)); + EXPECT_EQ(GetRenderSurface(front_facing_child_of_back_facing_surface), + GetRenderSurface(back_facing_surface)); + EXPECT_EQ(GetRenderSurface(back_facing_child_of_back_facing_surface), + GetRenderSurface(back_facing_surface)); EXPECT_EQ(3u, update_layer_list_impl()->size()); @@ -4583,11 +3948,12 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) { ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); - EXPECT_FALSE(child->GetRenderSurface()); - EXPECT_TRUE(animating_surface->GetRenderSurface()); - EXPECT_FALSE(child_of_animating_surface->GetRenderSurface()); - EXPECT_FALSE(animating_child->GetRenderSurface()); - EXPECT_FALSE(child2->GetRenderSurface()); + EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(root)); + EXPECT_TRUE(GetRenderSurface(animating_surface)); + EXPECT_EQ(GetRenderSurface(child_of_animating_surface), + GetRenderSurface(animating_surface)); + EXPECT_EQ(GetRenderSurface(animating_child), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(child2), GetRenderSurface(root)); EXPECT_EQ(1u, update_layer_list_impl()->size()); @@ -4643,12 +4009,12 @@ TEST_F(LayerTreeHostCommonTest, ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); // Verify which render surfaces were created and used. - EXPECT_TRUE(front_facing_surface->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(front_facing_surface)); // We expect the render surface to have been created, but remain unused. - EXPECT_TRUE(back_facing_surface->GetRenderSurface()); - EXPECT_FALSE(child1->GetRenderSurface()); - EXPECT_FALSE(child2->GetRenderSurface()); + EXPECT_NE(GetRenderSurface(back_facing_surface), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(child1), GetRenderSurface(front_facing_surface)); + EXPECT_EQ(GetRenderSurface(child2), GetRenderSurface(back_facing_surface)); EXPECT_EQ(2u, update_layer_list_impl()->size()); EXPECT_TRUE(UpdateLayerListImplContains(front_facing_surface->id())); @@ -4679,7 +4045,7 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { EXPECT_FLOAT_EQ(device_scale_factor, child->GetIdealContentsScale()); EXPECT_FLOAT_EQ(device_scale_factor, child2->GetIdealContentsScale()); - EXPECT_EQ(1u, render_surface_layer_list_impl()->size()); + EXPECT_EQ(1u, render_surface_list_impl()->size()); // Verify root transforms gfx::Transform expected_root_transform; @@ -4774,9 +4140,9 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { float device_scale_factor = 2.5f; float page_scale_factor = 3.f; - root->layer_tree_impl()->SetViewportLayersFromIds( - Layer::INVALID_ID, page_scale->id(), Layer::INVALID_ID, - Layer::INVALID_ID); + LayerTreeImpl::ViewportLayerIds viewport_ids; + viewport_ids.page_scale = page_scale->id(); + root->layer_tree_impl()->SetViewportLayersFromIds(viewport_ids); root->layer_tree_impl()->BuildLayerListAndPropertyTreesForTesting(); root->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale_factor); ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, @@ -4806,7 +4172,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { std::max(target_space_transform_scales.x(), target_space_transform_scales.y())); - EXPECT_EQ(3u, render_surface_layer_list_impl()->size()); + EXPECT_EQ(3u, render_surface_list_impl()->size()); gfx::Transform expected_parent_draw_transform; expected_parent_draw_transform.Scale(device_scale_factor * page_scale_factor, @@ -4832,7 +4198,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { device_scale_factor * page_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_perspective_surface_draw_transform, - perspective_surface->GetRenderSurface()->draw_transform()); + GetRenderSurface(perspective_surface)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_perspective_surface_layer_draw_transform, perspective_surface->DrawTransform()); @@ -4937,7 +4303,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { // 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_layer_list_impl()->size()); + EXPECT_EQ(2u, render_surface_list_impl()->size()); gfx::Transform expected_parent_transform; expected_parent_transform.Scale(device_scale_factor, device_scale_factor); @@ -4975,20 +4341,20 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { device_scale_factor * child->position().x(), device_scale_factor * child->position().y()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_render_surface_draw_transform, - child->GetRenderSurface()->draw_transform()); + GetRenderSurface(child)->draw_transform()); gfx::Transform expected_surface_draw_transform; expected_surface_draw_transform.Translate(device_scale_factor * 2.f, device_scale_factor * 2.f); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform, - child->GetRenderSurface()->draw_transform()); + GetRenderSurface(child)->draw_transform()); gfx::Transform expected_surface_screen_space_transform; expected_surface_screen_space_transform.Translate(device_scale_factor * 2.f, device_scale_factor * 2.f); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_surface_screen_space_transform, - child->GetRenderSurface()->screen_space_transform()); + GetRenderSurface(child)->screen_space_transform()); } TEST_F(LayerTreeHostCommonTest, @@ -5007,14 +4373,14 @@ TEST_F(LayerTreeHostCommonTest, // 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_layer_list_impl()->size()); + EXPECT_EQ(2u, render_surface_list_impl()->size()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - child->GetRenderSurface()->draw_transform()); + GetRenderSurface(child)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - child->GetRenderSurface()->draw_transform()); + GetRenderSurface(child)->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ( - gfx::Transform(), child->GetRenderSurface()->screen_space_transform()); + gfx::Transform(), GetRenderSurface(child)->screen_space_transform()); } TEST_F(LayerTreeHostCommonTest, LayerSearch) { @@ -5048,7 +4414,7 @@ TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { grand_child->SetBounds(gfx::Size(10, 10)); grand_child->SetDrawsContent(true); ExecuteCalculateDrawProperties(root); - EXPECT_FALSE(child->GetRenderSurface()); + EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(root)); } TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { @@ -5085,24 +4451,24 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { AddOpacityTransitionToElementWithPlayer(child_element_id, timeline, 10.0, 0.0f, 1.0f, false); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list); + root_layer, root_layer->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // 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_layer_list.size()); - ASSERT_EQ(2u, root_layer->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, render_surface_list.size()); + ASSERT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); // If the root itself is hidden, the child should not be drawn even if it has // an animating opacity. root_layer->test_properties()->opacity = 0.0f; root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - LayerImplList render_surface_layer_list2; + RenderSurfaceList render_surface_list2; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs2( - root_layer, root_layer->bounds(), &render_surface_layer_list2); + root_layer, root_layer->bounds(), &render_surface_list2); inputs2.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs2); @@ -5117,9 +4483,9 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { root_layer->test_properties()->opacity = 1.0f; child_ptr->test_properties()->opacity = 0.0f; root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; - LayerImplList render_surface_layer_list3; + RenderSurfaceList render_surface_list3; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs3( - root_layer, root_layer->bounds(), &render_surface_layer_list3); + root_layer, root_layer->bounds(), &render_surface_list3); inputs3.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs3); @@ -5384,29 +4750,32 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) { LayerImpl::Create(host_impl.pending_tree(), 2); child->SetBounds(gfx::Size(40, 40)); child->SetDrawsContent(true); + LayerImpl* child_layer = child.get(); std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl.pending_tree(), 3); grand_child->SetBounds(gfx::Size(30, 30)); grand_child->SetDrawsContent(true); grand_child->test_properties()->hide_layer_and_subtree = true; + LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); root->test_properties()->AddChild(std::move(child)); host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list); + root_layer, root_layer->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // We should have one render surface and two layers. The grand child has // hidden itself. - ASSERT_EQ(1u, render_surface_layer_list.size()); - ASSERT_EQ(2u, root_layer->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(1, root_layer->GetRenderSurface()->layer_list().at(0)->id()); - EXPECT_EQ(2, root_layer->GetRenderSurface()->layer_list().at(1)->id()); + ASSERT_EQ(1u, render_surface_list.size()); + ASSERT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); + EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child_layer->contributes_to_drawn_render_surface()); } TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) { @@ -5426,27 +4795,31 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) { child->SetBounds(gfx::Size(40, 40)); child->SetDrawsContent(true); child->test_properties()->hide_layer_and_subtree = true; + LayerImpl* child_layer = child.get(); std::unique_ptr<LayerImpl> grand_child = LayerImpl::Create(host_impl.pending_tree(), 3); grand_child->SetBounds(gfx::Size(30, 30)); grand_child->SetDrawsContent(true); + LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); root->test_properties()->AddChild(std::move(child)); host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list); + root_layer, root_layer->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - // We should have one render surface and one layers. The child has + // We should have one render surface and one layer. The child has // hidden itself and the grand child. - ASSERT_EQ(1u, render_surface_layer_list.size()); - ASSERT_EQ(1u, root_layer->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(1, root_layer->GetRenderSurface()->layer_list().at(0)->id()); + ASSERT_EQ(1u, render_surface_list.size()); + ASSERT_EQ(1, GetRenderSurface(root_layer)->num_contributors()); + EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(child_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child_layer->contributes_to_drawn_render_surface()); } void EmptyCopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {} @@ -5532,46 +4905,45 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { copy_layer->test_properties()->copy_requests.push_back( CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list); + root_layer, root_layer->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - EXPECT_GT(root_layer->num_copy_requests_in_target_subtree(), 0); - EXPECT_GT(copy_grand_parent_layer->num_copy_requests_in_target_subtree(), 0); - EXPECT_GT(copy_parent_layer->num_copy_requests_in_target_subtree(), 0); - EXPECT_GT(copy_layer->num_copy_requests_in_target_subtree(), 0); + EXPECT_TRUE(root_layer->has_copy_requests_in_target_subtree()); + EXPECT_TRUE(copy_grand_parent_layer->has_copy_requests_in_target_subtree()); + EXPECT_TRUE(copy_parent_layer->has_copy_requests_in_target_subtree()); + EXPECT_TRUE(copy_layer->has_copy_requests_in_target_subtree()); // 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_layer_list.size()); - EXPECT_EQ(root_layer->id(), render_surface_layer_list.at(0)->id()); - EXPECT_EQ(copy_grand_parent_layer->id(), - render_surface_layer_list.at(1)->id()); - EXPECT_EQ(copy_parent_layer->id(), render_surface_layer_list.at(2)->id()); - EXPECT_EQ(copy_layer->id(), render_surface_layer_list.at(3)->id()); + ASSERT_EQ(4u, render_surface_list.size()); + EXPECT_EQ(root_layer->id(), render_surface_list.at(0)->id()); + EXPECT_EQ(copy_grand_parent_layer->id(), render_surface_list.at(1)->id()); + EXPECT_EQ(copy_parent_layer->id(), render_surface_list.at(2)->id()); + EXPECT_EQ(copy_layer->id(), render_surface_list.at(3)->id()); // The root render surface should have 2 contributing layers. - ASSERT_EQ(2u, root_layer->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(root_layer->id(), - root_layer->GetRenderSurface()->layer_list().at(0)->id()); - EXPECT_EQ(copy_grand_parent_layer->id(), - root_layer->GetRenderSurface()->layer_list().at(1)->id()); + EXPECT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); + EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(copy_grand_parent_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(copy_grand_parent_sibling_before_layer + ->contributes_to_drawn_render_surface()); + EXPECT_FALSE(copy_grand_parent_sibling_after_layer + ->contributes_to_drawn_render_surface()); // Nothing actually draws into the copy parent, so only the copy_layer will // appear in its list, since it needs to be drawn for the copy request. - ASSERT_EQ(1u, copy_parent_layer->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(copy_layer->id(), - copy_parent_layer->GetRenderSurface()->layer_list().at(0)->id()); + ASSERT_EQ(1, GetRenderSurface(copy_parent_layer)->num_contributors()); + EXPECT_FALSE(copy_parent_layer->contributes_to_drawn_render_surface()); - // The copy_layer's render surface should have two contributing layers. - ASSERT_EQ(2u, copy_layer->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(copy_layer->id(), - copy_layer->GetRenderSurface()->layer_list().at(0)->id()); - EXPECT_EQ(copy_child_layer->id(), - copy_layer->GetRenderSurface()->layer_list().at(1)->id()); + // The copy layer's render surface should have 2 contributing layers. + ASSERT_EQ(2, GetRenderSurface(copy_layer)->num_contributors()); + EXPECT_TRUE(copy_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(copy_child_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(copy_grand_child_layer->contributes_to_drawn_render_surface()); // copy_grand_parent, copy_parent shouldn't be drawn because they are hidden, // but the copy_layer and copy_child should be drawn for the copy request. @@ -5592,7 +4964,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { // Though copy_layer is drawn, it shouldn't contribute to drawn surface as its // actually hidden. - EXPECT_FALSE(copy_layer->GetRenderSurface()->contributes_to_drawn_surface()); + EXPECT_FALSE(GetRenderSurface(copy_layer)->contributes_to_drawn_surface()); } TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { @@ -5629,23 +5001,66 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { copy_parent->test_properties()->AddChild(std::move(copy_layer)); root->test_properties()->AddChild(std::move(copy_parent)); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerImpl* root_layer = root.get(); root_layer->layer_tree_impl()->SetRootLayerForTesting(std::move(root)); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list); + root_layer, root_layer->bounds(), &render_surface_list); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); // We should have two render surface, as the others are clipped out. - ASSERT_EQ(2u, render_surface_layer_list.size()); - EXPECT_EQ(root_layer->id(), render_surface_layer_list.at(0)->id()); + ASSERT_EQ(2u, render_surface_list.size()); + EXPECT_EQ(root_layer->id(), render_surface_list.at(0)->id()); + + // The root render surface should have only 2 contributing layer, since the + // other layers are clipped away. + ASSERT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); + EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); +} + +TEST_F(LayerTreeHostCommonTest, SingularTransformAndCopyRequests) { + LayerImpl* root = root_layer_for_testing(); + root->SetBounds(gfx::Size(50, 50)); + root->SetDrawsContent(true); - // The root render surface should only have 2 contributing layer, since the - // other layers are empty/clipped away. - ASSERT_EQ(2u, root_layer->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(root_layer->id(), - root_layer->GetRenderSurface()->layer_list().at(0)->id()); + LayerImpl* singular_transform_layer = AddChild<LayerImpl>(root); + singular_transform_layer->SetBounds(gfx::Size(100, 100)); + singular_transform_layer->SetDrawsContent(true); + gfx::Transform singular; + singular.Scale3d(6.f, 6.f, 0.f); + singular_transform_layer->test_properties()->transform = singular; + + LayerImpl* copy_layer = AddChild<LayerImpl>(singular_transform_layer); + copy_layer->SetBounds(gfx::Size(100, 100)); + copy_layer->SetDrawsContent(true); + copy_layer->test_properties()->copy_requests.push_back( + CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + + LayerImpl* copy_child = AddChild<LayerImpl>(copy_layer); + copy_child->SetBounds(gfx::Size(100, 100)); + copy_child->SetDrawsContent(true); + + LayerImpl* copy_grand_child = AddChild<LayerImpl>(copy_child); + copy_grand_child->SetBounds(gfx::Size(100, 100)); + copy_grand_child->SetDrawsContent(true); + copy_grand_child->test_properties()->transform = singular; + + DCHECK(!copy_layer->test_properties()->copy_requests.empty()); + ExecuteCalculateDrawProperties(root); + DCHECK(copy_layer->test_properties()->copy_requests.empty()); + + // A layer with singular transform should not contribute to drawn render + // surface. + EXPECT_FALSE(singular_transform_layer->contributes_to_drawn_render_surface()); + // Even though copy_layer and copy_child have singular screen space transform, + // they still contribute to drawn render surface as their transform to the + // closest ancestor with copy request is not singular. + EXPECT_TRUE(copy_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(copy_child->contributes_to_drawn_render_surface()); + // copy_grand_child's transform to its closest ancestor with copy request is + // also singular. So, it doesn't contribute to drawn render surface. + EXPECT_FALSE(copy_grand_child->contributes_to_drawn_render_surface()); } TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCopyRequest) { @@ -5765,8 +5180,8 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { clip_child->SetBounds(gfx::Size(10, 10)); ExecuteCalculateDrawProperties(root); - ASSERT_TRUE(root->GetRenderSurface()); - ASSERT_TRUE(render_surface->GetRenderSurface()); + ASSERT_TRUE(GetRenderSurface(root)); + ASSERT_TRUE(GetRenderSurface(render_surface)); // Ensure that we've inherited our clip parent's clip and weren't affected // by the intervening clip layer. @@ -5777,14 +5192,14 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { // Ensure that the render surface reports a content rect that has been grown // to accomodate for the clip child. ASSERT_EQ(gfx::Rect(1, 1, 20, 20), - render_surface->GetRenderSurface()->content_rect()); + GetRenderSurface(render_surface)->content_rect()); // The above check implies the two below, but they nicely demonstrate that // we've grown, despite the intervening layer's clip. ASSERT_TRUE(clip_parent->clip_rect().Contains( - render_surface->GetRenderSurface()->content_rect())); + GetRenderSurface(render_surface)->content_rect())); ASSERT_FALSE(intervening->clip_rect().Contains( - render_surface->GetRenderSurface()->content_rect())); + GetRenderSurface(render_surface)->content_rect())); } TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { @@ -5830,16 +5245,16 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { clip_child->SetBounds(gfx::Size(60, 60)); ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_TRUE(render_surface1->GetRenderSurface()); - EXPECT_TRUE(render_surface2->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_TRUE(GetRenderSurface(render_surface1)); + EXPECT_TRUE(GetRenderSurface(render_surface2)); // render_surface1 should apply the clip from clip_parent. Though there is a // clip child, render_surface1 can apply the clip as there are no clips // between the clip parent and render_surface1 EXPECT_EQ(gfx::Rect(1, 1, 40, 40), - render_surface1->GetRenderSurface()->clip_rect()); - EXPECT_TRUE(render_surface1->GetRenderSurface()->is_clipped()); + GetRenderSurface(render_surface1)->clip_rect()); + EXPECT_TRUE(GetRenderSurface(render_surface1)->is_clipped()); EXPECT_EQ(gfx::Rect(), render_surface1->clip_rect()); EXPECT_FALSE(render_surface1->is_clipped()); @@ -5848,8 +5263,8 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { // So, it should not be clipped (their bounds would no longer be reliable). // We should resort to layer clipping in this case. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), - render_surface2->GetRenderSurface()->clip_rect()); - EXPECT_FALSE(render_surface2->GetRenderSurface()->is_clipped()); + GetRenderSurface(render_surface2)->clip_rect()); + EXPECT_FALSE(GetRenderSurface(render_surface2)->is_clipped()); // This value is inherited from the clipping ancestor layer, 'intervening'. EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface2->clip_rect()); @@ -5858,9 +5273,9 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { // The content rects of render_surface2 should have expanded to contain the // clip child. EXPECT_EQ(gfx::Rect(0, 0, 40, 40), - render_surface1->GetRenderSurface()->content_rect()); + GetRenderSurface(render_surface1)->content_rect()); EXPECT_EQ(gfx::Rect(-10, -10, 60, 60), - render_surface2->GetRenderSurface()->content_rect()); + GetRenderSurface(render_surface2)->content_rect()); // The clip child should have inherited the clip parent's clip (projected to // the right space, of course), but as render_surface1 already applies that @@ -5916,16 +5331,16 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { clip_child->SetBounds(gfx::Size(60, 60)); ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_TRUE(render_surface1->GetRenderSurface()); - EXPECT_TRUE(render_surface2->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_TRUE(GetRenderSurface(render_surface1)); + EXPECT_TRUE(GetRenderSurface(render_surface2)); // render_surface1 should apply the clip from clip_parent. Though there is a // clip child, render_surface1 can apply the clip as there are no clips // between the clip parent and render_surface1 EXPECT_EQ(gfx::Rect(3, 3, 40, 40), - render_surface1->GetRenderSurface()->clip_rect()); - EXPECT_TRUE(render_surface1->GetRenderSurface()->is_clipped()); + GetRenderSurface(render_surface1)->clip_rect()); + EXPECT_TRUE(GetRenderSurface(render_surface1)->is_clipped()); EXPECT_EQ(gfx::Rect(), render_surface1->clip_rect()); EXPECT_FALSE(render_surface1->is_clipped()); @@ -5934,8 +5349,8 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { // So, it should not be clipped (their bounds would no longer be reliable). // We should resort to layer clipping in this case. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), - render_surface2->GetRenderSurface()->clip_rect()); - EXPECT_FALSE(render_surface2->GetRenderSurface()->is_clipped()); + GetRenderSurface(render_surface2)->clip_rect()); + EXPECT_FALSE(GetRenderSurface(render_surface2)->is_clipped()); // This value is inherited from the clipping ancestor layer, 'intervening'. EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface2->clip_rect()); EXPECT_TRUE(render_surface2->is_clipped()); @@ -5943,9 +5358,9 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { // The content rects of render_surface2 should have expanded to contain the // clip child. EXPECT_EQ(gfx::Rect(0, 0, 40, 40), - render_surface1->GetRenderSurface()->content_rect()); + GetRenderSurface(render_surface1)->content_rect()); EXPECT_EQ(gfx::Rect(-10, -10, 60, 60), - render_surface2->GetRenderSurface()->content_rect()); + GetRenderSurface(render_surface2)->content_rect()); // The clip child should have inherited the clip parent's clip (projected to // the right space, of course), but as render_surface1 already applies that @@ -5987,7 +5402,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); // Neither the clip child nor its descendant should have inherited the clip // from |intervening|. @@ -6046,9 +5461,9 @@ TEST_F(LayerTreeHostCommonTest, ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_TRUE(render_surface1->GetRenderSurface()); - EXPECT_TRUE(render_surface2->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_TRUE(GetRenderSurface(render_surface1)); + EXPECT_TRUE(GetRenderSurface(render_surface2)); EXPECT_EQ(gfx::Rect(-5, -5, 10, 10), render_surface1->clip_rect()); EXPECT_TRUE(render_surface1->is_clipped()); @@ -6056,23 +5471,23 @@ TEST_F(LayerTreeHostCommonTest, // The render surface should not clip (it has unclipped descendants), instead // it should rely on layer clipping. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), - render_surface1->GetRenderSurface()->clip_rect()); - EXPECT_FALSE(render_surface1->GetRenderSurface()->is_clipped()); + GetRenderSurface(render_surface1)->clip_rect()); + EXPECT_FALSE(GetRenderSurface(render_surface1)->is_clipped()); // That said, it should have grown to accomodate the unclipped descendant and // its own size. EXPECT_EQ(gfx::Rect(-1, 0, 6, 5), - render_surface1->GetRenderSurface()->content_rect()); + GetRenderSurface(render_surface1)->content_rect()); // This render surface should clip. It has no unclipped descendants. EXPECT_EQ(gfx::Rect(0, 0, 10, 10), - render_surface2->GetRenderSurface()->clip_rect()); - EXPECT_TRUE(render_surface2->GetRenderSurface()->is_clipped()); + GetRenderSurface(render_surface2)->clip_rect()); + EXPECT_TRUE(GetRenderSurface(render_surface2)->is_clipped()); EXPECT_FALSE(render_surface2->is_clipped()); // It also shouldn't have grown to accomodate the clip child. EXPECT_EQ(gfx::Rect(0, 0, 5, 5), - render_surface2->GetRenderSurface()->content_rect()); + GetRenderSurface(render_surface2)->content_rect()); } TEST_F(LayerTreeHostCommonTest, @@ -6101,113 +5516,10 @@ TEST_F(LayerTreeHostCommonTest, ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); // Verify which render surfaces were created. - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_FALSE(child1->GetRenderSurface()); - EXPECT_TRUE(child2->GetRenderSurface()); - EXPECT_FALSE(child3->GetRenderSurface()); -} - -TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl.active_tree(), 12345); - std::unique_ptr<LayerImpl> child1 = - LayerImpl::Create(host_impl.active_tree(), 123456); - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl.active_tree(), 1234567); - std::unique_ptr<LayerImpl> child3 = - LayerImpl::Create(host_impl.active_tree(), 12345678); - - gfx::Size bounds(100, 100); - - root->SetBounds(bounds); - root->SetDrawsContent(true); - - // This layer structure normally forces render surface due to preserves3d - // behavior. - child1->SetBounds(bounds); - child1->SetDrawsContent(true); - child1->test_properties()->should_flatten_transform = false; - child1->test_properties()->sorting_context_id = 1; - child2->SetBounds(bounds); - child2->SetDrawsContent(true); - child2->test_properties()->sorting_context_id = 1; - child3->SetBounds(bounds); - child3->SetDrawsContent(true); - child3->test_properties()->sorting_context_id = 1; - - child2->test_properties()->AddChild(std::move(child3)); - child1->test_properties()->AddChild(std::move(child2)); - root->test_properties()->AddChild(std::move(child1)); - LayerImpl* root_layer = root.get(); - root_layer->layer_tree_impl()->SetRootLayerForTesting(std::move(root)); - - { - LayerImplList render_surface_layer_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list); - inputs.can_render_to_separate_surface = true; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - - EXPECT_EQ(2u, render_surface_layer_list.size()); - - int count_represents_target_render_surface = 0; - int count_represents_contributing_render_surface = 0; - int count_represents_itself = 0; - for (EffectTreeLayerListIterator it(host_impl.active_tree()); - it.state() != EffectTreeLayerListIterator::State::END; ++it) { - if (it.state() == EffectTreeLayerListIterator::State::TARGET_SURFACE) { - count_represents_target_render_surface++; - } else if (it.state() == - EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) { - count_represents_contributing_render_surface++; - } else { - count_represents_itself++; - } - } - - // Two render surfaces. - EXPECT_EQ(2, count_represents_target_render_surface); - // Second render surface contributes to root render surface. - EXPECT_EQ(1, count_represents_contributing_render_surface); - // All 4 layers represent itself. - EXPECT_EQ(4, count_represents_itself); - } - - { - LayerImplList render_surface_layer_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list); - inputs.can_render_to_separate_surface = false; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - - EXPECT_EQ(1u, render_surface_layer_list.size()); - - int count_represents_target_render_surface = 0; - int count_represents_contributing_render_surface = 0; - int count_represents_itself = 0; - for (EffectTreeLayerListIterator it(host_impl.active_tree()); - it.state() != EffectTreeLayerListIterator::State::END; ++it) { - if (it.state() == EffectTreeLayerListIterator::State::TARGET_SURFACE) { - count_represents_target_render_surface++; - } else if (it.state() == - EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) { - count_represents_contributing_render_surface++; - } else { - count_represents_itself++; - } - } - - // Only root layer has a render surface. - EXPECT_EQ(1, count_represents_target_render_surface); - // No layer contributes a render surface to root render surface. - EXPECT_EQ(0, count_represents_contributing_render_surface); - // All 4 layers represent itself. - EXPECT_EQ(4, count_represents_itself); - } + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(child1), GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(child2), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(child3), GetRenderSurface(child2)); } TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { @@ -6243,19 +5555,9 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { ExecuteCalculateDrawProperties(root); - EXPECT_EQ(3u, render_surface_layer_list_impl()->size()); - EXPECT_EQ(2u, - render_surface_layer_list_impl() - ->at(0) - ->GetRenderSurface() - ->layer_list() - .size()); - EXPECT_EQ(1u, - render_surface_layer_list_impl() - ->at(1) - ->GetRenderSurface() - ->layer_list() - .size()); + 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); @@ -6269,13 +5571,8 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { // 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_layer_list_impl()->size()); - EXPECT_EQ(1u, - render_surface_layer_list_impl() - ->at(0) - ->GetRenderSurface() - ->layer_list() - .size()); + EXPECT_EQ(2u, render_surface_list_impl()->size()); + EXPECT_EQ(1, render_surface_list_impl()->at(0)->num_contributors()); } TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { @@ -6294,12 +5591,8 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { grand_child->test_properties()->should_flatten_transform = false; ExecuteCalculateDrawProperties(root); - EXPECT_EQ(1u, render_surface_layer_list_impl()->size()); - EXPECT_EQ(grand_child, - render_surface_layer_list_impl() - ->at(0) - ->GetRenderSurface() - ->layer_list()[0]); + EXPECT_EQ(1u, render_surface_list_impl()->size()); + EXPECT_TRUE(grand_child->contributes_to_drawn_render_surface()); // As all layers have identity transform, we shouldn't check for backface // visibility. @@ -6321,13 +5614,8 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { child->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); - EXPECT_EQ(1u, render_surface_layer_list_impl()->size()); - EXPECT_EQ(0u, - render_surface_layer_list_impl() - ->at(0) - ->GetRenderSurface() - ->layer_list() - .size()); + 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 @@ -6348,13 +5636,8 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { grand_child->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); - EXPECT_EQ(1u, render_surface_layer_list_impl()->size()); - EXPECT_EQ(0u, - render_surface_layer_list_impl() - ->at(0) - ->GetRenderSurface() - ->layer_list() - .size()); + 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 @@ -6456,7 +5739,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) { scroll_child->SetBounds(gfx::Size(50, 50)); ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); EXPECT_EQ(gfx::Rect(0, 0, 30, 30), scroll_child->clip_rect()); EXPECT_TRUE(scroll_child->is_clipped()); @@ -6490,13 +5773,12 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { scroll_parent->SetBounds(gfx::Size(50, 50)); float device_scale_factor = 1.5f; - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; gfx::Size device_viewport_size = gfx::Size(root->bounds().width() * device_scale_factor, root->bounds().height() * device_scale_factor); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_size, gfx::Transform(), - &render_surface_layer_list_impl); + root, device_viewport_size, gfx::Transform(), &render_surface_list_impl); inputs.device_scale_factor = device_scale_factor; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); @@ -6527,7 +5809,7 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { child->test_properties()->sorting_context_id = 1; ExecuteCalculateDrawProperties(root); - EXPECT_EQ(3u, render_surface_layer_list_impl()->size()); + EXPECT_EQ(3u, render_surface_list_impl()->size()); gfx::Transform singular_transform; singular_transform.Scale3d( @@ -6538,7 +5820,7 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); - EXPECT_EQ(2u, render_surface_layer_list_impl()->size()); + EXPECT_EQ(2u, render_surface_list_impl()->size()); // Ensure that the entire subtree under a layer with singular transform does // not get rendered. @@ -6548,7 +5830,7 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); - EXPECT_EQ(1u, render_surface_layer_list_impl()->size()); + EXPECT_EQ(1u, render_surface_list_impl()->size()); } TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) { @@ -6584,7 +5866,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) { ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); EXPECT_EQ(gfx::Rect(0, 0, 30, 30), scroll_child->clip_rect()); EXPECT_TRUE(scroll_child->is_clipped()); @@ -6642,17 +5924,17 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) { ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); EXPECT_EQ(gfx::Rect(0, 0, 20, 20), scroll_child->clip_rect()); EXPECT_TRUE(scroll_child->is_clipped()); // Despite the fact that we visited the above layers out of order to get the // correct clip, the layer lists should be unaffected. - EXPECT_EQ(3u, root->GetRenderSurface()->layer_list().size()); - EXPECT_EQ(scroll_child, root->GetRenderSurface()->layer_list().at(0)); - EXPECT_EQ(scroll_parent, root->GetRenderSurface()->layer_list().at(1)); - EXPECT_EQ(scroll_grandparent, root->GetRenderSurface()->layer_list().at(2)); + EXPECT_EQ(3, GetRenderSurface(root)->num_contributors()); + EXPECT_TRUE(scroll_child->contributes_to_drawn_render_surface()); + EXPECT_TRUE(scroll_parent->contributes_to_drawn_render_surface()); + EXPECT_TRUE(scroll_grandparent->contributes_to_drawn_render_surface()); } TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) { @@ -6719,20 +6001,19 @@ TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) { ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); EXPECT_EQ(gfx::Rect(0, 0, 20, 20), scroll_child->clip_rect()); EXPECT_TRUE(scroll_child->is_clipped()); // Despite the fact that we had to process the layers out of order to get the - // right clip, our render_surface_layer_list's order should be unaffected. - EXPECT_EQ(3u, render_surface_layer_list_impl()->size()); - EXPECT_EQ(root, render_surface_layer_list_impl()->at(0)); - EXPECT_EQ(render_surface2, render_surface_layer_list_impl()->at(1)); - EXPECT_EQ(render_surface1, render_surface_layer_list_impl()->at(2)); - EXPECT_TRUE(render_surface_layer_list_impl()->at(0)->GetRenderSurface()); - EXPECT_TRUE(render_surface_layer_list_impl()->at(1)->GetRenderSurface()); - EXPECT_TRUE(render_surface_layer_list_impl()->at(2)->GetRenderSurface()); + // right clip, our render_surface_list's order should be unaffected. + EXPECT_EQ(3u, render_surface_list_impl()->size()); + EXPECT_EQ(GetRenderSurface(root), render_surface_list_impl()->at(0)); + EXPECT_EQ(GetRenderSurface(render_surface2), + render_surface_list_impl()->at(1)); + EXPECT_EQ(GetRenderSurface(render_surface1), + render_surface_list_impl()->at(2)); } TEST_F(LayerTreeHostCommonTest, FixedPositionWithInterveningRenderSurface) { @@ -6858,9 +6139,9 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { gfx::Vector2dF scroll_delta(3.0, 5.0); SetScrollOffsetDelta(scroll_layer, scroll_delta); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list); + root, root->bounds(), &render_surface_list); root->layer_tree_impl() ->property_trees() ->transform_tree.set_source_to_parent_updates_allowed(false); @@ -6884,9 +6165,9 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { gfx::Vector2dF rounded_scroll_delta(4.f, 8.f); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list); + root, root->bounds(), &render_surface_list); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -6912,9 +6193,9 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { gfx::Vector2dF scroll_delta(4.5f, 8.5f); SetScrollOffsetDelta(scroll_layer, scroll_delta); - LayerImplList render_surface_layer_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list); + root, root->bounds(), &render_surface_list); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -7308,7 +6589,11 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { scroller->AddChild(sticky_pos); host()->SetRootLayer(root); scroller->SetScrollClipLayerId(root->id()); - host()->RegisterViewportLayers(nullptr, root, scroller, nullptr); + LayerTreeHost::ViewportLayers viewport_layers; + viewport_layers.page_scale = root; + viewport_layers.inner_viewport_container = root; + viewport_layers.inner_viewport_scroll = scroller; + host()->RegisterViewportLayers(viewport_layers); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -7343,7 +6628,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { // We start to hide the toolbar, but not far enough that the sticky element // should be moved up yet. - root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -10.f)); + root_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -10.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, nullptr); EXPECT_VECTOR2DF_EQ( @@ -7351,7 +6636,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); // On hiding more of the toolbar the sticky element starts to stick. - root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -20.f)); + root_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -20.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, nullptr); EXPECT_VECTOR2DF_EQ( @@ -7360,7 +6645,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { // On hiding more the sticky element stops moving as it has reached its // limit. - root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -30.f)); + root_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -30.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, nullptr); EXPECT_VECTOR2DF_EQ( @@ -7381,7 +6666,13 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { host()->SetRootLayer(root); scroller->SetScrollClipLayerId(root->id()); outer_viewport->SetScrollClipLayerId(outer_clip->id()); - host()->RegisterViewportLayers(nullptr, root, scroller, outer_viewport); + LayerTreeHost::ViewportLayers viewport_layers; + viewport_layers.page_scale = root; + viewport_layers.inner_viewport_container = root; + viewport_layers.outer_viewport_container = outer_clip; + viewport_layers.inner_viewport_scroll = scroller; + viewport_layers.outer_viewport_scroll = outer_viewport; + host()->RegisterViewportLayers(viewport_layers); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -7420,7 +6711,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { // We start to hide the toolbar, but not far enough that the sticky element // should be moved up yet. - outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -10.f)); + outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -10.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, outer_scroll); EXPECT_VECTOR2DF_EQ( @@ -7428,7 +6719,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); // On hiding more of the toolbar the sticky element starts to stick. - outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -20.f)); + outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -20.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, outer_scroll); @@ -7438,7 +6729,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { gfx::Vector2dF(0.f, 60.f), sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -30.f)); + outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -30.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, outer_scroll); @@ -8402,11 +7693,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { // Start with nothing being drawn. ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); std::set<LayerImpl*> expected; std::set<LayerImpl*> actual; @@ -8420,11 +7711,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); expected.clear(); actual.clear(); @@ -8437,11 +7728,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); expected.clear(); expected.insert(grand_child1_raw); @@ -8460,11 +7751,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(grand_child2_raw->contributes_to_drawn_render_surface()); expected.clear(); expected.insert(grand_child2_raw); @@ -8480,13 +7771,13 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); EXPECT_TRUE(child_raw->test_properties() - ->mask_layer->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + ->mask_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(grand_child2_raw->contributes_to_drawn_render_surface()); expected.clear(); expected.insert(grand_child2_raw); @@ -8502,13 +7793,13 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); EXPECT_TRUE(child_raw->test_properties() - ->mask_layer->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + ->mask_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(grand_child2_raw->contributes_to_drawn_render_surface()); expected.clear(); expected.insert(grand_child2_raw); @@ -8525,13 +7816,13 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(child_raw->contributes_to_drawn_render_surface()); EXPECT_FALSE(child_raw->test_properties() - ->mask_layer->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + ->mask_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); expected.clear(); actual.clear(); @@ -8544,13 +7835,13 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_FALSE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(child_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child_raw->contributes_to_drawn_render_surface()); EXPECT_TRUE(child_raw->test_properties() - ->mask_layer->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_FALSE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + ->mask_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_FALSE(grand_child2_raw->contributes_to_drawn_render_surface()); expected.clear(); expected.insert(child_raw); @@ -8571,11 +7862,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { ExecuteCalculateDrawProperties(grand_parent_raw); - EXPECT_TRUE(grand_parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(parent_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(child_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(grand_child1_raw->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(grand_child2_raw->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(grand_parent_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(parent_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(grand_child1_raw->contributes_to_drawn_render_surface()); + EXPECT_TRUE(grand_child2_raw->contributes_to_drawn_render_surface()); expected.clear(); expected.insert(grand_parent_raw); @@ -8659,12 +7950,12 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { float page_scale_factor = 3.f; float device_scale_factor = 1.0f; - std::vector<LayerImpl*> render_surface_layer_list; + RenderSurfaceList render_surface_list; gfx::Size device_viewport_size = gfx::Size(root_layer->bounds().width() * device_scale_factor, root_layer->bounds().height() * device_scale_factor); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, device_viewport_size, &render_surface_layer_list); + root_layer, device_viewport_size, &render_surface_list); inputs.page_scale_factor = page_scale_factor; inputs.can_adjust_raster_scales = true; @@ -8839,10 +8130,9 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { content->test_properties()->force_render_surface = true; gfx::Size device_viewport_size(768, 582); - LayerImplList render_surface_layer_list_impl; + RenderSurfaceList render_surface_list_impl; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_size, gfx::Transform(), - &render_surface_layer_list_impl); + root, device_viewport_size, gfx::Transform(), &render_surface_list_impl); inputs.device_scale_factor = 2.f; inputs.page_scale_factor = 1.f; inputs.page_scale_layer = nullptr; @@ -8857,7 +8147,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), content->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) { +TEST_F(LayerTreeHostCommonTest, ViewportBoundsDeltaAffectVisibleContentRect) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); @@ -8881,6 +8171,12 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) { 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); + root->test_properties()->AddChild( LayerImpl::Create(host_impl.active_tree(), 2)); @@ -8890,14 +8186,14 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) { host_impl.active_tree()->BuildPropertyTreesForTesting(); - LayerImplList layer_impl_list; + RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_size, &layer_impl_list); + root, device_viewport_size, &render_surface_list); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect()); - root->SetBoundsDelta(gfx::Vector2dF(0.0, 50.0)); + root->SetViewportBoundsDelta(gfx::Vector2dF(0.0, 50.0)); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); gfx::Rect affected_by_delta(0, 0, root_size.width(), @@ -8905,7 +8201,7 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) { EXPECT_EQ(affected_by_delta, sublayer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, NodesAffectedByBoundsDeltaGetUpdated) { +TEST_F(LayerTreeHostCommonTest, NodesAffectedByViewportBoundsDeltaGetUpdated) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create(); scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); @@ -8926,8 +8222,13 @@ TEST_F(LayerTreeHostCommonTest, NodesAffectedByBoundsDeltaGetUpdated) { outer_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); host()->SetRootLayer(root); - host()->RegisterViewportLayers(nullptr, root, inner_viewport_scroll_layer, - outer_viewport_scroll_layer); + LayerTreeHost::ViewportLayers viewport_layers; + viewport_layers.page_scale = root; + viewport_layers.inner_viewport_container = inner_viewport_container_layer; + viewport_layers.outer_viewport_container = outer_viewport_container_layer; + viewport_layers.inner_viewport_scroll = inner_viewport_scroll_layer; + viewport_layers.outer_viewport_scroll = outer_viewport_scroll_layer; + host()->RegisterViewportLayers(viewport_layers); scoped_refptr<Layer> fixed_to_inner = Layer::Create(); scoped_refptr<Layer> fixed_to_outer = Layer::Create(); @@ -8994,14 +8295,31 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) { TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayerWithSingularTransform) { - LayerImpl* root = root_layer_for_testing(); - LayerImpl* clip = AddChild<LayerImpl>(root); - LayerImpl* animated = AddChild<LayerImpl>(clip); - LayerImpl* surface = AddChild<LayerImpl>(animated); - LayerImpl* descendant_of_animation = AddChild<LayerImpl>(surface); + host_impl()->CreatePendingTree(); + std::unique_ptr<LayerImpl> root_ptr = + LayerImpl::Create(host_impl()->pending_tree(), 1); + LayerImpl* root = root_ptr.get(); + host_impl()->pending_tree()->SetRootLayerForTesting(std::move(root_ptr)); + std::unique_ptr<LayerImpl> clip_ptr = + LayerImpl::Create(host_impl()->pending_tree(), 2); + LayerImpl* clip = clip_ptr.get(); + root->test_properties()->AddChild(std::move(clip_ptr)); + std::unique_ptr<LayerImpl> animated_ptr = + LayerImpl::Create(host_impl()->pending_tree(), 3); + LayerImpl* animated = animated_ptr.get(); + clip->test_properties()->AddChild(std::move(animated_ptr)); + std::unique_ptr<LayerImpl> surface_ptr = + LayerImpl::Create(host_impl()->pending_tree(), 4); + LayerImpl* surface = surface_ptr.get(); + animated->test_properties()->AddChild(std::move(surface_ptr)); + std::unique_ptr<LayerImpl> descendant_of_animation_ptr = + LayerImpl::Create(host_impl()->pending_tree(), 5); + LayerImpl* descendant_of_animation = descendant_of_animation_ptr.get(); + surface->test_properties()->AddChild(std::move(descendant_of_animation_ptr)); - SetElementIdsForTesting(); + host_impl()->pending_tree()->SetElementIdsForTesting(); + root->SetDrawsContent(true); animated->SetDrawsContent(true); surface->SetDrawsContent(true); descendant_of_animation->SetDrawsContent(true); @@ -9025,7 +8343,11 @@ TEST_F(LayerTreeHostCommonTest, AddAnimatedTransformToElementWithPlayer( animated->element_id(), timeline_impl(), 10.0, start_transform_operations, end_transform_operations); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + ExecuteCalculateDrawProperties(root); + // 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()); + EXPECT_TRUE(animated->raster_even_if_not_in_rsll()); // The animated layer has a singular transform and maps to a non-empty rect in // clipped target space, so is treated as fully visible. @@ -9040,7 +8362,7 @@ TEST_F(LayerTreeHostCommonTest, zero_matrix.Scale3d(0.f, 0.f, 0.f); root->layer_tree_impl()->SetTransformMutated(animated->element_id(), zero_matrix); - ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root); + ExecuteCalculateDrawProperties(root); // The animated layer will be treated as fully visible when we combine clips // in screen space. @@ -9051,6 +8373,22 @@ TEST_F(LayerTreeHostCommonTest, // |surface| and layers that draw into it as having empty visible rect. EXPECT_EQ(gfx::Rect(100, 100), surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(200, 200), descendant_of_animation->visible_layer_rect()); + + host_impl()->ActivateSyncTree(); + LayerImpl* active_root = host_impl()->active_tree()->LayerById(root->id()); + ExecuteCalculateDrawProperties(active_root); + + // Since the animated has singular transform, it is not be part of render + // surface layer list. + LayerImpl* active_animated = + host_impl()->active_tree()->LayerById(animated->id()); + EXPECT_TRUE(active_root->contributes_to_drawn_render_surface()); + EXPECT_FALSE(active_animated->contributes_to_drawn_render_surface()); + + // Since animated has singular transform, it is not be part of render + // surface layer list but should be rastered. + EXPECT_TRUE(animated->raster_even_if_not_in_rsll()); + EXPECT_EQ(gfx::Rect(120, 120), active_animated->visible_layer_rect()); } // Verify that having animated opacity but current opacity 1 still creates @@ -9072,9 +8410,14 @@ TEST_F(LayerTreeHostCommonTest, AnimatedOpacityCreatesRenderSurface) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(1.f, child->Opacity()); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_TRUE(child->GetRenderSurface()); - EXPECT_FALSE(grandchild->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(child), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(grandchild), GetRenderSurface(child)); +} + +static bool FilterIsAnimating(LayerImpl* layer) { + return layer->GetMutatorHost()->IsAnimatingFilterProperty( + layer->element_id(), layer->GetElementTypeForAnimation()); } // Verify that having an animated filter (but no current filter, as these @@ -9093,16 +8436,16 @@ TEST_F(LayerTreeHostCommonTest, AnimatedFilterCreatesRenderSurface) { 10.0, 0.1f, 0.2f); ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_TRUE(child->GetRenderSurface()); - EXPECT_FALSE(grandchild->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(child), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(grandchild), GetRenderSurface(child)); - EXPECT_TRUE(root->GetRenderSurface()->Filters().IsEmpty()); - EXPECT_TRUE(child->GetRenderSurface()->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurface(root)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurface(child)->Filters().IsEmpty()); - EXPECT_FALSE(root->FilterIsAnimating()); - EXPECT_TRUE(child->FilterIsAnimating()); - EXPECT_FALSE(grandchild->FilterIsAnimating()); + EXPECT_FALSE(FilterIsAnimating(root)); + EXPECT_TRUE(FilterIsAnimating(child)); + EXPECT_FALSE(FilterIsAnimating(grandchild)); } // Verify that having a filter animation with a delayed start time creates a @@ -9137,18 +8480,18 @@ TEST_F(LayerTreeHostCommonTest, DelayedFilterAnimationCreatesRenderSurface) { std::move(animation)); ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_TRUE(child->GetRenderSurface()); - EXPECT_FALSE(grandchild->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(child), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(grandchild), GetRenderSurface(child)); - EXPECT_TRUE(root->GetRenderSurface()->Filters().IsEmpty()); - EXPECT_TRUE(child->GetRenderSurface()->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurface(root)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurface(child)->Filters().IsEmpty()); - EXPECT_FALSE(root->FilterIsAnimating()); + EXPECT_FALSE(FilterIsAnimating(root)); EXPECT_FALSE(root->HasPotentiallyRunningFilterAnimation()); - EXPECT_FALSE(child->FilterIsAnimating()); + EXPECT_FALSE(FilterIsAnimating(child)); EXPECT_TRUE(child->HasPotentiallyRunningFilterAnimation()); - EXPECT_FALSE(grandchild->FilterIsAnimating()); + EXPECT_FALSE(FilterIsAnimating(grandchild)); EXPECT_FALSE(grandchild->HasPotentiallyRunningFilterAnimation()); } @@ -9344,14 +8687,7 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { static void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {} -TEST_F(LayerTreeHostCommonTest, NumCopyRequestsInTargetSubtree) { - // If the layer has a node in effect_tree, the return value of - // num_copy_requests_in_target_subtree() must be equal to the actual number - // of copy requests in the sub-layer_tree; Otherwise, the number is expected - // to be the value of its nearest ancestor that owns an effect node and - // greater than or equal to the actual number of copy requests in the - // sub-layer_tree. - +TEST_F(LayerTreeHostCommonTest, HasCopyRequestsInTargetSubtree) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> child1 = Layer::Create(); scoped_refptr<Layer> child2 = Layer::Create(); @@ -9371,11 +8707,11 @@ TEST_F(LayerTreeHostCommonTest, NumCopyRequestsInTargetSubtree) { child2->SetOpacity(0.f); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_EQ(root->num_copy_requests_in_target_subtree(), 2); - EXPECT_EQ(child1->num_copy_requests_in_target_subtree(), 2); - EXPECT_EQ(child2->num_copy_requests_in_target_subtree(), 0); - EXPECT_EQ(grandchild->num_copy_requests_in_target_subtree(), 2); - EXPECT_EQ(greatgrandchild->num_copy_requests_in_target_subtree(), 1); + EXPECT_TRUE(root->has_copy_requests_in_target_subtree()); + EXPECT_TRUE(child1->has_copy_requests_in_target_subtree()); + EXPECT_FALSE(child2->has_copy_requests_in_target_subtree()); + EXPECT_TRUE(grandchild->has_copy_requests_in_target_subtree()); + EXPECT_TRUE(greatgrandchild->has_copy_requests_in_target_subtree()); } TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { @@ -9781,10 +9117,10 @@ TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) { CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0); + EXPECT_TRUE(root->has_copy_requests_in_target_subtree()); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0); + EXPECT_TRUE(root->has_copy_requests_in_target_subtree()); } TEST_F(LayerTreeHostCommonTest, ResetPropertyTreeIndices) { @@ -9856,11 +9192,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { transform_tree.Node(significant_transform->transform_tree_index()); EXPECT_EQ(transform_node->owning_layer_id, significant_transform->id()); - EXPECT_TRUE(root->GetRenderSurface()); - EXPECT_FALSE(significant_transform->GetRenderSurface()); - EXPECT_TRUE(layer_clips_subtree->GetRenderSurface()); - EXPECT_TRUE(render_surface->GetRenderSurface()); - EXPECT_FALSE(test_layer->GetRenderSurface()); + EXPECT_TRUE(GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(significant_transform), GetRenderSurface(root)); + EXPECT_TRUE(GetRenderSurface(layer_clips_subtree)); + EXPECT_NE(GetRenderSurface(render_surface), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(test_layer), GetRenderSurface(render_surface)); EXPECT_EQ(gfx::Rect(30, 20), test_layer->visible_layer_rect()); } @@ -10066,13 +9402,13 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(50, 50), - unclipped_surface->GetRenderSurface()->content_rect()); + GetRenderSurface(unclipped_surface)->content_rect()); EXPECT_EQ(gfx::Rect(50, 50), - unclipped_desc_surface->GetRenderSurface()->content_rect()); + GetRenderSurface(unclipped_desc_surface)->content_rect()); EXPECT_EQ(gfx::Rect(60, 60), - unclipped_desc_surface2->GetRenderSurface()->content_rect()); + GetRenderSurface(unclipped_desc_surface2)->content_rect()); EXPECT_EQ(gfx::Rect(50, 50), - clipped_surface->GetRenderSurface()->content_rect()); + GetRenderSurface(clipped_surface)->content_rect()); } TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { @@ -10114,7 +9450,7 @@ TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(10, 10), - unclipped_desc_surface->GetRenderSurface()->content_rect()); + GetRenderSurface(unclipped_desc_surface)->content_rect()); } TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { @@ -10278,13 +9614,13 @@ TEST_F(LayerTreeHostCommonTest, SubtreeIsHiddenTest) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(0.f, - test->GetRenderSurface()->OwningEffectNode()->screen_space_opacity); + GetRenderSurface(test)->OwningEffectNode()->screen_space_opacity); hidden->test_properties()->hide_layer_and_subtree = false; root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_EQ(1.f, - test->GetRenderSurface()->OwningEffectNode()->screen_space_opacity); + GetRenderSurface(test)->OwningEffectNode()->screen_space_opacity); } TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { @@ -10338,9 +9674,10 @@ TEST_F(LayerTreeHostCommonTest, MaskLayerDrawProperties) { ExecuteCalculateDrawProperties(root); // The render surface created for the mask has no contributing content, so the - // mask isn't a drawn RSLL member. This means it has an empty visible rect, - // but its screen space transform can still be computed correctly on-demand. - EXPECT_FALSE(mask->is_drawn_render_surface_layer_list_member()); + // 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(mask->contributes_to_drawn_render_surface()); EXPECT_EQ(gfx::Rect(), mask->visible_layer_rect()); EXPECT_TRANSFORMATION_MATRIX_EQ(transform, mask->ScreenSpaceTransform()); @@ -10348,7 +9685,7 @@ TEST_F(LayerTreeHostCommonTest, MaskLayerDrawProperties) { child->SetDrawsContent(true); root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); - EXPECT_TRUE(mask->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(mask->contributes_to_drawn_render_surface()); EXPECT_EQ(gfx::Rect(20, 20), mask->visible_layer_rect()); EXPECT_TRANSFORMATION_MATRIX_EQ(transform, mask->ScreenSpaceTransform()); @@ -10471,7 +9808,7 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::RectF(), - render_surface1->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface1)->DrawableContentRect()); bool is_inf_or_nan = std::isinf(child->DrawTransform().matrix().get(0, 0)) || std::isnan(child->DrawTransform().matrix().get(0, 0)); @@ -10481,9 +9818,10 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { std::isnan(child->DrawTransform().matrix().get(1, 1)); EXPECT_TRUE(is_inf_or_nan); - // The root layer should be in the RenderSurfaceLayerListImpl. - const auto* rsll = render_surface_layer_list_impl(); - EXPECT_NE(std::find(rsll->begin(), rsll->end(), root), rsll->end()); + // The root layer should be in the RenderSurfaceList. + const auto* rsl = render_surface_list_impl(); + EXPECT_NE(std::find(rsl->begin(), rsl->end(), GetRenderSurface(root)), + rsl->end()); } TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { @@ -10717,7 +10055,11 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { parent5->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); parent5->SetBounds(gfx::Size(10, 10)); - host()->RegisterViewportLayers(nullptr, page_scale_layer, parent2, nullptr); + LayerTreeHost::ViewportLayers viewport_layers; + viewport_layers.page_scale = page_scale_layer; + viewport_layers.inner_viewport_container = root1; + viewport_layers.inner_viewport_scroll = parent2; + host()->RegisterViewportLayers(viewport_layers); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root1.get()); const int kRootPropertyTreeNodeId = 0; @@ -10860,10 +10202,10 @@ TEST_F(LayerTreeHostCommonTest, CanAdjustRasterScaleTest) { // Check surface draw properties. EXPECT_EQ(gfx::Rect(10, 10), - render_surface->GetRenderSurface()->content_rect()); - EXPECT_EQ(transform, render_surface->GetRenderSurface()->draw_transform()); + GetRenderSurface(render_surface)->content_rect()); + EXPECT_EQ(transform, GetRenderSurface(render_surface)->draw_transform()); EXPECT_EQ(gfx::RectF(50.0f, 50.0f), - render_surface->GetRenderSurface()->DrawableContentRect()); + GetRenderSurface(render_surface)->DrawableContentRect()); // Check child layer draw properties. EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index 05e4e3add0a..359d56d6e43 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -16,7 +16,7 @@ #include "base/auto_reset.h" #include "base/bind.h" -#include "base/containers/small_map.h" +#include "base/containers/flat_map.h" #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram.h" @@ -36,6 +36,7 @@ #include "cc/input/scroll_elasticity_helper.h" #include "cc/input/scroll_state.h" #include "cc/input/scrollbar_animation_controller.h" +#include "cc/input/scroller_size_metrics.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/effect_tree_layer_list_iterator.h" #include "cc/layers/heads_up_display_layer_impl.h" @@ -162,7 +163,7 @@ DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeDurationHistogramTimer, "Scheduling.%s.PendingTreeDuration"); LayerTreeHostImpl::FrameData::FrameData() - : render_surface_layer_list(nullptr), + : render_surface_list(nullptr), has_no_damage(false), may_contain_video(false) {} @@ -206,8 +207,6 @@ LayerTreeHostImpl::LayerTreeHostImpl( did_lock_scrolling_layer_(false), wheel_scrolling_(false), scroll_affects_scroll_handler_(false), - scroll_layer_id_mouse_currently_over_(Layer::INVALID_ID), - scroll_layer_id_mouse_currently_captured_(Layer::INVALID_ID), tile_priorities_dirty_(false), settings_(settings), visible_(false), @@ -243,7 +242,8 @@ LayerTreeHostImpl::LayerTreeHostImpl( scroll_animating_latched_node_id_(ScrollTree::kInvalidNodeId), has_scrolled_by_wheel_(false), has_scrolled_by_touch_(false), - touchpad_and_wheel_scroll_latching_enabled_(false) { + touchpad_and_wheel_scroll_latching_enabled_(false), + impl_thread_phase_(ImplThreadPhase::IDLE) { DCHECK(mutator_host_); mutator_host_->SetMutatorHostClient(this); @@ -325,15 +325,6 @@ void LayerTreeHostImpl::BeginMainFrameAborted( void LayerTreeHostImpl::BeginCommit() { TRACE_EVENT0("cc", "LayerTreeHostImpl::BeginCommit"); - // Ensure all textures are returned so partial texture updates can happen - // during the commit. - // TODO(ericrk): We should not need to ForceReclaimResources when using - // Impl-side-painting as it doesn't upload during commits. However, - // Display::Draw currently relies on resource being reclaimed to block drawing - // between BeginCommit / Swap. See crbug.com/489515. - if (compositor_frame_sink_) - compositor_frame_sink_->ForceReclaimResources(); - if (!CommitToActiveTree()) CreatePendingTree(); } @@ -341,6 +332,11 @@ void LayerTreeHostImpl::BeginCommit() { void LayerTreeHostImpl::CommitComplete() { TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete"); + // In high latency mode commit cannot finish within the same frame. We need to + // flush input here to make sure they got picked up by |PrepareTiles()|. + if (input_handler_client_ && impl_thread_phase_ == ImplThreadPhase::IDLE) + input_handler_client_->DeliverInputForBeginFrame(); + UpdateSyncTreeAfterCommitOrImplSideInvalidation(); micro_benchmark_controller_.DidCompleteCommit(); } @@ -350,6 +346,8 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() { tile_manager_.TakeImagesToInvalidateOnSyncTree()); if (CommitToActiveTree()) { + active_tree_->HandleScrollbarShowRequestsFromMain(); + // We have to activate animations here or "IsActive()" is true on the layers // but the animations aren't activated yet so they get ignored by // UpdateDrawProperties. @@ -416,7 +414,7 @@ bool LayerTreeHostImpl::CanDraw() const { if (resourceless_software_draw_) return true; - if (DrawViewportSize().IsEmpty()) { + if (DeviceViewport().IsEmpty()) { TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport", TRACE_EVENT_SCOPE_THREAD); return false; @@ -577,21 +575,20 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt( bool scroll_on_main_thread = false; uint32_t main_thread_scrolling_reasons; - LayerImpl* test_layer_impl = FindScrollLayerForDeviceViewportPoint( + auto* test_scroll_node = FindScrollNodeForDeviceViewportPoint( device_viewport_point, type, layer_impl, &scroll_on_main_thread, &main_thread_scrolling_reasons); if (scroll_on_main_thread) return false; - int test_scroll_tree_index = test_layer_impl->scroll_tree_index(); - if (scrolling_node->id == test_scroll_tree_index) + if (scrolling_node == test_scroll_node) return true; // For active scrolling state treat the inner/outer viewports interchangeably. if (scrolling_node->scrolls_inner_viewport || scrolling_node->scrolls_outer_viewport) { - return test_layer_impl == viewport()->MainScrollLayer(); + return test_scroll_node == OuterViewportScrollNode(); } return false; @@ -707,27 +704,6 @@ void LayerTreeHostImpl::QueueSwapPromiseForMainThreadScrollUpdate( std::move(swap_promise)); } -void LayerTreeHostImpl::TrackDamageForAllSurfaces( - const LayerImplList& render_surface_layer_list) { - // For now, we use damage tracking to compute a global scissor. To do this, we - // 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. - size_t render_surface_layer_list_size = render_surface_layer_list.size(); - for (size_t i = 0; i < render_surface_layer_list_size; ++i) { - size_t surface_index = render_surface_layer_list_size - 1 - i; - LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; - RenderSurfaceImpl* render_surface = - render_surface_layer->GetRenderSurface(); - DCHECK(render_surface); - render_surface->damage_tracker()->UpdateDamageTrackingState( - render_surface->layer_list(), render_surface, - render_surface->SurfacePropertyChangedOnlyFromDescendant(), - render_surface->content_rect(), render_surface->MaskLayer(), - render_surface->Filters()); - } -} - void LayerTreeHostImpl::FrameData::AsValueInto( base::trace_event::TracedValue* value) const { value->SetBoolean("has_no_damage", has_no_damage); @@ -758,11 +734,12 @@ DrawMode LayerTreeHostImpl::GetDrawMode() const { } } -static void AppendQuadsToFillScreen(const gfx::Rect& root_scroll_layer_rect, - RenderPass* target_render_pass, - RenderSurfaceImpl* root_render_surface, - SkColor screen_background_color, - const Region& fill_region) { +static void AppendQuadsToFillScreen( + const gfx::Rect& root_scroll_layer_rect, + RenderPass* target_render_pass, + const RenderSurfaceImpl* root_render_surface, + SkColor screen_background_color, + const Region& fill_region) { if (!root_render_surface || !SkColorGetA(screen_background_color)) return; if (fill_region.IsEmpty()) @@ -778,7 +755,7 @@ static void AppendQuadsToFillScreen(const gfx::Rect& root_scroll_layer_rect, int sorting_context_id = 0; SharedQuadState* shared_quad_state = target_render_pass->CreateAndAppendSharedQuadState(); - shared_quad_state->SetAll(gfx::Transform(), root_target_rect.size(), + shared_quad_state->SetAll(gfx::Transform(), root_target_rect, root_target_rect, root_target_rect, false, opacity, SkBlendMode::kSrcOver, sorting_context_id); @@ -807,19 +784,24 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { DCHECK(CanDraw()); DCHECK(!active_tree_->LayerListIsEmpty()); - TrackDamageForAllSurfaces(*frame->render_surface_layer_list); + // For now, we use damage tracking to compute a global scissor. To do this, we + // 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()); // If the root render surface has no visible damage, then don't generate a // frame at all. - RenderSurfaceImpl* root_surface = active_tree_->RootRenderSurface(); + const RenderSurfaceImpl* root_surface = active_tree_->RootRenderSurface(); bool root_surface_has_no_visible_damage = !root_surface->GetDamageRect().Intersects(root_surface->content_rect()); bool root_surface_has_contributing_layers = - !root_surface->layer_list().empty(); + !!root_surface->num_contributors(); bool hud_wants_to_draw_ = active_tree_->hud_layer() && active_tree_->hud_layer()->IsAnimatingHUDContents(); - bool resources_must_be_resent = - compositor_frame_sink_->capabilities().can_force_reclaim_resources; + bool must_always_swap = + compositor_frame_sink_->capabilities().must_always_swap; // When touch handle visibility changes there is no visible damage // because touch handles are composited in the browser. However we // still want the browser to be notified that the handles changed @@ -830,8 +812,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { if (root_surface_has_contributing_layers && root_surface_has_no_visible_damage && !active_tree_->property_trees()->effect_tree.HasCopyRequests() && - !resources_must_be_resent && !hud_wants_to_draw_ && - !handle_visibility_changed) { + !must_always_swap && !hud_wants_to_draw_ && !handle_visibility_changed) { TRACE_EVENT0("cc", "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect"); frame->has_no_damage = true; @@ -839,25 +820,22 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { return DRAW_SUCCESS; } - TRACE_EVENT_BEGIN2( - "cc", "LayerTreeHostImpl::CalculateRenderPasses", - "render_surface_layer_list.size()", - static_cast<uint64_t>(frame->render_surface_layer_list->size()), - "RequiresHighResToDraw", RequiresHighResToDraw()); + TRACE_EVENT_BEGIN2("cc", "LayerTreeHostImpl::CalculateRenderPasses", + "render_surface_list.size()", + static_cast<uint64_t>(frame->render_surface_list->size()), + "RequiresHighResToDraw", RequiresHighResToDraw()); // Create the render passes in dependency order. - size_t render_surface_layer_list_size = - frame->render_surface_layer_list->size(); - for (size_t i = 0; i < render_surface_layer_list_size; ++i) { - size_t surface_index = render_surface_layer_list_size - 1 - i; - LayerImpl* render_surface_layer = - (*frame->render_surface_layer_list)[surface_index]; + size_t render_surface_list_size = frame->render_surface_list->size(); + for (size_t i = 0; i < render_surface_list_size; ++i) { + size_t surface_index = render_surface_list_size - 1 - i; RenderSurfaceImpl* render_surface = - render_surface_layer->GetRenderSurface(); + (*frame->render_surface_list)[surface_index]; + bool is_root_surface = + render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; bool should_draw_into_render_pass = - active_tree_->IsRootLayer(render_surface_layer) || - render_surface->contributes_to_drawn_surface() || + is_root_surface || render_surface->contributes_to_drawn_surface() || render_surface->HasCopyRequest(); if (should_draw_into_render_pass) frame->render_passes.push_back(render_surface->CreateRenderPass()); @@ -967,15 +945,13 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { append_quads_data.checkerboarded_needs_raster_content_area; if (append_quads_data.num_missing_tiles > 0) { have_missing_animated_tiles |= - !layer->was_ever_ready_since_last_transform_animation() || layer->screen_space_transform_is_animating(); - } else { - layer->set_was_ever_ready_since_last_transform_animation(true); } } - frame->embedded_surfaces.insert(frame->embedded_surfaces.end(), - append_quads_data.embedded_surfaces.begin(), - append_quads_data.embedded_surfaces.end()); + frame->activation_dependencies.insert( + frame->activation_dependencies.end(), + append_quads_data.activation_dependencies.begin(), + append_quads_data.activation_dependencies.end()); } // If CommitToActiveTree() is true, then we wait to draw until @@ -1091,6 +1067,19 @@ void LayerTreeHostImpl::InvalidateContentOnImplSide() { if (!CommitToActiveTree()) CreatePendingTree(); + + // The state of PropertyTrees on the recycle tree can be stale if scrolling + // and animation updates were made on the active tree, since these are not + // replicated on the recycle tree. We use the function below to handle the + // similar case for updates from the main thread not being in sync with + // changes made on the active tree. + // Note that while in practice only the scroll state should need to be + // updated, since the animation state is updated both on the recycle and + // active tree. We use the same function as for main thread commits for + // consistency. + bool is_impl_side_update = true; + sync_tree()->UpdatePropertyTreeScrollingAndAnimationFromMainThread( + is_impl_side_update); UpdateSyncTreeAfterCommitOrImplSideInvalidation(); } @@ -1128,7 +1117,7 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { // they appear as part of the current frame being drawn. tile_manager_.Flush(); - frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList(); + frame->render_surface_list = &active_tree_->GetRenderSurfaceList(); frame->render_passes.clear(); frame->will_draw_layers.clear(); frame->has_no_damage = false; @@ -1158,10 +1147,10 @@ void LayerTreeHostImpl::RemoveRenderPasses(FrameData* frame) { DCHECK_GE(frame->render_passes.size(), 1u); // A set of RenderPasses that we have seen. - std::set<int> pass_exists; + base::flat_set<int> pass_exists; // A set of RenderPassDrawQuads that we have seen (stored by the RenderPasses // they refer to). - base::SmallMap<std::unordered_map<int, int>> pass_references; + base::flat_map<int, int> pass_references; // Iterate RenderPasses in draw order, removing empty render passes (except // the root RenderPass). @@ -1296,6 +1285,14 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy( // running work. if (image_decode_cache_) image_decode_cache_->SetShouldAggressivelyFreeResources(false); + } else { + // When the memory policy is set to zero, its important to release any + // decoded images cached by the tracker. But we can not re-checker any + // images that have been displayed since the resources, if held by the + // browser, may be re-used. Which is why its important to maintain the + // decode policy tracking. + bool can_clear_decode_policy_tracking = false; + tile_manager_.ClearCheckerImageTracking(can_clear_decode_policy_tracking); } DCHECK(resource_pool_); @@ -1352,11 +1349,23 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw( } gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace() const { + gfx::ColorSpace result; if (!settings_.enable_color_correct_rasterization) - return gfx::ColorSpace(); - if (!sync_tree()) - return gfx::ColorSpace::CreateSRGB(); - return sync_tree()->raster_color_space(); + return result; + + // The pending tree will have the most recently updated color space, so + // prefer that. + if (pending_tree_) + result = pending_tree_->raster_color_space(); + else if (active_tree_) + result = active_tree_->raster_color_space(); + + // Always specify a color space if color correct rasterization is requested + // (not specifying a color space indicates that no color conversion is + // required). + if (!result.IsValid()) + result = gfx::ColorSpace::CreateSRGB(); + return result; } void LayerTreeHostImpl::RequestImplSideInvalidation() { @@ -1674,8 +1683,8 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { if (debug_state_.ShowHudRects()) { debug_rect_history_->SaveDebugRectsForCurrentFrame( - active_tree(), active_tree_->hud_layer(), - *frame->render_surface_layer_list, debug_state_); + active_tree(), active_tree_->hud_layer(), *frame->render_surface_list, + debug_state_); } bool is_new_trace; @@ -1709,7 +1718,7 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { CompositorFrameMetadata metadata = MakeCompositorFrameMetadata(); metadata.may_contain_video = frame->may_contain_video; - metadata.embedded_surfaces = std::move(frame->embedded_surfaces); + metadata.activation_dependencies = std::move(frame->activation_dependencies); active_tree()->FinishSwapPromises(&metadata); for (auto& latency : metadata.latency_info) { TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", @@ -1745,7 +1754,8 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { compositor_frame.render_pass_list = std::move(frame->render_passes); // TODO(fsamuel): Once all clients get their LocalSurfaceId from their parent, // the LocalSurfaceId should hang off CompositorFrameMetadata. - if (active_tree()->local_surface_id().is_valid()) { + if (settings_.enable_surface_synchronization && + active_tree()->local_surface_id().is_valid()) { compositor_frame_sink_->SetLocalSurfaceId( active_tree()->local_surface_id()); } @@ -1759,8 +1769,8 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { // are noted as they occur. // TODO(boliu): If we did a temporary software renderer frame, propogate the // damage forward to the next frame. - for (size_t i = 0; i < frame->render_surface_layer_list->size(); i++) { - auto* surface = (*frame->render_surface_layer_list)[i]->GetRenderSurface(); + for (size_t i = 0; i < frame->render_surface_list->size(); i++) { + auto* surface = (*frame->render_surface_list)[i]; surface->damage_tracker()->DidDrawDamagedArea(); } active_tree_->ResetAllChangeTracking(); @@ -1857,14 +1867,13 @@ bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() { gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE; } else if (!has_gpu_rasterization_trigger_) { gpu_rasterization_status_ = GpuRasterizationStatus::OFF_VIEWPORT; - } else if (content_is_suitable_for_gpu_rasterization_) { - use_gpu = true; - gpu_rasterization_status_ = GpuRasterizationStatus::ON; - } else if (using_msaa_for_complex_content) { + } else if (!content_is_suitable_for_gpu_rasterization_ && + using_msaa_for_complex_content) { use_gpu = use_msaa = true; gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT; } else { - gpu_rasterization_status_ = GpuRasterizationStatus::OFF_CONTENT; + use_gpu = true; + gpu_rasterization_status_ = GpuRasterizationStatus::ON; } if (use_gpu && !use_gpu_rasterization_) { @@ -1929,13 +1938,21 @@ void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) { for (auto* it : video_frame_controllers_) it->OnBeginFrame(args); + + impl_thread_phase_ = ImplThreadPhase::INSIDE_IMPL_FRAME; } void LayerTreeHostImpl::DidFinishImplFrame() { + impl_thread_phase_ = ImplThreadPhase::IDLE; current_begin_frame_tracker_.Finish(); decoded_image_tracker_.NotifyFrameFinished(); } +void LayerTreeHostImpl::DidNotProduceFrame(const BeginFrameAck& ack) { + if (compositor_frame_sink_) + compositor_frame_sink_->DidNotProduceFrame(ack); +} + void LayerTreeHostImpl::UpdateViewportContainerSizes() { LayerImpl* inner_container = active_tree_->InnerViewportContainerLayer(); LayerImpl* outer_container = active_tree_->OuterViewportContainerLayer(); @@ -1964,7 +1981,7 @@ void LayerTreeHostImpl::UpdateViewportContainerSizes() { // for changes in the size (e.g. browser controls) since the last resize from // Blink. gfx::Vector2dF amount_to_expand(0.f, delta_from_top_controls); - inner_container->SetBoundsDelta(amount_to_expand); + inner_container->SetViewportBoundsDelta(amount_to_expand); if (outer_container && !outer_container->BoundsForScrolling().IsEmpty()) { // Adjust the outer viewport container as well, since adjusting only the @@ -1972,8 +1989,8 @@ void LayerTreeHostImpl::UpdateViewportContainerSizes() { // clamping. gfx::Vector2dF amount_to_expand_scaled = gfx::ScaleVector2d( amount_to_expand, 1.f / active_tree_->min_page_scale_factor()); - outer_container->SetBoundsDelta(amount_to_expand_scaled); - active_tree_->InnerViewportScrollLayer()->SetBoundsDelta( + outer_container->SetViewportBoundsDelta(amount_to_expand_scaled); + active_tree_->InnerViewportScrollLayer()->SetViewportBoundsDelta( amount_to_expand_scaled); anchor.ResetViewportToAnchoredPosition(); @@ -2049,9 +2066,38 @@ void LayerTreeHostImpl::CreatePendingTree() { pending_tree_duration_timer_.reset(new PendingTreeDurationHistogramTimer()); } +void LayerTreeHostImpl::PushScrollbarOpacitiesFromActiveToPending() { + if (!active_tree()) + return; + for (auto& pair : scrollbar_animation_controllers_) { + for (auto* scrollbar : pair.second->Scrollbars()) { + if (const EffectNode* source_effect_node = + active_tree() + ->property_trees() + ->effect_tree.FindNodeFromElementId( + scrollbar->element_id())) { + if (EffectNode* target_effect_node = + pending_tree() + ->property_trees() + ->effect_tree.FindNodeFromElementId( + scrollbar->element_id())) { + DCHECK(target_effect_node); + float source_opacity = source_effect_node->opacity; + float target_opacity = target_effect_node->opacity; + if (source_opacity == target_opacity) + continue; + target_effect_node->opacity = source_opacity; + pending_tree()->property_trees()->effect_tree.set_needs_update(true); + } + } + } + } +} + void LayerTreeHostImpl::ActivateSyncTree() { if (pending_tree_) { TRACE_EVENT_ASYNC_END0("cc", "PendingTree:waiting", pending_tree_.get()); + active_tree_->lifecycle().AdvanceTo(LayerTreeLifecycle::kBeginningSync); DCHECK(pending_tree_duration_timer_); // Reset will call the destructor and log the timer histogram. @@ -2067,25 +2113,21 @@ void LayerTreeHostImpl::ActivateSyncTree() { active_tree_.get()); } - // Property trees may store damage status. We preserve the active tree - // damage status by pushing the damage status from active tree property - // trees to pending tree property trees or by moving it onto the layers. - if (active_tree_->property_trees()->changed) { - if (pending_tree_->property_trees()->sequence_number == - active_tree_->property_trees()->sequence_number) - active_tree_->property_trees()->PushChangeTrackingTo( - pending_tree_->property_trees()); - else - active_tree_->MoveChangeTrackingToLayers(); - } + PushScrollbarOpacitiesFromActiveToPending(); + pending_tree_->PushPropertyTreesTo(active_tree_.get()); + active_tree_->lifecycle().AdvanceTo( + LayerTreeLifecycle::kSyncedPropertyTrees); + TreeSynchronizer::PushLayerProperties(pending_tree(), active_tree()); - active_tree_->property_trees()->PushOpacityIfNeeded( - pending_tree_->property_trees()); + active_tree_->lifecycle().AdvanceTo( + LayerTreeLifecycle::kSyncedLayerProperties); pending_tree_->PushPropertiesTo(active_tree_.get()); if (!pending_tree_->LayerListIsEmpty()) pending_tree_->property_trees()->ResetAllChangeTracking(); + active_tree_->lifecycle().AdvanceTo(LayerTreeLifecycle::kNotSyncing); + // Now that we've synced everything from the pending tree to the active // tree, rename the pending tree the recycle tree so we can reuse it on the // next sync. @@ -2264,7 +2306,8 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( *resource_pool = ResourcePool::Create(resource_provider_.get(), GetTaskRunner(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - ResourcePool::kDefaultExpirationDelay); + ResourcePool::kDefaultExpirationDelay, + settings_.disallow_non_exact_resource_reuse); *raster_buffer_provider = BitmapRasterBufferProvider::Create(resource_provider_.get()); @@ -2279,7 +2322,8 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( *resource_pool = ResourcePool::Create( resource_provider_.get(), GetTaskRunner(), ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, - ResourcePool::kDefaultExpirationDelay); + ResourcePool::kDefaultExpirationDelay, + settings_.disallow_non_exact_resource_reuse); int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0; @@ -2304,7 +2348,8 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( *resource_pool = ResourcePool::CreateForGpuMemoryBufferResources( resource_provider_.get(), GetTaskRunner(), gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - ResourcePool::kDefaultExpirationDelay); + ResourcePool::kDefaultExpirationDelay, + settings_.disallow_non_exact_resource_reuse); *raster_buffer_provider = ZeroCopyRasterBufferProvider::Create( resource_provider_.get(), @@ -2315,7 +2360,8 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( *resource_pool = ResourcePool::Create(resource_provider_.get(), GetTaskRunner(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - ResourcePool::kDefaultExpirationDelay); + ResourcePool::kDefaultExpirationDelay, + settings_.disallow_non_exact_resource_reuse); const int max_copy_texture_chromium_size = compositor_context_provider->ContextCapabilities() @@ -2367,6 +2413,10 @@ LayerTreeHostImpl::TakeCompletedImageDecodeCallbacks() { } void LayerTreeHostImpl::ClearImageCacheOnNavigation() { + // It is safe to clear the decode policy tracking on navigations since it + // comes with an invalidation and the image ids are never re-used. + bool can_clear_decode_policy_tracking = true; + tile_manager_.ClearCheckerImageTracking(can_clear_decode_policy_tracking); if (image_decode_cache_) image_decode_cache_->ClearCache(); } @@ -2514,17 +2564,6 @@ void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) { active_tree_->set_needs_update_draw_properties(); } -const gfx::Rect LayerTreeHostImpl::ViewportRectForTilePriority() const { - if (viewport_rect_for_tile_priority_.IsEmpty()) - return DeviceViewport(); - - return viewport_rect_for_tile_priority_; -} - -gfx::Size LayerTreeHostImpl::DrawViewportSize() const { - return DeviceViewport().size(); -} - gfx::Rect LayerTreeHostImpl::DeviceViewport() const { if (external_viewport_.IsEmpty()) return gfx::Rect(device_viewport_size_); @@ -2532,6 +2571,13 @@ gfx::Rect LayerTreeHostImpl::DeviceViewport() const { return external_viewport_; } +const gfx::Rect LayerTreeHostImpl::ViewportRectForTilePriority() const { + if (viewport_rect_for_tile_priority_.IsEmpty()) + return DeviceViewport(); + + return viewport_rect_for_tile_priority_; +} + const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { return external_transform_; } @@ -2656,7 +2702,7 @@ static bool IsMainThreadScrolling(const InputHandler::ScrollStatus& status, return false; } -LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( +ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint( const gfx::PointF& device_viewport_point, InputHandler::ScrollInputType type, LayerImpl* layer_impl, @@ -2681,7 +2727,7 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( if (IsMainThreadScrolling(status, scroll_node)) { *scroll_on_main_thread = true; *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; - return active_tree_->LayerById(scroll_node->owning_layer_id); + return scroll_node; } if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD && @@ -2711,11 +2757,7 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( } } - // TODO(pdr): Refactor this function to directly return |impl_scroll_node| - // instead of using ScrollNode's owning_layer_id to return a LayerImpl. - if (!impl_scroll_node) - return nullptr; - return active_tree_->LayerById(impl_scroll_node->owning_layer_id); + return impl_scroll_node; } InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( @@ -2800,13 +2842,25 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( } } - auto* scrolling_layer = FindScrollLayerForDeviceViewportPoint( + scrolling_node = FindScrollNodeForDeviceViewportPoint( device_viewport_point, type, layer_impl, &scroll_on_main_thread, &scroll_status.main_thread_scrolling_reasons); - ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; - scrolling_node = - scrolling_layer ? scroll_tree.Node(scrolling_layer->scroll_tree_index()) - : nullptr; + if (!scroll_on_main_thread && scrolling_node && + (settings_.is_layer_tree_for_subframe || + (!scrolling_node->scrolls_outer_viewport && + !scrolling_node->scrolls_inner_viewport))) { + if (IsWheelBasedScroll(type)) { + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Event.Scroll.ScrollerSize.OnScroll_Wheel", + scrolling_node->scroll_clip_layer_bounds.GetArea(), 1, + kScrollerSizeLargestBucket, kScrollerSizeBucketCount); + } else { + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Event.Scroll.ScrollerSize.OnScroll_Touch", + scrolling_node->scroll_clip_layer_bounds.GetArea(), 1, + kScrollerSizeLargestBucket, kScrollerSizeBucketCount); + } + } } if (scroll_on_main_thread) { @@ -2946,8 +3000,14 @@ bool LayerTreeHostImpl::ScrollAnimationCreate(ScrollNode* scroll_node, active_tree()->LayerById(scroll_node->owning_layer_id)->element_id()), scroll_node->element_id); + // Start the animation one full frame in. Without any offset, the animation + // doesn't start until next frame, increasing latency, and preventing our + // input latency tracking architecture from working. + base::TimeDelta animation_start_offset = CurrentBeginFrameArgs().interval; + mutator_host_->ImplOnlyScrollAnimationCreate( - scroll_node->element_id, target_offset, current_offset, delayed_by); + scroll_node->element_id, target_offset, current_offset, delayed_by, + animation_start_offset); SetNeedsOneBeginImplFrame(); @@ -2967,7 +3027,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( if (scroll_node) { // Flash the overlay scrollbar even if the scroll dalta is 0. ScrollbarAnimationController* animation_controller = - ScrollbarAnimationControllerForId(scroll_node->owning_layer_id); + ScrollbarAnimationControllerForElementId(scroll_node->element_id); if (animation_controller) animation_controller->WillUpdateScroll(); @@ -3018,7 +3078,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( if (scrolls_main_viewport_scroll_layer) { // Flash the overlay scrollbar even if the scroll dalta is 0. ScrollbarAnimationController* animation_controller = - ScrollbarAnimationControllerForId(scroll_node->owning_layer_id); + ScrollbarAnimationControllerForElementId(scroll_node->element_id); if (animation_controller) animation_controller->WillUpdateScroll(); @@ -3286,7 +3346,7 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( return InputHandlerScrollResult(); ScrollbarAnimationController* animation_controller = - ScrollbarAnimationControllerForId(scroll_node->owning_layer_id); + ScrollbarAnimationControllerForElementId(scroll_node->element_id); if (animation_controller) animation_controller->WillUpdateScroll(); @@ -3302,8 +3362,9 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( DistributeScrollDelta(scroll_state); - active_tree_->SetCurrentlyScrollingNode( - scroll_state->current_native_scrolling_node()); + ScrollNode* current_scrolling_node = + scroll_state->current_native_scrolling_node(); + active_tree_->SetCurrentlyScrollingNode(current_scrolling_node); did_lock_scrolling_layer_ = scroll_state->delta_consumed_for_scroll_sequence(); @@ -3311,6 +3372,8 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( bool did_scroll_y = scroll_state->caused_scroll_y(); bool did_scroll_content = did_scroll_x || did_scroll_y; 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. @@ -3371,6 +3434,7 @@ void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset( if (!changed) return; + ShowScrollbarsForImplScroll(OuterViewportScrollLayer()->element_id()); client_->SetNeedsCommitOnImplThread(); // After applying the synchronous input handler's scroll offset, tell it what // we ended up with. @@ -3409,38 +3473,24 @@ InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { return scroll_status; } -float LayerTreeHostImpl::DeviceSpaceDistanceToLayer( - const gfx::PointF& device_viewport_point, - LayerImpl* layer_impl) { - if (!layer_impl) - return std::numeric_limits<float>::max(); - - gfx::Rect layer_impl_bounds(layer_impl->bounds()); - - gfx::RectF device_viewport_layer_impl_bounds = MathUtil::MapClippedRect( - layer_impl->ScreenSpaceTransform(), gfx::RectF(layer_impl_bounds)); - - return device_viewport_layer_impl_bounds.ManhattanDistanceToPoint( - device_viewport_point); -} - void LayerTreeHostImpl::MouseDown() { ScrollbarAnimationController* animation_controller = - ScrollbarAnimationControllerForId(scroll_layer_id_mouse_currently_over_); + ScrollbarAnimationControllerForElementId( + scroll_element_id_mouse_currently_over_); if (animation_controller) { animation_controller->DidMouseDown(); - scroll_layer_id_mouse_currently_captured_ = - scroll_layer_id_mouse_currently_over_; + scroll_element_id_mouse_currently_captured_ = + scroll_element_id_mouse_currently_over_; } } void LayerTreeHostImpl::MouseUp() { - if (scroll_layer_id_mouse_currently_captured_ != Layer::INVALID_ID) { + if (scroll_element_id_mouse_currently_captured_) { ScrollbarAnimationController* animation_controller = - ScrollbarAnimationControllerForId( - scroll_layer_id_mouse_currently_captured_); + ScrollbarAnimationControllerForElementId( + scroll_element_id_mouse_currently_captured_); - scroll_layer_id_mouse_currently_captured_ = Layer::INVALID_ID; + scroll_element_id_mouse_currently_captured_ = ElementId(); if (animation_controller) animation_controller->DidMouseUp(); @@ -3455,52 +3505,48 @@ void LayerTreeHostImpl::MouseMoveAt(const gfx::Point& viewport_point) { // Check if mouse is over a scrollbar or not. // TODO(sahel): get rid of this extera checking when - // FindScrollLayerForDeviceViewportPoint finds the proper layer for - // scrolling on main thread when mouse is over scrollbar as well. - int new_id = Layer::INVALID_ID; + // FindScrollNodeForDeviceViewportPoint finds the proper node for scrolling on + // the main thread when the mouse is over a scrollbar as well. + ElementId scroll_element_id; if (layer_impl && layer_impl->ToScrollbarLayer()) - new_id = layer_impl->ToScrollbarLayer()->ScrollLayerId(); - if (new_id == Layer::INVALID_ID) { + scroll_element_id = layer_impl->ToScrollbarLayer()->scroll_element_id(); + if (!scroll_element_id) { bool scroll_on_main_thread = false; uint32_t main_thread_scrolling_reasons; - LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint( + auto* scroll_node = FindScrollNodeForDeviceViewportPoint( device_viewport_point, InputHandler::TOUCHSCREEN, layer_impl, &scroll_on_main_thread, &main_thread_scrolling_reasons); + if (scroll_node) + scroll_element_id = scroll_node->element_id; // Scrollbars for the viewport are registered with the outer viewport layer. - if (scroll_layer_impl == InnerViewportScrollLayer()) - scroll_layer_impl = OuterViewportScrollLayer(); - - new_id = scroll_layer_impl ? scroll_layer_impl->id() : Layer::INVALID_ID; + if (InnerViewportScrollLayer() && OuterViewportScrollLayer() && + scroll_element_id == InnerViewportScrollLayer()->element_id()) + scroll_element_id = OuterViewportScrollLayer()->element_id(); } - if (new_id != scroll_layer_id_mouse_currently_over_) { + if (scroll_element_id != scroll_element_id_mouse_currently_over_) { ScrollbarAnimationController* old_animation_controller = - ScrollbarAnimationControllerForId( - scroll_layer_id_mouse_currently_over_); + ScrollbarAnimationControllerForElementId( + scroll_element_id_mouse_currently_over_); if (old_animation_controller) { old_animation_controller->DidMouseLeave(); } - scroll_layer_id_mouse_currently_over_ = new_id; + scroll_element_id_mouse_currently_over_ = scroll_element_id; } ScrollbarAnimationController* new_animation_controller = - ScrollbarAnimationControllerForId(new_id); + ScrollbarAnimationControllerForElementId(scroll_element_id); if (!new_animation_controller) return; - for (ScrollbarLayerImplBase* scrollbar : ScrollbarsFor(new_id)) { - new_animation_controller->DidMouseMoveNear( - scrollbar->orientation(), - DeviceSpaceDistanceToLayer(device_viewport_point, scrollbar) / - active_tree_->device_scale_factor()); - } + new_animation_controller->DidMouseMove(device_viewport_point); } void LayerTreeHostImpl::MouseLeave() { for (auto& pair : scrollbar_animation_controllers_) pair.second->DidMouseLeave(); - scroll_layer_id_mouse_currently_over_ = Layer::INVALID_ID; + scroll_element_id_mouse_currently_over_ = ElementId(); } void LayerTreeHostImpl::PinchGestureBegin() { @@ -3569,8 +3615,9 @@ static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, static void CollectScrollbarUpdates( ScrollAndScaleSet* scroll_info, - std::unordered_map<int, std::unique_ptr<ScrollbarAnimationController>>* - controllers) { + std::unordered_map<ElementId, + std::unique_ptr<ScrollbarAnimationController>, + ElementIdHash>* controllers) { scroll_info->scrollbars.reserve(controllers->size()); for (auto& pair : *controllers) { scroll_info->scrollbars.push_back(LayerTreeHostCommon::ScrollbarsUpdateInfo( @@ -3600,7 +3647,7 @@ std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { } void LayerTreeHostImpl::SetFullViewportDamage() { - SetViewportDamage(gfx::Rect(DrawViewportSize())); + SetViewportDamage(gfx::Rect(DeviceViewport().size())); } bool LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) { @@ -3714,29 +3761,30 @@ std::string LayerTreeHostImpl::LayerTreeAsJson() const { } void LayerTreeHostImpl::RegisterScrollbarAnimationController( - int scroll_layer_id) { - if (settings().scrollbar_animator == LayerTreeSettings::NO_ANIMATOR) - return; - if (ScrollbarAnimationControllerForId(scroll_layer_id)) + ElementId scroll_element_id, + float scrollbar_opacity) { + if (ScrollbarAnimationControllerForElementId(scroll_element_id)) return; - scrollbar_animation_controllers_[scroll_layer_id] = - active_tree_->CreateScrollbarAnimationController(scroll_layer_id); + + scrollbar_animation_controllers_[scroll_element_id] = + active_tree_->CreateScrollbarAnimationController(scroll_element_id, + scrollbar_opacity); } void LayerTreeHostImpl::UnregisterScrollbarAnimationController( - int scroll_layer_id) { - scrollbar_animation_controllers_.erase(scroll_layer_id); + ElementId scroll_element_id) { + scrollbar_animation_controllers_.erase(scroll_element_id); } ScrollbarAnimationController* -LayerTreeHostImpl::ScrollbarAnimationControllerForId( - int scroll_layer_id) const { +LayerTreeHostImpl::ScrollbarAnimationControllerForElementId( + ElementId scroll_element_id) const { // The viewport layers have only one set of scrollbars and their controller // is registered with the outer viewport. if (InnerViewportScrollLayer() && OuterViewportScrollLayer() && - scroll_layer_id == InnerViewportScrollLayer()->id()) - scroll_layer_id = OuterViewportScrollLayer()->id(); - auto i = scrollbar_animation_controllers_.find(scroll_layer_id); + scroll_element_id == InnerViewportScrollLayer()->element_id()) + scroll_element_id = OuterViewportScrollLayer()->element_id(); + auto i = scrollbar_animation_controllers_.find(scroll_element_id); if (i == scrollbar_animation_controllers_.end()) return nullptr; return i->second.get(); @@ -3761,8 +3809,8 @@ void LayerTreeHostImpl::SetNeedsRedrawForScrollbarAnimation() { SetNeedsRedraw(); } -ScrollbarSet LayerTreeHostImpl::ScrollbarsFor(int scroll_layer_id) const { - return active_tree_->ScrollbarsFor(scroll_layer_id); +ScrollbarSet LayerTreeHostImpl::ScrollbarsFor(ElementId id) const { + return active_tree_->ScrollbarsFor(id); } void LayerTreeHostImpl::AddVideoFrameController( @@ -3920,9 +3968,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid, gfx::ColorSpace::CreateSRGB()); if (!scaled) { - AutoLockUIResourceBitmap bitmap_lock(bitmap); - auto* pixels = bitmap_lock.GetPixels(); - resource_provider_->CopyToResource(id, pixels, source_size); + resource_provider_->CopyToResource(id, bitmap.GetPixels(), source_size); } else { // Only support auto-resizing for N32 textures (since this is primarily for // scrollbars). Users of other types need to ensure they are not too big. @@ -3939,10 +3985,9 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid, source_size.width(), source_size.height(), kPremul_SkAlphaType); int row_bytes = source_size.width() * 4; - AutoLockUIResourceBitmap bitmap_lock(bitmap); SkBitmap source_bitmap; source_bitmap.setInfo(info, row_bytes); - source_bitmap.setPixels(const_cast<uint8_t*>(bitmap_lock.GetPixels())); + source_bitmap.setPixels(const_cast<uint8_t*>(bitmap.GetPixels())); // This applies the scale to draw the |bitmap| into |scaled_bitmap|. SkBitmap scaled_bitmap; @@ -3956,7 +4001,6 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid, scaled_canvas.clear(SK_ColorTRANSPARENT); scaled_canvas.drawBitmap(source_bitmap, 0, 0); - SkAutoLockPixels scaled_bitmap_lock(scaled_bitmap); auto* pixels = static_cast<uint8_t*>(scaled_bitmap.getPixels()); resource_provider_->CopyToResource(id, pixels, upload_size); } @@ -4172,6 +4216,7 @@ void LayerTreeHostImpl::SetElementScrollOffsetMutated( const gfx::ScrollOffset& scroll_offset) { if (list_type == ElementListType::ACTIVE) { SetTreeLayerScrollOffsetMutated(element_id, active_tree(), scroll_offset); + ShowScrollbarsForImplScroll(element_id); } else { SetTreeLayerScrollOffsetMutated(element_id, pending_tree(), scroll_offset); SetTreeLayerScrollOffsetMutated(element_id, recycle_tree(), scroll_offset); @@ -4213,12 +4258,6 @@ void LayerTreeHostImpl::ElementIsAnimatingChanged( list_type); property_trees->transform_tree.set_needs_update(true); tree->set_needs_update_draw_properties(); - // TODO(crbug.com/702777): - // was_ever_ready_since_last_transform_animation should not live on - // layers. - if (LayerImpl* layer = tree->LayerByElementId(element_id)) { - layer->set_was_ever_ready_since_last_transform_animation(false); - } } } break; @@ -4324,4 +4363,12 @@ void LayerTreeHostImpl::UpdateScrollSourceInfo(bool is_wheel_scroll) { has_scrolled_by_touch_ = true; } +void LayerTreeHostImpl::ShowScrollbarsForImplScroll(ElementId element_id) { + if (!element_id) + return; + if (ScrollbarAnimationController* animation_controller = + ScrollbarAnimationControllerForElementId(element_id)) + animation_controller->DidScrollUpdate(); +} + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index 0b72dc47333..b8553cb323b 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -16,6 +16,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/sequenced_task_runner.h" #include "base/time/time.h" #include "cc/base/synced_property.h" #include "cc/benchmarks/micro_benchmark_controller_impl.h" @@ -86,7 +87,11 @@ enum class GpuRasterizationStatus { OFF_DEVICE, OFF_VIEWPORT, MSAA_CONTENT, - OFF_CONTENT +}; + +enum class ImplThreadPhase { + IDLE, + INSIDE_IMPL_FRAME, }; // LayerTreeHost->Proxy callback interface. @@ -223,11 +228,11 @@ class CC_EXPORT LayerTreeHostImpl ~FrameData(); void AsValueInto(base::trace_event::TracedValue* value) const; - std::vector<SurfaceId> embedded_surfaces; + std::vector<SurfaceId> activation_dependencies; std::vector<gfx::Rect> occluding_screen_space_rects; std::vector<gfx::Rect> non_occluding_screen_space_rects; RenderPassList render_passes; - const LayerImplList* render_surface_layer_list; + const RenderSurfaceList* render_surface_list; LayerImplList will_draw_layers; bool has_no_damage; bool may_contain_video; @@ -322,20 +327,14 @@ class CC_EXPORT LayerTreeHostImpl size_t SourceAnimationFrameNumberForTesting() const; - void RegisterScrollbarAnimationController(int scroll_layer_id); - void UnregisterScrollbarAnimationController(int scroll_layer_id); - ScrollbarAnimationController* ScrollbarAnimationControllerForId( - int scroll_layer_id) const; + void RegisterScrollbarAnimationController(ElementId scroll_element_id, + float initial_opacity); + void UnregisterScrollbarAnimationController(ElementId scroll_element_id); + ScrollbarAnimationController* ScrollbarAnimationControllerForElementId( + ElementId scroll_element_id) const; DrawMode GetDrawMode() const; - // Viewport size in draw space: this size is in physical pixels and is used - // for draw properties, tilings, quads and render passes. - gfx::Size DrawViewportSize() const; - - // Viewport rect in view space used for tiling prioritization. - const gfx::Rect ViewportRectForTilePriority() const; - // TileManagerClient implementation. void NotifyReadyToActivate() override; void NotifyReadyToDraw() override; @@ -355,7 +354,7 @@ class CC_EXPORT LayerTreeHostImpl base::TimeDelta delay) override; void SetNeedsAnimateForScrollbarAnimation() override; void SetNeedsRedrawForScrollbarAnimation() override; - ScrollbarSet ScrollbarsFor(int scroll_layer_id) const override; + ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const override; void DidChangeScrollbarVisibility() override; // VideoBeginFrameSource implementation. @@ -416,6 +415,7 @@ class CC_EXPORT LayerTreeHostImpl virtual void WillBeginImplFrame(const BeginFrameArgs& args); virtual void DidFinishImplFrame(); + void DidNotProduceFrame(const BeginFrameAck& ack); void DidModifyTilePriorities(); LayerTreeImpl* active_tree() { return active_tree_.get(); } @@ -538,9 +538,13 @@ class CC_EXPORT LayerTreeHostImpl void ScheduleMicroBenchmark(std::unique_ptr<MicroBenchmarkImpl> benchmark); CompositorFrameMetadata MakeCompositorFrameMetadata() const; + // Viewport rectangle and clip in device space. These rects are used to // prioritize raster and determine what is submitted in a CompositorFrame. gfx::Rect DeviceViewport() const; + // Viewport rect to be used for tiling prioritization instead of the + // DeviceViewport(). + const gfx::Rect ViewportRectForTilePriority() const; // When a SwapPromiseMonitor is created on the impl thread, it calls // InsertSwapPromiseMonitor() to register itself with LayerTreeHostImpl. @@ -665,9 +669,6 @@ class CC_EXPORT LayerTreeHostImpl bool AnimateScrollbars(base::TimeTicks monotonic_time); bool AnimateBrowserControls(base::TimeTicks monotonic_time); - void TrackDamageForAllSurfaces( - const LayerImplList& render_surface_layer_list); - void UpdateTileManagerMemoryPolicy(const ManagedMemoryPolicy& policy); // This function should only be called from PrepareToDraw, as DidDrawAllLayers @@ -677,14 +678,12 @@ class CC_EXPORT LayerTreeHostImpl void ClearCurrentlyScrollingNode(); - LayerImpl* FindScrollLayerForDeviceViewportPoint( + ScrollNode* FindScrollNodeForDeviceViewportPoint( const gfx::PointF& device_viewport_point, InputHandler::ScrollInputType type, LayerImpl* layer_hit_by_point, bool* scroll_on_main_thread, uint32_t* main_thread_scrolling_reason) const; - float DeviceSpaceDistanceToLayer(const gfx::PointF& device_viewport_point, - LayerImpl* layer_impl); void StartScrollbarFadeRecursive(LayerImpl* layer); void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy); @@ -713,6 +712,11 @@ class CC_EXPORT LayerTreeHostImpl void UpdateScrollSourceInfo(bool is_wheel_scroll); bool IsScrolledBy(LayerImpl* child, ScrollNode* ancestor); + void ShowScrollbarsForImplScroll(ElementId element_id); + + // Copy any opacity values already in the active tree to the pending + // tree, because the active tree value always takes precedence for scrollbars. + void PushScrollbarOpacitiesFromActiveToPending(); using UIResourceMap = std::unordered_map<UIResourceId, UIResourceData>; UIResourceMap ui_resource_map_; @@ -763,8 +767,8 @@ class CC_EXPORT LayerTreeHostImpl bool did_lock_scrolling_layer_; bool wheel_scrolling_; bool scroll_affects_scroll_handler_; - int scroll_layer_id_mouse_currently_over_; - int scroll_layer_id_mouse_currently_captured_; + ElementId scroll_element_id_mouse_currently_over_; + ElementId scroll_element_id_mouse_currently_captured_; std::vector<std::unique_ptr<SwapPromise>> swap_promises_for_main_thread_scroll_update_; @@ -824,9 +828,11 @@ class CC_EXPORT LayerTreeHostImpl std::unique_ptr<MutatorHost> mutator_host_; std::set<VideoFrameController*> video_frame_controllers_; - // Map from scroll layer ID to scrollbar animation controller. + // Map from scroll element ID to scrollbar animation controller. // There is one animation controller per pair of overlay scrollbars. - std::unordered_map<int, std::unique_ptr<ScrollbarAnimationController>> + std::unordered_map<ElementId, + std::unique_ptr<ScrollbarAnimationController>, + ElementIdHash> scrollbar_animation_controllers_; RenderingStatsInstrumentation* rendering_stats_instrumentation_; @@ -872,6 +878,8 @@ class CC_EXPORT LayerTreeHostImpl bool touchpad_and_wheel_scroll_latching_enabled_; + ImplThreadPhase impl_thread_phase_; + DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl); }; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index a52bdf7996c..e8eba4fd251 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -15,6 +15,7 @@ #include "base/location.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" +#include "base/test/histogram_tester.h" #include "base/threading/thread_task_runner_handle.h" #include "cc/animation/animation_host.h" #include "cc/animation/animation_id_provider.h" @@ -127,6 +128,7 @@ class LayerTreeHostImplTest : public testing::Test, LayerTreeSettings DefaultSettings() { LayerTreeSettings settings; + settings.enable_surface_synchronization = true; settings.minimum_occlusion_tracking_size = gfx::Size(); settings.renderer_settings.texture_id_allocation_chunk_size = 1; settings.renderer_settings.buffer_to_texture_target_map = @@ -305,6 +307,10 @@ class LayerTreeHostImplTest : public testing::Test, 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. @@ -376,9 +382,13 @@ class LayerTreeHostImplTest : public testing::Test, layer_tree_impl->SetRootLayerForTesting(std::move(root)); layer_tree_impl->BuildPropertyTreesForTesting(); - layer_tree_impl->SetViewportLayersFromIds( - Layer::INVALID_ID, kPageScaleLayerId, kInnerViewportScrollLayerId, - kOuterViewportScrollLayerId); + 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); layer_tree_impl->DidBecomeActive(); return layer_tree_impl->InnerViewportScrollLayer(); @@ -754,6 +764,66 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { scroll_delta + scroll_delta2)); } +TEST_F(LayerTreeHostImplTest, ScrollerSizeOfCCScrollingHistogramRecordingTest) { + const gfx::Size content_size(800, 600); + const gfx::Size viewport_size(500, 500); + CreateBasicVirtualViewportLayers(viewport_size, content_size); + + 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); + std::unique_ptr<LayerImpl> child_clip = + LayerImpl::Create(host_impl_->active_tree(), id + 3); + + child_clip->SetBounds(gfx::Size(100, 100)); + + child->SetScrollClipLayer(child_clip->id()); + child->SetElementId(LayerIdToElementIdForTesting(child->id())); + child->SetBounds(gfx::Size(100, 400)); + child->SetPosition(gfx::PointF()); + child->SetDrawsContent(true); + + child_clip->test_properties()->AddChild(std::move(child)); + outer_viewport_scroll_layer->test_properties()->AddChild( + std::move(child_clip)); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + base::HistogramTester histogram_tester; + + // Test touch scroll. + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain, + status.main_thread_scrolling_reasons); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); + host_impl_->ScrollEnd(EndState().get()); + + histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Touch", + 10000, 1); + histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Touch", + 1); + + // Scrolling root layer doesn't add to count. + host_impl_->ScrollBegin(BeginState(gfx::Point(450, 450)).get(), + InputHandler::TOUCHSCREEN); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); + host_impl_->ScrollEnd(EndState().get()); + histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Touch", + 1); + + // Test wheel scroll. + host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get()); + host_impl_->ScrollEnd(EndState().get()); + histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Wheel", + 10000, 1); + histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Wheel", + 1); +} + TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -1041,7 +1111,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithOverlappingNonScrollableLayer) { false, true); scrollbar->SetBounds(scrollbar_size); scrollbar->SetPosition(gfx::PointF(345, 0)); - scrollbar->SetScrollLayerId(scroll->id()); + scrollbar->SetScrollElementId(scroll->element_id()); scrollbar->SetDrawsContent(true); scrollbar->test_properties()->opacity = 1.f; @@ -1113,7 +1183,7 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { false, true); drawn_scrollbar->SetBounds(scrollbar_size); drawn_scrollbar->SetPosition(gfx::PointF(345, 0)); - drawn_scrollbar->SetScrollLayerId(scroll->id()); + drawn_scrollbar->SetScrollElementId(scroll->element_id()); drawn_scrollbar->SetDrawsContent(true); drawn_scrollbar->test_properties()->opacity = 1.f; @@ -1559,7 +1629,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { // Set up the property trees so that UpdateDrawProperties will work in // CommitComplete below. - LayerImplList list; + RenderSurfaceList list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( root, gfx::Size(50, 50), &list); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); @@ -1657,91 +1727,6 @@ class MissingTilesLayer : public LayerImpl { bool has_missing_tiles_; }; -TEST_F(LayerTreeHostImplTest, AnimationMarksLayerNotReady) { - host_impl_->SetViewportSize(gfx::Size(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()->AddChild(std::unique_ptr<MissingTilesLayer>( - new MissingTilesLayer(host_impl_->active_tree(), 2))); - MissingTilesLayer* child = - static_cast<MissingTilesLayer*>(root->test_properties()->children[0]); - child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); - child->SetDrawsContent(true); - - host_impl_->active_tree()->SetElementIdsForTesting(); - - EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation()); - - // Add a translate from 6,7 to 8,9. - TransformOperations start; - start.AppendTranslate(6.f, 7.f, 0.f); - TransformOperations end; - end.AppendTranslate(8.f, 9.f, 0.f); - int animation_id = AddAnimatedTransformToElementWithPlayer( - child->element_id(), timeline(), 4.0, start, end); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - base::TimeTicks now = base::TimeTicks::Now(); - host_impl_->WillBeginImplFrame( - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2, now)); - - host_impl_->ActivateAnimations(); - host_impl_->Animate(); - - EXPECT_FALSE(child->was_ever_ready_since_last_transform_animation()); - - host_impl_->ResetRequiresHighResToDraw(); - - // Child layer has an animating transform but missing tiles. - TestFrameData frame; - DrawResult result = host_impl_->PrepareToDraw(&frame); - EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result); - host_impl_->DidDrawAllLayers(frame); - - child->set_has_missing_tiles(false); - - // Child layer has an animating and no missing tiles. - result = host_impl_->PrepareToDraw(&frame); - EXPECT_EQ(DRAW_SUCCESS, result); - EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation()); - host_impl_->DidDrawAllLayers(frame); - - // Remove the animation. - child->set_has_missing_tiles(true); - RemoveAnimationFromElementWithExistingPlayer(child->element_id(), timeline(), - animation_id); - child->draw_properties().screen_space_transform_is_animating = false; - - // Child layer doesn't have an animation, but was never ready since the last - // time it animated (and has missing tiles). - result = host_impl_->PrepareToDraw(&frame); - EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result); - EXPECT_FALSE(child->was_ever_ready_since_last_transform_animation()); - host_impl_->DidDrawAllLayers(frame); - - child->set_has_missing_tiles(false); - - // Child layer doesn't have an animation and all tiles are ready. - result = host_impl_->PrepareToDraw(&frame); - EXPECT_EQ(DRAW_SUCCESS, result); - EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation()); - host_impl_->DidDrawAllLayers(frame); - - child->set_has_missing_tiles(true); - - // Child layer doesn't have an animation, and was ready at least once since - // the last time it animated. - result = host_impl_->PrepareToDraw(&frame); - EXPECT_EQ(DRAW_SUCCESS, result); - EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation()); - host_impl_->DidDrawAllLayers(frame); -} - TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -2769,7 +2754,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { host_impl_->DidFinishImplFrame(); } -TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByBoundsDelta) { +TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->SetViewportSize(gfx::Size(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); @@ -2782,17 +2767,17 @@ TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByBoundsDelta) { DCHECK(inner_container); EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset()); - inner_container->SetBoundsDelta(gfx::Vector2dF(15.f, 15.f)); - inner_scroll->SetBoundsDelta(gfx::Vector2dF(7.f, 7.f)); + inner_container->SetViewportBoundsDelta(gfx::Vector2dF(15.f, 15.f)); + inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF(7.f, 7.f)); EXPECT_EQ(gfx::ScrollOffset(42, 42), inner_scroll->MaxScrollOffset()); - inner_container->SetBoundsDelta(gfx::Vector2dF()); - inner_scroll->SetBoundsDelta(gfx::Vector2dF()); + inner_container->SetViewportBoundsDelta(gfx::Vector2dF()); + inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF()); inner_scroll->SetBounds(gfx::Size()); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); - inner_scroll->SetBoundsDelta(gfx::Vector2dF(60.f, 60.f)); + inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF(60.f, 60.f)); EXPECT_EQ(gfx::ScrollOffset(10, 10), inner_scroll->MaxScrollOffset()); } @@ -2856,13 +2841,14 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { LayerImpl* scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); LayerImpl* root = host_impl_->active_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollLayerId(scroll->id()); + scrollbar->SetScrollElementId(scroll->element_id()); root->test_properties()->AddChild(std::move(scrollbar)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); + host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain(); DrawFrame(); - // SetScrollLayerId will initialize the scrollbar which will cause it to + // SetScrollElementId will initialize the scrollbar which will cause it to // show and request a redraw. did_request_redraw_ = false; } @@ -2871,8 +2857,6 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { LayerTreeSettings settings = DefaultSettings(); settings.scrollbar_animator = animator; settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); - settings.scrollbar_fade_out_resize_delay = - base::TimeDelta::FromMilliseconds(20); settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); // If no animator is set, scrollbar won't show and no animation is expected. @@ -2882,7 +2866,8 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { base::TimeTicks fake_now = base::TimeTicks::Now(); - if (expecting_animations) { + // Android Overlay Scrollbar does not have a initial show and fade out. + if (animator == LayerTreeSettings::AURA_OVERLAY) { // A task will be posted to fade the initial scrollbar. EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); @@ -2995,8 +2980,8 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { host_impl_->DidFinishImplFrame(); } - // Setting the scroll offset outside a scroll should also cause the - // scrollbar to appear and to schedule a scrollbar animation. + // Setting the scroll offset outside a scroll should not cause the + // scrollbar to appear or schedule a scrollbar animation. if (host_impl_->active_tree() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( @@ -3006,57 +2991,9 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { host_impl_->InnerViewportScrollLayer()->id()); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); - if (expecting_animations) { - EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), - requested_animation_delay_); - EXPECT_FALSE(animation_task_.Equals(base::Closure())); - requested_animation_delay_ = base::TimeDelta(); - animation_task_ = base::Closure(); - } else { - EXPECT_EQ(base::TimeDelta(), requested_animation_delay_); - EXPECT_TRUE(animation_task_.Equals(base::Closure())); - } - - if (expecting_animations) { - // Scrolling should have stopped the animation, so we should not be - // getting redraws. - begin_frame_args = - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 5, fake_now); - host_impl_->WillBeginImplFrame(begin_frame_args); - host_impl_->Animate(); - EXPECT_FALSE(did_request_next_frame_); - did_request_next_frame_ = false; - EXPECT_FALSE(did_request_redraw_); - did_request_redraw_ = false; - host_impl_->DidFinishImplFrame(); - } - - // For Andrdoid, scrollbar animation is not triggered unnecessarily. - // For Aura Overlay Scrollbar, scrollbar appears even if scroll offset did - // not change. - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL); - host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(5, 0)).get()); - EXPECT_FALSE(did_request_next_frame_); - EXPECT_TRUE(did_request_redraw_); - did_request_redraw_ = false; EXPECT_EQ(base::TimeDelta(), requested_animation_delay_); EXPECT_TRUE(animation_task_.Equals(base::Closure())); - host_impl_->ScrollEnd(EndState().get()); - EXPECT_FALSE(did_request_next_frame_); - EXPECT_FALSE(did_request_redraw_); - if (animator == LayerTreeSettings::AURA_OVERLAY) { - EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), - requested_animation_delay_); - EXPECT_FALSE(animation_task_.Equals(base::Closure())); - requested_animation_delay_ = base::TimeDelta(); - animation_task_ = base::Closure(); - } else { - EXPECT_EQ(base::TimeDelta(), requested_animation_delay_); - EXPECT_TRUE(animation_task_.Equals(base::Closure())); - } - // Changing page scale triggers scrollbar animation. host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f); host_impl_->active_tree()->SetPageScaleOnActiveTree(1.1f); @@ -3109,7 +3046,9 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer(); LayerImpl* container = host_impl_->pending_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollLayerId(scroll->id()); + scrollbar->SetScrollElementId(scroll->element_id()); + scrollbar->SetBounds(gfx::Size(10, 100)); + scrollbar->SetPosition(gfx::PointF(90, 0)); container->test_properties()->AddChild(std::move(scrollbar)); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); host_impl_->pending_tree()->BuildPropertyTreesForTesting(); @@ -3125,11 +3064,11 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { active_tree_node->opacity); if (expecting_animations) { - host_impl_->ScrollbarAnimationControllerForId(scroll->id()) - ->DidMouseMoveNear(VERTICAL, 0); + host_impl_->ScrollbarAnimationControllerForElementId(scroll->element_id()) + ->DidMouseMove(gfx::PointF(0, 90)); } else { - EXPECT_EQ(nullptr, - host_impl_->ScrollbarAnimationControllerForId(scroll->id())); + EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( + scroll->element_id())); } host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL); @@ -3149,9 +3088,6 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { EffectNode* pending_tree_node = host_impl_->pending_tree()->property_trees()->effect_tree.Node( pending_scrollbar_layer->effect_tree_index()); - host_impl_->pending_tree() - ->property_trees() - ->always_use_active_tree_opacity_effect_ids.push_back(400); if (expecting_animations) { EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity); EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity()); @@ -3203,14 +3139,17 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) { LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer(); LayerImpl* container = host_impl_->pending_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollLayerId(scroll->id()); + scrollbar->SetScrollElementId(scroll->element_id()); + scrollbar->SetBounds(gfx::Size(10, 100)); + scrollbar->SetPosition(gfx::PointF(90, 0)); container->test_properties()->AddChild(std::move(scrollbar)); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); host_impl_->pending_tree()->BuildPropertyTreesForTesting(); host_impl_->ActivateSyncTree(); ScrollbarAnimationController* scrollbar_controller = - host_impl_->ScrollbarAnimationControllerForId(scroll->id()); + host_impl_->ScrollbarAnimationControllerForElementId( + scroll->element_id()); // Scrollbars will flash shown but we should have a fade out animation // queued. Run it and fade out the scrollbars. @@ -3228,10 +3167,10 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) { } // Move the mouse over the scrollbar region. This should post a delayed fade - // in task. Execute it to show the scrollbars. + // in task. Execute it to fade in the scrollbars. { animation_task_ = base::Closure(); - scrollbar_controller->DidMouseMoveNear(VERTICAL, 0); + scrollbar_controller->DidMouseMove(gfx::PointF(90, 0)); ASSERT_FALSE(animation_task_.Equals(base::Closure())); ASSERT_FALSE(animation_task_.IsCancelled()); } @@ -3284,7 +3223,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) { LayerImpl::Create(host_impl_->active_tree(), child_clip_id); child->SetBounds(inner_viewport_size); - horiz_scrollbar->SetScrollLayerId(root_scroll->id()); + horiz_scrollbar->SetScrollElementId(root_scroll->element_id()); EXPECT_EQ(300, horiz_scrollbar->clip_layer_length()); } @@ -3307,22 +3246,36 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { const int child_scroll_id = 15; CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); + LayerImpl* container = + host_impl_->active_tree()->InnerViewportContainerLayer(); + container->SetBounds(viewport_size); LayerImpl* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - std::unique_ptr<SolidColorScrollbarLayerImpl> vert_1_scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_1_id, - VERTICAL, 5, 5, true, true); - std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_1_scrollbar = - SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), horiz_1_id, HORIZONTAL, 5, 5, true, true); - std::unique_ptr<SolidColorScrollbarLayerImpl> vert_2_scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_2_id, - VERTICAL, 5, 5, true, true); - std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_2_scrollbar = - SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), horiz_2_id, HORIZONTAL, 5, 5, true, true); + + container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( + host_impl_->active_tree(), vert_1_id, VERTICAL, 5, 5, true, true)); + SolidColorScrollbarLayerImpl* 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)); + SolidColorScrollbarLayerImpl* 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)); + SolidColorScrollbarLayerImpl* 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)); + SolidColorScrollbarLayerImpl* 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(content_size); @@ -3332,75 +3285,75 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { LayerImpl* child_ptr = child.get(); LayerImpl* child_clip_ptr = child_clip.get(); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + // Check scrollbar registration on the viewport layers. - EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); - EXPECT_EQ(nullptr, - host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); - vert_1_scrollbar->SetScrollLayerId(root_scroll->id()); - EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); - horiz_1_scrollbar->SetScrollLayerId(root_scroll->id()); - EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); - - // Changing one of the viewport layers should result in a scrollbar animation - // update. + EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); + EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( + root_scroll->element_id())); + vert_1_scrollbar->SetScrollElementId(root_scroll->element_id()); + EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForElementId( + root_scroll->element_id())); + horiz_1_scrollbar->SetScrollElementId(root_scroll->element_id()); + EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForElementId( + root_scroll->element_id())); + + // Scrolling the viewport should result in a scrollbar animation update. animation_task_ = base::Closure(); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBoundsDelta( - gfx::Vector2dF(10, 10)); - EXPECT_FALSE(animation_task_.Equals(base::Closure())); - animation_task_ = base::Closure(); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetCurrentScrollOffset( - gfx::ScrollOffset(10, 10)); - EXPECT_FALSE(animation_task_.Equals(base::Closure())); - animation_task_ = base::Closure(); - host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset( - gfx::ScrollOffset(10, 10)); + host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(10, 10)).get()); + host_impl_->ScrollEnd(EndState().get()); EXPECT_FALSE(animation_task_.Equals(base::Closure())); animation_task_ = base::Closure(); // Check scrollbar registration on a sublayer. child->SetScrollClipLayer(child_clip->id()); child->SetElementId(LayerIdToElementIdForTesting(child->id())); + ElementId child_scroll_element_id = child->element_id(); child_clip->test_properties()->AddChild(std::move(child)); root_scroll->test_properties()->AddChild(std::move(child_clip)); - EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); - EXPECT_EQ(nullptr, - host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); - vert_2_scrollbar->SetScrollLayerId(child_scroll_id); - EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); - horiz_2_scrollbar->SetScrollLayerId(child_scroll_id); - EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); + EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); + EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( + child_scroll_element_id)); + vert_2_scrollbar->SetScrollElementId(child_scroll_element_id); + EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForElementId( + child_scroll_element_id)); + horiz_2_scrollbar->SetScrollElementId(child_scroll_element_id); + EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForElementId( + child_scroll_element_id)); // Changing one of the child layers should result in a scrollbar animation // update. animation_task_ = base::Closure(); child_clip_ptr->SetBounds(gfx::Size(200, 200)); - EXPECT_FALSE(animation_task_.Equals(base::Closure())); - animation_task_ = base::Closure(); - child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(10, 10)); + child_ptr->set_needs_show_scrollbars(true); + host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain(); EXPECT_FALSE(animation_task_.Equals(base::Closure())); animation_task_ = base::Closure(); // Check scrollbar unregistration. - vert_1_scrollbar.reset(); - EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); - horiz_1_scrollbar.reset(); - EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); - EXPECT_EQ(nullptr, - host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); - - EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); - vert_2_scrollbar.reset(); - EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); - horiz_2_scrollbar.reset(); - EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); - EXPECT_EQ(nullptr, - host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); + 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()); + 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); + 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( @@ -3435,8 +3388,8 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( // The scrollbar is on the left side. std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 6, - VERTICAL, 5, 5, true, true); - scrollbar->SetScrollLayerId(root_scroll->id()); + VERTICAL, 15, 0, true, true); + scrollbar->SetScrollElementId(root_scroll->element_id()); scrollbar->SetDrawsContent(true); scrollbar->SetBounds(scrollbar_size); scrollbar->SetTouchEventHandlerRegion(gfx::Rect(scrollbar_size)); @@ -3451,32 +3404,46 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( host_impl_->active_tree()->UpdateDrawProperties(false); ScrollbarAnimationController* scrollbar_animation_controller = - host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()); + host_impl_->ScrollbarAnimationControllerForElementId( + root_scroll->element_id()); + + const float kMouseMoveDistanceToTriggerFadeIn = + ScrollbarAnimationController::kMouseMoveDistanceToTriggerFadeIn; - const float kMouseDistanceToTriggerAnimation = + const float kMouseMoveDistanceToTriggerExpand = SingleScrollbarAnimationControllerThinning:: - kDefaultMouseMoveDistanceToTriggerAnimation; + kMouseMoveDistanceToTriggerExpand; host_impl_->MouseMoveAt( - gfx::Point(15 + kMouseDistanceToTriggerAnimation * 2, 1)); + gfx::Point(15 + kMouseMoveDistanceToTriggerFadeIn, 1)); EXPECT_FALSE(scrollbar_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_FALSE( + scrollbar_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); host_impl_->MouseMoveAt( - gfx::Point(15 + kMouseDistanceToTriggerAnimation - 1, 50)); + gfx::Point(15 + kMouseMoveDistanceToTriggerExpand - 1, 10)); EXPECT_TRUE(scrollbar_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_TRUE( + scrollbar_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); host_impl_->MouseMoveAt( - gfx::Point(15 + kMouseDistanceToTriggerAnimation, 100)); + gfx::Point(15 + kMouseMoveDistanceToTriggerFadeIn, 100)); EXPECT_FALSE(scrollbar_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_FALSE( + scrollbar_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); did_request_redraw_ = false; - EXPECT_FALSE(scrollbar_animation_controller->MouseIsOverScrollbar(VERTICAL)); - host_impl_->MouseMoveAt(gfx::Point(10, 100)); - EXPECT_TRUE(scrollbar_animation_controller->MouseIsOverScrollbar(VERTICAL)); - host_impl_->MouseMoveAt(gfx::Point(10, 120)); - EXPECT_TRUE(scrollbar_animation_controller->MouseIsOverScrollbar(VERTICAL)); + EXPECT_FALSE( + scrollbar_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + host_impl_->MouseMoveAt(gfx::Point(10, 10)); + EXPECT_TRUE( + scrollbar_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + host_impl_->MouseMoveAt(gfx::Point(10, 0)); + EXPECT_TRUE( + scrollbar_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); host_impl_->MouseMoveAt(gfx::Point(150, 120)); - EXPECT_FALSE(scrollbar_animation_controller->MouseIsOverScrollbar(VERTICAL)); + EXPECT_FALSE( + scrollbar_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); } TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) { @@ -3487,24 +3454,33 @@ TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) { SetupMouseMoveAtWithDeviceScale(2.f); } -// This test verifies that only SurfaceLayers in the viewport are included -// in CompositorFrameMetadata's |embedded_surfaces|. -TEST_F(LayerTreeHostImplTest, EmbeddedSurfacesInMetadata) { +// This test verifies that only SurfaceLayers in the viewport and have fallbacks +// that are different are included in CompositorFrameMetadata's +// |activation_dependencies|. +TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->SetViewportSize(gfx::Size(50, 50)); LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - std::vector<SurfaceId> children = {MakeSurfaceId(FrameSinkId(1, 1), 1), - MakeSurfaceId(FrameSinkId(2, 2), 2), - MakeSurfaceId(FrameSinkId(3, 3), 3)}; - for (size_t i = 0; i < children.size(); ++i) { + std::vector<SurfaceId> primary_surfaces = { + MakeSurfaceId(FrameSinkId(1, 1), 1), MakeSurfaceId(FrameSinkId(2, 2), 2), + MakeSurfaceId(FrameSinkId(3, 3), 3)}; + + std::vector<SurfaceId> fallback_surfaces = { + MakeSurfaceId(FrameSinkId(4, 4), 1), MakeSurfaceId(FrameSinkId(4, 4), 2), + MakeSurfaceId(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->SetPosition(gfx::PointF(25.f * i, 0.f)); child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); child->SetPrimarySurfaceInfo( - SurfaceInfo(children[i], 1.f /* device_scale_factor */, + SurfaceInfo(primary_surfaces[i], 1.f /* device_scale_factor */, + gfx::Size(10, 10) /* size_in_pixels */)); + child->SetFallbackSurfaceInfo( + SurfaceInfo(fallback_surfaces[i], 1.f /* device_scale_factor */, gfx::Size(10, 10) /* size_in_pixels */)); root->test_properties()->AddChild(std::move(child)); } @@ -3517,11 +3493,13 @@ TEST_F(LayerTreeHostImplTest, EmbeddedSurfacesInMetadata) { host_impl_->compositor_frame_sink()); const CompositorFrameMetadata& metadata = fake_compositor_frame_sink->last_sent_frame()->metadata; - EXPECT_THAT(metadata.embedded_surfaces, - testing::UnorderedElementsAre(children[0], children[1])); + EXPECT_THAT( + metadata.activation_dependencies, + testing::UnorderedElementsAre(primary_surfaces[0], primary_surfaces[1])); EXPECT_THAT( metadata.referenced_surfaces, - testing::UnorderedElementsAre(children[0], children[1], children[2])); + testing::UnorderedElementsAre(fallback_surfaces[0], fallback_surfaces[1], + fallback_surfaces[2])); } TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { @@ -3879,8 +3857,8 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { EXPECT_TRUE(layer1->did_draw_called()); EXPECT_TRUE(layer2->did_draw_called()); - EXPECT_NE(root->GetRenderSurface(), layer1->GetRenderSurface()); - EXPECT_TRUE(layer1->GetRenderSurface()); + EXPECT_NE(GetRenderSurface(root), GetRenderSurface(layer1)); + EXPECT_TRUE(GetRenderSurface(layer1)); } class MissingTextureAnimatingLayer : public DidDrawCheckLayer { @@ -4251,6 +4229,8 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { outer_scroll->test_properties()->is_container_for_fixed_position_layers = true; + int inner_viewport_container_layer_id = root_clip->id(); + int outer_viewport_container_layer_id = outer_clip->id(); int inner_viewport_scroll_layer_id = root->id(); int outer_viewport_scroll_layer_id = outer_scroll->id(); int page_scale_layer_id = page_scale->id(); @@ -4261,9 +4241,13 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { root_clip->test_properties()->AddChild(std::move(page_scale)); tree_impl->SetRootLayerForTesting(std::move(root_clip)); - tree_impl->SetViewportLayersFromIds(Layer::INVALID_ID, page_scale_layer_id, - inner_viewport_scroll_layer_id, - outer_viewport_scroll_layer_id); + LayerTreeImpl::ViewportLayerIds viewport_ids; + viewport_ids.page_scale = page_scale_layer_id; + viewport_ids.inner_viewport_container = inner_viewport_container_layer_id; + viewport_ids.outer_viewport_container = outer_viewport_container_layer_id; + viewport_ids.inner_viewport_scroll = inner_viewport_scroll_layer_id; + viewport_ids.outer_viewport_scroll = outer_viewport_scroll_layer_id; + tree_impl->SetViewportLayersFromIds(viewport_ids); tree_impl->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(inner_viewport_size); @@ -4373,12 +4357,10 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta); host_impl_->browser_controls_manager()->ScrollEnd(); - LayerImpl* inner_viewport_scroll_layer = - host_impl_->active_tree()->InnerViewportScrollLayer(); - DCHECK(inner_viewport_scroll_layer); host_impl_->ScrollEnd(EndState().get()); + auto* property_trees = host_impl_->active_tree()->property_trees(); EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(), - inner_viewport_scroll_layer->FixedContainerSizeDelta().y()); + property_trees->inner_viewport_container_bounds_delta().y()); } // In this test, the outer viewport is initially unscrollable. We test that a @@ -4479,9 +4461,6 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, FixedContainerDelta) { host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); float page_scale = 1.5f; - LayerImpl* outer_viewport_scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - // Zoom in, since the fixed container is the outer viewport, the delta should // not be scaled. host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f); @@ -4499,8 +4478,10 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, FixedContainerDelta) { host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta); EXPECT_FLOAT_EQ(top_controls_height_ - top_controls_scroll_delta.y(), host_impl_->browser_controls_manager()->ContentTopOffset()); + + auto* property_trees = host_impl_->active_tree()->property_trees(); EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(), - outer_viewport_scroll_layer->FixedContainerSizeDelta().y()); + property_trees->outer_viewport_container_bounds_delta().y()); host_impl_->ScrollEnd(EndState().get()); // Scroll past the maximum extent. The delta shouldn't be greater than the @@ -4511,7 +4492,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, FixedContainerDelta) { host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height_), - outer_viewport_scroll_layer->FixedContainerSizeDelta()); + property_trees->outer_viewport_container_bounds_delta()); host_impl_->ScrollEnd(EndState().get()); // Scroll in the direction to make the browser controls show. @@ -4521,7 +4502,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, FixedContainerDelta) { host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_VECTOR_EQ( gfx::Vector2dF(0, top_controls_height_ - top_controls_scroll_delta.y()), - outer_viewport_scroll_layer->FixedContainerSizeDelta()); + property_trees->outer_viewport_container_bounds_delta()); host_impl_->browser_controls_manager()->ScrollEnd(); } @@ -4755,7 +4736,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // 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->bounds_delta()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), + inner_clip_ptr->ViewportBoundsDelta()); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); host_impl_->DidChangeBrowserControlsPosition(); @@ -4764,7 +4746,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->bounds_delta()); + 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()); } @@ -5608,7 +5591,8 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(gfx::ScrollOffset(0, 30), grand_child_layer->CurrentScrollOffset()); + // Should have started scrolling. + EXPECT_NE(gfx::ScrollOffset(0, 30), grand_child_layer->CurrentScrollOffset()); host_impl_->DidFinishImplFrame(); begin_frame_args.frame_time = @@ -5656,13 +5640,16 @@ 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 kPageScaleLayerId = 1; + const int kViewportClipLayerId = 2; + const int kViewportScrollLayerId = 3; std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_->active_tree(), 1); + LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); std::unique_ptr<LayerImpl> root_clip = - LayerImpl::Create(host_impl_->active_tree(), 2); + LayerImpl::Create(host_impl_->active_tree(), kViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scrolling = - CreateScrollableLayer(3, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scrolling = CreateScrollableLayer( + kViewportScrollLayerId, surface_size, root_clip.get()); root_scrolling->test_properties()->is_container_for_fixed_position_layers = true; @@ -5681,8 +5668,11 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { root_ptr->test_properties()->AddChild(std::move(root_clip)); host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 3, - Layer::INVALID_ID); + 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()->DidBecomeActive(); host_impl_->SetViewportSize(viewport_size); @@ -5801,17 +5791,20 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { // should be applied to one of its ancestors if possible. gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); + const int kPageScaleLayerId = 4; + const int kViewportClipLayerId = 1; + const int kViewportScrollLayerId = 2; std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_->active_tree(), 4); + LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), 3); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scroll = - CreateScrollableLayer(1, content_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer( + kViewportClipLayerId, content_size, root_clip.get()); // Make 'root' the clip layer for child: since they have the same sizes the // child will have zero max_scroll_offset and scrolls will bubble. - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, content_size, root_scroll.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer( + kViewportScrollLayerId, content_size, root_scroll.get()); child->test_properties()->is_container_for_fixed_position_layers = true; root_scroll->SetBounds(content_size); @@ -5821,8 +5814,11 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { root_ptr->test_properties()->AddChild(std::move(root_clip)); host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 2, - Layer::INVALID_ID); + 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(); host_impl_->active_tree()->DidBecomeActive(); @@ -5849,17 +5845,22 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { } TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { + const int kPageScaleLayerId = 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(), 1); + LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); std::unique_ptr<LayerImpl> inner_clip = - LayerImpl::Create(host_impl_->active_tree(), 2); - std::unique_ptr<LayerImpl> inner_scroll = - CreateScrollableLayer(3, surface_size, inner_clip.get()); + LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); + std::unique_ptr<LayerImpl> inner_scroll = CreateScrollableLayer( + kInnerViewportScrollLayerId, surface_size, inner_clip.get()); std::unique_ptr<LayerImpl> outer_clip = - LayerImpl::Create(host_impl_->active_tree(), 7); - std::unique_ptr<LayerImpl> outer_scroll = - CreateScrollableLayer(8, surface_size, outer_clip.get()); + LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId); + std::unique_ptr<LayerImpl> outer_scroll = CreateScrollableLayer( + kOuterViewportScrollLayerId, surface_size, outer_clip.get()); inner_clip->test_properties()->force_render_surface = true; inner_scroll->test_properties()->is_container_for_fixed_position_layers = true; @@ -5870,8 +5871,13 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { 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)); - host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 3, - 8); + 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; + host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); @@ -5881,17 +5887,22 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { // synchronization. DrawFrame(); + const int kPageScaleLayerId2 = 4; + 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(), 5); - std::unique_ptr<LayerImpl> inner_scroll2 = - CreateScrollableLayer(6, surface_size, inner_clip2.get()); + LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId2); + std::unique_ptr<LayerImpl> inner_scroll2 = CreateScrollableLayer( + kInnerViewportScrollLayerId2, surface_size, inner_clip2.get()); std::unique_ptr<LayerImpl> outer_clip2 = - LayerImpl::Create(host_impl_->active_tree(), 9); - std::unique_ptr<LayerImpl> outer_scroll2 = - CreateScrollableLayer(10, surface_size, outer_clip2.get()); + LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId2); + std::unique_ptr<LayerImpl> outer_scroll2 = CreateScrollableLayer( + kOuterViewportScrollLayerId2, surface_size, outer_clip2.get()); inner_scroll2->test_properties()->is_container_for_fixed_position_layers = true; outer_scroll2->test_properties()->is_container_for_fixed_position_layers = @@ -5903,8 +5914,13 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { root_ptr2->test_properties()->AddChild(std::move(inner_clip2)); host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr2)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 6, - 10); + LayerTreeImpl::ViewportLayerIds viewport_ids2; + viewport_ids2.page_scale = kPageScaleLayerId2; + 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(); // Scrolling should still work even though we did not draw yet. @@ -6471,12 +6487,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { // overscroll does not accumulate. InputHandlerScrollResult scroll_result; 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(), 4); + LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root = - CreateScrollableLayer(1, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> root = CreateScrollableLayer( + kInnerViewportScrollLayerId, surface_size, root_clip.get()); std::unique_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size, root_clip.get()); @@ -6486,8 +6504,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); - host_impl_->active_tree()->SetViewportLayersFromIds( - Layer::INVALID_ID, Layer::INVALID_ID, root->id(), Layer::INVALID_ID); + 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)); @@ -6890,9 +6910,11 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) { clip->test_properties()->AddChild(std::move(scroll)); content_layer->test_properties()->AddChild(std::move(clip)); - layer_tree_impl->SetViewportLayersFromIds( - Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(), - inner_scroll_layer->id(), scroll_layer->id()); + 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(); } @@ -7025,9 +7047,14 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) { clip2->test_properties()->AddChild(std::move(scroll2)); content_layer->test_properties()->AddChild(std::move(clip2)); - layer_tree_impl->SetViewportLayersFromIds( - Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(), - inner_scroll_layer->id(), outer_scroll_layer->id()); + 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()); @@ -7219,12 +7246,16 @@ class BlendStateCheckLayer : public LayerImpl { gfx::Size(1, 1), false, false); test_blending_draw_quad->visible_rect = quad_visible_rect_; EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending()); - EXPECT_EQ(has_render_surface_, !!GetRenderSurface()); + EXPECT_EQ(has_render_surface_, + GetRenderSurface(this) != GetRenderSurface(comparison_layer_)); } - void SetExpectation(bool blend, bool has_render_surface) { + void SetExpectation(bool blend, + bool has_render_surface, + LayerImpl* comparison_layer) { blend_ = blend; has_render_surface_ = has_render_surface; + comparison_layer_ = comparison_layer; quads_appended_ = false; } @@ -7243,6 +7274,7 @@ class BlendStateCheckLayer : public LayerImpl { : LayerImpl(tree_impl, id), blend_(false), has_render_surface_(false), + comparison_layer_(nullptr), quads_appended_(false), quad_rect_(5, 5, 5, 5), quad_visible_rect_(5, 5, 5, 5), @@ -7258,6 +7290,7 @@ class BlendStateCheckLayer : public LayerImpl { bool blend_; bool has_render_surface_; + LayerImpl* comparison_layer_; bool quads_appended_; gfx::Rect quad_rect_; gfx::Rect opaque_content_rect_; @@ -7286,7 +7319,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Opaque layer, drawn without blending. layer1->SetContentsOpaque(true); - layer1->SetExpectation(false, false); + layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -7296,7 +7329,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Layer with translucent content and painting, so drawn with blending. layer1->SetContentsOpaque(false); - layer1->SetExpectation(true, 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(); @@ -7309,7 +7342,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->test_properties()->opacity = 0.5f; layer1->NoteLayerPropertyChanged(); - layer1->SetExpectation(true, false); + layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -7321,7 +7354,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->test_properties()->opacity = 0.5f; layer1->NoteLayerPropertyChanged(); - layer1->SetExpectation(true, false); + layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -7339,12 +7372,12 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->test_properties()->opacity = 1.f; layer1->NoteLayerPropertyChanged(); - layer1->SetExpectation(false, false); + layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); layer2->test_properties()->opacity = 1.f; layer2->NoteLayerPropertyChanged(); - layer2->SetExpectation(false, false); + 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(); @@ -7357,9 +7390,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Parent layer with translucent content, drawn with blending. // Child layer with opaque content, drawn without blending. layer1->SetContentsOpaque(false); - layer1->SetExpectation(true, false); + layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - layer2->SetExpectation(false, false); + 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(); @@ -7373,9 +7406,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // blending. // Child layer with opaque content, drawn without blending. layer1->SetContentsOpaque(true); - layer1->SetExpectation(false, false); + layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - layer2->SetExpectation(false, false); + layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -7393,9 +7426,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->test_properties()->opacity = 0.5f; layer1->NoteLayerPropertyChanged(); layer1->test_properties()->force_render_surface = true; - layer1->SetExpectation(false, true); + layer1->SetExpectation(false, true, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - layer2->SetExpectation(false, false); + layer2->SetExpectation(false, false, layer1); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -7410,12 +7443,12 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->test_properties()->opacity = 1.f; layer1->NoteLayerPropertyChanged(); - layer1->SetExpectation(false, false); + layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); layer2->test_properties()->opacity = 0.5f; layer2->NoteLayerPropertyChanged(); - layer2->SetExpectation(true, false); + layer2->SetExpectation(true, false, layer1); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -7428,12 +7461,12 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->test_properties()->opacity = 1.f; layer1->NoteLayerPropertyChanged(); - layer1->SetExpectation(false, false); + layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(false); layer2->test_properties()->opacity = 1.f; layer2->NoteLayerPropertyChanged(); - layer2->SetExpectation(true, false); + layer2->SetExpectation(true, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -7447,12 +7480,12 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->test_properties()->opacity = 1.f; layer1->NoteLayerPropertyChanged(); - layer1->SetExpectation(false, false); + layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); layer2->test_properties()->opacity = 1.f; layer2->NoteLayerPropertyChanged(); - layer2->SetExpectation(false, false); + layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); host_impl_->active_tree()->BuildPropertyTreesForTesting(); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -7466,7 +7499,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); - layer1->SetExpectation(true, 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(); @@ -7480,7 +7513,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); - layer1->SetExpectation(true, 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(); @@ -7494,7 +7527,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); - layer1->SetExpectation(true, 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(); @@ -7509,7 +7542,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); - layer1->SetExpectation(false, false); + 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(); @@ -7599,7 +7632,8 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { ->root_layer_for_testing() ->test_properties() ->children[0]); - child_->SetExpectation(false, false); + child_->SetExpectation(false, false, + host_impl_->active_tree()->root_layer_for_testing()); child_->SetContentsOpaque(true); } @@ -7982,7 +8016,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - EXPECT_EQ(1u, frame.render_surface_layer_list->size()); + EXPECT_EQ(1u, frame.render_surface_list->size()); EXPECT_EQ(1u, frame.render_passes.size()); host_impl_->DidDrawAllLayers(frame); } @@ -8293,7 +8327,7 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) { host_impl_->active_tree()->BuildPropertyTreesForTesting(); // Draw a frame. In the first frame, the entire viewport should be damaged. - gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); + gfx::Rect full_frame_damage(host_impl_->DeviceViewport().size()); DrawFrameAndTestDamage(full_frame_damage); // The second frame has damage that doesn't touch the child layer. Its quads @@ -8339,7 +8373,7 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { LayerImpl* scrolling_layer = scoped_scrolling_layer.get(); root->test_properties()->AddChild(std::move(scoped_scrolling_layer)); - gfx::Size content_layer_bounds(100000, 100); + gfx::Size content_layer_bounds(100001, 100); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(content_layer_bounds)); @@ -8367,7 +8401,7 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { bool update_lcd_text = false; host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); - ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size()); + ASSERT_EQ(1u, host_impl_->active_tree()->GetRenderSurfaceList().size()); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -8757,11 +8791,12 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { TestContextProvider::Create(); FrameSinkClient test_client_(context_provider); + constexpr bool synchronous_composite = true; + constexpr bool disable_display_vsync = false; auto compositor_frame_sink = base::MakeUnique<TestCompositorFrameSink>( context_provider, TestContextProvider::CreateWorker(), nullptr, nullptr, RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(), - true /* synchronous_composite */, - false /* force_disable_reclaim_resources */); + synchronous_composite, disable_display_vsync); compositor_frame_sink->SetClient(&test_client_); CreateHostImpl(DefaultSettings(), std::move(compositor_frame_sink)); @@ -8798,14 +8833,17 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { // bubble). gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); + const int kPageScaleLayerId = 4; + const int kInnerViewportClipLayerId = 3; + const int kInnerViewportScrollLayerId = 1; std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_->active_tree(), 4); + LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); std::unique_ptr<LayerImpl> root_clip = - LayerImpl::Create(host_impl_->active_tree(), 3); + LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scroll = - CreateScrollableLayer(1, content_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer( + kInnerViewportScrollLayerId, content_size, root_clip.get()); root_scroll->test_properties()->is_container_for_fixed_position_layers = true; std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size, root_clip.get()); @@ -8817,8 +8855,11 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { host_impl_->SetViewportSize(surface_size); host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 1, - Layer::INVALID_ID); + LayerTreeImpl::ViewportLayerIds viewport_ids; + viewport_ids.page_scale = kPageScaleLayerId; + viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; + viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; + host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); @@ -9122,7 +9163,7 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { new LatencyInfoSwapPromise(latency_info)); host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise)); - gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); + gfx::Rect full_frame_damage(host_impl_->DeviceViewport().size()); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); EXPECT_TRUE(host_impl_->DrawLayers(&frame)); @@ -9166,7 +9207,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { // Trigger a draw-swap sequence. host_impl_->SetNeedsRedraw(); - gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); + gfx::Rect full_frame_damage(host_impl_->DeviceViewport().size()); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); EXPECT_TRUE(host_impl_->DrawLayers(&frame)); @@ -9825,6 +9866,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); LayerImpl* scroll_layer = nullptr; + LayerImpl* clip_layer = nullptr; // Initialization: Add a child scrolling layer to the outer scroll layer and // set its scroll layer as the outer viewport. This simulates setting a @@ -9841,12 +9883,18 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, 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)); - layer_tree_impl->SetViewportLayersFromIds( - Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(), - inner_scroll->id(), scroll_layer->id()); + 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(); } @@ -9935,9 +9983,13 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { inner_clip->test_properties()->force_render_surface = true; layer_tree_impl->SetRootLayerForTesting(std::move(inner_clip)); - layer_tree_impl->SetViewportLayersFromIds( - Layer::INVALID_ID, kPageScaleLayerId, kInnerViewportScrollLayerId, - kOuterViewportScrollLayerId); + 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(); @@ -10746,7 +10798,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); + EXPECT_NE(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); host_impl_->DidFinishImplFrame(); begin_frame_args.frame_time = @@ -10887,13 +10939,15 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) { begin_frame_args.sequence_number++; host_impl_->WillBeginImplFrame(begin_frame_args); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); + EXPECT_NE(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); host_impl_->DidFinishImplFrame(); - // Second tick after 50ms, animation should be half way done since - // the duration due to delay is 100ms. - begin_frame_args.frame_time = - start_time + base::TimeDelta::FromMilliseconds(50); + // Second tick after 50ms, animation should be half way done since the + // duration due to delay is 100ms. Subtract off the frame interval since we + // progress a full frame on the first tick. + base::TimeTicks half_way_time = start_time - begin_frame_args.interval + + base::TimeDelta::FromMilliseconds(50); + begin_frame_args.frame_time = half_way_time; begin_frame_args.sequence_number++; host_impl_->WillBeginImplFrame(begin_frame_args); host_impl_->UpdateAnimationState(true); @@ -10950,7 +11004,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { EXPECT_TRUE(GetImplAnimationHost()->HasAnyAnimationTargetingProperty( scrolling_layer->element_id(), TargetProperty::SCROLL_OFFSET)); - EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); + EXPECT_NE(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); host_impl_->DidFinishImplFrame(); begin_frame_args.frame_time = @@ -11019,7 +11073,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); + EXPECT_NE(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); host_impl_->DidFinishImplFrame(); begin_frame_args.frame_time = @@ -11255,7 +11309,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) { host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); + EXPECT_NE(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); host_impl_->DidFinishImplFrame(); begin_frame_args.frame_time = @@ -11706,13 +11760,22 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusTrigger) { // Tests that SetContentIsSuitableForGpuRasterization behaves as expected. TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSuitability) { + std::unique_ptr<TestWebGraphicsContext3D> context_with_msaa = + TestWebGraphicsContext3D::Create(); + context_with_msaa->SetMaxSamples(4); + context_with_msaa->set_gpu_rasterization(true); + LayerTreeSettings msaaSettings = DefaultSettings(); + msaaSettings.gpu_rasterization_msaa_sample_count = 4; + EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeCompositorFrameSink::Create3d( + std::move(context_with_msaa)))); + // Set initial state, before varying GPU rasterization suitability. host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentIsSuitableForGpuRasterization(false); host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_TRUE(host_impl_->use_msaa()); // Toggle suitability on. host_impl_->SetContentIsSuitableForGpuRasterization(true); @@ -11724,10 +11787,10 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSuitability) { // And off. host_impl_->SetContentIsSuitableForGpuRasterization(false); host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); - EXPECT_FALSE(host_impl_->use_msaa()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + EXPECT_TRUE(host_impl_->use_msaa()); } // Tests that SetDeviceScaleFactor correctly impacts GPU rasterization. @@ -11746,9 +11809,8 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) { host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentIsSuitableForGpuRasterization(false); host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, - host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); // Set device scale factor to 2, which lowers the required MSAA samples from // 8 to 4. @@ -11762,9 +11824,8 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) { // Set device scale factor back to 1. host_impl_->active_tree()->SetDeviceScaleFactor(1.0f); host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, - host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_FALSE(host_impl_->use_msaa()); } @@ -11850,40 +11911,14 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { EXPECT_TRUE(host_impl_->use_gpu_rasterization()); // Ensure that with the msaa_is_slow cap we don't raster unsuitable content - // with msaa. + // with msaa (we'll still use GPU raster, though). CreateHostImplWithMsaaIsSlow(true); host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentIsSuitableForGpuRasterization(false); host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, - host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); -} - -// A mock output surface which lets us detect calls to ForceReclaimResources. -class MockReclaimResourcesCompositorFrameSink : public FakeCompositorFrameSink { - public: - MockReclaimResourcesCompositorFrameSink() - : FakeCompositorFrameSink(TestContextProvider::Create(), - TestContextProvider::CreateWorker()) {} - - MOCK_METHOD0(ForceReclaimResources, void()); -}; - -// Display::Draw (and the planned Display Scheduler) currently rely on resources -// being reclaimed to block drawing between BeginCommit / Swap. This test -// ensures that BeginCommit triggers ForceReclaimResources. See -// crbug.com/489515. -TEST_F(LayerTreeHostImplTest, BeginCommitReclaimsResources) { - auto compositor_frame_sink = - base::MakeUnique<MockReclaimResourcesCompositorFrameSink>(); - // Hold an unowned pointer to the output surface to use for mock expectations. - MockReclaimResourcesCompositorFrameSink* mock_compositor_frame_sink = - compositor_frame_sink.get(); - - CreateHostImpl(DefaultSettings(), std::move(compositor_frame_sink)); - EXPECT_CALL(*mock_compositor_frame_sink, ForceReclaimResources()).Times(1); - host_impl_->BeginCommit(); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + EXPECT_FALSE(host_impl_->use_msaa()); } TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { @@ -12093,12 +12128,14 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( // scrollbar_1 on root scroll. std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_1 = SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_1_id, VERTICAL, 5, 5, true, - true); - scrollbar_1->SetScrollLayerId(root_scroll->id()); + scrollbar_1_id, VERTICAL, 15, 0, + true, true); + scrollbar_1->SetScrollElementId(root_scroll->element_id()); scrollbar_1->SetDrawsContent(true); scrollbar_1->SetBounds(scrollbar_size_1); scrollbar_1->SetTouchEventHandlerRegion(gfx::Rect(scrollbar_size_1)); + scrollbar_1->SetCurrentPos(0); + scrollbar_1->SetPosition(gfx::PointF(0, 0)); host_impl_->active_tree() ->InnerViewportContainerLayer() ->test_properties() @@ -12111,46 +12148,81 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( host_impl_->active_tree()->UpdateDrawProperties(false); ScrollbarAnimationController* scrollbar_1_animation_controller = - host_impl_->ScrollbarAnimationControllerForId(root_scroll->id()); + host_impl_->ScrollbarAnimationControllerForElementId( + root_scroll->element_id()); EXPECT_TRUE(scrollbar_1_animation_controller); - const float kMouseDistanceToTriggerAnimation = + const float kMouseMoveDistanceToTriggerFadeIn = + ScrollbarAnimationController::kMouseMoveDistanceToTriggerFadeIn; + + const float kMouseMoveDistanceToTriggerExpand = SingleScrollbarAnimationControllerThinning:: - kDefaultMouseMoveDistanceToTriggerAnimation; + kMouseMoveDistanceToTriggerExpand; // Mouse moves close to the scrollbar, goes over the scrollbar, and // moves back to where it was. host_impl_->MouseMoveAt( - gfx::Point(15 + kMouseDistanceToTriggerAnimation, 150)); + gfx::Point(15 + kMouseMoveDistanceToTriggerFadeIn, 0)); EXPECT_FALSE( scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); EXPECT_FALSE( - scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_FALSE( + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + + host_impl_->MouseMoveAt( + gfx::Point(15 + kMouseMoveDistanceToTriggerExpand, 0)); + EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_FALSE( + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_FALSE( + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + host_impl_->MouseMoveAt( - gfx::Point(14 + kMouseDistanceToTriggerAnimation, 150)); + gfx::Point(14 + kMouseMoveDistanceToTriggerExpand, 0)); EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_TRUE( + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); EXPECT_FALSE( - scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); - host_impl_->MouseMoveAt(gfx::Point(10, 150)); + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + + host_impl_->MouseMoveAt(gfx::Point(10, 0)); EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); - EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); + EXPECT_TRUE( + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_TRUE( + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + host_impl_->MouseMoveAt( - gfx::Point(14 + kMouseDistanceToTriggerAnimation, 150)); + gfx::Point(14 + kMouseMoveDistanceToTriggerExpand, 0)); EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_TRUE( + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); EXPECT_FALSE( - scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + host_impl_->MouseMoveAt( - gfx::Point(15 + kMouseDistanceToTriggerAnimation, 150)); + gfx::Point(15 + kMouseMoveDistanceToTriggerExpand, 0)); + EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_FALSE( + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_FALSE( + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + + host_impl_->MouseMoveAt( + gfx::Point(15 + kMouseMoveDistanceToTriggerFadeIn, 0)); EXPECT_FALSE( scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); EXPECT_FALSE( - scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_FALSE( + 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, 5, 5, true, - true); + scrollbar_2_id, VERTICAL, 15, 0, + true, true); std::unique_ptr<LayerImpl> child_clip = LayerImpl::Create(host_impl_->active_tree(), child_clip_id); std::unique_ptr<LayerImpl> child = @@ -12160,15 +12232,18 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( child->SetDrawsContent(true); child->SetScrollClipLayer(child_clip_id); child->SetElementId(LayerIdToElementIdForTesting(child->id())); + ElementId child_element_id = child->element_id(); if (main_thread_scrolling) { child->set_main_thread_scrolling_reasons( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); } - scrollbar_2->SetScrollLayerId(child_scroll_id); + scrollbar_2->SetScrollElementId(child_element_id); scrollbar_2->SetDrawsContent(true); scrollbar_2->SetBounds(scrollbar_size_2); + scrollbar_2->SetCurrentPos(0); + scrollbar_2->SetPosition(gfx::PointF(0, 0)); child->test_properties()->AddChild(std::move(scrollbar_2)); child_clip->test_properties()->AddChild(std::move(child)); @@ -12178,50 +12253,70 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( host_impl_->active_tree()->DidBecomeActive(); ScrollbarAnimationController* scrollbar_2_animation_controller = - host_impl_->ScrollbarAnimationControllerForId(child_scroll_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 // scrollbar_1, goes over scrollbar_1. - host_impl_->MouseMoveAt(gfx::Point(60, 150)); + host_impl_->MouseMoveAt(gfx::Point(60, 60)); EXPECT_FALSE( scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); EXPECT_FALSE( - scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_FALSE( + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); EXPECT_TRUE(scrollbar_2_animation_controller->MouseIsNearScrollbar(VERTICAL)); - EXPECT_TRUE(scrollbar_2_animation_controller->MouseIsOverScrollbar(VERTICAL)); + EXPECT_TRUE( + scrollbar_2_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_TRUE( + scrollbar_2_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + host_impl_->MouseMoveAt( - gfx::Point(64 + kMouseDistanceToTriggerAnimation, 150)); + gfx::Point(64 + kMouseMoveDistanceToTriggerExpand, 50)); EXPECT_FALSE( scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); EXPECT_FALSE( - scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_FALSE( + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); EXPECT_TRUE(scrollbar_2_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_TRUE( + scrollbar_2_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); EXPECT_FALSE( - scrollbar_2_animation_controller->MouseIsOverScrollbar(VERTICAL)); + scrollbar_2_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); host_impl_->MouseMoveAt( - gfx::Point(14 + kMouseDistanceToTriggerAnimation, 150)); + gfx::Point(14 + kMouseMoveDistanceToTriggerExpand, 0)); EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); + EXPECT_TRUE( + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); EXPECT_FALSE( - scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); EXPECT_FALSE( scrollbar_2_animation_controller->MouseIsNearScrollbar(VERTICAL)); EXPECT_FALSE( - scrollbar_2_animation_controller->MouseIsOverScrollbar(VERTICAL)); - host_impl_->MouseMoveAt(gfx::Point(10, 150)); + scrollbar_2_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_FALSE( + scrollbar_2_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); + host_impl_->MouseMoveAt(gfx::Point(10, 0)); EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsNearScrollbar(VERTICAL)); - EXPECT_TRUE(scrollbar_1_animation_controller->MouseIsOverScrollbar(VERTICAL)); + EXPECT_TRUE( + scrollbar_1_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_TRUE( + scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); EXPECT_FALSE( scrollbar_2_animation_controller->MouseIsNearScrollbar(VERTICAL)); EXPECT_FALSE( - scrollbar_2_animation_controller->MouseIsOverScrollbar(VERTICAL)); + scrollbar_2_animation_controller->MouseIsNearScrollbarThumb(VERTICAL)); + EXPECT_FALSE( + scrollbar_2_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); // Capture scrollbar_1, then move mouse to scrollbar_2's layer, should post an // event to fade out scrollbar_1. + scrollbar_1_animation_controller->DidScrollUpdate(); animation_task_ = base::Closure(); host_impl_->MouseDown(); - host_impl_->MouseMoveAt(gfx::Point(100, 150)); + host_impl_->MouseMoveAt(gfx::Point(60, 50)); host_impl_->MouseUp(); EXPECT_FALSE(animation_task_.Equals(base::Closure())); @@ -12239,17 +12334,17 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( // scrollbar_2_animation_controller, then mouse up should not cause crash. host_impl_->MouseMoveAt(gfx::Point(40, 150)); host_impl_->MouseDown(); - host_impl_->UnregisterScrollbarAnimationController(root_scroll->id()); + host_impl_->UnregisterScrollbarAnimationController(root_scroll->element_id()); host_impl_->MouseUp(); } TEST_F(LayerTreeHostImplTest, - LayerTreeHostImplTestScrollbarStatesInMainThreadScorlling) { + LayerTreeHostImplTestScrollbarStatesInMainThreadScrolling) { SetupMouseMoveAtTestScrollbarStates(true); } TEST_F(LayerTreeHostImplTest, - LayerTreeHostImplTestScrollbarStatesInNotMainThreadScorlling) { + LayerTreeHostImplTestScrollbarStatesInNotMainThreadScrolling) { SetupMouseMoveAtTestScrollbarStates(false); } @@ -12263,9 +12358,8 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { std::unique_ptr<FakeRecordingSource> recording_source = FakeRecordingSource::CreateFilledRecordingSource(layer_size); - recording_source->SetGenerateDiscardableImagesMetadata(true); - sk_sp<SkImage> checkerable_image = - CreateDiscardableImage(gfx::Size(500, 500)); + PaintImage checkerable_image = PaintImage( + PaintImage::GetNextId(), CreateDiscardableImage(gfx::Size(500, 500))); recording_source->add_draw_image(checkerable_image, gfx::Point(0, 0)); SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67); @@ -12325,9 +12419,22 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { EXPECT_FALSE(tile->HasRasterTask()); } Region expected_invalidation( - raster_source->GetRectForImage(checkerable_image->uniqueID())); + raster_source->GetRectForImage(checkerable_image.stable_id())); EXPECT_EQ(expected_invalidation, *(root->GetPendingInvalidation())); } +TEST_F(LayerTreeHostImplTest, RasterColorSpaceNoColorCorrection) { + LayerTreeSettings settings = DefaultSettings(); + CreateHostImpl(settings, CreateCompositorFrameSink()); + EXPECT_FALSE(host_impl_->GetRasterColorSpace().IsValid()); +} + +TEST_F(LayerTreeHostImplTest, RasterColorSpace) { + LayerTreeSettings settings = DefaultSettings(); + settings.enable_color_correct_rasterization = true; + CreateHostImpl(settings, CreateCompositorFrameSink()); + EXPECT_EQ(host_impl_->GetRasterColorSpace(), gfx::ColorSpace::CreateSRGB()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc index ff17af70317..7649a527fa2 100644 --- a/chromium/cc/trees/layer_tree_host_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_perftest.cc @@ -23,6 +23,7 @@ #include "cc/test/layer_tree_json_parser.h" #include "cc/test/layer_tree_test.h" #include "cc/test/paths.h" +#include "cc/test/test_compositor_frame_sink.h" #include "cc/trees/layer_tree_impl.h" #include "testing/perf/perf_test.h" @@ -45,12 +46,18 @@ class LayerTreeHostPerfTest : public LayerTreeTest { measure_commit_cost_(false) { } - void InitializeSettings(LayerTreeSettings* settings) override { - // LayerTreeTests give the Display's BeginFrameSource directly to the - // LayerTreeHost like we do in the Browser process via - // TestDelegatingOutputSurface, so setting disable_display_vsync here - // unthrottles both the DisplayScheduler and the Scheduler. - settings->renderer_settings.disable_display_vsync = true; + std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { + constexpr bool disable_display_vsync = true; + bool synchronous_composite = + !HasImplThread() && + !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; + return base::MakeUnique<TestCompositorFrameSink>( + compositor_context_provider, std::move(worker_context_provider), + shared_bitmap_manager(), gpu_memory_buffer_manager(), + layer_tree_host()->GetSettings().renderer_settings, + ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync); } void BeginTest() override { @@ -149,13 +156,25 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { }; // Simulates a tab switcher scene with two stacks of 10 tabs each. -TEST_F(LayerTreeHostPerfTestJsonReader, TenTenSingleThread) { +// Timed out on Android: http://crbug.com/723821 +#if defined(OS_ANDROID) +#define MAYBE_TenTenSingleThread DISABLED_TenTenSingleThread +#else +#define MAYBE_TenTenSingleThread TenTenSingleThread +#endif +TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenSingleThread) { SetTestName("10_10_single_thread"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::SINGLE_THREADED); } -TEST_F(LayerTreeHostPerfTestJsonReader, TenTenThreaded) { +// Timed out on Android: http://crbug.com/723821 +#if defined(OS_ANDROID) +#define MAYBE_TenTenThreaded DISABLED_TenTenThreaded +#else +#define MAYBE_TenTenThreaded TenTenThreaded +#endif +TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenThreaded) { SetTestName("10_10_threaded_impl_side"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::THREADED); @@ -211,7 +230,8 @@ TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenSingleThread) { RunTest(CompositorMode::SINGLE_THREADED); } -TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenThreaded) { +// Timed out on Android: http://crbug.com/723821 +TEST_F(LayerTreeHostPerfTestLeafInvalidates, MAYBE_TenTenThreaded) { SetTestName("10_10_threaded_impl_side_leaf_invalidates"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::THREADED); @@ -242,13 +262,26 @@ class ScrollingLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader { scoped_refptr<Layer> scrollable_; }; -TEST_F(ScrollingLayerTreePerfTest, LongScrollablePageSingleThread) { +// Timed out on Android: http://crbug.com/723821 +#if defined(OS_ANDROID) +#define MAYBE_LongScrollablePageSingleThread \ + DISABLED_LongScrollablePageSingleThread +#else +#define MAYBE_LongScrollablePageSingleThread LongScrollablePageSingleThread +#endif +TEST_F(ScrollingLayerTreePerfTest, MAYBE_LongScrollablePageSingleThread) { SetTestName("long_scrollable_page"); ReadTestFile("long_scrollable_page"); RunTest(CompositorMode::SINGLE_THREADED); } -TEST_F(ScrollingLayerTreePerfTest, LongScrollablePageThreaded) { +// Timed out on Android: http://crbug.com/723821 +#if defined(OS_ANDROID) +#define MAYBE_LongScrollablePageThreaded DISABLED_LongScrollablePageThreaded +#else +#define MAYBE_LongScrollablePageThreaded LongScrollablePageThreaded +#endif +TEST_F(ScrollingLayerTreePerfTest, MAYBE_LongScrollablePageThreaded) { SetTestName("long_scrollable_page_threaded_impl_side"); ReadTestFile("long_scrollable_page"); RunTest(CompositorMode::THREADED); @@ -343,7 +376,13 @@ TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUIThreaded) { } // Simulates a page with several large, transformed and animated layers. -TEST_F(LayerTreeHostPerfTestJsonReader, HeavyPageThreaded) { +// Timed out on Android: http://crbug.com/723821 +#if defined(OS_ANDROID) +#define MAYBE_HeavyPageThreaded DISABLED_HeavyPageThreaded +#else +#define MAYBE_HeavyPageThreaded HeavyPageThreaded +#endif +TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_HeavyPageThreaded) { begin_frame_driven_drawing_ = true; measure_commit_cost_ = true; SetTestName("heavy_page"); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc index 05f94594ae4..656d2922e02 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc @@ -6,6 +6,7 @@ #include "cc/layers/picture_image_layer.h" #include "cc/layers/solid_color_layer.h" +#include "cc/paint/paint_image.h" #include "cc/test/layer_tree_pixel_resource_test.h" #include "cc/test/pixel_comparator.h" #include "third_party/skia/include/core/SkImage.h" @@ -145,7 +146,8 @@ class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest { scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create(); layer->SetIsDrawable(true); layer->SetBounds(gfx::Size(width, height)); - layer->SetImage(backing_store->makeImageSnapshot()); + layer->SetImage(PaintImage(PaintImage::GetNextId(), + backing_store->makeImageSnapshot())); return layer; } @@ -167,7 +169,8 @@ class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest { bounds.width() - kMaskOffset * 2, bounds.height() - kMaskOffset * 2), paint); - mask->SetImage(surface->makeImageSnapshot()); + mask->SetImage( + PaintImage(PaintImage::GetNextId(), surface->makeImageSnapshot())); layer->SetMaskLayer(mask.get()); } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc index eed99f6a625..1d1d70b2cdd 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -11,7 +11,9 @@ #include "cc/layers/solid_color_layer.h" #include "cc/paint/drawing_display_item.h" #include "cc/paint/paint_flags.h" +#include "cc/paint/paint_image.h" #include "cc/paint/paint_recorder.h" +#include "cc/test/fake_picture_layer.h" #include "cc/test/layer_tree_pixel_resource_test.h" #include "cc/test/pixel_comparator.h" #include "cc/test/solid_color_content_layer_client.h" @@ -40,7 +42,7 @@ class MaskContentLayerClient : public ContentLayerClient { PaintingControlSetting picture_control) override { PaintRecorder recorder; PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(bounds_))); + recorder.beginRecording(gfx::RectToSkRect(PaintableRegion())); PaintFlags flags; flags.setStyle(PaintFlags::kStroke_Style); @@ -60,7 +62,8 @@ class MaskContentLayerClient : public ContentLayerClient { auto display_list = make_scoped_refptr(new DisplayItemList); display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( - PaintableRegion(), recorder.finishRecordingAsPicture()); + PaintableRegion(), recorder.finishRecordingAsPicture(), + gfx::RectToSkRect(PaintableRegion())); display_list->Finalize(); return display_list; @@ -71,8 +74,8 @@ class MaskContentLayerClient : public ContentLayerClient { }; TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder( gfx::Rect(25, 25, 50, 50), kCSSGreen, 1, SK_ColorBLACK); @@ -83,7 +86,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) { scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK); + mask->SetLayerMaskType(mask_type_); green->SetMaskLayer(mask.get()); RunPixelResourceTest(background, @@ -91,14 +94,14 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) { } TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); gfx::Size mask_bounds(50, 50); scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create(); mask->SetIsDrawable(true); - mask->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK); + mask->SetLayerMaskType(mask_type_); mask->SetBounds(mask_bounds); sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(200, 200); @@ -108,8 +111,9 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { scoped_refptr<DisplayItemList> mask_display_list = client.PaintContentsToDisplayList( ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); - mask_display_list->Raster(canvas, nullptr); - mask->SetImage(surface->makeImageSnapshot()); + mask_display_list->Raster(canvas); + mask->SetImage( + PaintImage(PaintImage::GetNextId(), surface->makeImageSnapshot())); scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder( gfx::Rect(25, 25, 50, 50), kCSSGreen, 1, SK_ColorBLACK); @@ -121,8 +125,8 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { } TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); // Clip to the top half of the green layer. scoped_refptr<Layer> clip = Layer::Create(); @@ -140,7 +144,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK); + mask->SetLayerMaskType(mask_type_); green->SetMaskLayer(mask.get()); RunPixelResourceTest( @@ -148,6 +152,63 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { base::FilePath(FILE_PATH_LITERAL("mask_of_clipped_layer.png"))); } +TEST_P(LayerTreeHostMasksPixelTest, MaskOfLargerLayer) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder( + gfx::Rect(0, 0, 100, 100), kCSSGreen, 1, SK_ColorBLACK); + background->AddChild(green); + + gfx::Size mask_bounds(50, 50); + MaskContentLayerClient client(mask_bounds); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + mask->SetBounds(mask_bounds); + mask->SetIsDrawable(true); + mask->SetLayerMaskType(mask_type_); + green->SetMaskLayer(mask.get()); + + if (raster_buffer_provider_type_ == RASTER_BUFFER_PROVIDER_TYPE_BITMAP) { + // Bitmap produces a sharper (but equivalent sized) mask. + float percentage_pixels_large_error = 40.0f; + float percentage_pixels_small_error = 0.0f; + float average_error_allowed_in_bad_pixels = 65.0f; + int large_error_allowed = 120; + int small_error_allowed = 0; + pixel_comparator_.reset(new FuzzyPixelComparator( + true, // discard_alpha + percentage_pixels_large_error, percentage_pixels_small_error, + average_error_allowed_in_bad_pixels, large_error_allowed, + small_error_allowed)); + } + + RunPixelResourceTest( + background, + base::FilePath(FILE_PATH_LITERAL("mask_of_larger_layer.png"))); +} + +TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayerNonExactTextureSize) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder( + gfx::Rect(0, 0, 100, 100), kCSSGreen, 1, SK_ColorBLACK); + background->AddChild(green); + + gfx::Size mask_bounds(100, 100); + MaskContentLayerClient client(mask_bounds); + 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.get()); + + RunPixelResourceTest(background, + base::FilePath(FILE_PATH_LITERAL( + "mask_with_non_exact_texture_size.png"))); +} + class CheckerContentLayerClient : public ContentLayerClient { public: CheckerContentLayerClient(const gfx::Size& bounds, @@ -162,7 +223,7 @@ class CheckerContentLayerClient : public ContentLayerClient { PaintingControlSetting picture_control) override { PaintRecorder recorder; PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(bounds_))); + recorder.beginRecording(gfx::RectToSkRect(PaintableRegion())); PaintFlags flags; flags.setStyle(PaintFlags::kStroke_Style); @@ -181,7 +242,8 @@ class CheckerContentLayerClient : public ContentLayerClient { auto display_list = make_scoped_refptr(new DisplayItemList); display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( - PaintableRegion(), recorder.finishRecordingAsPicture()); + PaintableRegion(), recorder.finishRecordingAsPicture(), + gfx::RectToSkRect(PaintableRegion())); display_list->Finalize(); return display_list; @@ -205,7 +267,7 @@ class CircleContentLayerClient : public ContentLayerClient { PaintingControlSetting picture_control) override { PaintRecorder recorder; PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(bounds_))); + recorder.beginRecording(gfx::RectToSkRect(PaintableRegion())); PaintFlags flags; flags.setStyle(PaintFlags::kFill_Style); @@ -216,7 +278,8 @@ class CircleContentLayerClient : public ContentLayerClient { auto display_list = make_scoped_refptr(new DisplayItemList); display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( - PaintableRegion(), recorder.finishRecordingAsPicture()); + PaintableRegion(), recorder.finishRecordingAsPicture(), + gfx::RectToSkRect(PaintableRegion())); display_list->Finalize(); return display_list; @@ -229,16 +292,20 @@ class CircleContentLayerClient : public ContentLayerClient { using LayerTreeHostMasksForBackgroundFiltersPixelTest = ParameterizedPixelResourceTest; -INSTANTIATE_TEST_CASE_P(PixelResourceTest, - LayerTreeHostMasksForBackgroundFiltersPixelTest, - ::testing::Values(SOFTWARE, - GL_GPU_RASTER_2D_DRAW, - GL_ONE_COPY_2D_STAGING_2D_DRAW, - GL_ONE_COPY_RECT_STAGING_2D_DRAW, - GL_ONE_COPY_EXTERNAL_STAGING_2D_DRAW, - GL_ZERO_COPY_2D_DRAW, - GL_ZERO_COPY_RECT_DRAW, - GL_ZERO_COPY_EXTERNAL_DRAW)); +INSTANTIATE_TEST_CASE_P( + PixelResourceTest, + LayerTreeHostMasksForBackgroundFiltersPixelTest, + ::testing::Combine( + ::testing::Values(SOFTWARE, + GL_GPU_RASTER_2D_DRAW, + GL_ONE_COPY_2D_STAGING_2D_DRAW, + GL_ONE_COPY_RECT_STAGING_2D_DRAW, + GL_ONE_COPY_EXTERNAL_STAGING_2D_DRAW, + GL_ZERO_COPY_2D_DRAW, + GL_ZERO_COPY_RECT_DRAW, + GL_ZERO_COPY_EXTERNAL_DRAW), + ::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK, + Layer::LayerMaskType::MULTI_TEXTURE_MASK))); TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest, MaskOfLayerWithBackgroundFilter) { @@ -265,7 +332,7 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest, scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK); + mask->SetLayerMaskType(mask_type_); blur->SetMaskLayer(mask.get()); float percentage_pixels_large_error = 2.5f; // 2.5%, ~250px / (100*100) @@ -316,7 +383,7 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest, scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK); + mask->SetLayerMaskType(mask_type_); picture_horizontal->SetMaskLayer(mask.get()); float percentage_pixels_large_error = 0.04f; // 0.04%, ~6px / (128*128) diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc index 9e6c405beb3..93d29ad071b 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc @@ -88,7 +88,7 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, NoScale) { auto scrollbar = base::MakeUnique<PaintedScrollbar>(); scoped_refptr<PaintedScrollbarLayer> layer = - PaintedScrollbarLayer::Create(std::move(scrollbar), Layer::INVALID_ID); + PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); layer->SetBounds(gfx::Size(200, 200)); background->AddChild(layer); @@ -107,7 +107,7 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, DeviceScaleFactor) { auto scrollbar = base::MakeUnique<PaintedScrollbar>(); scoped_refptr<PaintedScrollbarLayer> layer = - PaintedScrollbarLayer::Create(std::move(scrollbar), Layer::INVALID_ID); + PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); layer->SetBounds(gfx::Size(100, 100)); background->AddChild(layer); @@ -122,7 +122,7 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, TransformScale) { auto scrollbar = base::MakeUnique<PaintedScrollbar>(); scoped_refptr<PaintedScrollbarLayer> layer = - PaintedScrollbarLayer::Create(std::move(scrollbar), Layer::INVALID_ID); + PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); layer->SetBounds(gfx::Size(100, 100)); background->AddChild(layer); @@ -144,7 +144,7 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, HugeTransformScale) { auto scrollbar = base::MakeUnique<PaintedScrollbar>(); scrollbar->set_paint_scale(1); scoped_refptr<PaintedScrollbarLayer> layer = - PaintedScrollbarLayer::Create(std::move(scrollbar), Layer::INVALID_ID); + PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); layer->SetBounds(gfx::Size(10, 400)); background->AddChild(layer); @@ -239,8 +239,7 @@ TEST_F(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledUp) { auto scrollbar = base::MakeUnique<PaintedOverlayScrollbar>(); scoped_refptr<PaintedOverlayScrollbarLayer> layer = - PaintedOverlayScrollbarLayer::Create(std::move(scrollbar), - Layer::INVALID_ID); + PaintedOverlayScrollbarLayer::Create(std::move(scrollbar)); scrollbar_layer_id_ = layer->id(); thickness_scale_ = 5.f; @@ -264,8 +263,7 @@ TEST_F(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledDown) { auto scrollbar = base::MakeUnique<PaintedOverlayScrollbar>(); scoped_refptr<PaintedOverlayScrollbarLayer> layer = - PaintedOverlayScrollbarLayer::Create(std::move(scrollbar), - Layer::INVALID_ID); + PaintedOverlayScrollbarLayer::Create(std::move(scrollbar)); scrollbar_layer_id_ = layer->id(); thickness_scale_ = 0.4f; diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc index d6145d577c8..e2fc6d64670 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -113,7 +113,7 @@ class BlueYellowClient : public ContentLayerClient { PaintRecorder recorder; PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(size_))); + recorder.beginRecording(gfx::RectToSkRect(PaintableRegion())); gfx::Rect top(0, 0, size_.width(), size_.height() / 2); gfx::Rect bottom(0, size_.height() / 2, size_.width(), size_.height() / 2); @@ -129,7 +129,8 @@ class BlueYellowClient : public ContentLayerClient { canvas->drawRect(gfx::RectToSkRect(yellow_rect), flags); display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( - PaintableRegion(), recorder.finishRecordingAsPicture()); + PaintableRegion(), recorder.finishRecordingAsPicture(), + gfx::RectToSkRect(PaintableRegion())); display_list->Finalize(); return display_list; } @@ -157,11 +158,17 @@ class LayerTreeHostTilesTestPartialInvalidation void DidCommitAndDrawFrame() override { switch (layer_tree_host()->SourceFrameNumber()) { case 1: - // We have done one frame, so the layer's content has been rastered. - // Now we change the picture behind it to record something completely - // different, but we give a smaller invalidation rect. The layer should - // only re-raster the stuff in the rect. If it doesn't do partial raster - // it would re-raster the whole thing instead. + // We have done one frame, but the resource may not be available for + // partial raster yet. Force a second frame. + picture_layer_->SetNeedsDisplayRect(gfx::Rect(50, 50, 100, 100)); + break; + case 2: + // We have done two frames, so the layer's content has been rastered + // twice and the first frame's resource is available for partial + // raster. Now we change the picture behind it to record something + // completely different, but we give a smaller invalidation rect. The + // layer should only re-raster the stuff in the rect. If it doesn't do + // partial raster it would re-raster the whole thing instead. client_.set_blue_top(false); Finish(); picture_layer_->SetNeedsDisplayRect(gfx::Rect(50, 50, 100, 100)); @@ -203,30 +210,15 @@ TEST_F(LayerTreeHostTilesTestPartialInvalidation, base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png"))); } -// crbug.com/707711 -#if defined(OS_LINUX) -#define MAYBE_PartialRaster_MultiThread_OneCopy \ - DISABLED_PartialRaster_MultiThread_OneCopy -#else -#define MAYBE_PartialRaster_MultiThread_OneCopy \ - PartialRaster_MultiThread_OneCopy -#endif TEST_F(LayerTreeHostTilesTestPartialInvalidation, - MAYBE_PartialRaster_MultiThread_OneCopy) { + PartialRaster_MultiThread_OneCopy) { RunRasterPixelTest( true, PARTIAL_ONE_COPY, picture_layer_, base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png"))); } -// crbug.com/707711 -#if defined(OS_LINUX) -#define MAYBE_FullRaster_MultiThread_OneCopy \ - DISABLED_FullRaster_MultiThread_OneCopy -#else -#define MAYBE_FullRaster_MultiThread_OneCopy FullRaster_MultiThread_OneCopy -#endif TEST_F(LayerTreeHostTilesTestPartialInvalidation, - MAYBE_FullRaster_MultiThread_OneCopy) { + FullRaster_MultiThread_OneCopy) { RunRasterPixelTest( true, FULL_ONE_COPY, picture_layer_, base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png"))); diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index 2e7457a49aa..9a657f521e4 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -46,6 +46,7 @@ #include "cc/test/fake_scoped_ui_resource.h" #include "cc/test/fake_video_frame_provider.h" #include "cc/test/geometry_test_utils.h" +#include "cc/test/layer_test_common.h" #include "cc/test/layer_tree_test.h" #include "cc/test/push_properties_counting_layer.h" #include "cc/test/push_properties_counting_layer_impl.h" @@ -1043,29 +1044,29 @@ class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest { LayerImpl* child_impl = impl->active_tree()->LayerById(child_->id()); switch (impl->active_tree()->source_frame_number()) { case 0: - EXPECT_TRUE(root_impl->GetRenderSurface()->AncestorPropertyChanged()); - EXPECT_TRUE(child_impl->GetRenderSurface()->AncestorPropertyChanged()); + EXPECT_TRUE(GetRenderSurface(root_impl)->AncestorPropertyChanged()); + EXPECT_TRUE(GetRenderSurface(child_impl)->AncestorPropertyChanged()); PostSetNeedsCommitToMainThread(); break; case 1: - EXPECT_FALSE(root_impl->GetRenderSurface()->AncestorPropertyChanged()); - EXPECT_FALSE(child_impl->GetRenderSurface()->AncestorPropertyChanged()); + EXPECT_FALSE(GetRenderSurface(root_impl)->AncestorPropertyChanged()); + EXPECT_FALSE(GetRenderSurface(child_impl)->AncestorPropertyChanged()); PostSetNeedsCommitToMainThread(); break; case 2: - EXPECT_TRUE(root_impl->GetRenderSurface()->AncestorPropertyChanged()); - EXPECT_TRUE(child_impl->GetRenderSurface()->AncestorPropertyChanged()); + EXPECT_TRUE(GetRenderSurface(root_impl)->AncestorPropertyChanged()); + EXPECT_TRUE(GetRenderSurface(child_impl)->AncestorPropertyChanged()); PostSetNeedsCommitToMainThread(); break; case 3: - EXPECT_FALSE(root_impl->GetRenderSurface()->AncestorPropertyChanged()); - EXPECT_TRUE(child_impl->GetRenderSurface()->AncestorPropertyChanged()); + EXPECT_FALSE(GetRenderSurface(root_impl)->AncestorPropertyChanged()); + EXPECT_TRUE(GetRenderSurface(child_impl)->AncestorPropertyChanged()); EndTest(); PostSetNeedsCommitToMainThread(); break; case 4: - EXPECT_FALSE(root_impl->GetRenderSurface()->AncestorPropertyChanged()); - EXPECT_FALSE(child_impl->GetRenderSurface()->AncestorPropertyChanged()); + EXPECT_FALSE(GetRenderSurface(root_impl)->AncestorPropertyChanged()); + EXPECT_FALSE(GetRenderSurface(child_impl)->AncestorPropertyChanged()); EndTest(); break; } @@ -1179,6 +1180,227 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { SINGLE_THREAD_TEST_F(LayerTreeHostTestPropertyTreesChangedSync); +// Simple base class for tests that just need to mutate the layer tree +// host and observe results without any impl thread, multi-layer, or +// multi-frame antics. +class LayerTreeHostTestLayerListsTest : public LayerTreeHostTest { + public: + explicit LayerTreeHostTestLayerListsTest(bool use_layer_lists) + : use_layer_lists_(use_layer_lists) {} + + protected: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->use_layer_lists = use_layer_lists_; + } + + void SetupTree() override { + root_ = Layer::Create(); + layer_tree_host()->SetRootLayer(root_); + LayerTreeHostTest::SetupTree(); + } + + void AfterTest() override {} + + scoped_refptr<Layer> root_; + + private: + bool use_layer_lists_; +}; + +class LayerTreeHostTestAnimationOpacityMutatedNotUsingLayerLists + : public LayerTreeHostTestLayerListsTest { + public: + LayerTreeHostTestAnimationOpacityMutatedNotUsingLayerLists() + : LayerTreeHostTestLayerListsTest(false) {} + + protected: + void BeginTest() override { + EXPECT_EQ(1.0f, root_->opacity()); + layer_tree_host()->SetElementOpacityMutated(root_->element_id(), + ElementListType::ACTIVE, 0.3f); + // When not using layer lists, opacity is stored on the layer. + EXPECT_EQ(0.3f, root_->opacity()); + EndTest(); + } +}; + +SINGLE_THREAD_TEST_F( + LayerTreeHostTestAnimationOpacityMutatedNotUsingLayerLists); + +class LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists + : public LayerTreeHostTestLayerListsTest { + public: + LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists() + : LayerTreeHostTestLayerListsTest(true) {} + + protected: + void BeginTest() override { + // Insert a dummy effect node to observe its mutation. This would + // normally have been created by PaintArtifactCompositor. + int effect_node_id = + layer_tree_host()->property_trees()->effect_tree.Insert( + EffectNode(), EffectTree::kInvalidNodeId); + layer_tree_host() + ->property_trees() + ->element_id_to_effect_node_index[root_->element_id()] = effect_node_id; + + EXPECT_EQ(1.0f, root_->opacity()); + EXPECT_EQ(1.0f, + layer_tree_host() + ->property_trees() + ->effect_tree.FindNodeFromElementId(root_->element_id()) + ->opacity); + + layer_tree_host()->SetElementOpacityMutated(root_->element_id(), + ElementListType::ACTIVE, 0.3f); + + // When using layer lists, we don't have to store the opacity on the layer. + EXPECT_EQ(1.0f, root_->opacity()); + // The opacity should have been set directly on the effect node instead. + EXPECT_EQ(0.3f, + layer_tree_host() + ->property_trees() + ->effect_tree.FindNodeFromElementId(root_->element_id()) + ->opacity); + EndTest(); + } +}; + +SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists); + +class LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists + : public LayerTreeHostTestLayerListsTest { + public: + LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists() + : LayerTreeHostTestLayerListsTest(false) {} + + protected: + void BeginTest() override { + EXPECT_EQ(gfx::Transform(), root_->transform()); + gfx::Transform expected_transform; + expected_transform.Translate(42, 42); + layer_tree_host()->SetElementTransformMutated( + root_->element_id(), ElementListType::ACTIVE, expected_transform); + // When not using layer lists, transform is stored on the layer. + EXPECT_EQ(expected_transform, root_->transform()); + EndTest(); + } +}; + +SINGLE_THREAD_TEST_F( + LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists); + +class LayerTreeHostTestAnimationTransformMutatedUsingLayerLists + : public LayerTreeHostTestLayerListsTest { + public: + LayerTreeHostTestAnimationTransformMutatedUsingLayerLists() + : LayerTreeHostTestLayerListsTest(true) {} + + protected: + void BeginTest() override { + // Insert a dummy transform node to observe its mutation. This would + // normally have been created by PaintArtifactCompositor. + int transform_node_id = + layer_tree_host()->property_trees()->transform_tree.Insert( + TransformNode(), TransformTree::kInvalidNodeId); + layer_tree_host() + ->property_trees() + ->element_id_to_transform_node_index[root_->element_id()] = + transform_node_id; + + EXPECT_EQ(gfx::Transform(), root_->transform()); + EXPECT_EQ(gfx::Transform(), + layer_tree_host() + ->property_trees() + ->transform_tree.FindNodeFromElementId(root_->element_id()) + ->local); + + gfx::Transform expected_transform; + expected_transform.Translate(42, 42); + layer_tree_host()->SetElementTransformMutated( + root_->element_id(), ElementListType::ACTIVE, expected_transform); + + // When using layer lists, we don't have to store the transform on the + // layer. + EXPECT_EQ(gfx::Transform(), root_->transform()); + // The transform should have been set directly on the transform node + // instead. + EXPECT_EQ(expected_transform, + layer_tree_host() + ->property_trees() + ->transform_tree.FindNodeFromElementId(root_->element_id()) + ->local); + EndTest(); + } +}; + +SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationTransformMutatedUsingLayerLists); + +class LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists + : public LayerTreeHostTestLayerListsTest { + public: + LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists() + : LayerTreeHostTestLayerListsTest(false) {} + + protected: + void BeginTest() override { + FilterOperations filters; + EXPECT_EQ(FilterOperations(), root_->filters()); + filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); + layer_tree_host()->SetElementFilterMutated( + root_->element_id(), ElementListType::ACTIVE, filters); + // When not using layer lists, filters are just stored directly on the + // layer. + EXPECT_EQ(filters, root_->filters()); + EndTest(); + } +}; + +SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationFilterMutatedNotUsingLayerLists); + +class LayerTreeHostTestAnimationFilterMutatedUsingLayerLists + : public LayerTreeHostTestLayerListsTest { + public: + LayerTreeHostTestAnimationFilterMutatedUsingLayerLists() + : LayerTreeHostTestLayerListsTest(true) {} + + protected: + void BeginTest() override { + // Insert a dummy effect node to observe its mutation. This would + // normally have been created by PaintArtifactCompositor. + int effect_node_id = + layer_tree_host()->property_trees()->effect_tree.Insert( + EffectNode(), EffectTree::kInvalidNodeId); + layer_tree_host() + ->property_trees() + ->element_id_to_effect_node_index[root_->element_id()] = effect_node_id; + + EXPECT_EQ(FilterOperations(), root_->filters()); + EXPECT_EQ(FilterOperations(), + layer_tree_host() + ->property_trees() + ->effect_tree.FindNodeFromElementId(root_->element_id()) + ->filters); + + FilterOperations filters; + filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); + layer_tree_host()->SetElementFilterMutated( + root_->element_id(), ElementListType::ACTIVE, filters); + + // When using layer lists, we don't have to store the filters on the layer. + EXPECT_EQ(FilterOperations(), root_->filters()); + // The filter should have been set directly on the effect node instead. + EXPECT_EQ(filters, + layer_tree_host() + ->property_trees() + ->effect_tree.FindNodeFromElementId(root_->element_id()) + ->filters); + EndTest(); + } +}; + +SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationFilterMutatedUsingLayerLists); + class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest { protected: void SetupTree() override { @@ -1376,8 +1598,8 @@ class LayerTreeHostTestTransformTreeDamageIsUpdated : public LayerTreeHostTest { root_->SetBounds(gfx::Size(50, 50)); - // Make sure child is registerd for animation. - child_->SetElementId(ElementId(2, 0)); + // Make sure child is registered for animation. + child_->SetElementId(ElementId(2)); // Make sure child and grand_child have transform nodes. gfx::Transform rotation; @@ -1442,6 +1664,21 @@ class LayerTreeHostTestTransformTreeDamageIsUpdated : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTransformTreeDamageIsUpdated); +class UpdateCountingLayer : public Layer { + public: + bool Update() override { + update_count_++; + return false; + } + + int update_count() const { return update_count_; } + + private: + ~UpdateCountingLayer() override = default; + + int update_count_ = 0; +}; + // Test that when mask layers switches layers, this gets pushed onto impl. // Also test that mask layer is in the layer update list even if its owning // layer isn't. @@ -1450,11 +1687,11 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { void SetupTree() override { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(10, 10)); - scoped_refptr<Layer> child = Layer::Create(); - mask_layer = Layer::Create(); - mask_layer->SetBounds(gfx::Size(10, 10)); - child->SetMaskLayer(mask_layer.get()); - root->AddChild(std::move(child)); + child_layer_ = make_scoped_refptr(new UpdateCountingLayer); + mask_layer_ = make_scoped_refptr(new UpdateCountingLayer); + mask_layer_->SetBounds(gfx::Size(10, 10)); + child_layer_->SetMaskLayer(mask_layer_.get()); + root->AddChild(child_layer_); layer_tree_host()->SetRootLayer(root); LayerTreeHostTest::SetupTree(); } @@ -1470,19 +1707,11 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { // 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. - EXPECT_EQ(mask_layer->paint_properties().source_frame_number, - layer_tree_host() - ->root_layer() - ->paint_properties() - .source_frame_number); - EXPECT_NE(mask_layer->paint_properties().source_frame_number, - layer_tree_host() - ->root_layer() - ->child_at(0) - ->paint_properties() - .source_frame_number); + EXPECT_EQ(mask_layer_->update_count(), 1); + EXPECT_EQ(child_layer_->update_count(), 0); + layer_tree_host()->root_layer()->RemoveAllChildren(); - layer_tree_host()->root_layer()->SetMaskLayer(mask_layer.get()); + layer_tree_host()->root_layer()->SetMaskLayer(mask_layer_.get()); break; } } @@ -1491,16 +1720,14 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { switch (index_) { case 0: index_++; - EXPECT_FALSE(impl->sync_tree() - ->root_layer_for_testing() - ->GetRenderSurface() - ->MaskLayer()); + EXPECT_FALSE( + GetRenderSurface(impl->sync_tree()->root_layer_for_testing()) + ->MaskLayer()); break; case 1: - EXPECT_TRUE(impl->sync_tree() - ->root_layer_for_testing() - ->GetRenderSurface() - ->MaskLayer()); + EXPECT_TRUE( + GetRenderSurface(impl->sync_tree()->root_layer_for_testing()) + ->MaskLayer()); EndTest(); break; } @@ -1508,7 +1735,8 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { void AfterTest() override {} - scoped_refptr<Layer> mask_layer; + scoped_refptr<UpdateCountingLayer> mask_layer_; + scoped_refptr<UpdateCountingLayer> child_layer_; int index_; }; @@ -1750,7 +1978,7 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate bool paint_scrollbar = true; bool has_thumb = false; scrollbar_ = FakePaintedScrollbarLayer::Create(paint_scrollbar, has_thumb, - root_layer_->id()); + root_layer_->element_id()); scrollbar_->SetPosition(gfx::PointF(0.f, 10.f)); scrollbar_->SetBounds(gfx::Size(10, 10)); @@ -2298,7 +2526,7 @@ class LayerTreeHostTestCommit : public LayerTreeHostTest { } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize()); + EXPECT_EQ(gfx::Rect(20, 20), impl->DeviceViewport()); EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color()); EXPECT_EQ(EventListenerProperties::kPassive, impl->active_tree()->event_listener_properties( @@ -2473,15 +2701,16 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { break; case 1: EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); + // Once the animation starts, an ImplFrame will be requested. However, + // main frames may be happening in the mean-time due to high-latency + // mode. If one happens before the next impl frame, then the source + // frame number may increment twice instead of just once. break; case 2: + case 3: EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor()); EndTest(); break; - case 3: - break; - default: - NOTREACHED(); } } @@ -2570,7 +2799,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers EXPECT_NEAR(impl->active_tree()->device_scale_factor(), 1.5f, 0.00001f); // Device viewport is scaled. - EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize()); + EXPECT_EQ(gfx::Rect(60, 60), impl->DeviceViewport()); FakePictureLayerImpl* root = static_cast<FakePictureLayerImpl*>( impl->active_tree()->root_layer_for_testing()); @@ -2586,18 +2815,16 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers impl->PrepareToDraw(&frame_data); impl->DidDrawAllLayers(frame_data); - const LayerImplList& render_surface_layer_list = - *frame_data.render_surface_layer_list; + const RenderSurfaceList& render_surface_list = + *frame_data.render_surface_list; // Both layers should be drawing into the root render surface. - ASSERT_EQ(1u, render_surface_layer_list.size()); - ASSERT_EQ(root->GetRenderSurface(), - render_surface_layer_list[0]->GetRenderSurface()); - ASSERT_EQ(2u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, render_surface_list.size()); + ASSERT_EQ(GetRenderSurface(root), render_surface_list[0]); + ASSERT_EQ(2, GetRenderSurface(root)->num_contributors()); // The root render surface is the size of the viewport. - EXPECT_EQ(gfx::Rect(0, 0, 60, 60), - root->GetRenderSurface()->content_rect()); + EXPECT_EQ(gfx::Rect(0, 0, 60, 60), GetRenderSurface(root)->content_rect()); // The max tiling scale of the child should be scaled. EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale()); @@ -3085,7 +3312,6 @@ class OnDrawCompositorFrameSink : public TestCompositorFrameSink { const RendererSettings& renderer_settings, base::SingleThreadTaskRunner* task_runner, bool synchronous_composite, - bool force_disable_reclaim_resources, base::Closure invalidate_callback) : TestCompositorFrameSink(std::move(compositor_context_provider), std::move(worker_context_provider), @@ -3094,7 +3320,7 @@ class OnDrawCompositorFrameSink : public TestCompositorFrameSink { renderer_settings, task_runner, synchronous_composite, - force_disable_reclaim_resources), + false /* disable_display_vsync */), invalidate_callback_(std::move(invalidate_callback)) {} // TestCompositorFrameSink overrides. @@ -3130,7 +3356,6 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, ImplThreadTaskRunner(), false /* synchronous_composite */, - false /* force_disable_reclaim_resources */, std::move(on_draw_callback)); compositor_frame_sink_ = frame_sink.get(); return std::move(frame_sink); @@ -3737,7 +3962,7 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed bool paint_scrollbar = true; bool has_thumb = false; scrollbar_layer_ = FakePaintedScrollbarLayer::Create( - paint_scrollbar, has_thumb, root_->id()); + paint_scrollbar, has_thumb, root_->element_id()); root_->AddChild(scrollbar_layer_); @@ -4496,9 +4721,12 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { inner_viewport_scroll_layer->AddChild(content_layer); layer_tree_host()->SetRootLayer(root_layer_); - layer_tree_host()->RegisterViewportLayers( - overscroll_elasticity_layer, page_scale_layer, - inner_viewport_scroll_layer, nullptr); + LayerTreeHost::ViewportLayers viewport_layers; + viewport_layers.overscroll_elasticity = overscroll_elasticity_layer; + 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()); } @@ -5300,15 +5528,15 @@ class LayerTreeHostTestGpuRasterizationEnabled // Ensure the suitability bit sticks. EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); - EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); - EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_gpu_rasterization()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); - EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); - EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_gpu_rasterization()); EndTest(); } @@ -5324,6 +5552,23 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); class LayerTreeHostTestGpuRasterizationReenabled : public LayerTreeHostWithGpuRasterizationTest { protected: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->gpu_rasterization_msaa_sample_count = 4; + } + + std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( + scoped_refptr<ContextProvider> compositor_context_provider, + scoped_refptr<ContextProvider> worker_context_provider) override { + std::unique_ptr<TestWebGraphicsContext3D> context = + TestWebGraphicsContext3D::Create(); + context->SetMaxSamples(4); + context->set_gpu_rasterization(true); + compositor_context_provider = + TestContextProvider::Create(std::move(context)); + return LayerTreeTest::CreateCompositorFrameSink(compositor_context_provider, + worker_context_provider); + } + void SetupTree() override { LayerTreeHostTest::SetupTree(); @@ -5362,10 +5607,10 @@ class LayerTreeHostTestGpuRasterizationReenabled void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { SCOPED_TRACE(base::StringPrintf("commit %d", num_commits_)); - if (expected_gpu_enabled_) { - EXPECT_TRUE(host_impl->use_gpu_rasterization()); + if (expected_use_msaa_) { + EXPECT_TRUE(host_impl->use_msaa()); } else { - EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); } ++num_commits_; @@ -5380,7 +5625,7 @@ class LayerTreeHostTestGpuRasterizationReenabled layer_->set_force_unsuitable_for_gpu_rasterization(false); break; case 90: - expected_gpu_enabled_ = true; + expected_use_msaa_ = false; break; } PostSetNeedsCommitToMainThread(); @@ -5394,7 +5639,7 @@ class LayerTreeHostTestGpuRasterizationReenabled FakePictureLayer* layer_; FakeRecordingSource* recording_source_; int num_commits_ = 0; - bool expected_gpu_enabled_ = false; + bool expected_use_msaa_ = true; }; MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationReenabled); @@ -5666,7 +5911,7 @@ class LayerTreeHostTestRenderSurfaceEffectTreeIndex : public LayerTreeHostTest { LayerImpl* grand_child_impl = host_impl->sync_tree()->LayerById(grand_child_->id()); EXPECT_EQ(grand_child_impl->effect_tree_index(), - grand_child_impl->GetRenderSurface()->EffectTreeIndex()); + GetRenderSurface(grand_child_impl)->EffectTreeIndex()); } } @@ -5680,12 +5925,12 @@ class LayerTreeHostTestRenderSurfaceEffectTreeIndex : public LayerTreeHostTest { case 1: case 2: EXPECT_EQ(grand_child_impl->effect_tree_index(), - grand_child_impl->GetRenderSurface()->EffectTreeIndex()); + GetRenderSurface(grand_child_impl)->EffectTreeIndex()); PostSetNeedsCommitToMainThread(); break; case 3: EXPECT_EQ(grand_child_impl->effect_tree_index(), - grand_child_impl->GetRenderSurface()->EffectTreeIndex()); + GetRenderSurface(grand_child_impl)->EffectTreeIndex()); EndTest(); } } @@ -5727,17 +5972,15 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( scoped_refptr<ContextProvider> compositor_context_provider, scoped_refptr<ContextProvider> worker_context_provider) override { + constexpr bool disable_display_vsync = false; bool synchronous_composite = !HasImplThread() && !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; - // Relaiming resources is parameterized for this test. - bool force_disable_reclaim_resources = !reclaim_resources_; return base::MakeUnique<TestCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, - ImplThreadTaskRunner(), synchronous_composite, - force_disable_reclaim_resources); + ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync); } void BeginTest() override { @@ -5784,19 +6027,13 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise EXPECT_TRUE(swap_promise_result_[0].dtor_called); } - // Second swap promise fails to swap if not reclaiming resources from the - // Display. + // Second swap promise fails to swap. { base::AutoLock lock(swap_promise_result_[1].lock); EXPECT_TRUE(swap_promise_result_[1].did_activate_called); - if (!reclaim_resources_) { - EXPECT_FALSE(swap_promise_result_[1].did_swap_called); - EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); - EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); - } else { - EXPECT_TRUE(swap_promise_result_[1].did_swap_called); - EXPECT_FALSE(swap_promise_result_[1].did_not_swap_called); - } + EXPECT_FALSE(swap_promise_result_[1].did_swap_called); + EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); + EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); EXPECT_TRUE(swap_promise_result_[1].dtor_called); } @@ -5811,20 +6048,12 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise } } - bool reclaim_resources_; int commit_count_ = 0; TestSwapPromiseResult swap_promise_result_[3]; }; -TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise, NoReclaim) { - reclaim_resources_ = false; - RunTest(CompositorMode::SINGLE_THREADED); -} - -TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise, Reclaim) { - reclaim_resources_ = true; - RunTest(CompositorMode::SINGLE_THREADED); -} +// Synchronous composite is a single-threaded only feature. +SINGLE_THREAD_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise); // Make sure page scale and top control deltas are applied to the client even // when the LayerTreeHost doesn't have a root layer. @@ -5901,8 +6130,11 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { // pinch. pinch->AddChild(layer); - layer_tree_host()->RegisterViewportLayers(NULL, page_scale_layer, pinch, - nullptr); + LayerTreeHost::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(); @@ -6205,8 +6437,11 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles // pinch. pinch->AddChild(layer); - layer_tree_host()->RegisterViewportLayers(NULL, page_scale_layer, pinch, - nullptr); + LayerTreeHost::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(); @@ -6508,7 +6743,7 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest { void WillCommit() override { switch (layer_tree_host()->SourceFrameNumber()) { case 1: - EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0); + EXPECT_TRUE(root->has_copy_requests_in_target_subtree()); break; } } @@ -6531,7 +6766,7 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest { child->SetTransform(transform); break; case 3: - EXPECT_EQ(root->num_copy_requests_in_target_subtree(), 0); + EXPECT_FALSE(root->has_copy_requests_in_target_subtree()); EndTest(); break; } @@ -6641,8 +6876,27 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin FakeContentLayerClient client_; }; +class LayerTreeTestSingleTextureMaskLayerForSurfaceWithContentRectNotAtOrigin + : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + } +}; + SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin); + LayerTreeTestSingleTextureMaskLayerForSurfaceWithContentRectNotAtOrigin); + +class LayerTreeTestMultiTextureMaskLayerForSurfaceWithContentRectNotAtOrigin + : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMultiTextureMaskLayerForSurfaceWithContentRectNotAtOrigin); class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { protected: @@ -6754,15 +7008,30 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { FakeContentLayerClient client_; }; +class LayerTreeTestSingleTextureMaskLayerForSurfaceWithClippedLayer + : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + } +}; + SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeTestMaskLayerForSurfaceWithClippedLayer); + LayerTreeTestSingleTextureMaskLayerForSurfaceWithClippedLayer); -class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { - protected: +class LayerTreeTestMultiTextureMaskLayerForSurfaceWithClippedLayer + : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer { + public: void InitializeSettings(LayerTreeSettings* settings) override { - settings->layer_transforms_should_scale_layer_contents = true; + settings->enable_mask_tiling = true; } +}; +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMultiTextureMaskLayerForSurfaceWithClippedLayer); + +class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { + protected: void SetupTree() override { // Root // | @@ -6878,7 +7147,27 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { FakeContentLayerClient client_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling); +class LayerTreeTestSingleTextureMaskLayerWithScaling + : public LayerTreeTestMaskLayerWithScaling { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + settings->layer_transforms_should_scale_layer_contents = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestSingleTextureMaskLayerWithScaling); + +class LayerTreeTestMultiTextureMaskLayerWithScaling + : public LayerTreeTestMaskLayerWithScaling { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = true; + settings->layer_transforms_should_scale_layer_contents = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMultiTextureMaskLayerWithScaling); class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest { protected: @@ -6983,7 +7272,103 @@ class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest { FakeContentLayerClient client_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithDifferentBounds); +class LayerTreeTestSingleTextureMaskLayerWithDifferentBounds + : public LayerTreeTestMaskLayerWithDifferentBounds { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = false; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestSingleTextureMaskLayerWithDifferentBounds); + +class LayerTreeTestMultiTextureMaskLayerWithDifferentBounds + : public LayerTreeTestMaskLayerWithDifferentBounds { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_mask_tiling = true; + } +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMultiTextureMaskLayerWithDifferentBounds); + +class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { + protected: + void SetupTree() override { + // The masked layer has bounds 100x100, but is allocated a 120x150 texture. + + scoped_refptr<Layer> root = Layer::Create(); + + scoped_refptr<FakePictureLayer> content_layer = + FakePictureLayer::Create(&client_); + 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(); + + scoped_refptr<FakePictureLayer> mask_layer = + FakePictureLayer::CreateWithRecordingSource( + &client_, std::move(recording_source)); + content_layer->SetMaskLayer(mask_layer.get()); + + 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); + 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); + LayerTreeTest::SetupTree(); + client_.set_bounds(root->bounds()); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { + EXPECT_EQ(2u, frame_data->render_passes.size()); + RenderPass* root_pass = frame_data->render_passes.back().get(); + EXPECT_EQ(2u, root_pass->quad_list.size()); + + // There's a solid color quad under everything. + EXPECT_EQ(DrawQuad::SOLID_COLOR, root_pass->quad_list.back()->material); + + // The surface is 100x100 + EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material); + const RenderPassDrawQuad* render_pass_quad = + 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()); + EndTest(); + return draw_result; + } + + void AfterTest() override {} + + int mask_layer_id_; + FakeContentLayerClient client_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskWithNonExactTextureSize); class LayerTreeTestPageScaleFlags : public LayerTreeTest { protected: @@ -7015,12 +7400,9 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest { layer_tree_host()->SetRootLayer(root); LayerTreeTest::SetupTree(); - scoped_refptr<Layer> overscroll_elasticity_layer = nullptr; - scoped_refptr<Layer> inner_viewport_scroll_layer = nullptr; - scoped_refptr<Layer> outer_viewport_scroll_layer = nullptr; - layer_tree_host()->RegisterViewportLayers( - overscroll_elasticity_layer, page_scale, inner_viewport_scroll_layer, - outer_viewport_scroll_layer); + LayerTreeHost::ViewportLayers viewport_layers; + viewport_layers.page_scale = page_scale; + layer_tree_host()->RegisterViewportLayers(viewport_layers); affected_by_page_scale_.push_back(page_scale->id()); affected_by_page_scale_.push_back(page_scale_child1->id()); @@ -7104,6 +7486,10 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor); // Makes sure that LocalSurfaceId is propagated to the CompositorFrameSink. class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest { protected: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_surface_synchronization = true; + } + void BeginTest() override { expected_local_surface_id_ = allocator_.GenerateId(); PostSetLocalSurfaceIdToMainThread(expected_local_surface_id_); @@ -7162,7 +7548,6 @@ class GpuRasterizationSucceedsWithLargeImage : public LayerTreeHostTest { recording->add_draw_image(CreateDiscardableImage(large_image_size_), gfx::Point(0, 0)); - recording->SetGenerateDiscardableImagesMetadata(true); recording->Rerecord(); scoped_refptr<FakePictureLayer> root = @@ -7502,5 +7887,86 @@ class LayerTreeHostTestHudLayerWithLayerLists : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHudLayerWithLayerLists); +// Verifies that LayerTreeHostClient does not receive frame acks from a released +// CompositorFrameSink. +class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest { + protected: + void SetupTree() override { + scoped_refptr<Layer> root = Layer::Create(); + root->SetBounds(gfx::Size(10, 10)); + layer_tree_host()->SetRootLayer(std::move(root)); + LayerTreeHostTest::SetupTree(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void WillReceiveCompositorFrameAckOnThread( + LayerTreeHostImpl* host_impl) override { + // This method is called before ack is posted to main thread. This ensures + // that WillReceiveCompositorFrameAck which we PostTask below will be called + // before DidReceiveCompositorFrameAck. + MainThreadTaskRunner()->PostTask( + FROM_HERE, base::Bind(&LayerTreeHostTestDiscardAckAfterRelease:: + WillReceiveCompositorFrameAck, + base::Unretained(this))); + } + + void WillReceiveCompositorFrameAck() { + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + // For the first commit, don't release the CompositorFrameSink. We must + // receive the ack later on. + break; + case 2: + // Release the CompositorFrameSink for the second commit. We'll later + // check that the ack is discarded. + layer_tree_host()->SetVisible(false); + layer_tree_host()->ReleaseCompositorFrameSink(); + break; + default: + NOTREACHED(); + } + } + + void DidReceiveCompositorFrameAckOnThread( + LayerTreeHostImpl* host_impl) override { + // Since this method is called after ack is posted to main thread, we can be + // sure that if the ack is not discarded, it will be definitely received + // before we are in CheckFrameAck. + MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&LayerTreeHostTestDiscardAckAfterRelease::CheckFrameAck, + base::Unretained(this))); + } + + void DidReceiveCompositorFrameAck() override { received_ack_ = true; } + + void CheckFrameAck() { + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + // CompositorFrameSink was not released. We must receive the ack. + EXPECT_TRUE(received_ack_); + // Cause damage so that we draw and swap. + layer_tree_host()->root_layer()->SetBackgroundColor(SK_ColorGREEN); + break; + case 2: + // CompositorFrameSink was released. The ack must be discarded. + EXPECT_FALSE(received_ack_); + EndTest(); + break; + default: + NOTREACHED(); + } + received_ack_ = false; + } + + void AfterTest() override {} + + private: + bool received_ack_ = false; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDiscardAckAfterRelease); + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc index f25dc93e40f..b9fa010f632 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -5,6 +5,7 @@ #include "cc/trees/layer_tree_host.h" #include <stdint.h> +#include <climits> #include "cc/animation/animation_curve.h" #include "cc/animation/animation_host.h" @@ -489,7 +490,7 @@ class LayerTreeHostAnimationTestLayerAddedWithAnimation AttachPlayersToTimeline(); scoped_refptr<Layer> layer = Layer::Create(); - layer->SetElementId(ElementId(42, 0)); + layer->SetElementId(ElementId(42)); player_->AttachElement(layer->element_id()); player_->set_animation_delegate(this); @@ -810,7 +811,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationTakeover if (host_impl->sync_tree()->source_frame_number() == 0) { GetImplAnimationHost(host_impl)->ImplOnlyScrollAnimationCreate( scroll_layer_->element_id(), gfx::ScrollOffset(650.f, 750.f), - gfx::ScrollOffset(10, 20), base::TimeDelta()); + gfx::ScrollOffset(10, 20), base::TimeDelta(), base::TimeDelta()); } } @@ -905,7 +906,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted if (host_impl->sync_tree()->source_frame_number() == 0) { GetImplAnimationHost(host_impl)->ImplOnlyScrollAnimationCreate( scroll_layer_->element_id(), gfx::ScrollOffset(650.f, 750.f), - gfx::ScrollOffset(10, 20), base::TimeDelta()); + gfx::ScrollOffset(10, 20), base::TimeDelta(), base::TimeDelta()); } } @@ -1403,7 +1404,11 @@ class LayerTreeHostAnimationTestRemoveAnimation player_child_->AttachElement(layer_->element_id()); } - void BeginTest() override { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { + animation_stopped_ = false; + last_frame_number_ = INT_MAX; + PostSetNeedsCommitToMainThread(); + } void DidCommit() override { switch (layer_tree_host()->SourceFrameNumber()) { @@ -1433,6 +1438,7 @@ class LayerTreeHostAnimationTestRemoveAnimation } void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + GetImplTimelineAndPlayerByID(*host_impl); LayerImpl* child = host_impl->active_tree()->LayerById(layer_->id()); switch (host_impl->active_tree()->source_frame_number()) { case 0: @@ -1443,18 +1449,37 @@ class LayerTreeHostAnimationTestRemoveAnimation EXPECT_TRUE(child->screen_space_transform_is_animating()); break; case 2: { - // The animation is removed, the transform that was set afterward is + // The animation is stopped, the transform that was set afterward is // applied. gfx::Transform expected_transform; expected_transform.Translate(10.f, 10.f); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, child->DrawTransform()); EXPECT_FALSE(child->screen_space_transform_is_animating()); - EndTest(); + animation_stopped_ = true; + PostSetNeedsCommitToMainThread(); break; } - default: - NOTREACHED(); + } + } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + if (host_impl->sync_tree()->source_frame_number() >= last_frame_number_) { + // Check that eventually the animation is removed. + EXPECT_FALSE(player_child_impl_->has_any_animation()); + EndTest(); + } + } + + void UpdateAnimationState(LayerTreeHostImpl* host_impl, + bool has_unfinished_animation) override { + // Non impl only animations are removed during commit. After the animation + // is fully stopped on compositor thread, make sure another commit happens. + if (animation_stopped_ && !has_unfinished_animation) { + last_frame_number_ = + std::min(last_frame_number_, + host_impl->active_tree()->source_frame_number() + 1); + PostSetNeedsCommitToMainThread(); } } @@ -1463,6 +1488,9 @@ class LayerTreeHostAnimationTestRemoveAnimation private: scoped_refptr<Layer> layer_; FakeContentLayerClient client_; + + int last_frame_number_; + bool animation_stopped_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation); @@ -1620,6 +1648,84 @@ class LayerTreeHostAnimationTestAnimationFinishesDuringCommit // compositor thread. MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit); +class LayerTreeHostAnimationTestImplSideInvalidation + : public LayerTreeHostAnimationTest { + public: + void SetupTree() override { + LayerTreeHostAnimationTest::SetupTree(); + layer_ = FakePictureLayer::Create(&client_); + layer_->SetBounds(gfx::Size(4, 4)); + client_.set_bounds(layer_->bounds()); + layer_tree_host()->root_layer()->AddChild(layer_); + + AttachPlayersToTimeline(); + + player_->AttachElement(layer_tree_host()->root_layer()->element_id()); + player_child_->AttachElement(layer_->element_id()); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidCommit() override { + if (layer_tree_host()->SourceFrameNumber() == 1) + AddAnimatedTransformToPlayer(player_child_.get(), 0.04, 5, 5); + } + + void WillCommit() override { + if (layer_tree_host()->SourceFrameNumber() == 2) { + // Block until the animation finishes on the compositor thread. Since + // animations have already been ticked on the main thread, when the commit + // happens the state on the main thread will be consistent with having a + // running animation but the state on the compositor thread will be + // consistent with having only a finished animation. + completion_.Wait(); + } + } + + void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { + DCHECK(did_request_impl_side_invalidation_); + completion_.Signal(); + } + + void UpdateAnimationState(LayerTreeHostImpl* host_impl, + bool has_unfinished_animation) override { + if (host_impl->active_tree()->source_frame_number() == 1 && + !has_unfinished_animation && !did_request_impl_side_invalidation_) { + // The animation on the active tree has finished, now request an impl-side + // invalidation and make sure it finishes before the main thread is + // released. + did_request_impl_side_invalidation_ = true; + host_impl->RequestImplSideInvalidation(); + } + } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + switch (host_impl->sync_tree()->source_frame_number()) { + case 1: + PostSetNeedsCommitToMainThread(); + break; + case 2: + gfx::Transform expected_transform; + expected_transform.Translate(5.f, 5.f); + LayerImpl* layer_impl = host_impl->sync_tree()->LayerById(layer_->id()); + EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, + layer_impl->DrawTransform()); + EndTest(); + break; + } + } + + void AfterTest() override {} + + private: + scoped_refptr<Layer> layer_; + FakeContentLayerClient client_; + CompletionEvent completion_; + bool did_request_impl_side_invalidation_ = false; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestImplSideInvalidation); + class LayerTreeHostAnimationTestNotifyAnimationFinished : public LayerTreeHostAnimationTest { public: diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc index 37b3e1b006f..0828b107c44 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc @@ -21,7 +21,6 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest { void AfterTest() override {} void InitializeSettings(LayerTreeSettings* settings) override { - settings->image_decode_tasks_enabled = true; settings->enable_checker_imaging = true; } diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc index 3c7351f3ff4..d1337cb9904 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_context.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc @@ -973,7 +973,7 @@ class LayerTreeHostContextTestDontUseLostResources scoped_refptr<PaintedScrollbarLayer> scrollbar = PaintedScrollbarLayer::Create( - std::unique_ptr<Scrollbar>(new FakeScrollbar), layer->id()); + std::unique_ptr<Scrollbar>(new FakeScrollbar), layer->element_id()); scrollbar->SetBounds(gfx::Size(10, 10)); scrollbar->SetIsDrawable(true); root->AddChild(scrollbar); @@ -1088,8 +1088,8 @@ class ScrollbarLayerLostContext : public LayerTreeHostContextTest { void BeginTest() override { scoped_refptr<Layer> scroll_layer = Layer::Create(); - scrollbar_layer_ = - FakePaintedScrollbarLayer::Create(false, true, scroll_layer->id()); + scrollbar_layer_ = FakePaintedScrollbarLayer::Create( + false, true, scroll_layer->element_id()); scrollbar_layer_->SetBounds(gfx::Size(10, 100)); layer_tree_host()->root_layer()->AddChild(scrollbar_layer_); layer_tree_host()->root_layer()->AddChild(scroll_layer); diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc index 73d71a2d6dd..578324f785e 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc @@ -12,6 +12,7 @@ #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_painted_scrollbar_layer.h" #include "cc/test/fake_picture_layer.h" +#include "cc/test/layer_test_common.h" #include "cc/test/layer_tree_test.h" #include "cc/trees/damage_tracker.h" #include "cc/trees/layer_tree_impl.h" @@ -55,7 +56,7 @@ class LayerTreeHostDamageTestSetNeedsRedraw EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - impl->active_tree()->root_layer_for_testing()->GetRenderSurface(); + GetRenderSurface(impl->active_tree()->root_layer_for_testing()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -118,7 +119,7 @@ class LayerTreeHostDamageTestSetViewportSize EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - impl->active_tree()->root_layer_for_testing()->GetRenderSurface(); + GetRenderSurface(impl->active_tree()->root_layer_for_testing()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -260,7 +261,7 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - host_impl->active_tree()->root_layer_for_testing()->GetRenderSurface(); + GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -340,6 +341,8 @@ class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest { scoped_refptr<Layer> scroll_clip_layer = Layer::Create(); content_layer_ = FakePictureLayer::Create(&client_); + content_layer_->SetElementId( + LayerIdToElementIdForTesting(content_layer_->id())); content_layer_->SetScrollClipLayerId(scroll_clip_layer->id()); content_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); content_layer_->SetBounds(gfx::Size(100, 200)); @@ -350,8 +353,8 @@ class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest { scroll_clip_layer->AddChild(content_layer_); root_layer->AddChild(scroll_clip_layer); - scoped_refptr<Layer> scrollbar_layer = - FakePaintedScrollbarLayer::Create(false, true, content_layer_->id()); + scoped_refptr<Layer> scrollbar_layer = FakePaintedScrollbarLayer::Create( + false, true, content_layer_->element_id()); scrollbar_layer->SetPosition(gfx::PointF(300.f, 300.f)); scrollbar_layer->SetBounds(gfx::Size(10, 100)); root_layer->AddChild(scrollbar_layer); @@ -385,7 +388,7 @@ class LayerTreeHostDamageTestScrollbarDoesDamage DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - host_impl->active_tree()->root_layer_for_testing()->GetRenderSurface(); + GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -471,7 +474,7 @@ class LayerTreeHostDamageTestScrollbarCommitDoesNoDamage DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - host_impl->active_tree()->root_layer_for_testing()->GetRenderSurface(); + GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); diff --git a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc index 3202bb93f1a..d979e0b46ea 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc @@ -7,6 +7,7 @@ #include "cc/layers/layer.h" #include "cc/layers/picture_layer.h" #include "cc/test/fake_content_layer_client.h" +#include "cc/test/layer_test_common.h" #include "cc/test/layer_tree_test.h" #include "cc/trees/layer_tree_impl.h" @@ -52,8 +53,8 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnLayer LayerImpl* child = impl->active_tree()->LayerById(child_->id()); // Verify the draw properties are valid. - EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); + EXPECT_TRUE(root->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child->contributes_to_drawn_render_surface()); EXPECT_OCCLUSION_EQ( Occlusion(child->DrawTransform(), SimpleEnclosedRegion(), @@ -106,13 +107,13 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnSurface void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer_for_testing(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - RenderSurfaceImpl* surface = child->GetRenderSurface(); + RenderSurfaceImpl* surface = GetRenderSurface(child); // Verify the draw properties are valid. - EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(child->GetRenderSurface()); - EXPECT_EQ(child->GetRenderSurface(), child->render_target()); + 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_OCCLUSION_EQ( Occlusion(surface->draw_transform(), SimpleEnclosedRegion(), @@ -173,14 +174,14 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer_for_testing(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - RenderSurfaceImpl* surface = child->GetRenderSurface(); + RenderSurfaceImpl* surface = GetRenderSurface(child); LayerImpl* mask = surface->MaskLayer(); // Verify the draw properties are valid. - EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member()); - EXPECT_TRUE(child->GetRenderSurface()); - EXPECT_EQ(child->GetRenderSurface(), child->render_target()); + 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()); gfx::Transform transform = surface->draw_transform(); transform.PreconcatTransform(child->DrawTransform()); @@ -245,7 +246,7 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - LayerImpl* mask = child->GetRenderSurface()->MaskLayer(); + LayerImpl* mask = GetRenderSurface(child)->MaskLayer(); gfx::Transform scale; scale.Scale(2, 2); diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc index 55eabcb1eb7..e4fefef207c 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc @@ -423,8 +423,11 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale picture_->SetBounds(gfx::Size(100, 100)); pinch_->AddChild(picture_); - layer_tree_host()->RegisterViewportLayers(NULL, page_scale_layer, pinch_, - nullptr); + LayerTreeHost::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_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc index b547fefcc45..e9a1e5d6b2e 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc @@ -1417,7 +1417,8 @@ class LayerTreeHostScrollTestLayerStructureChange virtual void DidScroll(Layer* layer) { if (scroll_destroy_whole_tree_) { - layer_tree_host()->RegisterViewportLayers(NULL, NULL, NULL, NULL); + layer_tree_host()->RegisterViewportLayers( + LayerTreeHost::ViewportLayers()); layer_tree_host()->SetRootLayer(NULL); EndTest(); return; @@ -2132,6 +2133,25 @@ class LayerTreeHostScrollTestImplSideInvalidation SignalCompletionIfPossible(); } + void WillNotifyReadyToActivateOnThread( + LayerTreeHostImpl* host_impl) override { + // Ensure that the scroll-offsets on the TransformTree are consistent with + // the synced scroll offsets, for the pending tree. + if (!host_impl->pending_tree()) + return; + + LayerImpl* scroll_layer = + host_impl->pending_tree()->OuterViewportScrollLayer(); + gfx::ScrollOffset scroll_offset = scroll_layer->CurrentScrollOffset(); + int transform_index = scroll_layer->transform_tree_index(); + gfx::ScrollOffset transform_tree_scroll_offset = + host_impl->pending_tree() + ->property_trees() + ->transform_tree.Node(transform_index) + ->scroll_offset; + EXPECT_EQ(scroll_offset, transform_tree_scroll_offset); + } + void SignalCompletionIfPossible() { if (!invalidated_on_impl_thread_ || !impl_side_invalidation_event_) return; diff --git a/chromium/cc/trees/layer_tree_host_unittest_video.cc b/chromium/cc/trees/layer_tree_host_unittest_video.cc index ae48abaa7b3..1c659af77e1 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_video.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_video.cc @@ -8,6 +8,7 @@ #include "cc/layers/video_layer.h" #include "cc/layers/video_layer_impl.h" #include "cc/test/fake_video_frame_provider.h" +#include "cc/test/layer_test_common.h" #include "cc/test/layer_tree_test.h" #include "cc/trees/damage_tracker.h" #include "cc/trees/layer_tree_impl.h" @@ -48,7 +49,7 @@ class LayerTreeHostVideoTestSetNeedsDisplay LayerTreeHostImpl::FrameData* frame, DrawResult draw_result) override { LayerImpl* root_layer = host_impl->active_tree()->root_layer_for_testing(); - RenderSurfaceImpl* root_surface = root_layer->GetRenderSurface(); + RenderSurfaceImpl* root_surface = GetRenderSurface(root_layer); gfx::Rect damage_rect; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&damage_rect)); diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index 12ebf3fa413..2c57e5a1f0e 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -51,6 +51,21 @@ namespace cc { +void LayerTreeLifecycle::AdvanceTo(LifecycleState next_state) { + switch (next_state) { + case (kNotSyncing): + DCHECK_EQ(state_, kLastSyncState); + break; + case (kBeginningSync): + case (kSyncedPropertyTrees): + case (kSyncedLayerProperties): + // Only allow tree synchronization states to be transitioned in order. + DCHECK_EQ(state_ + 1, next_state); + break; + } + state_ = next_state; +} + LayerTreeImpl::LayerTreeImpl( LayerTreeHostImpl* layer_tree_host_impl, scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, @@ -64,10 +79,6 @@ LayerTreeImpl::LayerTreeImpl( background_color_(0), has_transparent_background_(false), last_scrolled_scroll_node_index_(ScrollTree::kInvalidNodeId), - overscroll_elasticity_layer_id_(Layer::INVALID_ID), - page_scale_layer_id_(Layer::INVALID_ID), - inner_viewport_scroll_layer_id_(Layer::INVALID_ID), - outer_viewport_scroll_layer_id_(Layer::INVALID_ID), page_scale_factor_(page_scale_factor), min_page_scale_factor_(0), max_page_scale_factor_(0), @@ -139,21 +150,26 @@ void LayerTreeImpl::RecreateTileResources() { } bool LayerTreeImpl::IsViewportLayerId(int id) const { - if (id == inner_viewport_scroll_layer_id_ || - id == outer_viewport_scroll_layer_id_) - return true; - if (InnerViewportContainerLayer() && - id == InnerViewportContainerLayer()->id()) - return true; - if (OuterViewportContainerLayer() && - id == OuterViewportContainerLayer()->id()) - return true; - +#if DCHECK_IS_ON() + // Ensure the LayerImpl viewport layer types correspond to the LayerTreeImpl's + // viewport layers. + if (id == viewport_layer_ids_.inner_viewport_container) + DCHECK(LayerById(id)->viewport_layer_type() == INNER_VIEWPORT_CONTAINER); + if (id == viewport_layer_ids_.outer_viewport_container) + DCHECK(LayerById(id)->viewport_layer_type() == OUTER_VIEWPORT_CONTAINER); + if (id == viewport_layer_ids_.inner_viewport_scroll) + DCHECK(LayerById(id)->viewport_layer_type() == INNER_VIEWPORT_SCROLL); + if (id == viewport_layer_ids_.outer_viewport_scroll) + DCHECK(LayerById(id)->viewport_layer_type() == OUTER_VIEWPORT_SCROLL); +#endif + if (auto* layer = LayerById(id)) + return layer->viewport_layer_type() != NOT_VIEWPORT_LAYER; return false; } void LayerTreeImpl::DidUpdateScrollOffset(int layer_id) { DidUpdateScrollState(layer_id); + DCHECK(lifecycle().AllowsPropertyTreeAccess()); TransformTree& transform_tree = property_trees()->transform_tree; ScrollTree& scroll_tree = property_trees()->scroll_tree; int transform_id = TransformTree::kInvalidNodeId; @@ -191,6 +207,12 @@ void LayerTreeImpl::DidUpdateScrollState(int layer_id) { if (!IsActiveTree()) return; + DCHECK(lifecycle().AllowsPropertyTreeAccess()); + + // The scroll_clip_layer Layer properties should be up-to-date. + // TODO(pdr): This DCHECK fails on existing tests but should be enabled. + // DCHECK(lifecycle().AllowsLayerPropertyAccess()); + if (layer_id == Layer::INVALID_ID) return; @@ -202,8 +224,8 @@ void LayerTreeImpl::DidUpdateScrollState(int layer_id) { // For scrollbar purposes, a change to any of the four viewport layers // should affect the scrollbars tied to the outermost layers, which express // the sum of the entire viewport. - scroll_layer_id = outer_viewport_scroll_layer_id_; - clip_layer_id = InnerViewportContainerLayer()->id(); + scroll_layer_id = viewport_layer_ids_.outer_viewport_scroll; + clip_layer_id = viewport_layer_ids_.inner_viewport_container; } else { // If the clip layer id was passed in, then look up the scroll layer, or // vice versa. @@ -242,55 +264,28 @@ void LayerTreeImpl::UpdateScrollbars(int scroll_layer_id, int clip_layer_id) { clip_size.Scale(1 / current_page_scale_factor()); } - bool scrollbar_needs_animation = false; - bool clip_layer_size_did_change = false; - bool scroll_layer_size_did_change = false; bool y_offset_did_change = false; - for (ScrollbarLayerImplBase* scrollbar : ScrollbarsFor(scroll_layer_id)) { + for (auto* scrollbar : ScrollbarsFor(scroll_layer->element_id())) { if (scrollbar->orientation() == HORIZONTAL) { - scrollbar_needs_animation |= scrollbar->SetCurrentPos(current_offset.x()); - clip_layer_size_did_change |= - scrollbar->SetClipLayerLength(clip_size.width()); - scroll_layer_size_did_change |= - scrollbar->SetScrollLayerLength(scroll_size.width()); + scrollbar->SetCurrentPos(current_offset.x()); + scrollbar->SetClipLayerLength(clip_size.width()); + scrollbar->SetScrollLayerLength(scroll_size.width()); } else { - scrollbar_needs_animation |= y_offset_did_change |= - scrollbar->SetCurrentPos(current_offset.y()); - clip_layer_size_did_change |= - scrollbar->SetClipLayerLength(clip_size.height()); - scroll_layer_size_did_change |= - scrollbar->SetScrollLayerLength(scroll_size.height()); + y_offset_did_change = scrollbar->SetCurrentPos(current_offset.y()); + scrollbar->SetClipLayerLength(clip_size.height()); + scrollbar->SetScrollLayerLength(scroll_size.height()); } - scrollbar_needs_animation |= - scrollbar->SetVerticalAdjust(clip_layer->bounds_delta().y()); + scrollbar->SetVerticalAdjust(clip_layer->ViewportBoundsDelta().y()); } - scrollbar_needs_animation |= - (clip_layer_size_did_change || scroll_layer_size_did_change); - if (y_offset_did_change && IsViewportLayerId(scroll_layer_id)) TRACE_COUNTER_ID1("cc", "scroll_offset_y", scroll_layer->id(), current_offset.y()); - - if (scrollbar_needs_animation) { - ScrollbarAnimationController* controller = - layer_tree_host_impl_->ScrollbarAnimationControllerForId( - scroll_layer_id); - if (!controller) - return; - - // TODO(chaopeng) clip_layer_size_did_change should call DidResize after - // crbug.com/701810 got fixed. - if (scroll_layer_size_did_change) { - controller->DidResize(); - } else { - controller->DidScrollUpdate(); - } - } } -RenderSurfaceImpl* LayerTreeImpl::RootRenderSurface() const { - return layer_list_.empty() ? nullptr : layer_list_[0]->GetRenderSurface(); +const RenderSurfaceImpl* LayerTreeImpl::RootRenderSurface() const { + return property_trees_.effect_tree.GetRenderSurface( + EffectTree::kContentsRootNodeId); } bool LayerTreeImpl::LayerListIsEmpty() const { @@ -330,7 +325,7 @@ void LayerTreeImpl::BuildLayerListForTesting() { } void LayerTreeImpl::InvalidateRegionForImages( - const ImageIdFlatSet& images_to_invalidate) { + const PaintImageIdFlatSet& images_to_invalidate) { DCHECK(IsSyncTree()); if (images_to_invalidate.empty()) @@ -344,14 +339,6 @@ bool LayerTreeImpl::IsRootLayer(const LayerImpl* layer) const { return layer_list_.empty() ? false : layer_list_[0] == layer; } -LayerImpl* LayerTreeImpl::InnerViewportScrollLayer() const { - return LayerById(inner_viewport_scroll_layer_id_); -} - -LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const { - return LayerById(outer_viewport_scroll_layer_id_); -} - gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const { gfx::ScrollOffset offset; @@ -379,28 +366,13 @@ gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const { std::unique_ptr<OwnedLayerImplList> LayerTreeImpl::DetachLayers() { root_layer_for_testing_ = nullptr; layer_list_.clear(); - render_surface_layer_list_.clear(); + render_surface_list_.clear(); set_needs_update_draw_properties(); std::unique_ptr<OwnedLayerImplList> ret = std::move(layers_); layers_.reset(new OwnedLayerImplList); return ret; } -static void UpdateClipTreeForBoundsDeltaOnLayer(LayerImpl* layer, - ClipTree* clip_tree) { - if (layer && layer->masks_to_bounds()) { - ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index()); - if (clip_node) { - DCHECK_EQ(layer->id(), clip_node->owning_layer_id); - gfx::SizeF bounds = gfx::SizeF(layer->bounds()); - if (clip_node->clip.size() != bounds) { - clip_node->clip.set_size(bounds); - clip_tree->set_needs_update(true); - } - } - } -} - void LayerTreeImpl::SetPropertyTrees(PropertyTrees* property_trees) { std::vector<std::unique_ptr<RenderSurfaceImpl>> old_render_surfaces; property_trees_.effect_tree.TakeRenderSurfaces(&old_render_surfaces); @@ -421,33 +393,17 @@ void LayerTreeImpl::SetPropertyTrees(PropertyTrees* property_trees) { property_trees_.effect_tree.set_needs_update(true); } -void LayerTreeImpl::UpdatePropertyTreesForBoundsDelta() { - DCHECK(IsActiveTree()); - LayerImpl* inner_container = InnerViewportContainerLayer(); - LayerImpl* outer_container = OuterViewportContainerLayer(); - LayerImpl* inner_scroll = InnerViewportScrollLayer(); - - UpdateClipTreeForBoundsDeltaOnLayer(inner_container, - &property_trees_.clip_tree); - UpdateClipTreeForBoundsDeltaOnLayer(InnerViewportScrollLayer(), - &property_trees_.clip_tree); - UpdateClipTreeForBoundsDeltaOnLayer(outer_container, - &property_trees_.clip_tree); - - if (inner_container) - property_trees_.SetInnerViewportContainerBoundsDelta( - inner_container->bounds_delta()); - if (outer_container) - property_trees_.SetOuterViewportContainerBoundsDelta( - outer_container->bounds_delta()); - if (inner_scroll) - property_trees_.SetInnerViewportScrollBoundsDelta( - inner_scroll->bounds_delta()); -} - -void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { - // The request queue should have been processed and does not require a push. - DCHECK_EQ(ui_resource_request_queue_.size(), 0u); +void LayerTreeImpl::PushPropertyTreesTo(LayerTreeImpl* target_tree) { + // Property trees may store damage status. We preserve the active tree + // damage status by pushing the damage status from active tree property + // trees to pending tree property trees or by moving it onto the layers. + if (target_tree->property_trees()->changed) { + if (property_trees()->sequence_number == + target_tree->property_trees()->sequence_number) + target_tree->property_trees()->PushChangeTrackingTo(property_trees()); + else + target_tree->MoveChangeTrackingToLayers(); + } // To maintain the current scrolling node we need to use element ids which // are stable across the property tree update in SetPropertyTrees. @@ -459,24 +415,19 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { ScrollNode* scrolling_node = nullptr; if (scrolling_element_id) { - auto& scroll_node_index_map = - target_tree->property_trees()->element_id_to_scroll_node_index; - auto scrolling_node_it = scroll_node_index_map.find(scrolling_element_id); - if (scrolling_node_it != scroll_node_index_map.end()) { - int index = scrolling_node_it->second; - scrolling_node = target_tree->property_trees()->scroll_tree.Node(index); - } + auto& scroll_tree = target_tree->property_trees()->scroll_tree; + scrolling_node = scroll_tree.FindNodeFromElementId(scrolling_element_id); } target_tree->SetCurrentlyScrollingNode(scrolling_node); +} + +void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { + // The request queue should have been processed and does not require a push. + DCHECK_EQ(ui_resource_request_queue_.size(), 0u); target_tree->property_trees()->scroll_tree.PushScrollUpdatesFromPendingTree( &property_trees_, target_tree); - // This needs to be called early so that we don't clamp with incorrect max - // offsets when UpdateViewportContainerSizes is called from e.g. - // PushBrowserControls - target_tree->UpdatePropertyTreesForBoundsDelta(); - if (next_activation_forces_redraw_) { target_tree->ForceRedrawNextActivation(); next_activation_forces_redraw_ = false; @@ -491,6 +442,10 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->set_bottom_controls_height(bottom_controls_height_); target_tree->PushBrowserControls(nullptr); + // 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_); + // Active tree already shares the page_scale_factor object with pending // tree so only the limits need to be provided. target_tree->PushPageScaleFactorAndLimits(nullptr, min_page_scale_factor(), @@ -507,10 +462,6 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->pending_page_scale_animation_ = std::move(pending_page_scale_animation_); - target_tree->SetViewportLayersFromIds( - overscroll_elasticity_layer_id_, page_scale_layer_id_, - inner_viewport_scroll_layer_id_, outer_viewport_scroll_layer_id_); - target_tree->RegisterSelection(selection_); // This should match the property synchronization in @@ -543,16 +494,17 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->has_ever_been_drawn_ = false; // Note: this needs to happen after SetPropertyTrees. - target_tree->ShowScrollbars(); + target_tree->HandleScrollbarShowRequestsFromMain(); } -void LayerTreeImpl::ShowScrollbars() { +void LayerTreeImpl::HandleScrollbarShowRequestsFromMain() { LayerTreeHostCommon::CallFunctionForEveryLayer(this, [this]( LayerImpl* layer) { if (!layer->needs_show_scrollbars()) return; ScrollbarAnimationController* controller = - layer_tree_host_impl_->ScrollbarAnimationControllerForId(layer->id()); + layer_tree_host_impl_->ScrollbarAnimationControllerForElementId( + layer->element_id()); if (controller) { controller->DidRequestShowFromMainThread(); layer->set_needs_show_scrollbars(false); @@ -654,24 +606,14 @@ void LayerTreeImpl::RemoveFromElementMap(LayerImpl* layer) { element_layers_map_.erase(layer->element_id()); } -void LayerTreeImpl::AddToOpacityAnimationsMap(int id, float opacity) { - if (LayerImpl* layer = LayerById(id)) - element_id_to_opacity_animations_[layer->element_id()] = opacity; -} - void LayerTreeImpl::SetTransformMutated(ElementId element_id, const gfx::Transform& transform) { DCHECK_EQ(1u, property_trees()->element_id_to_transform_node_index.count( element_id)); element_id_to_transform_animations_[element_id] = transform; - if (!property_trees()->transform_tree.OnTransformAnimated(element_id, - transform)) - return; - - if (LayerImpl* layer = LayerByElementId(element_id)) - layer->set_was_ever_ready_since_last_transform_animation(false); - - set_needs_update_draw_properties(); + if (property_trees()->transform_tree.OnTransformAnimated(element_id, + transform)) + set_needs_update_draw_properties(); } void LayerTreeImpl::SetOpacityMutated(ElementId element_id, float opacity) { @@ -691,18 +633,6 @@ void LayerTreeImpl::SetFilterMutated(ElementId element_id, set_needs_update_draw_properties(); } -LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const { - return InnerViewportScrollLayer() - ? InnerViewportScrollLayer()->scroll_clip_layer() - : NULL; -} - -LayerImpl* LayerTreeImpl::OuterViewportContainerLayer() const { - return OuterViewportScrollLayer() - ? OuterViewportScrollLayer()->scroll_clip_layer() - : NULL; -} - ScrollNode* LayerTreeImpl::CurrentlyScrollingNode() { DCHECK(IsActiveTree()); return property_trees_.scroll_tree.CurrentlyScrollingNode(); @@ -736,14 +666,12 @@ void LayerTreeImpl::SetCurrentlyScrollingNode(ScrollNode* node) { if (old_element_id == new_element_id) return; - // TODO(pdr): Make the scrollbar animation controller lookup based on - // element ids instead of layer ids. ScrollbarAnimationController* old_animation_controller = - layer_tree_host_impl_->ScrollbarAnimationControllerForId( - LayerIdByElementId(old_element_id)); + layer_tree_host_impl_->ScrollbarAnimationControllerForElementId( + old_element_id); ScrollbarAnimationController* new_animation_controller = - layer_tree_host_impl_->ScrollbarAnimationControllerForId( - LayerIdByElementId(new_element_id)); + layer_tree_host_impl_->ScrollbarAnimationControllerForElementId( + new_element_id); if (old_animation_controller) old_animation_controller->DidScrollEnd(); @@ -766,7 +694,8 @@ float LayerTreeImpl::ClampPageScaleFactorToLimits( return page_scale_factor; } -void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() { +void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread( + bool is_impl_side_update) { // TODO(enne): This should get replaced by pulling out scrolling and // animations into their own trees. Then scrolls and animations would have // their own ways of synchronizing across commits. This occurs to push @@ -775,13 +704,19 @@ void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() { // frame to a newly-committed property tree. if (layer_list_.empty()) return; + + // Entries from |element_id_to_*_animations_| should be deleted only after + // they have been synchronized with the main thread, which will not be the + // case if this is an impl-side invalidation. + const bool can_delete_animations = !is_impl_side_update; auto element_id_to_opacity = element_id_to_opacity_animations_.begin(); while (element_id_to_opacity != element_id_to_opacity_animations_.end()) { const ElementId id = element_id_to_opacity->first; if (EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating_opacity || - node->opacity == element_id_to_opacity->second) { + if ((!node->is_currently_animating_opacity || + node->opacity == element_id_to_opacity->second) && + can_delete_animations) { element_id_to_opacity_animations_.erase(element_id_to_opacity++); continue; } @@ -796,8 +731,9 @@ void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() { const ElementId id = element_id_to_filter->first; if (EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating_filter || - node->filters == element_id_to_filter->second) { + if ((!node->is_currently_animating_filter || + node->filters == element_id_to_filter->second) && + can_delete_animations) { element_id_to_filter_animations_.erase(element_id_to_filter++); continue; } @@ -812,8 +748,9 @@ void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() { const ElementId id = element_id_to_transform->first; if (TransformNode* node = property_trees_.transform_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating || - node->local == element_id_to_transform->second) { + if ((!node->is_currently_animating || + node->local == element_id_to_transform->second) && + can_delete_animations) { element_id_to_transform_animations_.erase(element_id_to_transform++); continue; } @@ -831,6 +768,7 @@ void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() { void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) { DCHECK(IsActiveTree()); + DCHECK(lifecycle().AllowsPropertyTreeAccess()); if (page_scale_factor()->SetCurrent( ClampPageScaleFactorToLimits(active_page_scale))) { DidUpdatePageScale(); @@ -881,6 +819,7 @@ void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor, if (changed_page_scale) DidUpdatePageScale(); + DCHECK(lifecycle().AllowsPropertyTreeAccess()); if (page_scale_factor) { if (PageScaleLayer()) { draw_property_utils::UpdatePageScaleFactor( @@ -970,7 +909,14 @@ void LayerTreeImpl::DidUpdatePageScale() { ClampPageScaleFactorToLimits(current_page_scale_factor())); set_needs_update_draw_properties(); - DidUpdateScrollState(inner_viewport_scroll_layer_id_); + DidUpdateScrollState(viewport_layer_ids_.inner_viewport_scroll); + + if (IsActiveTree() && layer_tree_host_impl_->ViewportMainScrollLayer()) { + if (ScrollbarAnimationController* controller = + layer_tree_host_impl_->ScrollbarAnimationControllerForElementId( + OuterViewportScrollLayer()->element_id())) + controller->DidScrollUpdate(); + } } void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) { @@ -1031,22 +977,22 @@ void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { property_trees()->scroll_tree.ApplySentScrollDeltasFromAbortedCommit(); } -void LayerTreeImpl::SetViewportLayersFromIds( - int overscroll_elasticity_layer_id, - int page_scale_layer_id, - int inner_viewport_scroll_layer_id, - int outer_viewport_scroll_layer_id) { - overscroll_elasticity_layer_id_ = overscroll_elasticity_layer_id; - page_scale_layer_id_ = page_scale_layer_id; - inner_viewport_scroll_layer_id_ = inner_viewport_scroll_layer_id; - outer_viewport_scroll_layer_id_ = outer_viewport_scroll_layer_id; +void LayerTreeImpl::SetViewportLayersFromIds(const ViewportLayerIds& ids) { + viewport_layer_ids_ = ids; + + // 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); } void LayerTreeImpl::ClearViewportLayers() { - overscroll_elasticity_layer_id_ = Layer::INVALID_ID; - page_scale_layer_id_ = Layer::INVALID_ID; - inner_viewport_scroll_layer_id_ = Layer::INVALID_ID; - outer_viewport_scroll_layer_id_ = Layer::INVALID_ID; + SetViewportLayersFromIds(ViewportLayerIds()); } // For unit tests, we use the layer's id as its element id. @@ -1077,7 +1023,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { // Clear this after the renderer early out, as it should still be // possible to hit test even without a renderer. - render_surface_layer_list_.clear(); + render_surface_list_.clear(); if (layer_list_.empty()) return false; @@ -1087,24 +1033,18 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { TRACE_EVENT2( "cc", "LayerTreeImpl::UpdateDrawProperties::CalculateDrawProperties", "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_); - // TODO(crbug.com/692780): Remove this option entirely once this get to - // stable and proves it works. - bool can_render_to_separate_surface = true; - // 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], DrawViewportSize(), + layer_list_[0], DeviceViewport().size(), layer_tree_host_impl_->DrawTransform(), device_scale_factor(), current_page_scale_factor(), PageScaleLayer(), InnerViewportScrollLayer(), OuterViewportScrollLayer(), elastic_overscroll()->Current(IsActiveTree()), OverscrollElasticityLayer(), resource_provider()->max_texture_size(), - can_render_to_separate_surface, settings().layer_transforms_should_scale_layer_contents, - settings().use_layer_lists, &render_surface_layer_list_, - &property_trees_); + &render_surface_list_, &property_trees_); LayerTreeHostCommon::CalculateDrawProperties(&inputs); if (const char* client_name = GetClientNameForMetrics()) { UMA_HISTOGRAM_COUNTS( @@ -1114,7 +1054,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { timer.Elapsed().InMicroseconds()); UMA_HISTOGRAM_COUNTS_100( base::StringPrintf("Compositing.%s.NumRenderSurfaces", client_name), - base::saturated_cast<int>(render_surface_layer_list_.size())); + base::saturated_cast<int>(render_surface_list_.size())); } } @@ -1122,8 +1062,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { TRACE_EVENT2("cc", "LayerTreeImpl::UpdateDrawProperties::Occlusion", "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_); - OcclusionTracker occlusion_tracker( - layer_list_[0]->GetRenderSurface()->content_rect()); + OcclusionTracker occlusion_tracker(RootRenderSurface()->content_rect()); occlusion_tracker.set_minimum_tracking_size( settings().minimum_occlusion_tracking_size); @@ -1205,7 +1144,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { size_t layers_updated_count = 0; bool tile_priorities_updated = false; for (PictureLayerImpl* layer : picture_layers_) { - if (!layer->is_drawn_render_surface_layer_list_member()) + if (!layer->contributes_to_drawn_render_surface()) continue; ++layers_updated_count; tile_priorities_updated |= layer->UpdateTiles(); @@ -1237,36 +1176,40 @@ void LayerTreeImpl::BuildPropertyTreesForTesting() { OuterViewportScrollLayer(), OverscrollElasticityLayer(), elastic_overscroll()->Current(IsActiveTree()), current_page_scale_factor(), device_scale_factor(), - gfx::Rect(DrawViewportSize()), layer_tree_host_impl_->DrawTransform(), - &property_trees_); + gfx::Rect(DeviceViewport().size()), + layer_tree_host_impl_->DrawTransform(), &property_trees_); property_trees_.transform_tree.set_source_to_parent_updates_allowed(false); } -const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const { +const RenderSurfaceList& LayerTreeImpl::GetRenderSurfaceList() const { // If this assert triggers, then the list is dirty. DCHECK(!needs_update_draw_properties_); - return render_surface_layer_list_; + return render_surface_list_; } const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const { - // If this assert triggers, then the render_surface_layer_list_ is dirty, so - // the unoccluded_screen_space_region_ is not valid anymore. + // If this assert triggers, then the render_surface_list_ is dirty, so the + // unoccluded_screen_space_region_ is not valid anymore. DCHECK(!needs_update_draw_properties_); return unoccluded_screen_space_region_; } gfx::SizeF LayerTreeImpl::ScrollableSize() const { - LayerImpl* root_scroll_layer = OuterViewportScrollLayer() - ? OuterViewportScrollLayer() - : InnerViewportScrollLayer(); - if (!root_scroll_layer) + LayerImpl* root_scroll_layer = nullptr; + LayerImpl* root_container_layer = nullptr; + if (OuterViewportScrollLayer()) { + root_scroll_layer = OuterViewportScrollLayer(); + root_container_layer = OuterViewportContainerLayer(); + } else if (InnerViewportScrollLayer()) { + root_scroll_layer = InnerViewportScrollLayer(); + root_container_layer = InnerViewportContainerLayer(); + } + + if (!root_scroll_layer || !root_container_layer) return gfx::SizeF(); gfx::SizeF content_size = root_scroll_layer->BoundsForScrolling(); - gfx::SizeF viewport_size = - root_scroll_layer->scroll_clip_layer()->BoundsForScrolling(); - - content_size.SetToMax(viewport_size); + content_size.SetToMax(root_container_layer->BoundsForScrolling()); return content_size; } @@ -1460,36 +1403,31 @@ gfx::Rect LayerTreeImpl::DeviceViewport() const { return layer_tree_host_impl_->DeviceViewport(); } -gfx::Size LayerTreeImpl::DrawViewportSize() const { - return layer_tree_host_impl_->DrawViewportSize(); -} - const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const { return layer_tree_host_impl_->ViewportRectForTilePriority(); } std::unique_ptr<ScrollbarAnimationController> -LayerTreeImpl::CreateScrollbarAnimationController(int scroll_layer_id) { +LayerTreeImpl::CreateScrollbarAnimationController(ElementId scroll_element_id, + float initial_opacity) { DCHECK(!settings().scrollbar_fade_delay.is_zero()); DCHECK(!settings().scrollbar_fade_duration.is_zero()); base::TimeDelta fade_delay = settings().scrollbar_fade_delay; - base::TimeDelta fade_out_resize_delay = - settings().scrollbar_fade_out_resize_delay; base::TimeDelta fade_duration = settings().scrollbar_fade_duration; switch (settings().scrollbar_animator) { case LayerTreeSettings::ANDROID_OVERLAY: { return ScrollbarAnimationController:: CreateScrollbarAnimationControllerAndroid( - scroll_layer_id, layer_tree_host_impl_, fade_delay, - fade_out_resize_delay, fade_duration); + scroll_element_id, layer_tree_host_impl_, fade_delay, + fade_duration, initial_opacity); } case LayerTreeSettings::AURA_OVERLAY: { base::TimeDelta thinning_duration = settings().scrollbar_thinning_duration; return ScrollbarAnimationController:: CreateScrollbarAnimationControllerAuraOverlay( - scroll_layer_id, layer_tree_host_impl_, fade_delay, - fade_out_resize_delay, fade_duration, thinning_duration); + scroll_element_id, layer_tree_host_impl_, fade_delay, + fade_duration, thinning_duration, initial_opacity); } case LayerTreeSettings::NO_ANIMATOR: NOTREACHED(); @@ -1522,7 +1460,7 @@ 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->is_drawn_render_surface_layer_list_member()) + if (!layer_impl->contributes_to_drawn_render_surface()) continue; layer_impl->GetAllPrioritizedTilesForTracing(prioritized_tiles); } @@ -1534,7 +1472,7 @@ void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const { state->BeginArray("render_surface_layer_list"); for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) { - if (!(*it)->is_drawn_render_surface_layer_list_member()) + if (!(*it)->contributes_to_drawn_render_surface()) continue; TracedValue::AppendIDRef(*it, state); } @@ -1719,41 +1657,65 @@ void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { } void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) { - if (scrollbar_layer->ScrollLayerId() == Layer::INVALID_ID) + ElementId scroll_element_id = scrollbar_layer->scroll_element_id(); + if (!scroll_element_id) return; - scrollbar_map_.insert(std::pair<int, int>(scrollbar_layer->ScrollLayerId(), - scrollbar_layer->id())); - if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar()) + auto& scrollbar_ids = element_id_to_scrollbar_layer_ids_[scroll_element_id]; + if (scrollbar_layer->orientation() == HORIZONTAL) { + DCHECK_EQ(scrollbar_ids.horizontal, Layer::INVALID_ID) + << "Existing scrollbar should have been unregistered."; + scrollbar_ids.horizontal = scrollbar_layer->id(); + } else { + DCHECK_EQ(scrollbar_ids.vertical, Layer::INVALID_ID) + << "Existing scrollbar should have been unregistered."; + scrollbar_ids.vertical = scrollbar_layer->id(); + } + + if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar() && + scrollbar_layer->GetScrollbarAnimator() != + LayerTreeSettings::NO_ANIMATOR) { layer_tree_host_impl_->RegisterScrollbarAnimationController( - scrollbar_layer->ScrollLayerId()); + scroll_element_id, scrollbar_layer->Opacity()); + } - DidUpdateScrollState(scrollbar_layer->ScrollLayerId()); + // TODO(pdr): Refactor DidUpdateScrollState to use ElementIds instead of + // layer ids and remove this use of LayerIdByElementId. + DidUpdateScrollState(LayerIdByElementId(scroll_element_id)); } void LayerTreeImpl::UnregisterScrollbar( ScrollbarLayerImplBase* scrollbar_layer) { - int scroll_layer_id = scrollbar_layer->ScrollLayerId(); - if (scroll_layer_id == Layer::INVALID_ID) + ElementId scroll_element_id = scrollbar_layer->scroll_element_id(); + if (!scroll_element_id) return; - auto scrollbar_range = scrollbar_map_.equal_range(scroll_layer_id); - for (auto i = scrollbar_range.first; i != scrollbar_range.second; ++i) - if (i->second == scrollbar_layer->id()) { - scrollbar_map_.erase(i); - break; + auto& scrollbar_ids = element_id_to_scrollbar_layer_ids_[scroll_element_id]; + if (scrollbar_layer->orientation() == HORIZONTAL) + scrollbar_ids.horizontal = Layer::INVALID_ID; + else + scrollbar_ids.vertical = Layer::INVALID_ID; + + if (scrollbar_ids.horizontal == Layer::INVALID_ID && + scrollbar_ids.vertical == Layer::INVALID_ID) { + element_id_to_scrollbar_layer_ids_.erase(scroll_element_id); + if (IsActiveTree()) { + layer_tree_host_impl_->UnregisterScrollbarAnimationController( + scroll_element_id); } - - if (IsActiveTree() && scrollbar_map_.count(scroll_layer_id) == 0) - layer_tree_host_impl_->UnregisterScrollbarAnimationController( - scroll_layer_id); + } } -ScrollbarSet LayerTreeImpl::ScrollbarsFor(int scroll_layer_id) const { +ScrollbarSet LayerTreeImpl::ScrollbarsFor(ElementId scroll_element_id) const { ScrollbarSet scrollbars; - auto scrollbar_range = scrollbar_map_.equal_range(scroll_layer_id); - for (auto i = scrollbar_range.first; i != scrollbar_range.second; ++i) - scrollbars.insert(LayerById(i->second)->ToScrollbarLayer()); + auto it = element_id_to_scrollbar_layer_ids_.find(scroll_element_id); + if (it != element_id_to_scrollbar_layer_ids_.end()) { + const ScrollbarLayerIds& layer_ids = it->second; + if (layer_ids.horizontal != Layer::INVALID_ID) + scrollbars.insert(LayerById(layer_ids.horizontal)->ToScrollbarLayer()); + if (layer_ids.vertical != Layer::INVALID_ID) + scrollbars.insert(LayerById(layer_ids.vertical)->ToScrollbarLayer()); + } return scrollbars; } @@ -1765,6 +1727,9 @@ void LayerTreeImpl::RegisterScrollLayer(LayerImpl* layer) { std::pair<int, int>(layer->scroll_clip_layer_id(), layer->id())); DidUpdateScrollState(layer->id()); + + if (settings().scrollbar_animator == LayerTreeSettings::AURA_OVERLAY) + layer->set_needs_show_scrollbars(true); } void LayerTreeImpl::UnregisterScrollLayer(LayerImpl* layer) { @@ -1854,20 +1819,6 @@ static bool PointHitsRegion(const gfx::PointF& screen_space_point, gfx::ToRoundedPoint(hit_test_point_in_layer_space)); } -static const gfx::Transform SurfaceScreenSpaceTransform( - const LayerImpl* layer) { - const PropertyTrees* property_trees = - layer->layer_tree_impl()->property_trees(); - RenderSurfaceImpl* render_surface = layer->GetRenderSurface(); - DCHECK(render_surface); - return layer->is_drawn_render_surface_layer_list_member() - ? render_surface->screen_space_transform() - : property_trees - ->ToScreenSpaceTransformWithoutSurfaceContentsScale( - render_surface->TransformTreeIndex(), - render_surface->EffectTreeIndex()); -} - static bool PointIsClippedByAncestorClipNode( const gfx::PointF& screen_space_point, const LayerImpl* layer) { @@ -1901,15 +1852,6 @@ static bool PointIsClippedByAncestorClipNode( return true; } } - const LayerImpl* clip_node_owner = - layer->layer_tree_impl()->LayerById(clip_node->owning_layer_id); - RenderSurfaceImpl* render_surface = clip_node_owner->GetRenderSurface(); - if (render_surface && - !PointHitsRect(screen_space_point, - SurfaceScreenSpaceTransform(clip_node_owner), - render_surface->content_rect(), NULL)) { - return true; - } } return false; } @@ -2013,7 +1955,7 @@ LayerTreeImpl::FindFirstScrollingLayerOrDrawnScrollbarThatIsHitByPoint( struct HitTestVisibleScrollableOrTouchableFunctor { bool operator()(LayerImpl* layer) const { return layer->scrollable() || - layer->is_drawn_render_surface_layer_list_member() || + layer->contributes_to_drawn_render_surface() || !layer->touch_event_handler_region().IsEmpty(); } }; diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index 1d785f86e4e..ccff3c2447b 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -54,6 +54,35 @@ typedef std::vector<UIResourceRequest> UIResourceRequestQueue; typedef SyncedProperty<AdditionGroup<float>> SyncedBrowserControls; typedef SyncedProperty<AdditionGroup<gfx::Vector2dF>> SyncedElasticOverscroll; +class LayerTreeLifecycle { + public: + enum LifecycleState { + kNotSyncing, + + // The following states are the steps performed when syncing properties to + // this tree (see: LayerTreeHost::FinishCommitOnImplThread or + // LayerTreeHostImpl::ActivateSyncTree). + kBeginningSync, + kSyncedPropertyTrees, + kSyncedLayerProperties, + kLastSyncState = kSyncedLayerProperties, + + // TODO(pdr): Add states to cover more than just the synchronization steps. + }; + + void AdvanceTo(LifecycleState); + + bool AllowsPropertyTreeAccess() const { + return state_ == kNotSyncing || state_ >= kSyncedPropertyTrees; + } + bool AllowsLayerPropertyAccess() const { + return state_ == kNotSyncing || state_ >= kSyncedLayerProperties; + } + + private: + LifecycleState state_ = kNotSyncing; +}; + class CC_EXPORT LayerTreeImpl { public: // This is the number of times a fixed point has to be hit continuously by a @@ -92,10 +121,10 @@ class CC_EXPORT LayerTreeImpl { BeginFrameArgs CurrentBeginFrameArgs() const; base::TimeDelta CurrentBeginFrameInterval() const; gfx::Rect DeviceViewport() const; - gfx::Size DrawViewportSize() const; const gfx::Rect ViewportRectForTilePriority() const; std::unique_ptr<ScrollbarAnimationController> - CreateScrollbarAnimationController(int scroll_layer_id); + CreateScrollbarAnimationController(ElementId scroll_element_id, + float initial_opacity); void DidAnimateScrollOffset(); bool use_gpu_rasterization() const; GpuRasterizationStatus GetGpuRasterizationStatus() const; @@ -122,7 +151,7 @@ class CC_EXPORT LayerTreeImpl { LayerImpl* root_layer_for_testing() { return layer_list_.empty() ? nullptr : layer_list_[0]; } - RenderSurfaceImpl* RootRenderSurface() const; + const RenderSurfaceImpl* RootRenderSurface() const; bool LayerListIsEmpty() const; void SetRootLayerForTesting(std::unique_ptr<LayerImpl>); void OnCanDrawStateChangedForTree(); @@ -130,10 +159,14 @@ class CC_EXPORT LayerTreeImpl { std::unique_ptr<OwnedLayerImplList> DetachLayers(); void SetPropertyTrees(PropertyTrees* property_trees); - PropertyTrees* property_trees() { return &property_trees_; } - - void UpdatePropertyTreesForBoundsDelta(); + PropertyTrees* property_trees() { + // TODO(pdr): We should enable this DCHECK because it will catch uses of + // stale property trees, but it currently fails too many existing tests. + // DCHECK(lifecycle().AllowsPropertyTreeAccess()); + return &property_trees_; + } + void PushPropertyTreesTo(LayerTreeImpl* tree_impl); void PushPropertiesTo(LayerTreeImpl* tree_impl); void MoveChangeTrackingToLayers(); @@ -145,10 +178,6 @@ class CC_EXPORT LayerTreeImpl { LayerImplList::reverse_iterator rbegin(); LayerImplList::reverse_iterator rend(); - // TODO(crbug.com/702832): This won't be needed if overlay scrollbars have - // element ids. - void AddToOpacityAnimationsMap(int id, float opacity); - void SetTransformMutated(ElementId element_id, const gfx::Transform& transform); void SetOpacityMutated(ElementId element_id, float opacity); @@ -173,29 +202,44 @@ class CC_EXPORT LayerTreeImpl { hud_layer_ = layer_impl; } - LayerImpl* InnerViewportScrollLayer() const; - // This function may return NULL, it is the caller's responsibility to check. - LayerImpl* OuterViewportScrollLayer() const; gfx::ScrollOffset TotalScrollOffset() const; gfx::ScrollOffset TotalMaxScrollOffset() const; - LayerImpl* InnerViewportContainerLayer() const; - LayerImpl* OuterViewportContainerLayer() const; ScrollNode* CurrentlyScrollingNode(); const ScrollNode* CurrentlyScrollingNode() const; int LastScrolledScrollNodeIndex() const; void SetCurrentlyScrollingNode(ScrollNode* node); void ClearCurrentlyScrollingNode(); - void SetViewportLayersFromIds(int overscroll_elasticity_layer, - int page_scale_layer_id, - int inner_viewport_scroll_layer_id, - int outer_viewport_scroll_layer_id); + struct ViewportLayerIds { + int overscroll_elasticity = Layer::INVALID_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; + }; + void SetViewportLayersFromIds(const ViewportLayerIds& viewport_layer_ids); void ClearViewportLayers(); - LayerImpl* OverscrollElasticityLayer() { - return LayerById(overscroll_elasticity_layer_id_); + LayerImpl* OverscrollElasticityLayer() const { + return LayerById(viewport_layer_ids_.overscroll_elasticity); + } + 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); } - LayerImpl* PageScaleLayer() { return LayerById(page_scale_layer_id_); } + LayerImpl* OuterViewportScrollLayer() const { + return LayerById(viewport_layer_ids_.outer_viewport_scroll); + } + void ApplySentScrollAndScaleDeltasFromAbortedCommit(); SkColor background_color() const { return background_color_; } @@ -208,7 +252,8 @@ class CC_EXPORT LayerTreeImpl { has_transparent_background_ = transparent; } - void UpdatePropertyTreeScrollingAndAnimationFromMainThread(); + void UpdatePropertyTreeScrollingAndAnimationFromMainThread( + bool is_impl_side_update); void SetPageScaleOnActiveTree(float active_page_scale); void PushPageScaleFromMainThread(float page_scale_factor, float min_page_scale_factor, @@ -294,7 +339,7 @@ class CC_EXPORT LayerTreeImpl { void set_ui_resource_request_queue(UIResourceRequestQueue queue); - const LayerImplList& RenderSurfaceLayerList() const; + const RenderSurfaceList& GetRenderSurfaceList() const; const Region& UnoccludedScreenSpaceRegion() const; // These return the size of the root scrollable area and the size of @@ -395,7 +440,7 @@ class CC_EXPORT LayerTreeImpl { void RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer); void UnregisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer); - ScrollbarSet ScrollbarsFor(int scroll_layer_id) const; + ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const; void RegisterScrollLayer(LayerImpl* layer); void UnregisterScrollLayer(LayerImpl* layer); @@ -465,8 +510,12 @@ class CC_EXPORT LayerTreeImpl { void ClearLayerList(); void BuildLayerListForTesting(); + void HandleScrollbarShowRequestsFromMain(); + + void InvalidateRegionForImages( + const PaintImageIdFlatSet& images_to_invalidate); - void InvalidateRegionForImages(const ImageIdFlatSet& images_to_invalidate); + LayerTreeLifecycle& lifecycle() { return lifecycle_; } protected: float ClampPageScaleFactorToLimits(float page_scale_factor) const; @@ -477,7 +526,6 @@ class CC_EXPORT LayerTreeImpl { float max_page_scale_factor); bool IsViewportLayerId(int id) const; void UpdateScrollbars(int scroll_layer_id, int clip_layer_id); - void ShowScrollbars(); void DidUpdatePageScale(); void PushBrowserControls(const float* top_controls_shown_ratio); bool ClampBrowserControlsShownRatio(); @@ -492,10 +540,8 @@ class CC_EXPORT LayerTreeImpl { bool has_transparent_background_; int last_scrolled_scroll_node_index_; - int overscroll_elasticity_layer_id_; - int page_scale_layer_id_; - int inner_viewport_scroll_layer_id_; - int outer_viewport_scroll_layer_id_; + + ViewportLayerIds viewport_layer_ids_; LayerSelection selection_; @@ -532,18 +578,21 @@ class CC_EXPORT LayerTreeImpl { // derived from LayerImpl::scroll_clip_layer_ and exists to avoid O(n) walks.) std::unordered_map<int, int> clip_scroll_map_; - // Maps scroll layer ids to scrollbar layer ids. For each scroll layer, there - // may be 1 or 2 scrollbar layers (for vertical and horizontal). (This is - // derived from ScrollbarLayerImplBase::scroll_layer_id_ and exists to avoid - // O(n) walks.) - std::multimap<int, int> scrollbar_map_; + struct ScrollbarLayerIds { + int horizontal = Layer::INVALID_ID; + int vertical = Layer::INVALID_ID; + }; + // Each scroll layer can have up to two scrollbar layers (vertical and + // horizontal). This mapping is maintained as part of scrollbar registration. + base::flat_map<ElementId, ScrollbarLayerIds> + element_id_to_scrollbar_layer_ids_; std::vector<PictureLayerImpl*> picture_layers_; LayerImplList surface_layers_; - // List of visible layers for the most recently prepared frame. - LayerImplList render_surface_layer_list_; - // After drawing the |render_surface_layer_list_| the areas in this region + // List of render surfaces for the most recently prepared frame. + RenderSurfaceList render_surface_list_; + // After drawing the |render_surface_list_| the areas in this region // would not be fully covered by opaque content. Region unoccluded_screen_space_region_; @@ -581,6 +630,10 @@ class CC_EXPORT LayerTreeImpl { std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_; + // Tracks the lifecycle which is used for enforcing dependencies between + // lifecycle states. See: |LayerTreeLifecycle|. + LayerTreeLifecycle lifecycle_; + private: DISALLOW_COPY_AND_ASSIGN(LayerTreeImpl); }; diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc index 3b0cbeec663..836ba530118 100644 --- a/chromium/cc/trees/layer_tree_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_impl_unittest.cc @@ -36,8 +36,8 @@ class LayerTreeImplTest : public testing::Test { LayerImpl* root_layer() { return impl_test_.root_layer_for_testing(); } - const LayerImplList& RenderSurfaceLayerList() const { - return host_impl().active_tree()->RenderSurfaceLayerList(); + const RenderSurfaceList& GetRenderSurfaceList() const { + return host_impl().active_tree()->GetRenderSurfaceList(); } void ExecuteCalculateDrawProperties(LayerImpl* root_layer) { @@ -45,9 +45,9 @@ class LayerTreeImplTest : public testing::Test { // empty. DCHECK(!root_layer->bounds().IsEmpty()); - render_surface_layer_list_impl_.clear(); + render_surface_list_impl_.clear(); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_layer, root_layer->bounds(), &render_surface_layer_list_impl_); + root_layer, root_layer->bounds(), &render_surface_list_impl_); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); } @@ -105,7 +105,7 @@ class LayerTreeImplTest : public testing::Test { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayerForTesting(std::move(root)); host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); - CHECK_EQ(1u, RenderSurfaceLayerList().size()); + CHECK_EQ(1u, GetRenderSurfaceList().size()); gfx::PointF test_point = gfx::PointF(1.f, 1.f); LayerImpl* result_layer = @@ -117,7 +117,7 @@ class LayerTreeImplTest : public testing::Test { private: LayerTestCommon::LayerImplTest impl_test_; - std::vector<LayerImpl*> render_surface_layer_list_impl_; + RenderSurfaceList render_surface_list_impl_; }; TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { @@ -130,8 +130,8 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root_layer()->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); // Hit testing for a point outside the layer should return a null pointer. gfx::PointF test_point(101.f, 101.f); @@ -199,8 +199,8 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(2u, root_layer()->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(2, GetRenderSurface(root_layer())->num_contributors()); // Hit testing for a point inside HUD, but outside root should return null gfx::PointF test_point(101.f, 101.f); @@ -244,8 +244,8 @@ TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) { host_impl().SetViewportSize(root->bounds()); host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root_layer()->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); ASSERT_FALSE(root_layer()->ScreenSpaceTransform().IsInvertible()); // Hit testing any point should not hit the layer. If the invertible matrix is @@ -299,8 +299,8 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root_layer()->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); // Hit testing for a point outside the layer should return a null pointer. gfx::PointF test_point(49.f, 49.f); @@ -344,8 +344,8 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root_layer()->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); // Hit testing for points outside the layer. // These corners would have been inside the un-transformed layer, but they @@ -461,37 +461,6 @@ TEST_F(LayerTreeImplTest, HitTestingSiblings) { EXPECT_EQ(3, result_layer->id()); } -TEST_F(LayerTreeImplTest, HitTestingPointOutsideMaxTextureSize) { - gfx::Transform identity_matrix; - int max_texture_size = - host_impl().active_tree()->resource_provider()->max_texture_size(); - gfx::Size bounds(max_texture_size + 100, max_texture_size + 100); - - LayerImpl* root = root_layer(); - root->SetBounds(bounds); - - std::unique_ptr<LayerImpl> surface = - LayerImpl::Create(host_impl().active_tree(), 2); - surface->SetBounds(bounds); - surface->SetMasksToBounds(true); - surface->SetDrawsContent(true); - surface->test_properties()->force_render_surface = true; - - root->test_properties()->AddChild(std::move(surface)); - host_impl().SetViewportSize(root->bounds()); - host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); - - gfx::PointF test_point(max_texture_size - 50, max_texture_size - 50); - LayerImpl* result_layer = - host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - EXPECT_TRUE(result_layer); - - test_point = gfx::PointF(max_texture_size + 50, max_texture_size + 50); - result_layer = - host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point); - EXPECT_FALSE(result_layer); -} - TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) { // perspective_projection_about_center * translation_by_z is designed so that // the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50). @@ -512,8 +481,8 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root_layer()->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); // Hit testing for points outside the layer. // These corners would have been inside the un-transformed layer, but they @@ -570,9 +539,10 @@ TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root_layer()->GetRenderSurface()->layer_list().size()); - ASSERT_EQ(456, root_layer()->GetRenderSurface()->layer_list().at(0)->id()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); + LayerImpl* child_layer = host_impl().active_tree()->LayerById(456); + EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface()); // Hit testing for a point outside the layer should return a null pointer. // Despite the child layer being very large, it should be clipped to the root @@ -747,9 +717,10 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root_layer()->GetRenderSurface()->layer_list().size()); - ASSERT_EQ(456, root_layer()->GetRenderSurface()->layer_list().at(0)->id()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors()); + LayerImpl* child_layer = host_impl().active_tree()->LayerById(456); + EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface()); // Hit testing for a point outside the layer should return a null pointer. gfx::PointF test_point(69.f, 69.f); @@ -827,14 +798,14 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) { ASSERT_TRUE(child1); ASSERT_TRUE(child2); ASSERT_TRUE(grand_child1); - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); - RenderSurfaceImpl* root_render_surface = root->GetRenderSurface(); - ASSERT_EQ(4u, root_render_surface->layer_list().size()); - ASSERT_EQ(1, root_render_surface->layer_list().at(0)->id()); // root layer - ASSERT_EQ(2, root_render_surface->layer_list().at(1)->id()); // child1 - ASSERT_EQ(4, root_render_surface->layer_list().at(2)->id()); // grand_child1 - ASSERT_EQ(3, root_render_surface->layer_list().at(3)->id()); // child2 + RenderSurfaceImpl* root_render_surface = GetRenderSurface(root); + ASSERT_EQ(4, root_render_surface->num_contributors()); + EXPECT_TRUE(root_layer()->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child1->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child2->contributes_to_drawn_render_surface()); + EXPECT_TRUE(grand_child1->contributes_to_drawn_render_surface()); // Nothing overlaps the root at (1, 1), so hit testing there should find // the root layer. @@ -979,7 +950,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { ASSERT_TRUE(child1); ASSERT_TRUE(child2); ASSERT_TRUE(grand_child1); - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); // Nothing overlaps the root_layer at (1, 1), so hit testing there should find // the root layer. @@ -1176,21 +1147,21 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { ASSERT_TRUE(child1); ASSERT_TRUE(child2); ASSERT_TRUE(grand_child1); - ASSERT_TRUE(child1->GetRenderSurface()); - ASSERT_TRUE(child2->GetRenderSurface()); - ASSERT_TRUE(grand_child1->GetRenderSurface()); - ASSERT_EQ(4u, RenderSurfaceLayerList().size()); + ASSERT_TRUE(GetRenderSurface(child1)); + ASSERT_TRUE(GetRenderSurface(child2)); + ASSERT_TRUE(GetRenderSurface(grand_child1)); + ASSERT_EQ(4u, GetRenderSurfaceList().size()); // The root surface has the root layer, and child1's and child2's render // surfaces. - ASSERT_EQ(3u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(3, GetRenderSurface(root)->num_contributors()); // The child1 surface has the child1 layer and grand_child1's render surface. - ASSERT_EQ(2u, child1->GetRenderSurface()->layer_list().size()); - ASSERT_EQ(1u, child2->GetRenderSurface()->layer_list().size()); - ASSERT_EQ(1u, grand_child1->GetRenderSurface()->layer_list().size()); - ASSERT_EQ(1, RenderSurfaceLayerList().at(0)->id()); // root layer - ASSERT_EQ(2, RenderSurfaceLayerList()[1]->id()); // child1 - ASSERT_EQ(4, RenderSurfaceLayerList().at(2)->id()); // grand_child1 - ASSERT_EQ(3, RenderSurfaceLayerList()[3]->id()); // child2 + ASSERT_EQ(2, GetRenderSurface(child1)->num_contributors()); + ASSERT_EQ(1, GetRenderSurface(child2)->num_contributors()); + ASSERT_EQ(1, GetRenderSurface(grand_child1)->num_contributors()); + EXPECT_TRUE(root_layer()->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child1->contributes_to_drawn_render_surface()); + EXPECT_TRUE(grand_child1->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child2->contributes_to_drawn_render_surface()); // Nothing overlaps the root at (1, 1), so hit testing there should find // the root layer. @@ -1251,8 +1222,8 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); // Hit checking for any point should return a null pointer for a layer without // any touch event handler regions. @@ -1328,8 +1299,8 @@ TEST_F(LayerTreeImplTest, host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); ASSERT_FALSE(root->ScreenSpaceTransform().IsInvertible()); // Hit checking any point should not hit the touch handler region on the @@ -1395,8 +1366,8 @@ TEST_F(LayerTreeImplTest, host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); // Hit checking for a point outside the layer should return a null pointer. gfx::PointF test_point(49.f, 49.f); @@ -1468,8 +1439,10 @@ TEST_F(LayerTreeImplTest, host_impl().SetViewportSize(scaled_bounds_for_root); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); - host_impl().active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 1, - Layer::INVALID_ID); + LayerTreeImpl::ViewportLayerIds viewport_ids; + viewport_ids.page_scale = 1; + viewport_ids.inner_viewport_scroll = 1; + host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl().active_tree()->PushPageScaleFromMainThread( page_scale_factor, page_scale_factor, max_page_scale_factor); @@ -1480,8 +1453,8 @@ TEST_F(LayerTreeImplTest, // The visible content rect for test_layer is actually 100x100, even though // its layout size is 50x50, positioned at 25x25. LayerImpl* test_layer = root->test_properties()->children[0]; - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); // Check whether the child layer fits into the root after scaled. EXPECT_EQ(gfx::Rect(test_layer->bounds()), test_layer->visible_layer_rect()); @@ -1607,9 +1580,10 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root->GetRenderSurface()->layer_list().size()); - ASSERT_EQ(456, root->GetRenderSurface()->layer_list().at(0)->id()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); + LayerImpl* child_layer = host_impl().active_tree()->LayerById(456); + EXPECT_TRUE(child_layer->contributes_to_drawn_render_surface()); // Hit checking for a point outside the layer should return a null pointer. // Despite the child layer being very large, it should be clipped to the root @@ -1694,8 +1668,10 @@ TEST_F(LayerTreeImplTest, host_impl().SetViewportSize(scaled_bounds_for_root); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); - host_impl().active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 1, - Layer::INVALID_ID); + LayerTreeImpl::ViewportLayerIds viewport_ids; + viewport_ids.page_scale = 1; + viewport_ids.inner_viewport_scroll = 1; + host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); host_impl().active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl().active_tree()->PushPageScaleFromMainThread( page_scale_factor, page_scale_factor, max_page_scale_factor); @@ -1703,7 +1679,7 @@ TEST_F(LayerTreeImplTest, host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(2u, RenderSurfaceLayerList().size()); + ASSERT_EQ(2u, GetRenderSurfaceList().size()); // Hit checking for a point outside the layer should return a null pointer. // Despite the child layer being very large, it should be clipped to the root @@ -1760,10 +1736,12 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(2u, root->GetRenderSurface()->layer_list().size()); - ASSERT_EQ(123, root->GetRenderSurface()->layer_list().at(0)->id()); - ASSERT_EQ(1234, root->GetRenderSurface()->layer_list().at(1)->id()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(2, GetRenderSurface(root)->num_contributors()); + LayerImpl* touch_layer = host_impl().active_tree()->LayerById(123); + LayerImpl* notouch_layer = host_impl().active_tree()->LayerById(1234); + EXPECT_TRUE(touch_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(notouch_layer->contributes_to_drawn_render_surface()); gfx::PointF test_point(35.f, 35.f); LayerImpl* result_layer = @@ -1816,10 +1794,10 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); LayerImpl* test_layer = root->test_properties()->children[0]; - // As test_layer doesn't draw content, the layer list of root's render surface - // should contain only the root layer. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root->GetRenderSurface()->layer_list().size()); + // As test_layer doesn't draw content, it shouldn't contribute content to the + // root surface. + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + EXPECT_FALSE(test_layer->contributes_to_drawn_render_surface()); // Hit testing for a point outside the test layer should return null pointer. // We also implicitly check that the updated screen space transform of a layer @@ -1837,7 +1815,7 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion( test_point); EXPECT_FALSE(result_layer); - EXPECT_FALSE(test_layer->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(test_layer->contributes_to_drawn_render_surface()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_screen_space_transform, draw_property_utils::ScreenSpaceTransform( @@ -1859,7 +1837,7 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { test_point); ASSERT_TRUE(result_layer); ASSERT_EQ(test_layer, result_layer); - EXPECT_FALSE(result_layer->is_drawn_render_surface_layer_list_member()); + EXPECT_FALSE(result_layer->contributes_to_drawn_render_surface()); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_screen_space_transform, draw_property_utils::ScreenSpaceTransform( @@ -1876,8 +1854,8 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); - ASSERT_EQ(1u, root->GetRenderSurface()->layer_list().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); + ASSERT_EQ(1, GetRenderSurface(root)->num_contributors()); LayerSelection input; @@ -1957,7 +1935,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); LayerSelection input; input.start.type = gfx::SelectionBound::LEFT; @@ -2084,18 +2062,19 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { root->bounds(), device_scale_factor * page_scale_factor); host_impl().SetViewportSize(scaled_bounds_for_root); - host_impl().active_tree()->SetViewportLayersFromIds(0, root->id(), 0, 0); + LayerTreeImpl::ViewportLayerIds viewport_ids; + viewport_ids.page_scale = root->id(); + host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - host_impl().active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 1, - Layer::INVALID_ID); + host_impl().active_tree()->PushPageScaleFromMainThread( page_scale_factor, page_scale_factor, page_scale_factor); host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. - ASSERT_EQ(1u, RenderSurfaceLayerList().size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); LayerSelection input; input.start.type = gfx::SelectionBound::LEFT; @@ -2263,7 +2242,7 @@ TEST_F(LayerTreeImplTest, HitTestingCorrectLayerWheelListener) { host_impl().SetViewportSize(root->bounds()); host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); - CHECK_EQ(1u, RenderSurfaceLayerList().size()); + CHECK_EQ(1u, GetRenderSurfaceList().size()); gfx::PointF test_point = gfx::PointF(1.f, 1.f); LayerImpl* result_layer = diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index 90348788b5e..5191cdc20e3 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -50,7 +50,6 @@ class CC_EXPORT LayerTreeSettings { }; ScrollbarAnimator scrollbar_animator = NO_ANIMATOR; base::TimeDelta scrollbar_fade_delay; - base::TimeDelta scrollbar_fade_out_resize_delay; base::TimeDelta scrollbar_fade_duration; base::TimeDelta scrollbar_thinning_duration; SkColor solid_color_scrollbar_color = SK_ColorWHITE; @@ -79,11 +78,6 @@ class CC_EXPORT LayerTreeSettings { bool ignore_root_layer_flings = false; size_t scheduled_raster_task_limit = 32; bool use_occlusion_for_tile_prioritization = false; - - // TODO(khushalsagar): Enable for all client and remove this flag if possible. - // See crbug/com/696864. - bool image_decode_tasks_enabled = false; - bool use_layer_lists = false; int max_staging_buffer_usage_in_bytes = 32 * 1024 * 1024; ManagedMemoryPolicy gpu_memory_policy; @@ -112,6 +106,11 @@ class CC_EXPORT LayerTreeSettings { // 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; + + // Determines whether we disallow non-exact matches when finding resources + // in ResourcePool. Only used for layout or pixel tests, as non-deterministic + // resource sizes can lead to floating point error and noise in these tests. + bool disallow_non_exact_resource_reuse = false; }; } // namespace cc diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h index d454539c874..0c9825107da 100644 --- a/chromium/cc/trees/mutator_host.h +++ b/chromium/cc/trees/mutator_host.h @@ -116,7 +116,8 @@ class MutatorHost { ElementId element_id, const gfx::ScrollOffset& target_offset, const gfx::ScrollOffset& current_offset, - base::TimeDelta delayed_by) = 0; + base::TimeDelta delayed_by, + base::TimeDelta animation_start_offset) = 0; virtual bool ImplOnlyScrollAnimationUpdateTarget( ElementId element_id, const gfx::Vector2dF& scroll_delta, diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc index 523b01f830f..8aa513bfe17 100644 --- a/chromium/cc/trees/occlusion_tracker.cc +++ b/chromium/cc/trees/occlusion_tracker.cc @@ -221,16 +221,17 @@ static void ReduceOcclusionBelowSurface( if (affected_area_in_target.IsEmpty()) return; + // The filter's bounds for asymmetric filters (ex: drop shadow) are + // relative to the target surface, which moves the pixels from outside of the + // clip to the filtered surface. As a result, |affected_area| needs to expand. + // Since we are concerned with the target surface, we need to swap the outsets + // before applying them to the filtered surface bounds. int outset_top, outset_right, outset_bottom, outset_left; contributing_surface->BackgroundFilters().GetOutsets( - &outset_top, &outset_right, &outset_bottom, &outset_left); - - // The filter can move pixels from outside of the clip, so allow affected_area - // to expand outside the clip. Notably the content we're concerned with here - // is not the affected area, but rather stuff slightly outside it. Thus the - // directions of the outsets are reversed from normal. - affected_area_in_target.Inset(-outset_right, -outset_bottom, -outset_left, - -outset_top); + &outset_bottom, &outset_left, &outset_top, &outset_right); + + affected_area_in_target.Inset(-outset_left, -outset_top, -outset_right, + -outset_bottom); SimpleEnclosedRegion affected_occlusion = *occlusion_from_inside_target; affected_occlusion.Intersect(affected_area_in_target); diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc index 8f635a30ccd..a0218f64497 100644 --- a/chromium/cc/trees/occlusion_tracker_unittest.cc +++ b/chromium/cc/trees/occlusion_tracker_unittest.cc @@ -19,6 +19,7 @@ #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/test_occlusion_tracker.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_host_common.h" @@ -77,7 +78,8 @@ class TestOcclusionTrackerWithClip : public TestOcclusionTracker { gfx::Rect UnoccludedSurfaceContentRect(const LayerImpl* layer, const gfx::Rect& content_rect) const { - RenderSurfaceImpl* surface = layer->GetRenderSurface(); + const RenderSurfaceImpl* surface = + GetRenderSurface(const_cast<LayerImpl*>(layer)); return this->GetCurrentOcclusionForContributingSurface( surface->draw_transform()) .GetUnoccludedContentRect(content_rect); @@ -188,7 +190,7 @@ class OcclusionTrackerTest : public testing::Test { void DestroyLayers() { host_->host_impl()->active_tree()->SetRootLayerForTesting(nullptr); - render_surface_layer_list_impl_.clear(); + render_surface_list_impl_.clear(); mask_layers_.clear(); layer_iterator_.reset(); } @@ -217,7 +219,7 @@ class OcclusionTrackerTest : public testing::Test { root->layer_tree_impl()->property_trees()->needs_rebuild = true; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), &render_surface_layer_list_impl_); + root, root->bounds(), &render_surface_list_impl_); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); @@ -247,7 +249,7 @@ class OcclusionTrackerTest : public testing::Test { void EnterContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) { ASSERT_EQ(layer_iterator_->target_render_surface(), - layer->GetRenderSurface()); + GetRenderSurface(layer)); ASSERT_TRUE(layer_iterator_->state() == EffectTreeLayerListIterator::State::TARGET_SURFACE); occlusion->EnterLayer(*layer_iterator_); @@ -260,7 +262,7 @@ class OcclusionTrackerTest : public testing::Test { void LeaveContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) { ASSERT_EQ(layer_iterator_->current_render_surface(), - layer->GetRenderSurface()); + GetRenderSurface(layer)); ASSERT_TRUE(layer_iterator_->state() == EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE); occlusion->LeaveLayer(*layer_iterator_); @@ -305,7 +307,7 @@ class OcclusionTrackerTest : public testing::Test { std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> host_; // These hold ownership of the layers for the duration of the test. - LayerImplList render_surface_layer_list_impl_; + RenderSurfaceList render_surface_list_impl_; std::unique_ptr<EffectTreeLayerListIterator> layer_iterator_; LayerList mask_layers_; int next_layer_impl_id_; diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc index 4d1ca75e387..f450baa7067 100644 --- a/chromium/cc/trees/property_tree.cc +++ b/chromium/cc/trees/property_tree.cc @@ -352,24 +352,25 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { return gfx::Vector2dF(); StickyPositionNodeData* sticky_data = tree->StickyPositionData(node->id); const LayerStickyPositionConstraint& constraint = sticky_data->constraints; + auto& property_trees = *tree->property_trees(); ScrollNode* scroll_node = - tree->property_trees()->scroll_tree.Node(sticky_data->scroll_ancestor); - gfx::ScrollOffset scroll_offset = - tree->property_trees()->scroll_tree.current_scroll_offset( - scroll_node->owning_layer_id); + property_trees.scroll_tree.Node(sticky_data->scroll_ancestor); + TransformNode* transform_node = + property_trees.transform_tree.Node(scroll_node->transform_id); + const auto& scroll_offset = transform_node->scroll_offset; + DCHECK(property_trees.scroll_tree.current_scroll_offset( + scroll_node->owning_layer_id) == scroll_offset); gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); - TransformNode* scroll_ancestor_transform_node = - tree->Node(scroll_node->transform_id); - if (scroll_ancestor_transform_node->scrolls) { + if (transform_node->scrolls) { // The scroll position does not include snapping which shifts the scroll // offset to align to a pixel boundary, we need to manually include it here. // In this case, snapping is caused by a scroll. - scroll_position -= scroll_ancestor_transform_node->snap_amount; + scroll_position -= transform_node->snap_amount; } gfx::RectF clip( scroll_position, - gfx::SizeF(tree->property_trees()->scroll_tree.scroll_clip_layer_bounds( + gfx::SizeF(property_trees.scroll_tree.scroll_clip_layer_bounds( scroll_node->id))); gfx::Vector2dF layer_offset(sticky_data->main_thread_offset); @@ -824,7 +825,8 @@ void EffectTree::UpdateBackfaceVisibility(EffectNode* node, if (parent_node && parent_node->hidden_by_backface_visibility) { node->hidden_by_backface_visibility = true; return; - } else if (node->double_sided) { + } + if (node->double_sided) { node->hidden_by_backface_visibility = false; return; } @@ -870,11 +872,6 @@ EffectNode* EffectTree::FindNodeFromElementId(ElementId id) { bool EffectTree::OnOpacityAnimated(ElementId id, float opacity) { EffectNode* node = FindNodeFromElementId(id); DCHECK(node); - // TODO(crbug.com/706766): Avoid crash. Need more investigation for what is - // calling this without setting element id. - if (!node) - return false; - if (node->opacity == opacity) return false; node->opacity = opacity; @@ -888,11 +885,6 @@ bool EffectTree::OnFilterAnimated(ElementId id, const FilterOperations& filters) { EffectNode* node = FindNodeFromElementId(id); DCHECK(node); - // TODO(crbug.com/706766): Avoid crash. Need more investigation for what is - // calling this without setting element id. - if (!node) - return false; - if (node->filters == filters) return false; node->filters = filters; @@ -986,8 +978,9 @@ bool EffectTree::HasCopyRequests() const { void EffectTree::ClearCopyRequests() { for (auto& node : nodes()) { - node.num_copy_requests_in_subtree = 0; + node.subtree_has_copy_request = false; node.has_copy_request = false; + node.closest_ancestor_with_copy_request_id = EffectTree::kInvalidNodeId; } // Any copy requests that are still left will be aborted (sending an empty @@ -996,33 +989,29 @@ void EffectTree::ClearCopyRequests() { set_needs_update(true); } -int EffectTree::ClosestAncestorWithCopyRequest(int id) const { - DCHECK_GE(id, EffectTree::kRootNodeId); - const EffectNode* node = Node(id); - while (node->id > EffectTree::kContentsRootNodeId) { - if (node->has_copy_request) - return node->id; - - node = parent(node); +int EffectTree::LowestCommonAncestorWithRenderSurface(int id_1, + int id_2) const { + DCHECK(GetRenderSurface(id_1)); + DCHECK(GetRenderSurface(id_2)); + while (id_1 != id_2) { + if (id_1 < id_2) + id_2 = Node(id_2)->target_id; + else + id_1 = Node(id_1)->target_id; } - if (node->has_copy_request) - return node->id; - else - return EffectTree::kInvalidNodeId; + return id_1; } void EffectTree::AddMaskLayerId(int id) { mask_layer_ids_.push_back(id); } -void EffectTree::UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl, - bool non_root_surfaces_enabled) { +void EffectTree::UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl) { for (int id = kContentsRootNodeId; id < static_cast<int>(size()); ++id) { EffectNode* effect_node = Node(id); bool needs_render_surface = - id == kContentsRootNodeId || - (non_root_surfaces_enabled && effect_node->has_render_surface); + id == kContentsRootNodeId || effect_node->has_render_surface; if (needs_render_surface == !!render_surfaces_[id]) continue; @@ -1211,6 +1200,14 @@ void ScrollTree::CopyCompleteTreeState(const ScrollTree& other) { } #endif +ScrollNode* ScrollTree::FindNodeFromElementId(ElementId id) { + auto iterator = property_trees()->element_id_to_scroll_node_index.find(id); + if (iterator == property_trees()->element_id_to_scroll_node_index.end()) + return nullptr; + + return Node(iterator->second); +} + void ScrollTree::clear() { PropertyTree<ScrollNode>::clear(); @@ -1349,11 +1346,9 @@ SyncedScrollOffset* ScrollTree::GetOrCreateSyncedScrollOffset(int layer_id) { const SyncedScrollOffset* ScrollTree::GetSyncedScrollOffset( int layer_id) const { DCHECK(!property_trees()->is_main_thread); - if (layer_id_to_synced_scroll_offset_map_.find(layer_id) == - layer_id_to_synced_scroll_offset_map_.end()) { - return nullptr; - } - return layer_id_to_synced_scroll_offset_map_.at(layer_id).get(); + auto it = layer_id_to_synced_scroll_offset_map_.find(layer_id); + return it != layer_id_to_synced_scroll_offset_map_.end() ? it->second.get() + : nullptr; } const gfx::ScrollOffset ScrollTree::current_scroll_offset(int layer_id) const { @@ -1606,7 +1601,6 @@ PropertyTreesCachedData::~PropertyTreesCachedData() {} PropertyTrees::PropertyTrees() : needs_rebuild(true), - non_root_surfaces_enabled(true), can_adjust_raster_scales(true), changed(false), full_tree_damaged(false), @@ -1631,13 +1625,10 @@ bool PropertyTrees::operator==(const PropertyTrees& other) const { other.element_id_to_scroll_node_index && element_id_to_transform_node_index == other.element_id_to_transform_node_index && - always_use_active_tree_opacity_effect_ids == - other.always_use_active_tree_opacity_effect_ids && needs_rebuild == other.needs_rebuild && changed == other.changed && full_tree_damaged == other.full_tree_damaged && is_main_thread == other.is_main_thread && is_active == other.is_active && - non_root_surfaces_enabled == other.non_root_surfaces_enabled && can_adjust_raster_scales == other.can_adjust_raster_scales && sequence_number == other.sequence_number; } @@ -1647,15 +1638,12 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) { effect_tree = from.effect_tree; clip_tree = from.clip_tree; scroll_tree = from.scroll_tree; - always_use_active_tree_opacity_effect_ids = - from.always_use_active_tree_opacity_effect_ids; element_id_to_effect_node_index = from.element_id_to_effect_node_index; element_id_to_scroll_node_index = from.element_id_to_scroll_node_index; element_id_to_transform_node_index = from.element_id_to_transform_node_index; needs_rebuild = from.needs_rebuild; changed = from.changed; full_tree_damaged = from.full_tree_damaged; - non_root_surfaces_enabled = from.non_root_surfaces_enabled; can_adjust_raster_scales = from.can_adjust_raster_scales; sequence_number = from.sequence_number; is_main_thread = from.is_main_thread; @@ -1682,12 +1670,10 @@ void PropertyTrees::clear() { element_id_to_effect_node_index.clear(); element_id_to_scroll_node_index.clear(); element_id_to_transform_node_index.clear(); - always_use_active_tree_opacity_effect_ids.clear(); needs_rebuild = true; full_tree_damaged = false; changed = false; - non_root_surfaces_enabled = true; can_adjust_raster_scales = true; sequence_number++; @@ -1729,22 +1715,6 @@ void PropertyTrees::SetInnerViewportScrollBoundsDelta( inner_viewport_scroll_bounds_delta_ = bounds_delta; } -void PropertyTrees::PushOpacityIfNeeded(PropertyTrees* target_tree) { - for (int id : target_tree->always_use_active_tree_opacity_effect_ids) { - if (const EffectNode* source_effect_node = - effect_tree.FindNodeFromOwningLayerId(id)) { - EffectNode* target_effect_node = - target_tree->effect_tree.UpdateNodeFromOwningLayerId(id); - float source_opacity = source_effect_node->opacity; - float target_opacity = target_effect_node->opacity; - if (source_opacity == target_opacity) - continue; - target_effect_node->opacity = source_opacity; - target_tree->effect_tree.set_needs_update(true); - } - } -} - void PropertyTrees::RemoveIdFromIdToIndexMaps(int id) { transform_tree.SetOwningLayerIdForNode(nullptr, id); clip_tree.SetOwningLayerIdForNode(nullptr, id); diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h index de5cc2823de..3ea602ad1c0 100644 --- a/chromium/cc/trees/property_tree.h +++ b/chromium/cc/trees/property_tree.h @@ -378,7 +378,10 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { bool HasCopyRequests() const; void ClearCopyRequests(); - int ClosestAncestorWithCopyRequest(int id) const; + // Given the ids of two effect nodes that have render surfaces, returns the + // id of the lowest common ancestor effect node that also has a render + // 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_; } @@ -391,8 +394,7 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { return render_surfaces_[id].get(); } - void UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl, - bool non_root_surfaces_enabled); + void UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl); bool ContributesToDrawnSurface(int id); @@ -499,10 +501,12 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { void CopyCompleteTreeState(const ScrollTree& other); #endif + ScrollNode* FindNodeFromElementId(ElementId id); + private: - using ScrollOffsetMap = std::unordered_map<int, gfx::ScrollOffset>; + using ScrollOffsetMap = base::flat_map<int, gfx::ScrollOffset>; using SyncedScrollOffsetMap = - std::unordered_map<int, scoped_refptr<SyncedScrollOffset>>; + base::flat_map<int, scoped_refptr<SyncedScrollOffset>>; int currently_scrolling_node_id_; @@ -639,20 +643,15 @@ class CC_EXPORT PropertyTrees final { // from layer id to the respective property node. Completing that work is // pending the launch of Slimming Paint v2 and reworking UI compositor logic // to produce cc property trees and these maps. - std::unordered_map<ElementId, int, ElementIdHash> - element_id_to_effect_node_index; - std::unordered_map<ElementId, int, ElementIdHash> - element_id_to_scroll_node_index; - std::unordered_map<ElementId, int, ElementIdHash> - element_id_to_transform_node_index; - - std::vector<int> always_use_active_tree_opacity_effect_ids; + base::flat_map<ElementId, int> element_id_to_effect_node_index; + base::flat_map<ElementId, int> element_id_to_scroll_node_index; + base::flat_map<ElementId, int> element_id_to_transform_node_index; + TransformTree transform_tree; EffectTree effect_tree; ClipTree clip_tree; ScrollTree scroll_tree; bool needs_rebuild; - bool non_root_surfaces_enabled; bool can_adjust_raster_scales; // Change tracking done on property trees needs to be preserved across commits // (when they are not rebuild). We cache a global bool which stores whether @@ -674,7 +673,6 @@ class CC_EXPORT PropertyTrees final { void SetInnerViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); void SetOuterViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); void SetInnerViewportScrollBoundsDelta(gfx::Vector2dF bounds_delta); - void PushOpacityIfNeeded(PropertyTrees* target_tree); void RemoveIdFromIdToIndexMaps(int id); void UpdateChangeTracking(); void PushChangeTrackingTo(PropertyTrees* tree); diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc index 02fb9bd306c..a7efa0a7155 100644 --- a/chromium/cc/trees/property_tree_builder.cc +++ b/chromium/cc/trees/property_tree_builder.cc @@ -35,10 +35,10 @@ struct DataForRecursion { PropertyTrees* property_trees; LayerType* transform_tree_parent; LayerType* transform_fixed_parent; - int render_target; int clip_tree_parent; int effect_tree_parent; int scroll_tree_parent; + int closest_ancestor_with_copy_request; const LayerType* page_scale_layer; const LayerType* inner_viewport_scroll_layer; const LayerType* outer_viewport_scroll_layer; @@ -54,21 +54,11 @@ struct DataForRecursion { bool scroll_tree_parent_created_by_uninheritable_criteria; const gfx::Transform* device_transform; gfx::Transform compound_transform_since_render_target; - bool axis_align_since_render_target; + bool animation_axis_aligned_since_render_target; + bool not_axis_aligned_since_last_clip; SkColor safe_opaque_background_color; }; -template <typename LayerType> -struct DataForRecursionFromChild { - int num_copy_requests_in_subtree; - - DataForRecursionFromChild() : num_copy_requests_in_subtree(0) {} - - void Merge(const DataForRecursionFromChild& data) { - num_copy_requests_in_subtree += data.num_copy_requests_in_subtree; - } -}; - static LayerPositionConstraint PositionConstraint(Layer* layer) { return layer->position_constraint(); } @@ -366,14 +356,6 @@ bool AddTransformNodeIfNeeded( const bool has_surface = created_render_surface; - // A transform node is needed to change the render target for subtree when - // a scroll child's render target is different from the scroll parent's render - // target. - const bool scroll_child_has_different_target = - ScrollParent(layer) && - Parent(layer)->effect_tree_index() != - ScrollParent(layer)->effect_tree_index(); - const bool is_at_boundary_of_3d_rendering_context = IsAtBoundaryOf3dRenderingContext(layer); @@ -381,8 +363,7 @@ bool AddTransformNodeIfNeeded( bool requires_node = is_root || is_snapped || has_significant_transform || has_any_transform_animation || has_surface || is_fixed || is_page_scale_layer || is_overscroll_elasticity_layer || - has_proxied_transform_related_property || - scroll_child_has_different_target || is_sticky || + has_proxied_transform_related_property || is_sticky || is_at_boundary_of_3d_rendering_context; int parent_index = TransformTree::kRootNodeId; @@ -718,14 +699,6 @@ static inline bool HideLayerAndSubtree(LayerImpl* layer) { return layer->test_properties()->hide_layer_and_subtree; } -static inline bool AlwaysUseActiveTreeOpacity(Layer* layer) { - return layer->AlwaysUseActiveTreeOpacity(); -} - -static inline bool AlwaysUseActiveTreeOpacity(LayerImpl* layer) { - return false; -} - static inline bool HasCopyRequest(Layer* layer) { return layer->HasCopyRequest(); } @@ -745,10 +718,9 @@ static inline bool PropertyChanged(LayerImpl* layer) { template <typename LayerType> bool ShouldCreateRenderSurface(LayerType* layer, gfx::Transform current_transform, - bool axis_aligned) { + bool animation_axis_aligned) { const bool preserves_2d_axis_alignment = - (current_transform * Transform(layer)).Preserves2dAxisAlignment() && - axis_aligned && AnimationsPreserveAxisAlignment(layer); + current_transform.Preserves2dAxisAlignment() && animation_axis_aligned; const bool is_root = !Parent(layer); if (is_root) return true; @@ -858,6 +830,38 @@ static void TakeCopyRequests( 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 subtree_has_copy_request = false; + if (HasCopyRequest(layer)) + subtree_has_copy_request = true; + for (size_t i = 0; i < Children(layer).size(); ++i) { + LayerType* current_child = ChildAt(layer, i); + subtree_has_copy_request |= + UpdateSubtreeHasCopyRequestRecursive(current_child); + } + SetSubtreeHasCopyRequest(layer, subtree_has_copy_request); + return subtree_has_copy_request; +} + template <typename LayerType> bool AddEffectNodeIfNeeded( const DataForRecursion<LayerType>& data_from_ancestor, @@ -871,14 +875,27 @@ bool AddEffectNodeIfNeeded( HasPotentiallyRunningFilterAnimation(layer); const bool has_proxied_opacity = !!(layer->mutable_properties() & MutableProperty::kOpacity); - const bool should_create_render_surface = ShouldCreateRenderSurface( - layer, data_from_ancestor.compound_transform_since_render_target, - data_from_ancestor.axis_align_since_render_target); - data_for_children->axis_align_since_render_target &= + + data_for_children->animation_axis_aligned_since_render_target &= AnimationsPreserveAxisAlignment(layer); + data_for_children->compound_transform_since_render_target *= Transform(layer); + const bool should_create_render_surface = ShouldCreateRenderSurface( + layer, data_for_children->compound_transform_since_render_target, + data_for_children->animation_axis_aligned_since_render_target); + + bool not_axis_aligned_since_last_clip = + data_from_ancestor.not_axis_aligned_since_last_clip + ? true + : !AnimationsPreserveAxisAlignment(layer) || + !Transform(layer).Preserves2dAxisAlignment(); + // A non-axis aligned clip may need a render surface. So, we create an effect + // node. + bool has_non_axis_aligned_clip = + not_axis_aligned_since_last_clip && LayerClipsSubtree(layer); bool requires_node = is_root || has_transparency || has_potential_opacity_animation || has_proxied_opacity || + has_non_axis_aligned_clip || should_create_render_surface; int parent_id = data_from_ancestor.effect_tree_parent; @@ -886,38 +903,38 @@ bool AddEffectNodeIfNeeded( if (!requires_node) { layer->SetEffectTreeIndex(parent_id); data_for_children->effect_tree_parent = parent_id; - data_for_children->compound_transform_since_render_target *= - Transform(layer); return false; } - EffectNode node; - node.owning_layer_id = layer->id(); - if (AlwaysUseActiveTreeOpacity(layer)) { - data_for_children->property_trees->always_use_active_tree_opacity_effect_ids - .push_back(node.owning_layer_id); - } + EffectTree& effect_tree = data_for_children->property_trees->effect_tree; + int node_id = effect_tree.Insert(EffectNode(), parent_id); + EffectNode* node = effect_tree.back(); - node.opacity = Opacity(layer); - node.blend_mode = BlendMode(layer); - node.unscaled_mask_target_size = layer->bounds(); - node.has_render_surface = should_create_render_surface; - node.has_copy_request = HasCopyRequest(layer); - node.filters = Filters(layer); - node.background_filters = BackgroundFilters(layer); - node.filters_origin = FiltersOrigin(layer); - 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.is_currently_animating_opacity = OpacityIsAnimating(layer); - node.is_currently_animating_filter = FilterIsAnimating(layer); - node.effect_changed = PropertyChanged(layer); + node->owning_layer_id = layer->id(); + node->opacity = Opacity(layer); + node->blend_mode = BlendMode(layer); + node->unscaled_mask_target_size = layer->bounds(); + node->has_render_surface = should_create_render_surface; + node->has_copy_request = HasCopyRequest(layer); + node->filters = Filters(layer); + node->background_filters = BackgroundFilters(layer); + node->filters_origin = FiltersOrigin(layer); + 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->is_currently_animating_opacity = OpacityIsAnimating(layer); + node->is_currently_animating_filter = FilterIsAnimating(layer); + node->effect_changed = PropertyChanged(layer); + node->subtree_has_copy_request = SubtreeHasCopyRequest(layer); + node->closest_ancestor_with_copy_request_id = + HasCopyRequest(layer) + ? node_id + : data_from_ancestor.closest_ancestor_with_copy_request; - EffectTree& effect_tree = data_for_children->property_trees->effect_tree; if (MaskLayer(layer)) { - node.mask_layer_id = MaskLayer(layer)->id(); - effect_tree.AddMaskLayerId(node.mask_layer_id); + node->mask_layer_id = MaskLayer(layer)->id(); + effect_tree.AddMaskLayerId(node->mask_layer_id); } if (!is_root) { @@ -928,19 +945,23 @@ bool AddEffectNodeIfNeeded( // 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. - node.transform_id = + node->transform_id = data_from_ancestor.property_trees->transform_tree.next_available_id(); } - node.clip_id = data_from_ancestor.clip_tree_parent; + node->clip_id = data_from_ancestor.clip_tree_parent; } else { - // Root render surface acts the unbounded and untransformed to draw content - // into. Transform node created from root layer (includes device scale - // factor) and clip node created from root layer (include viewports) applies - // to root render surface's content, but not root render surface itself. - node.transform_id = TransformTree::kRootNodeId; - node.clip_id = ClipTree::kViewportNodeId; + // 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. + node->transform_id = TransformTree::kRootNodeId; + node->clip_id = ClipTree::kViewportNodeId; } - int node_id = effect_tree.Insert(node, parent_id); + + data_for_children->closest_ancestor_with_copy_request = + node->closest_ancestor_with_copy_request_id; data_for_children->effect_tree_parent = node_id; layer->SetEffectTreeIndex(node_id); data_for_children->property_trees->effect_tree.SetOwningLayerIdForNode( @@ -963,7 +984,7 @@ bool AddEffectNodeIfNeeded( if (should_create_render_surface) { data_for_children->compound_transform_since_render_target = gfx::Transform(); - data_for_children->axis_align_since_render_target = true; + data_for_children->animation_axis_aligned_since_render_target = true; } return should_create_render_surface; } @@ -1082,7 +1103,7 @@ void SetBackfaceVisibilityTransform(LayerType* layer, (Is3dSorted(layer) && is_at_boundary_of_3d_rendering_context); layer->SetUseLocalTransformForBackfaceVisibility(use_local_transform); - // A double-sided layer's backface can been shown when its visibile. + // A double-sided layer's backface can been shown when its visible. if (DoubleSided(layer)) layer->SetShouldCheckBackfaceVisibility(false); // The backface of a layer that uses local transform for backface visibility @@ -1120,8 +1141,7 @@ static void SetLayerPropertyChangedForChild(LayerImpl* parent, template <typename LayerType> void BuildPropertyTreesInternal( LayerType* layer, - const DataForRecursion<LayerType>& data_from_parent, - DataForRecursionFromChild<LayerType>* data_to_parent) { + const DataForRecursion<LayerType>& data_from_parent) { layer->set_property_tree_sequence_number( data_from_parent.property_trees->sequence_number); @@ -1130,8 +1150,6 @@ void BuildPropertyTreesInternal( bool created_render_surface = AddEffectNodeIfNeeded(data_from_parent, layer, &data_for_children); - if (created_render_surface) - data_for_children.render_target = data_for_children.effect_tree_parent; bool created_transform_node = AddTransformNodeIfNeeded( data_from_parent, layer, created_render_surface, &data_for_children); @@ -1143,14 +1161,21 @@ void BuildPropertyTreesInternal( SetBackfaceVisibilityTransform(layer, created_transform_node); SetSafeOpaqueBackgroundColor(data_from_parent, layer, &data_for_children); + bool not_axis_aligned_since_last_clip = + data_from_parent.not_axis_aligned_since_last_clip + ? true + : !AnimationsPreserveAxisAlignment(layer) || + !Transform(layer).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; + for (size_t i = 0; i < Children(layer).size(); ++i) { LayerType* current_child = ChildAt(layer, i); SetLayerPropertyChangedForChild(layer, current_child); if (!ScrollParent(current_child)) { - DataForRecursionFromChild<LayerType> data_from_child; - BuildPropertyTreesInternal(current_child, data_for_children, - &data_from_child); - data_to_parent->Merge(data_from_child); + BuildPropertyTreesInternal(current_child, data_for_children); } else { // The child should be included in its scroll parent's list of scroll // children. @@ -1161,15 +1186,10 @@ void BuildPropertyTreesInternal( if (ScrollChildren(layer)) { for (LayerType* scroll_child : *ScrollChildren(layer)) { DCHECK_EQ(ScrollParent(scroll_child), layer); - DataForRecursionFromChild<LayerType> data_from_child; DCHECK(Parent(scroll_child)); data_for_children.effect_tree_parent = Parent(scroll_child)->effect_tree_index(); - data_for_children.render_target = - Parent(scroll_child)->effect_tree_index(); - BuildPropertyTreesInternal(scroll_child, data_for_children, - &data_from_child); - data_to_parent->Merge(data_from_child); + BuildPropertyTreesInternal(scroll_child, data_for_children); } } @@ -1183,16 +1203,6 @@ void BuildPropertyTreesInternal( MaskLayer(layer)->SetEffectTreeIndex(layer->effect_tree_index()); MaskLayer(layer)->SetScrollTreeIndex(layer->scroll_tree_index()); } - - EffectNode* effect_node = data_for_children.property_trees->effect_tree.Node( - data_for_children.effect_tree_parent); - - if (effect_node->owning_layer_id == layer->id()) { - if (effect_node->has_copy_request) - data_to_parent->num_copy_requests_in_subtree++; - effect_node->num_copy_requests_in_subtree = - data_to_parent->num_copy_requests_in_subtree; - } } } // namespace @@ -1246,10 +1256,11 @@ void BuildPropertyTreesTopLevelInternal( data_for_recursion.property_trees = property_trees; data_for_recursion.transform_tree_parent = nullptr; data_for_recursion.transform_fixed_parent = nullptr; - data_for_recursion.render_target = EffectTree::kRootNodeId; data_for_recursion.clip_tree_parent = ClipTree::kRootNodeId; data_for_recursion.effect_tree_parent = EffectTree::kInvalidNodeId; data_for_recursion.scroll_tree_parent = ScrollTree::kRootNodeId; + data_for_recursion.closest_ancestor_with_copy_request = + EffectTree::kInvalidNodeId; data_for_recursion.page_scale_layer = page_scale_layer; data_for_recursion.inner_viewport_scroll_layer = inner_viewport_scroll_layer; data_for_recursion.outer_viewport_scroll_layer = outer_viewport_scroll_layer; @@ -1269,7 +1280,8 @@ void BuildPropertyTreesTopLevelInternal( data_for_recursion.property_trees->clear(); data_for_recursion.compound_transform_since_render_target = gfx::Transform(); - data_for_recursion.axis_align_since_render_target = true; + data_for_recursion.animation_axis_aligned_since_render_target = true; + data_for_recursion.not_axis_aligned_since_last_clip = false; data_for_recursion.property_trees->transform_tree.set_device_scale_factor( device_scale_factor); data_for_recursion.safe_opaque_background_color = color; @@ -1282,8 +1294,7 @@ void BuildPropertyTreesTopLevelInternal( data_for_recursion.property_trees->clip_tree.Insert( root_clip, ClipTree::kRootNodeId); - DataForRecursionFromChild<LayerType> data_from_child; - BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child); + BuildPropertyTreesInternal(root_layer, data_for_recursion); property_trees->needs_rebuild = false; // The transform tree is kept up to date as it is built, but the @@ -1333,6 +1344,8 @@ void PropertyTreeBuilder::BuildPropertyTrees( 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); BuildPropertyTreesTopLevelInternal( root_layer, page_scale_layer, inner_viewport_scroll_layer, outer_viewport_scroll_layer, overscroll_elasticity_layer, @@ -1343,6 +1356,11 @@ void PropertyTreeBuilder::BuildPropertyTrees( CheckScrollAndClipPointersForLayer(layer); #endif 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( @@ -1365,6 +1383,7 @@ void PropertyTreeBuilder::BuildPropertyTrees( SkColor color = root_layer->layer_tree_impl()->background_color(); if (SkColorGetA(color) != 255) color = SkColorSetA(color, 255); + UpdateSubtreeHasCopyRequestRecursive(root_layer); BuildPropertyTreesTopLevelInternal( root_layer, page_scale_layer, inner_viewport_scroll_layer, outer_viewport_scroll_layer, overscroll_elasticity_layer, diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc index afced7e5c42..01a96109c89 100644 --- a/chromium/cc/trees/proxy_impl.cc +++ b/chromium/cc/trees/proxy_impl.cc @@ -126,10 +126,13 @@ void ProxyImpl::UpdateBrowserControlsStateOnImpl( } void ProxyImpl::InitializeCompositorFrameSinkOnImpl( - CompositorFrameSink* compositor_frame_sink) { + CompositorFrameSink* compositor_frame_sink, + base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr) { TRACE_EVENT0("cc", "ProxyImpl::InitializeCompositorFrameSinkOnImplThread"); DCHECK(IsImplThread()); + proxy_main_frame_sink_bound_weak_ptr_ = proxy_main_frame_sink_bound_weak_ptr; + LayerTreeHostImpl* host_impl = layer_tree_host_impl_.get(); bool success = host_impl->InitializeRenderer(compositor_frame_sink); MainThreadTaskRunner()->PostTask( @@ -232,19 +235,26 @@ NOINLINE void ProxyImpl::DumpForBeginMainFrameHang() { DCHECK(IsImplThread()); DCHECK(scheduler_); - char stack_string[20000] = ""; - base::debug::Alias(&stack_string); + auto state = base::MakeUnique<base::trace_event::TracedValue>(); - std::unique_ptr<base::trace_event::ConvertableToTraceFormat> scheduler_state = - scheduler_->AsValue(); - strncat(stack_string, scheduler_state->ToString().c_str(), - arraysize(stack_string) - strlen(stack_string) - 1); + state->SetBoolean("commit_completion_waits_for_activation", + commit_completion_waits_for_activation_); + state->SetBoolean("commit_completion_event", !!commit_completion_event_); + state->SetBoolean("activation_completion_event", + !!activation_completion_event_); - std::unique_ptr<base::trace_event::ConvertableToTraceFormat> - tile_manager_state = - layer_tree_host_impl_->tile_manager()->ActivationStateAsValue(); - strncat(stack_string, tile_manager_state->ToString().c_str(), - arraysize(stack_string) - strlen(stack_string) - 1); + state->BeginDictionary("scheduler_state"); + scheduler_->AsValueInto(state.get()); + state->EndDictionary(); + + state->BeginDictionary("tile_manager_state"); + layer_tree_host_impl_->tile_manager()->ActivationStateAsValueInto( + state.get()); + state->EndDictionary(); + + char stack_string[50000] = ""; + base::debug::Alias(&stack_string); + strncpy(stack_string, state->ToString().c_str(), arraysize(stack_string) - 1); base::debug::DumpWithoutCrashing(); } @@ -307,7 +317,7 @@ void ProxyImpl::DidReceiveCompositorFrameAckOnImplThread() { scheduler_->DidReceiveCompositorFrameAck(); MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&ProxyMain::DidReceiveCompositorFrameAck, - proxy_main_weak_ptr_)); + proxy_main_frame_sink_bound_weak_ptr_)); } void ProxyImpl::OnCanDrawStateChanged(bool can_draw) { @@ -473,6 +483,11 @@ void ProxyImpl::DidFinishImplFrame() { layer_tree_host_impl_->DidFinishImplFrame(); } +void ProxyImpl::DidNotProduceFrame(const BeginFrameAck& ack) { + DCHECK(IsImplThread()); + layer_tree_host_impl_->DidNotProduceFrame(ack); +} + void ProxyImpl::ScheduledActionSendBeginMainFrame(const BeginFrameArgs& args) { DCHECK(IsImplThread()); unsigned int begin_frame_id = nextBeginFrameId++; @@ -602,6 +617,14 @@ void ProxyImpl::SendBeginMainFrameNotExpectedSoon() { proxy_main_weak_ptr_)); } +void ProxyImpl::ScheduledActionBeginMainFrameNotExpectedUntil( + base::TimeTicks time) { + DCHECK(IsImplThread()); + MainThreadTaskRunner()->PostTask( + FROM_HERE, base::Bind(&ProxyMain::BeginMainFrameNotExpectedUntil, + proxy_main_weak_ptr_, time)); +} + DrawResult ProxyImpl::DrawInternal(bool forced_draw) { TRACE_EVENT_SYNTHETIC_DELAY("cc.Draw"); diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h index 68edc334515..0953ae7a0e1 100644 --- a/chromium/cc/trees/proxy_impl.h +++ b/chromium/cc/trees/proxy_impl.h @@ -34,7 +34,8 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), BrowserControlsState current, bool animate); void InitializeCompositorFrameSinkOnImpl( - CompositorFrameSink* compositor_frame_sink); + CompositorFrameSink* compositor_frame_sink, + base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr); void InitializeMutatorOnImpl(std::unique_ptr<LayerTreeMutator> mutator); void MainThreadHasStoppedFlingingOnImpl(); void SetInputThrottledUntilCommitOnImpl(bool is_throttled); @@ -97,6 +98,7 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), // SchedulerClient implementation void WillBeginImplFrame(const BeginFrameArgs& args) override; void DidFinishImplFrame() override; + void DidNotProduceFrame(const BeginFrameAck& ack) override; void ScheduledActionSendBeginMainFrame(const BeginFrameArgs& args) override; DrawResult ScheduledActionDrawIfPossible() override; DrawResult ScheduledActionDrawForced() override; @@ -107,6 +109,8 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void ScheduledActionInvalidateCompositorFrameSink() override; void ScheduledActionPerformImplSideInvalidation() override; void SendBeginMainFrameNotExpectedSoon() override; + void ScheduledActionBeginMainFrameNotExpectedUntil( + base::TimeTicks time) override; DrawResult DrawInternal(bool forced_draw); @@ -149,6 +153,10 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), // Used to post tasks to ProxyMain on the main thread. base::WeakPtr<ProxyMain> proxy_main_weak_ptr_; + // A weak pointer to ProxyMain that is invalidated when CompositorFrameSink is + // released. + base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr_; + DISALLOW_COPY_AND_ASSIGN(ProxyImpl); }; diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc index 6b06f0ee80f..8632105c293 100644 --- a/chromium/cc/trees/proxy_main.cc +++ b/chromium/cc/trees/proxy_main.cc @@ -36,6 +36,7 @@ ProxyMain::ProxyMain(LayerTreeHost* layer_tree_host, commit_waits_for_activation_(false), started_(false), defer_commits_(false), + frame_sink_bound_weak_factory_(this), weak_factory_(this) { TRACE_EVENT0("cc", "ProxyMain::ProxyMain"); DCHECK(task_runner_provider_); @@ -74,6 +75,12 @@ void ProxyMain::BeginMainFrameNotExpectedSoon() { layer_tree_host_->BeginMainFrameNotExpectedSoon(); } +void ProxyMain::BeginMainFrameNotExpectedUntil(base::TimeTicks time) { + TRACE_EVENT0("cc", "ProxyMain::BeginMainFrameNotExpectedUntil"); + DCHECK(IsMainThread()); + layer_tree_host_->BeginMainFrameNotExpectedUntil(time); +} + void ProxyMain::DidCommitAndDrawFrame() { DCHECK(IsMainThread()); layer_tree_host_->DidCommitAndDrawFrame(); @@ -288,9 +295,10 @@ bool ProxyMain::CommitToActiveTree() const { void ProxyMain::SetCompositorFrameSink( CompositorFrameSink* compositor_frame_sink) { ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyImpl::InitializeCompositorFrameSinkOnImpl, - base::Unretained(proxy_impl_.get()), - compositor_frame_sink)); + FROM_HERE, + base::BindOnce(&ProxyImpl::InitializeCompositorFrameSinkOnImpl, + base::Unretained(proxy_impl_.get()), compositor_frame_sink, + frame_sink_bound_weak_factory_.GetWeakPtr())); } void ProxyMain::SetVisible(bool visible) { @@ -469,6 +477,7 @@ bool ProxyMain::MainFrameWillHappenForTesting() { void ProxyMain::ReleaseCompositorFrameSink() { DCHECK(IsMainThread()); + frame_sink_bound_weak_factory_.InvalidateWeakPtrs(); DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); CompletionEvent completion; ImplThreadTaskRunner()->PostTask( diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h index 3d97276193a..e4ab354345e 100644 --- a/chromium/cc/trees/proxy_main.h +++ b/chromium/cc/trees/proxy_main.h @@ -42,6 +42,7 @@ class CC_EXPORT ProxyMain : public Proxy { void DidReceiveCompositorFrameAck(); void BeginMainFrameNotExpectedSoon(); + void BeginMainFrameNotExpectedUntil(base::TimeTicks time); void DidCommitAndDrawFrame(); void SetAnimationEvents(std::unique_ptr<MutatorEvents> events); void DidLoseCompositorFrameSink(); @@ -129,6 +130,10 @@ class CC_EXPORT ProxyMain : public Proxy { // run before we destroy it on the impl thread. std::unique_ptr<ProxyImpl> proxy_impl_; + // WeakPtrs generated by this factory will be invalidated when + // CompositorFrameSink is released. + base::WeakPtrFactory<ProxyMain> frame_sink_bound_weak_factory_; + base::WeakPtrFactory<ProxyMain> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ProxyMain); diff --git a/chromium/cc/trees/scroll_node.cc b/chromium/cc/trees/scroll_node.cc index 050dbf00294..3c8bcf78d02 100644 --- a/chromium/cc/trees/scroll_node.cc +++ b/chromium/cc/trees/scroll_node.cc @@ -16,9 +16,9 @@ ScrollNode::ScrollNode() : id(ScrollTree::kInvalidNodeId), parent_id(ScrollTree::kInvalidNodeId), owning_layer_id(Layer::INVALID_ID), - scrollable(false), main_thread_scrolling_reasons( MainThreadScrollingReason::kNotScrollingOnMain), + scrollable(false), max_scroll_offset_affected_by_page_scale(false), scrolls_inner_viewport(false), scrolls_outer_viewport(false), diff --git a/chromium/cc/trees/scroll_node.h b/chromium/cc/trees/scroll_node.h index 4eefe42aff1..43841bf2f15 100644 --- a/chromium/cc/trees/scroll_node.h +++ b/chromium/cc/trees/scroll_node.h @@ -32,11 +32,6 @@ struct CC_EXPORT ScrollNode { // composited layer list. int owning_layer_id; - // This is used for subtrees that should not be scrolled independently. For - // example, when there is a layer that is not scrollable itself but is inside - // a scrolling layer. - bool scrollable; - uint32_t main_thread_scrolling_reasons; Region non_fast_scrollable_region; @@ -48,17 +43,21 @@ struct CC_EXPORT ScrollNode { // Bounds of the overflow scrolling area. gfx::Size bounds; - bool max_scroll_offset_affected_by_page_scale; - bool scrolls_inner_viewport; - bool scrolls_outer_viewport; + // This is used for subtrees that should not be scrolled independently. For + // example, when there is a layer that is not scrollable itself but is inside + // a scrolling layer. + bool scrollable : 1; + bool max_scroll_offset_affected_by_page_scale : 1; + bool scrolls_inner_viewport : 1; + bool scrolls_outer_viewport : 1; + bool should_flatten : 1; + bool user_scrollable_horizontal : 1; + bool user_scrollable_vertical : 1; // This offset is used when |scrollable| is false and there isn't a transform // node already present that covers this offset. gfx::Vector2dF offset_to_transform_parent; - bool should_flatten; - bool user_scrollable_horizontal; - bool user_scrollable_vertical; ElementId element_id; int transform_id; diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index 07b5afa607a..1769c19fe60 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -52,6 +52,7 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, inside_synchronous_composite_(false), compositor_frame_sink_creation_requested_(false), compositor_frame_sink_lost_(true), + frame_sink_bound_weak_factory_(this), weak_factory_(this) { TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); DCHECK(task_runner_provider_); @@ -123,6 +124,7 @@ void SingleThreadProxy::RequestNewCompositorFrameSink() { void SingleThreadProxy::ReleaseCompositorFrameSink() { compositor_frame_sink_lost_ = true; + frame_sink_bound_weak_factory_.InvalidateWeakPtrs(); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidLoseCompositorFrameSink(); return layer_tree_host_impl_->ReleaseCompositorFrameSink(); @@ -141,6 +143,7 @@ void SingleThreadProxy::SetCompositorFrameSink( } if (success) { + frame_sink_bound_weak_ptr_ = frame_sink_bound_weak_factory_.GetWeakPtr(); layer_tree_host_->DidInitializeCompositorFrameSink(); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidCreateAndInitializeCompositorFrameSink(); @@ -425,7 +428,12 @@ void SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread() { "SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread"); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidReceiveCompositorFrameAck(); - layer_tree_host_->DidReceiveCompositorFrameAck(); + // We do a PostTask here because freeing resources in some cases (such as in + // TextureLayer) is PostTasked and we want to make sure ack is received after + // resources are returned. + task_runner_provider_->MainThreadTaskRunner()->PostTask( + FROM_HERE, base::Bind(&SingleThreadProxy::DidReceiveCompositorFrameAck, + frame_sink_bound_weak_ptr_)); } void SingleThreadProxy::OnDrawForCompositorFrameSink( @@ -624,6 +632,11 @@ void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() { layer_tree_host_->BeginMainFrameNotExpectedSoon(); } +void SingleThreadProxy::ScheduledActionBeginMainFrameNotExpectedUntil( + base::TimeTicks time) { + layer_tree_host_->BeginMainFrameNotExpectedUntil(time); +} + void SingleThreadProxy::BeginMainFrame(const BeginFrameArgs& begin_frame_args) { if (scheduler_on_impl_thread_) { scheduler_on_impl_thread_->NotifyBeginMainFrameStarted( @@ -794,4 +807,13 @@ void SingleThreadProxy::DidFinishImplFrame() { #endif } +void SingleThreadProxy::DidNotProduceFrame(const BeginFrameAck& ack) { + DebugScopedSetImplThread impl(task_runner_provider_); + layer_tree_host_impl_->DidNotProduceFrame(ack); +} + +void SingleThreadProxy::DidReceiveCompositorFrameAck() { + layer_tree_host_->DidReceiveCompositorFrameAck(); +} + } // namespace cc diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h index 4a091950a27..54842c41bf2 100644 --- a/chromium/cc/trees/single_thread_proxy.h +++ b/chromium/cc/trees/single_thread_proxy.h @@ -62,6 +62,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // SchedulerClient implementation void WillBeginImplFrame(const BeginFrameArgs& args) override; void DidFinishImplFrame() override; + void DidNotProduceFrame(const BeginFrameAck& ack) override; void ScheduledActionSendBeginMainFrame(const BeginFrameArgs& args) override; DrawResult ScheduledActionDrawIfPossible() override; DrawResult ScheduledActionDrawForced() override; @@ -72,6 +73,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void ScheduledActionInvalidateCompositorFrameSink() override; void ScheduledActionPerformImplSideInvalidation() override; void SendBeginMainFrameNotExpectedSoon() override; + void ScheduledActionBeginMainFrameNotExpectedUntil( + base::TimeTicks time) override; // LayerTreeHostImplClient implementation void DidLoseCompositorFrameSinkOnImplThread() override; @@ -122,6 +125,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy, bool ShouldComposite() const; void ScheduleRequestNewCompositorFrameSink(); + void DidReceiveCompositorFrameAck(); + // Accessed on main thread only. LayerTreeHost* layer_tree_host_; LayerTreeHostSingleThreadClient* single_thread_client_; @@ -158,6 +163,12 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // This is the callback for the scheduled RequestNewCompositorFrameSink. base::CancelableClosure compositor_frame_sink_creation_callback_; + base::WeakPtr<SingleThreadProxy> frame_sink_bound_weak_ptr_; + + // WeakPtrs generated by this factory will be invalidated when + // CompositorFrameSink is released. + base::WeakPtrFactory<SingleThreadProxy> frame_sink_bound_weak_factory_; + base::WeakPtrFactory<SingleThreadProxy> weak_factory_; DISALLOW_COPY_AND_ASSIGN(SingleThreadProxy); diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h index 76f2a7c2ffc..2abfb1cc004 100644 --- a/chromium/cc/trees/transform_node.h +++ b/chromium/cc/trees/transform_node.h @@ -69,14 +69,27 @@ struct CC_EXPORT TransformNode { // TODO(vollick): will be moved when accelerated effects are implemented. bool needs_local_transform_update : 1; + // Whether this node or any ancestor has a potentially running + // (i.e., irrespective of exact timeline) transform animation or an + // invertible transform. bool node_and_ancestors_are_animated_or_invertible : 1; bool is_invertible : 1; + // Whether the transform from this node to the screen is + // invertible. bool ancestors_are_invertible : 1; + // Whether this node has a potentially running (i.e., irrespective + // of exact timeline) transform animation. bool has_potential_animation : 1; + // Whether this node has a currently running transform animation. bool is_currently_animating : 1; + // Whether this node *or an ancestor* has a potentially running + // (i.e., irrespective of exact timeline) transform + // animation. bool to_screen_is_potentially_animated : 1; + // Whether all animations on this transform node are simple + // translations. bool has_only_translation_animations : 1; // Flattening, when needed, is only applied to a node's inherited transform, diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc index 52f1bb384c7..87efee06cab 100644 --- a/chromium/cc/trees/tree_synchronizer.cc +++ b/chromium/cc/trees/tree_synchronizer.cc @@ -74,6 +74,25 @@ std::unique_ptr<LayerImpl> ReuseOrCreateLayerImpl(OwnedLayerImplMap* old_layers, return layer_impl; } +#if DCHECK_IS_ON() +template <typename LayerType> +static void AssertValidPropertyTreeIndices(LayerType* layer) { + DCHECK(layer); + DCHECK_NE(layer->transform_tree_index(), TransformTree::kInvalidNodeId); + DCHECK_NE(layer->effect_tree_index(), EffectTree::kInvalidNodeId); + DCHECK_NE(layer->clip_tree_index(), ClipTree::kInvalidNodeId); + DCHECK_NE(layer->scroll_tree_index(), ScrollTree::kInvalidNodeId); +} + +static bool LayerHasValidPropertyTreeIndices(LayerImpl* layer) { + DCHECK(layer); + return layer->transform_tree_index() != TransformTree::kInvalidNodeId && + layer->effect_tree_index() != EffectTree::kInvalidNodeId && + layer->clip_tree_index() != ClipTree::kInvalidNodeId && + layer->scroll_tree_index() != ScrollTree::kInvalidNodeId; +} +#endif + template <typename LayerTreeType> void PushLayerList(OwnedLayerImplMap* old_layers, LayerTreeType* host, @@ -83,6 +102,15 @@ void PushLayerList(OwnedLayerImplMap* old_layers, std::unique_ptr<LayerImpl> layer_impl( ReuseOrCreateLayerImpl(old_layers, layer, tree_impl)); +#if DCHECK_IS_ON() + // Every layer should have valid property tree indices + AssertValidPropertyTreeIndices(layer); + // Every layer_impl should either have valid property tree indices already + // or the corresponding layer should push them onto layer_impl. + DCHECK(LayerHasValidPropertyTreeIndices(layer_impl.get()) || + host->LayerNeedsPushPropertiesForTesting(layer)); +#endif + tree_impl->AddToLayerList(layer_impl.get()); tree_impl->AddLayer(std::move(layer_impl)); } diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc index cbae4e4aea1..1def71a2b67 100644 --- a/chromium/cc/trees/tree_synchronizer_unittest.cc +++ b/chromium/cc/trees/tree_synchronizer_unittest.cc @@ -165,6 +165,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) { layer_tree_root->AddChild(Layer::Create()); host_->SetRootLayer(layer_tree_root); + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); @@ -186,6 +187,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { int second_layer_impl_id = layer_tree_root->children()[1]->id(); host_->SetRootLayer(layer_tree_root); + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); @@ -206,6 +208,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { // Synchronize again. After the sync the trees should be equivalent and we // should have created and destroyed one LayerImpl. + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); @@ -236,6 +239,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { host_->SetRootLayer(layer_tree_root); + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); LayerImpl* layer_impl_tree_root = @@ -252,12 +256,15 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { // re-insert the layer and sync again. child2->RemoveFromParent(); layer_tree_root->AddChild(child2); + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); + host_->active_tree()->SetPropertyTrees( + layer_tree_root->layer_tree_host()->property_trees()); TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), host_->active_tree()); @@ -284,9 +291,9 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) { gfx::Size second_child_bounds = gfx::Size(25, 53); layer_tree_root->children()[1]->SetBounds(second_child_bounds); - layer_tree_root->children()[1]->SavePaintProperties(); int second_child_id = layer_tree_root->children()[1]->id(); + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); LayerImpl* layer_impl_tree_root = @@ -335,6 +342,7 @@ TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { scoped_refptr<Layer> layer_d = layer_b->children()[1]; host_->SetRootLayer(layer_tree_root); + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); @@ -363,6 +371,7 @@ TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { // After another synchronize our trees should match and we should not have // destroyed any LayerImpls + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); @@ -392,6 +401,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id(); int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id(); + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(), host_->active_tree()); LayerImpl* layer_impl_tree_root = @@ -411,6 +421,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { scoped_refptr<Layer> new_layer_tree_root = Layer::Create(); host_->SetRootLayer(new_layer_tree_root); + host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(), host_->active_tree()); layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); @@ -493,7 +504,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) { transient_scroll_layer->AddChild(scroll_clip_layer); scroll_clip_layer->AddChild(scroll_layer); - ElementId scroll_element_id = ElementId(5, 4); + ElementId scroll_element_id = ElementId(5); scroll_layer->SetElementId(scroll_element_id); transient_scroll_layer->SetScrollClipLayerId( @@ -540,7 +551,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) { scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> transient_scroll_layer = Layer::Create(); - ElementId scroll_element_id = ElementId(5, 4); + ElementId scroll_element_id = ElementId(5); scroll_layer->SetElementId(scroll_element_id); layer_tree_root->AddChild(transient_scroll_clip_layer); |