diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/cc/trees | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/cc/trees')
62 files changed, 4343 insertions, 3169 deletions
diff --git a/chromium/cc/trees/blocking_task_runner.cc b/chromium/cc/trees/blocking_task_runner.cc index 78ef04e1eec..b6c8a49a3b8 100644 --- a/chromium/cc/trees/blocking_task_runner.cc +++ b/chromium/cc/trees/blocking_task_runner.cc @@ -34,19 +34,19 @@ bool BlockingTaskRunner::BelongsToCurrentThread() { } bool BlockingTaskRunner::PostTask(const tracked_objects::Location& from_here, - const base::Closure& task) { + base::OnceClosure task) { base::AutoLock lock(lock_); DCHECK(task_runner_.get() || capture_); if (!capture_) - return task_runner_->PostTask(from_here, task); - captured_tasks_.push_back(task); + return task_runner_->PostTask(from_here, std::move(task)); + captured_tasks_.push_back(std::move(task)); return true; } void BlockingTaskRunner::SetCapture(bool capture) { DCHECK(BelongsToCurrentThread()); - std::vector<base::Closure> tasks; + std::vector<base::OnceClosure> tasks; { base::AutoLock lock(lock_); @@ -60,7 +60,7 @@ void BlockingTaskRunner::SetCapture(bool capture) { tasks.swap(captured_tasks_); } for (size_t i = 0; i < tasks.size(); ++i) - tasks[i].Run(); + std::move(tasks[i]).Run(); } BlockingTaskRunner::CapturePostTasks::CapturePostTasks( diff --git a/chromium/cc/trees/blocking_task_runner.h b/chromium/cc/trees/blocking_task_runner.h index d34e2f20cd4..25d227a6b15 100644 --- a/chromium/cc/trees/blocking_task_runner.h +++ b/chromium/cc/trees/blocking_task_runner.h @@ -76,7 +76,7 @@ class CC_EXPORT BlockingTaskRunner { // until the capturing stops. At that time the tasks will be run directly // instead of being posted to the SingleThreadTaskRunner. bool PostTask(const tracked_objects::Location& from_here, - const base::Closure& task); + base::OnceClosure task); private: explicit BlockingTaskRunner( @@ -89,7 +89,7 @@ class CC_EXPORT BlockingTaskRunner { base::Lock lock_; int capture_; - std::vector<base::Closure> captured_tasks_; + std::vector<base::OnceClosure> captured_tasks_; DISALLOW_COPY_AND_ASSIGN(BlockingTaskRunner); }; diff --git a/chromium/cc/trees/clip_node.cc b/chromium/cc/trees/clip_node.cc index c8d2eff7f65..76272e39c9e 100644 --- a/chromium/cc/trees/clip_node.cc +++ b/chromium/cc/trees/clip_node.cc @@ -14,16 +14,13 @@ namespace cc { ClipNode::ClipNode() : id(ClipTree::kInvalidNodeId), parent_id(ClipTree::kInvalidNodeId), - owning_layer_id(Layer::INVALID_ID), clip_type(ClipType::APPLIES_LOCAL_CLIP), transform_id(TransformTree::kInvalidNodeId) { - cached_clip_rects = std::vector<ClipRectData>(defaultCachedClipsSize); } ClipNode::ClipNode(const ClipNode& other) : id(other.id), parent_id(other.parent_id), - owning_layer_id(other.owning_layer_id), clip_type(other.clip_type), clip(other.clip), transform_id(other.transform_id) { @@ -39,7 +36,6 @@ ClipNode::ClipNode(const ClipNode& other) ClipNode& ClipNode::operator=(const ClipNode& other) { id = other.id; parent_id = other.parent_id; - owning_layer_id = other.owning_layer_id; clip_type = other.clip_type; clip = other.clip; transform_id = other.transform_id; @@ -66,7 +62,6 @@ bool ClipNode::operator==(const ClipNode& other) const { (!clip_expander && other.clip_expander)) return false; return id == other.id && parent_id == other.parent_id && - owning_layer_id == other.owning_layer_id && clip_type == other.clip_type && clip == other.clip && transform_id == other.transform_id; } @@ -74,7 +69,6 @@ bool ClipNode::operator==(const ClipNode& other) const { void ClipNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); - value->SetInteger("owning_layer_id", owning_layer_id); value->SetInteger("clip_type", static_cast<int>(clip_type)); MathUtil::AddToTracedValue("clip", clip, value); value->SetInteger("transform_id", transform_id); diff --git a/chromium/cc/trees/clip_node.h b/chromium/cc/trees/clip_node.h index 5c204549d1c..506b4932873 100644 --- a/chromium/cc/trees/clip_node.h +++ b/chromium/cc/trees/clip_node.h @@ -7,6 +7,7 @@ #include <memory> +#include "base/containers/stack_container.h" #include "cc/cc_export.h" #include "cc/trees/clip_expander.h" #include "ui/gfx/geometry/rect_f.h" @@ -27,14 +28,10 @@ struct CC_EXPORT ClipNode { ~ClipNode(); - static const int defaultCachedClipsSize = 1; - // The node index of this node in the clip tree node vector. int id; // The node index of the parent node in the clip tree node vector. int parent_id; - // The layer id of the layer that owns this node. - int owning_layer_id; enum class ClipType { // The node contributes a new clip (that is, |clip| needs to be applied). @@ -56,8 +53,13 @@ struct CC_EXPORT ClipNode { gfx::RectF clip; // Each element of this cache stores the accumulated clip from this clip - // node to a particular target. - mutable std::vector<ClipRectData> cached_clip_rects; + // node to a particular target. The number of cached clip rects required + // per node is roughly proportional to the number of render targets a + // given clip rect participates in. On many pages with only a root + // render target, the number of cached clip rects per node is 1. + // Any more than 3, and this will overflow rects onto the heap, so this + // number is a tradeoff of ClipNode size on average and access speed. + mutable base::StackVector<ClipRectData, 3> cached_clip_rects; // This rect accumulates all clips from this node to the root in screen space. // It is used in the computation of layer's visible rect. diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc index d740521408d..e6aec42ecd3 100644 --- a/chromium/cc/trees/damage_tracker.cc +++ b/chromium/cc/trees/damage_tracker.cc @@ -25,8 +25,7 @@ std::unique_ptr<DamageTracker> DamageTracker::Create() { return base::WrapUnique(new DamageTracker()); } -DamageTracker::DamageTracker() - : mailboxId_(0) {} +DamageTracker::DamageTracker() : mailboxId_(0) {} DamageTracker::~DamageTracker() {} @@ -175,10 +174,15 @@ void DamageTracker::ComputeSurfaceDamage(RenderSurfaceImpl* render_surface) { DamageAccumulator damage_from_surface_mask = TrackDamageFromSurfaceMask(render_surface->MaskLayer()); DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects(); + // True if any layer is removed. + has_damage_from_contributing_content_ |= + !damage_from_leftover_rects.IsEmpty(); if (render_surface->SurfacePropertyChangedOnlyFromDescendant()) { damage_for_this_update_ = DamageAccumulator(); damage_for_this_update_.Union(render_surface->content_rect()); + // True if there is surface property change from descendant. + has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty(); } else { // TODO(shawnsingh): can we clamp this damage to the surface's content rect? // (affects performance, but not correctness) @@ -187,7 +191,7 @@ void DamageTracker::ComputeSurfaceDamage(RenderSurfaceImpl* render_surface) { gfx::Rect damage_rect; bool is_rect_valid = damage_for_this_update_.GetAsRect(&damage_rect); - if (is_rect_valid) { + if (is_rect_valid && !damage_rect.IsEmpty()) { damage_rect = render_surface->Filters().MapRect( damage_rect, render_surface->SurfaceScale().matrix()); damage_for_this_update_ = DamageAccumulator(); @@ -221,7 +225,7 @@ DamageTracker::LayerRectMapData& DamageTracker::RectDataForLayer( } DamageTracker::SurfaceRectMapData& DamageTracker::RectDataForSurface( - int surface_id, + uint64_t surface_id, bool* surface_is_new) { SurfaceRectMapData data(surface_id); @@ -258,6 +262,7 @@ DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask( void DamageTracker::PrepareForUpdate() { mailboxId_++; damage_for_this_update_ = DamageAccumulator(); + has_damage_from_contributing_content_ = false; } DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromLeftoverRects() { @@ -331,9 +336,9 @@ void DamageTracker::ExpandDamageInsideRectWithFilters( const FilterOperations& filters) { gfx::Rect damage_rect; 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) + // If the damage accumulated so far isn't a valid rect or empty, then there is + // no point in trying to make it bigger. + if (!is_valid_rect || damage_rect.IsEmpty()) return; // Compute the pixels in the background of the surface that could be affected @@ -364,7 +369,6 @@ void DamageTracker::AccumulateDamageFromLayer(LayerImpl* layer) { // its target RenderSurface, even if that layer owns the target RenderSurface // itself. To consider how a layer's target surface contributes to the // ancestor surface, ExtendDamageForRenderSurface() must be called instead. - bool layer_is_new = false; LayerRectMapData& data = RectDataForLayer(layer->id(), &layer_is_new); gfx::Rect old_rect_in_target_space = data.rect_; @@ -380,18 +384,25 @@ void DamageTracker::AccumulateDamageFromLayer(LayerImpl* layer) { // The layer's old region is now exposed on the target surface, too. // Note old_rect_in_target_space is already in target space. damage_for_this_update_.Union(old_rect_in_target_space); - return; + } else { + // If the layer properties haven't changed, then the the target surface is + // only affected by the layer's damaged area, which could be empty. + gfx::Rect damage_rect = + gfx::UnionRects(layer->update_rect(), layer->damage_rect()); + damage_rect.Intersect(gfx::Rect(layer->bounds())); + + if (!damage_rect.IsEmpty()) { + gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect( + layer->DrawTransform(), damage_rect); + damage_for_this_update_.Union(damage_rect_in_target_space); + } } - // If the layer properties haven't changed, then the the target surface is - // only affected by the layer's damaged area, which could be empty. - gfx::Rect damage_rect = - gfx::UnionRects(layer->update_rect(), layer->damage_rect()); - damage_rect.Intersect(gfx::Rect(layer->bounds())); - if (!damage_rect.IsEmpty()) { - gfx::Rect damage_rect_in_target_space = - MathUtil::MapEnclosingClippedRect(layer->DrawTransform(), damage_rect); - damage_for_this_update_.Union(damage_rect_in_target_space); + // Property changes from animaiton will not be considered as damage from + // contributing content. + if (layer_is_new || layer->LayerPropertyChangedNotFromPropertyTrees() || + !layer->update_rect().IsEmpty() || !layer->damage_rect().IsEmpty()) { + has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty(); } } @@ -456,6 +467,9 @@ void DamageTracker::AccumulateDamageFromRenderSurface( ExpandDamageInsideRectWithFilters(surface_rect_in_target_space, background_filters); } + + // True if any changes from contributing render surface. + has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty(); } bool DamageTracker::DamageAccumulator::GetAsRect(gfx::Rect* rect) { diff --git a/chromium/cc/trees/damage_tracker.h b/chromium/cc/trees/damage_tracker.h index 751eeb977e5..c320db43350 100644 --- a/chromium/cc/trees/damage_tracker.h +++ b/chromium/cc/trees/damage_tracker.h @@ -36,11 +36,18 @@ class CC_EXPORT DamageTracker { LayerTreeImpl* layer_tree_impl, const RenderSurfaceList& render_surface_list); - void DidDrawDamagedArea() { current_damage_ = DamageAccumulator(); } + void DidDrawDamagedArea() { + current_damage_ = DamageAccumulator(); + has_damage_from_contributing_content_ = false; + } void AddDamageNextUpdate(const gfx::Rect& dmg) { current_damage_.Union(dmg); } bool GetDamageRectIfValid(gfx::Rect* rect); + bool has_damage_from_contributing_content() const { + return has_damage_from_contributing_content_; + } + private: DamageTracker(); @@ -114,7 +121,7 @@ class CC_EXPORT DamageTracker { struct SurfaceRectMapData { SurfaceRectMapData() : surface_id_(0), mailboxId_(0) {} - explicit SurfaceRectMapData(int surface_id) + explicit SurfaceRectMapData(uint64_t surface_id) : surface_id_(surface_id), mailboxId_(0) {} void Update(const gfx::Rect& rect, unsigned int mailboxId) { mailboxId_ = mailboxId; @@ -125,7 +132,7 @@ class CC_EXPORT DamageTracker { return surface_id_ < other.surface_id_; } - int surface_id_; + uint64_t surface_id_; unsigned int mailboxId_; gfx::Rect rect_; }; @@ -133,13 +140,16 @@ class CC_EXPORT DamageTracker { typedef std::vector<SurfaceRectMapData> SortedRectMapForSurfaces; LayerRectMapData& RectDataForLayer(int layer_id, bool* layer_is_new); - SurfaceRectMapData& RectDataForSurface(int layer_id, bool* layer_is_new); + SurfaceRectMapData& RectDataForSurface(uint64_t surface_id, + bool* layer_is_new); SortedRectMapForLayers rect_history_for_layers_; SortedRectMapForSurfaces rect_history_for_surfaces_; unsigned int mailboxId_; DamageAccumulator current_damage_; + // Damage from contributing render surface and layer + bool has_damage_from_contributing_content_; // Damage accumulated since the last call to PrepareForUpdate(). DamageAccumulator damage_for_this_update_; diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc index d036723038e..de3731096c3 100644 --- a/chromium/cc/trees/damage_tracker_unittest.cc +++ b/chromium/cc/trees/damage_tracker_unittest.cc @@ -189,6 +189,9 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { &root_damage_rect)); EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { @@ -217,6 +220,13 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), child_damage_rect.ToString()); EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); + + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { @@ -261,6 +271,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(120, 125, 1, 2).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { @@ -318,6 +331,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { &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))); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { @@ -364,6 +380,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 110, 17, 18))); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { @@ -388,6 +407,12 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 2: If a layer moves due to property change, it damages both the new // location and the old (exposed) location. The old location is the @@ -415,6 +440,111 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_FLOAT_RECT_EQ(expected_rect, root_damage_rect); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // Transform from browser animation should not be considered as damage from + // contributing layer since it is applied to the whole layer which has a + // render surface. + EXPECT_FALSE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); +} + +TEST_F(DamageTrackerTest, + VerifyDamageForPropertyChangesFromContributingContents) { + LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); + LayerImpl* child1 = root->test_properties()->children[0]; + LayerImpl* child2 = root->test_properties()->children[1]; + LayerImpl* grandchild1 = child1->test_properties()->children[0]; + + // CASE 1: The child1's opacity changed. + ClearDamageForAllSurfaces(root); + root->layer_tree_impl()->SetOpacityMutated(child1->element_id(), 0.5f); + EmulateDrawingOneFrame(root); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); + + // CASE 2: The layer2's opacity changed. + child2->test_properties()->force_render_surface = true; + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + EmulateDrawingOneFrame(root); + ClearDamageForAllSurfaces(root); + root->layer_tree_impl()->SetOpacityMutated(child2->element_id(), 0.5f); + EmulateDrawingOneFrame(root); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); + + // CASE 3: The grandchild1's opacity changed. + grandchild1->test_properties()->force_render_surface = true; + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + EmulateDrawingOneFrame(root); + ClearDamageForAllSurfaces(root); + root->layer_tree_impl()->SetOpacityMutated(grandchild1->element_id(), 0.5f); + EmulateDrawingOneFrame(root); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); +} + +TEST_F(DamageTrackerTest, + VerifyDamageForUpdateAndDamageRectsFromContributingContents) { + LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); + LayerImpl* child1 = root->test_properties()->children[0]; + LayerImpl* child2 = root->test_properties()->children[1]; + LayerImpl* grandchild1 = child1->test_properties()->children[0]; + + // CASE 1: Adding the layer1's damage rect and update rect should cause the + // corresponding damage to the surface. + child1->SetDrawsContent(true); + ClearDamageForAllSurfaces(root); + child1->AddDamageRect(gfx::Rect(105, 106, 12, 15)); + child1->SetUpdateRect(gfx::Rect(115, 116, 12, 15)); + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + EmulateDrawingOneFrame(root); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); + + // CASE 2: Adding the layer2's damage rect and update rect should cause the + // corresponding damage to the surface. + ClearDamageForAllSurfaces(root); + child2->AddDamageRect(gfx::Rect(11, 11, 12, 15)); + child2->SetUpdateRect(gfx::Rect(12, 12, 12, 15)); + EmulateDrawingOneFrame(root); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); + + // CASE 3: Adding the grandchild1's damage rect and update rect should cause + // the corresponding damage to the surface. + ClearDamageForAllSurfaces(root); + grandchild1->AddDamageRect(gfx::Rect(1, 0, 2, 5)); + grandchild1->SetUpdateRect(gfx::Rect(2, 1, 2, 5)); + EmulateDrawingOneFrame(root); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageWhenSurfaceRemoved) { @@ -434,6 +564,9 @@ TEST_F(DamageTrackerTest, VerifyDamageWhenSurfaceRemoved) { &root_damage_rect)); EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { @@ -461,6 +594,14 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(85, 85, 45, 45).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // Layer's layer_property_changed_ should be considered as damage to render + // surface. + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); // With the anchor on the layer's center, now we can test the rotation more // intuitively, since it applies about the layer's anchor. @@ -479,6 +620,15 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(expected_rect.ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // Transform from browser animation should not be considered as damage from + // contributing layer since it is applied to the whole layer which has a + // render surface. + EXPECT_FALSE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { @@ -533,6 +683,12 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { &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)); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { @@ -543,11 +699,17 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(5.f)); - // Setting the filter will damage the whole surface. + // Setting the filter should not damage the conrresponding render surface. ClearDamageForAllSurfaces(root); surface->test_properties()->filters = filters; root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); + EXPECT_FALSE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(surface) + ->damage_tracker() + ->has_damage_from_contributing_content()); // Setting the update rect should cause the corresponding damage to the // surface, blurred based on the size of the blur filter. @@ -563,6 +725,12 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(286, 287, 33, 34), root_damage_rect); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(surface) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { @@ -578,10 +746,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { SkBlurImageFilter::Make(2, 2, nullptr))); // Setting the filter will damage the whole surface. - ClearDamageForAllSurfaces(root); child->test_properties()->force_render_surface = true; root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); + ClearDamageForAllSurfaces(root); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -595,6 +763,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { // gfx::Rect(0, 0, 30, 30), expanded by 6px for the 2px blur filter. EXPECT_EQ(gfx::Rect(-6, -6, 42, 42), child_damage_rect); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // CASE 1: Setting the update rect should damage the whole surface (for now) ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(1, 1)); @@ -610,6 +785,33 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { // gfx::Rect(0, 0, 1, 1), expanded by 6px for the 2px blur filter. EXPECT_EQ(gfx::Rect(-6, -6, 13, 13), child_damage_rect); + + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); + + // CASE 2: No changes, so should not damage the surface. + ClearDamageForAllSurfaces(root); + EmulateDrawingOneFrame(root); + + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( + &root_damage_rect)); + EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + + // Should not be expanded by the blur filter. + EXPECT_EQ(gfx::Rect(), root_damage_rect); + EXPECT_EQ(gfx::Rect(), child_damage_rect); + + EXPECT_FALSE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { @@ -847,6 +1049,26 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // 100,100. expected_damage_rect = gfx::Rect(100, 100, 7, 7); EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); + + // CASE 7: No changes, so should not damage the surface. + ClearDamageForAllSurfaces(root); + // We want to make sure that the background filter doesn't cause empty damage + // to get expanded. We position child1 so that an expansion of the empty rect + // would have non-empty intersection with child1 in its target space (root + // space). + child1->SetPosition(gfx::PointF()); + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + EmulateDrawingOneFrame(root); + + gfx::Rect child_damage_rect; + EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( + &root_damage_rect)); + EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + &child_damage_rect)); + + // Should not be expanded by the blur filter. + EXPECT_EQ(gfx::Rect(), root_damage_rect); + EXPECT_EQ(gfx::Rect(), child_damage_rect); } TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { @@ -875,6 +1097,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 2: If the layer is removed, its entire old layer becomes exposed, not // just the last update rect. @@ -899,6 +1124,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { &root_damage_rect)); EXPECT_EQ(gfx::Rect(100, 100, 30, 30).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { @@ -935,6 +1163,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(400, 380, 6, 8).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { @@ -969,6 +1200,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { &root_damage_rect)); EXPECT_EQ(gfx::Rect(100, 100, 303, 284).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { @@ -995,6 +1229,18 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { &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()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child2) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(grand_child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 2: Same as previous case, but with additional damage elsewhere that // should be properly unioned. @@ -1013,6 +1259,18 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { EXPECT_EQ(gfx::Rect(200, 200, 6, 8).ToString(), child_damage_rect.ToString()); EXPECT_EQ(gfx::Rect(11, 11, 295, 297).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child2) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(grand_child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { @@ -1049,6 +1307,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { // space). EXPECT_EQ(gfx::Rect(290, 290, 16, 23).ToString(), root_damage_rect.ToString()); + + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { @@ -1089,6 +1354,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { // - new child1 surface in target space: gfx::Rect(240, 240, 16, 18) EXPECT_EQ(gfx::Rect(240, 240, 66, 68).ToString(), root_damage_rect.ToString()); + + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { @@ -1113,6 +1385,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // CASE 2: If a descendant surface appears, its entire old area becomes // exposed. @@ -1145,6 +1421,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { child_damage_rect.ToString()); EXPECT_EQ(gfx::Rect(290, 290, 16, 18).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { @@ -1164,6 +1443,9 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { &root_damage_rect)); EXPECT_TRUE(child_damage_rect.IsEmpty()); EXPECT_TRUE(root_damage_rect.IsEmpty()); + EXPECT_FALSE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 2: If nothing changes twice in a row, the damage rect should still be // empty. @@ -1177,6 +1459,9 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { &root_damage_rect)); EXPECT_TRUE(child_damage_rect.IsEmpty()); EXPECT_TRUE(root_damage_rect.IsEmpty()); + EXPECT_FALSE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { @@ -1197,6 +1482,9 @@ TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { &root_damage_rect)); EXPECT_TRUE(child_damage_rect.IsEmpty()); EXPECT_TRUE(root_damage_rect.IsEmpty()); + EXPECT_FALSE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForMask) { @@ -1243,6 +1531,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { &child_damage_rect)); EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // CASE 2: a property change on the mask layer should damage the entire // target surface. @@ -1265,6 +1560,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { &child_damage_rect)); EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_FALSE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // CASE 3: removing the mask also damages the entire target surface. // @@ -1291,6 +1593,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { @@ -1312,6 +1618,9 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { EXPECT_EQ(gfx::UnionRects(gfx::Rect(15, 16, 32, 33), gfx::Rect(100 + 10, 100 + 11, 12, 13)).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); // Case 2: An additional sanity check that adding damage works even when // nothing on the layer tree changed. @@ -1324,6 +1633,9 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString()); + EXPECT_FALSE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageWithNoContributingLayers) { @@ -1341,6 +1653,9 @@ TEST_F(DamageTrackerTest, VerifyDamageWithNoContributingLayers) { EXPECT_TRUE( target_surface->damage_tracker()->GetDamageRectIfValid(&damage_rect)); EXPECT_TRUE(damage_rect.IsEmpty()); + EXPECT_FALSE(GetRenderSurface(root_ptr) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { @@ -1359,6 +1674,9 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_EQ(gfx::Rect(110, 111, 1, 2).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); // New damage, without having cleared the previous damage, should be unioned // to the previous one. @@ -1369,6 +1687,9 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { &root_damage_rect)); EXPECT_EQ(gfx::Rect(110, 111, 11, 16).ToString(), root_damage_rect.ToString()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); // If we notify the damage tracker that we drew the damaged area, then damage // should be emptied. @@ -1376,6 +1697,9 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); + EXPECT_FALSE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); // Damage should remain empty even after one frame, since there's yet no new // damage. @@ -1384,6 +1708,9 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); + EXPECT_FALSE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, HugeDamageRect) { @@ -1420,6 +1747,9 @@ TEST_F(DamageTrackerTest, HugeDamageRect) { 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()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } } @@ -1447,6 +1777,9 @@ TEST_F(DamageTrackerTest, DamageRectTooBig) { &damage_rect)); EXPECT_EQ(GetRenderSurface(root)->content_rect(), GetRenderSurface(root)->GetDamageRect()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) { @@ -1478,6 +1811,9 @@ TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) { &damage_rect)); EXPECT_EQ(GetRenderSurface(root)->content_rect(), GetRenderSurface(root)->GetDamageRect()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) { @@ -1526,6 +1862,13 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) { gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // Add new damage, without changing properties, which goes down a different // path in the damage tracker. root->layer_tree_impl()->ResetAllChangeTracking(); @@ -1554,6 +1897,13 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) { EXPECT_TRUE(damage_rect.Contains( gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); + + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) { @@ -1608,6 +1958,13 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) { gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); + // Add new damage, without changing properties, which goes down a different // path in the damage tracker. root->layer_tree_impl()->ResetAllChangeTracking(); @@ -1636,6 +1993,13 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) { EXPECT_TRUE(damage_rect.Contains( gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); + + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child1) + ->damage_tracker() + ->has_damage_from_contributing_content()); } } // namespace diff --git a/chromium/cc/trees/debug_rect_history.cc b/chromium/cc/trees/debug_rect_history.cc index 35c8db1073d..41960510cac 100644 --- a/chromium/cc/trees/debug_rect_history.cc +++ b/chromium/cc/trees/debug_rect_history.cc @@ -135,12 +135,17 @@ void DebugRectHistory::SaveTouchEventHandlerRects(LayerTreeImpl* tree_impl) { } void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) { - for (Region::Iterator iter(layer->touch_event_handler_region()); - iter.has_rect(); iter.next()) { - debug_rects_.push_back( - DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE, - MathUtil::MapEnclosingClippedRect( - layer->ScreenSpaceTransform(), iter.rect()))); + const TouchActionRegion& touch_action_region = layer->touch_action_region(); + for (int touch_action_index = kTouchActionNone; + touch_action_index != kTouchActionMax; ++touch_action_index) { + auto touch_action = static_cast<TouchAction>(touch_action_index); + Region region = touch_action_region.GetRegionForTouchAction(touch_action); + for (Region::Iterator iter(region); iter.has_rect(); iter.next()) { + debug_rects_.emplace_back(TOUCH_EVENT_HANDLER_RECT_TYPE, + MathUtil::MapEnclosingClippedRect( + layer->ScreenSpaceTransform(), iter.rect()), + touch_action); + } } } diff --git a/chromium/cc/trees/debug_rect_history.h b/chromium/cc/trees/debug_rect_history.h index 7728237eb54..2e9c239b7a2 100644 --- a/chromium/cc/trees/debug_rect_history.h +++ b/chromium/cc/trees/debug_rect_history.h @@ -9,6 +9,7 @@ #include <vector> #include "base/macros.h" +#include "cc/input/touch_action.h" #include "cc/layers/layer_collections.h" #include "ui/gfx/geometry/rect.h" @@ -46,11 +47,21 @@ enum DebugRectType { }; struct DebugRect { + DebugRect(DebugRectType new_type, + const gfx::Rect& new_rect, + TouchAction new_touch_action) + : type(new_type), rect(new_rect), touch_action(new_touch_action) { + if (type != TOUCH_EVENT_HANDLER_RECT_TYPE) + DCHECK_EQ(touch_action, kTouchActionNone); + } DebugRect(DebugRectType new_type, const gfx::Rect& new_rect) - : type(new_type), rect(new_rect) {} + : DebugRect(new_type, new_rect, kTouchActionNone) {} DebugRectType type; gfx::Rect rect; + // Valid when |type| is |TOUCH_EVENT_HANDLER_RECT_TYPE|, otherwise default to + // |kTouchActionNone|. + TouchAction touch_action; }; // This class maintains a history of rects of various types that can be used diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index 43120259e3d..e458ba70b0e 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -238,7 +238,8 @@ static ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, while (target_node->clip_id < clip_node->id) { if (parent_chain.size() > 0) { // Search the cache. - for (auto& data : clip_node->cached_clip_rects) { + for (size_t i = 0; i < clip_node->cached_clip_rects->size(); ++i) { + auto& data = clip_node->cached_clip_rects[i]; if (data.target_id == target_id) { cache_hit = true; cached_clip = data.clip; @@ -354,11 +355,9 @@ static void SetHasContributingLayerThatEscapesClip(int lca_clip_id, template <typename LayerType> static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, const TransformTree& tree) { - if (!layer->use_parent_backface_visibility()) + if (!layer->use_parent_backface_visibility() || !layer->has_transform_node()) return layer->transform_tree_index(); - const TransformNode* node = tree.Node(layer->transform_tree_index()); - return layer->id() == node->owning_layer_id ? tree.parent(node)->id - : node->id; + return tree.Node(layer->transform_tree_index())->parent_id; } static bool IsTargetSpaceTransformBackFaceVisible( @@ -385,12 +384,8 @@ template <typename LayerType> static bool IsLayerBackFaceVisible(LayerType* layer, int transform_tree_index, const PropertyTrees* property_trees) { - const TransformNode* node = - property_trees->transform_tree.Node(transform_tree_index); - return layer->use_local_transform_for_backface_visibility() - ? node->local.IsBackFaceVisible() - : IsTargetSpaceTransformBackFaceVisible( - layer, transform_tree_index, property_trees); + return IsTargetSpaceTransformBackFaceVisible(layer, transform_tree_index, + property_trees); } static inline bool TransformToScreenIsKnown(Layer* layer, @@ -562,7 +557,7 @@ static void SetSurfaceIsClipped(const ClipTree& clip_tree, is_clipped = false; } else if (render_surface->ClipTreeIndex() == render_surface->render_target()->ClipTreeIndex()) { - // There is no clip between between the render surface and its target, so + // There is no clip between the render surface and its target, so // the surface need not be clipped. is_clipped = false; } else { @@ -671,17 +666,22 @@ 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_cache_render_surface = + effect_node->closest_ancestor_with_cached_render_surface_id; int effect_ancestor_with_copy_request = effect_node->closest_ancestor_with_copy_request_id; - bool non_root_copy_request = - effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId; + int lower_effect_closest_ancestor = + std::max(effect_ancestor_with_cache_render_surface, + effect_ancestor_with_copy_request); + bool non_root_copy_request_or_cache_render_surface = + lower_effect_closest_ancestor > EffectTree::kContentsRootNodeId; gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); gfx::RectF accumulated_clip_in_root_space; - if (non_root_copy_request) { + if (non_root_copy_request_or_cache_render_surface) { bool include_expanding_clips = true; ConditionalClip accumulated_clip = ComputeAccumulatedClip( property_trees, include_expanding_clips, layer->clip_tree_index(), - effect_ancestor_with_copy_request); + lower_effect_closest_ancestor); if (!accumulated_clip.is_clipped) return layer_content_rect; accumulated_clip_in_root_space = accumulated_clip.clip_rect; @@ -693,8 +693,8 @@ static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, } const EffectNode* root_effect_node = - non_root_copy_request - ? property_trees->effect_tree.Node(effect_ancestor_with_copy_request) + non_root_copy_request_or_cache_render_surface + ? property_trees->effect_tree.Node(lower_effect_closest_ancestor) : property_trees->effect_tree.Node(EffectTree::kContentsRootNodeId); ConditionalClip accumulated_clip_in_layer_space = ComputeTargetRectInLocalSpace( @@ -740,23 +740,6 @@ static void UpdateRenderTarget(EffectTree* effect_tree) { } } -static void UpdateScrollTree(ScrollTree* scroll_tree, - const LayerTreeHost* layer_tree_host) { - if (!scroll_tree->needs_update()) - return; - - for (int i = ScrollTree::kRootNodeId; - i < static_cast<int>(scroll_tree->size()); ++i) { - ScrollNode* scroll_node = scroll_tree->Node(i); - if (Layer* scroll_layer = - layer_tree_host->LayerById(scroll_node->owning_layer_id)) { - if (Layer* scroll_clip_layer = scroll_layer->scroll_clip_layer()) { - scroll_node->scroll_clip_layer_bounds = scroll_clip_layer->bounds(); - } - } - } -} - static void ComputeClips(PropertyTrees* property_trees) { DCHECK(!property_trees->transform_tree.needs_update()); ClipTree* clip_tree = &property_trees->clip_tree; @@ -769,7 +752,7 @@ static void ComputeClips(PropertyTrees* property_trees) { i < static_cast<int>(clip_tree->size()); ++i) { ClipNode* clip_node = clip_tree->Node(i); // Clear the clip rect cache - clip_node->cached_clip_rects = std::vector<ClipRectData>(1); + clip_node->cached_clip_rects->clear(); if (clip_node->id == ClipTree::kViewportNodeId) { clip_node->cached_accumulated_rect_in_screen_space = clip_node->clip; continue; @@ -843,6 +826,10 @@ 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()); + layer_impl->EnsureValidPropertyTreeIndices(); + if (!IsRootLayer(layer_impl) && LayerShouldBeSkippedForDrawPropertiesComputation( layer_impl, transform_tree, effect_tree)) @@ -883,7 +870,6 @@ void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, property_trees->clip_tree.set_needs_update(true); property_trees->effect_tree.set_needs_update(true); } - UpdateScrollTree(&property_trees->scroll_tree, layer_tree_host); ComputeTransforms(&property_trees->transform_tree); ComputeEffects(&property_trees->effect_tree); // Computation of clips uses ToScreen which is updated while computing diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc index 7a556277530..ce158903ba1 100644 --- a/chromium/cc/trees/effect_node.cc +++ b/chromium/cc/trees/effect_node.cc @@ -12,11 +12,12 @@ namespace cc { EffectNode::EffectNode() : id(EffectTree::kInvalidNodeId), parent_id(EffectTree::kInvalidNodeId), - owning_layer_id(Layer::INVALID_ID), + stable_id(INVALID_STABLE_ID), opacity(1.f), screen_space_opacity(1.f), blend_mode(SkBlendMode::kSrcOver), has_render_surface(false), + cache_render_surface(false), has_copy_request(false), hidden_by_backface_visibility(false), double_sided(false), @@ -32,15 +33,17 @@ EffectNode::EffectNode() clip_id(0), target_id(1), mask_layer_id(Layer::INVALID_ID), + closest_ancestor_with_cached_render_surface_id(-1), closest_ancestor_with_copy_request_id(-1) {} EffectNode::EffectNode(const EffectNode& other) = default; bool EffectNode::operator==(const EffectNode& other) const { return id == other.id && parent_id == other.parent_id && - owning_layer_id == other.owning_layer_id && opacity == other.opacity && + stable_id == other.stable_id && opacity == other.opacity && screen_space_opacity == other.screen_space_opacity && has_render_surface == other.has_render_surface && + cache_render_surface == other.cache_render_surface && has_copy_request == other.has_copy_request && filters == other.filters && background_filters == other.background_filters && @@ -62,6 +65,8 @@ bool EffectNode::operator==(const EffectNode& other) const { 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 && + closest_ancestor_with_cached_render_surface_id == + other.closest_ancestor_with_cached_render_surface_id && closest_ancestor_with_copy_request_id == other.closest_ancestor_with_copy_request_id; } @@ -69,9 +74,10 @@ bool EffectNode::operator==(const EffectNode& other) const { void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); - value->SetInteger("owning_layer_id", owning_layer_id); + value->SetInteger("stable_id", stable_id); value->SetDouble("opacity", opacity); value->SetBoolean("has_render_surface", has_render_surface); + value->SetBoolean("cache_render_surface", cache_render_surface); value->SetBoolean("has_copy_request", has_copy_request); value->SetBoolean("double_sided", double_sided); value->SetBoolean("is_drawn", is_drawn); @@ -85,6 +91,8 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("clip_id", clip_id); value->SetInteger("target_id", target_id); value->SetInteger("mask_layer_id", mask_layer_id); + value->SetInteger("closest_ancestor_with_cached_render_surface_id", + closest_ancestor_with_cached_render_surface_id); value->SetInteger("closest_ancestor_with_copy_request_id", closest_ancestor_with_copy_request_id); } diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h index 8079f898283..48e25e9b209 100644 --- a/chromium/cc/trees/effect_node.h +++ b/chromium/cc/trees/effect_node.h @@ -23,12 +23,17 @@ struct CC_EXPORT EffectNode { EffectNode(); EffectNode(const EffectNode& other); + enum StableIdLabels { INVALID_STABLE_ID = 0 }; + // The node index of this node in the effect tree node vector. int id; // The node index of the parent node in the effect tree node vector. int parent_id; - // The layer id of the layer that owns this node. - int owning_layer_id; + // An opaque, unique, stable identifer for this effect that persists across + // frame commits. This id is used only for internal implementation + // details such as RenderSurface and RenderPass ids, and should not + // be assumed to have semantic meaning. + uint64_t stable_id; float opacity; float screen_space_opacity; @@ -44,6 +49,7 @@ struct CC_EXPORT EffectNode { gfx::Size unscaled_mask_target_size; bool has_render_surface : 1; + bool cache_render_surface : 1; bool has_copy_request : 1; bool hidden_by_backface_visibility : 1; bool double_sided : 1; @@ -78,6 +84,7 @@ struct CC_EXPORT EffectNode { // The layer id of the mask layer, if any, to apply to this effect // node's content when rendering to a surface. int mask_layer_id; + int closest_ancestor_with_cached_render_surface_id; int closest_ancestor_with_copy_request_id; bool operator==(const EffectNode& other) const; diff --git a/chromium/cc/trees/latency_info_swap_promise_monitor.cc b/chromium/cc/trees/latency_info_swap_promise_monitor.cc index cb0af9ee9a2..c8e933dac6d 100644 --- a/chromium/cc/trees/latency_info_swap_promise_monitor.cc +++ b/chromium/cc/trees/latency_info_swap_promise_monitor.cc @@ -90,12 +90,12 @@ void LatencyInfoSwapPromiseMonitor::OnForwardScrollUpdateToMainThreadOnImpl() { if (!new_sequence_number) return; ui::LatencyInfo new_latency; - new_latency.AddLatencyNumberWithTraceName( - ui::LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT, 0, - new_sequence_number, "ScrollUpdate"); new_latency.CopyLatencyFrom( *latency_, ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT); + new_latency.AddLatencyNumberWithTraceName( + ui::LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT, 0, + new_sequence_number, "ScrollUpdate"); std::unique_ptr<SwapPromise> swap_promise( new LatencyInfoSwapPromise(new_latency)); layer_tree_host_impl_->QueueSwapPromiseForMainThreadScrollUpdate( diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc index 8db96130c74..29d7f07f9b8 100644 --- a/chromium/cc/trees/layer_tree_host.cc +++ b/chromium/cc/trees/layer_tree_host.cc @@ -41,6 +41,7 @@ #include "cc/layers/painted_scrollbar_layer.h" #include "cc/resources/ui_resource_manager.h" #include "cc/tiles/frame_viewer_instrumentation.h" +#include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_host_client.h" @@ -49,6 +50,7 @@ #include "cc/trees/mutator_host.h" #include "cc/trees/property_tree_builder.h" #include "cc/trees/proxy_main.h" +#include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/swap_promise_manager.h" #include "cc/trees/transform_node.h" @@ -57,7 +59,7 @@ #include "ui/gfx/geometry/vector2d_conversions.h" namespace { -static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number; +static base::AtomicSequenceNumber s_layer_tree_host_sequence_number; } namespace cc { @@ -216,7 +218,7 @@ const LayerTreeSettings& LayerTreeHost::GetSettings() const { return settings_; } -void LayerTreeHost::SetFrameSinkId(const FrameSinkId& frame_sink_id) { +void LayerTreeHost::SetFrameSinkId(const viz::FrameSinkId& frame_sink_id) { surface_sequence_generator_.set_frame_sink_id(frame_sink_id); } @@ -225,8 +227,7 @@ void LayerTreeHost::QueueSwapPromise( swap_promise_manager_.QueueSwapPromise(std::move(swap_promise)); } -SurfaceSequenceGenerator* -LayerTreeHost::GetSurfaceSequenceGenerator() { +viz::SurfaceSequenceGenerator* LayerTreeHost::GetSurfaceSequenceGenerator() { return &surface_sequence_generator_; } @@ -317,6 +318,7 @@ void LayerTreeHost::FinishCommitOnImplThread( PushPropertyTreesTo(sync_tree); sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kSyncedPropertyTrees); + PushSurfaceIdsTo(sync_tree); TreeSynchronizer::PushLayerProperties(this, sync_tree); sync_tree->lifecycle().AdvanceTo( LayerTreeLifecycle::kSyncedLayerProperties); @@ -345,9 +347,7 @@ void LayerTreeHost::FinishCommitOnImplThread( // Animation::InEffect and we want the old InEffect value for updating // property tree scrolling and animation. // TODO(pdr): Enforce this comment with DCHECKS and a lifecycle state. - bool is_impl_side_update = false; - sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread( - is_impl_side_update); + sync_tree->UpdatePropertyTreeAnimationFromMainThread(); TRACE_EVENT0("cc", "LayerTreeHostInProcess::AnimationHost::PushProperties"); DCHECK(host_impl->mutator_host()); @@ -403,43 +403,42 @@ void LayerTreeHost::CommitComplete() { } } -void LayerTreeHost::SetCompositorFrameSink( - std::unique_ptr<CompositorFrameSink> surface) { - TRACE_EVENT0("cc", "LayerTreeHostInProcess::SetCompositorFrameSink"); +void LayerTreeHost::SetLayerTreeFrameSink( + std::unique_ptr<LayerTreeFrameSink> surface) { + TRACE_EVENT0("cc", "LayerTreeHostInProcess::SetLayerTreeFrameSink"); DCHECK(surface); - DCHECK(!new_compositor_frame_sink_); - new_compositor_frame_sink_ = std::move(surface); - proxy_->SetCompositorFrameSink(new_compositor_frame_sink_.get()); + DCHECK(!new_layer_tree_frame_sink_); + new_layer_tree_frame_sink_ = std::move(surface); + proxy_->SetLayerTreeFrameSink(new_layer_tree_frame_sink_.get()); } -std::unique_ptr<CompositorFrameSink> -LayerTreeHost::ReleaseCompositorFrameSink() { +std::unique_ptr<LayerTreeFrameSink> LayerTreeHost::ReleaseLayerTreeFrameSink() { DCHECK(!visible_); - DidLoseCompositorFrameSink(); - proxy_->ReleaseCompositorFrameSink(); - return std::move(current_compositor_frame_sink_); + DidLoseLayerTreeFrameSink(); + proxy_->ReleaseLayerTreeFrameSink(); + return std::move(current_layer_tree_frame_sink_); } -void LayerTreeHost::RequestNewCompositorFrameSink() { - client_->RequestNewCompositorFrameSink(); +void LayerTreeHost::RequestNewLayerTreeFrameSink() { + client_->RequestNewLayerTreeFrameSink(); } -void LayerTreeHost::DidInitializeCompositorFrameSink() { - DCHECK(new_compositor_frame_sink_); - current_compositor_frame_sink_ = std::move(new_compositor_frame_sink_); - client_->DidInitializeCompositorFrameSink(); +void LayerTreeHost::DidInitializeLayerTreeFrameSink() { + DCHECK(new_layer_tree_frame_sink_); + current_layer_tree_frame_sink_ = std::move(new_layer_tree_frame_sink_); + client_->DidInitializeLayerTreeFrameSink(); } -void LayerTreeHost::DidFailToInitializeCompositorFrameSink() { - DCHECK(new_compositor_frame_sink_); +void LayerTreeHost::DidFailToInitializeLayerTreeFrameSink() { + DCHECK(new_layer_tree_frame_sink_); // Note: It is safe to drop all output surface references here as // LayerTreeHostImpl will not keep a pointer to either the old or - // new CompositorFrameSink after failing to initialize the new one. - current_compositor_frame_sink_ = nullptr; - new_compositor_frame_sink_ = nullptr; - client_->DidFailToInitializeCompositorFrameSink(); + // new LayerTreeFrameSink after failing to initialize the new one. + current_layer_tree_frame_sink_ = nullptr; + new_layer_tree_frame_sink_ = nullptr; + client_->DidFailToInitializeLayerTreeFrameSink(); } std::unique_ptr<LayerTreeHostImpl> @@ -456,15 +455,15 @@ LayerTreeHost::CreateLayerTreeHostImpl( rendering_stats_instrumentation_.get(), task_graph_runner_, std::move(mutator_host_impl), id_, std::move(image_worker_task_runner_)); host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); - host_impl->SetContentIsSuitableForGpuRasterization( - content_is_suitable_for_gpu_rasterization_); + host_impl->SetContentHasSlowPaths(content_has_slow_paths_); + host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_); task_graph_runner_ = NULL; input_handler_weak_ptr_ = host_impl->AsWeakPtr(); return host_impl; } -void LayerTreeHost::DidLoseCompositorFrameSink() { - TRACE_EVENT0("cc", "LayerTreeHostInProcess::DidLoseCompositorFrameSink"); +void LayerTreeHost::DidLoseLayerTreeFrameSink() { + TRACE_EVENT0("cc", "LayerTreeHostInProcess::DidLoseLayerTreeFrameSink"); DCHECK(task_runner_provider_->IsMainThread()); SetNeedsCommit(); } @@ -538,7 +537,8 @@ void LayerTreeHost::SetDebugState( } void LayerTreeHost::ResetGpuRasterizationTracking() { - content_is_suitable_for_gpu_rasterization_ = true; + content_has_slow_paths_ = false; + content_has_non_aa_paint_ = false; gpu_rasterization_histogram_recorded_ = false; } @@ -642,9 +642,9 @@ void LayerTreeHost::RecordGpuRasterizationHistogram( return; bool gpu_rasterization_enabled = false; - if (host_impl->compositor_frame_sink()) { - ContextProvider* compositor_context_provider = - host_impl->compositor_frame_sink()->context_provider(); + if (host_impl->layer_tree_frame_sink()) { + viz::ContextProvider* compositor_context_provider = + host_impl->layer_tree_frame_sink()->context_provider(); if (compositor_context_provider) { gpu_rasterization_enabled = compositor_context_provider->ContextCapabilities().gpu_rasterization; @@ -661,11 +661,13 @@ void LayerTreeHost::RecordGpuRasterizationHistogram( UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered", has_gpu_rasterization_trigger_); UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent", - content_is_suitable_for_gpu_rasterization_); + !content_has_slow_paths_); + UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSlowPathsWithNonAAPaint", + content_has_slow_paths_ && content_has_non_aa_paint_); // Record how many pages actually get gpu rasterization when enabled. - UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed", - (has_gpu_rasterization_trigger_ && - content_is_suitable_for_gpu_rasterization_)); + UMA_HISTOGRAM_BOOLEAN( + "Renderer4.GpuRasterizationUsed", + (has_gpu_rasterization_trigger_ && !content_has_slow_paths_)); } gpu_rasterization_histogram_recorded_ = true; @@ -728,31 +730,40 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { TRACE_EVENT_SCOPE_THREAD, "property_trees", property_trees->AsTracedValue()); } + draw_property_utils::UpdatePropertyTrees(this, property_trees); draw_property_utils::FindLayersThatNeedUpdates(this, property_trees, &update_layer_list); } - bool content_is_suitable_for_gpu = true; - bool did_paint_content = - PaintContent(update_layer_list, &content_is_suitable_for_gpu); - - if (content_is_suitable_for_gpu) { - ++num_consecutive_frames_suitable_for_gpu_; - if (num_consecutive_frames_suitable_for_gpu_ >= - kNumFramesToConsiderBeforeGpuRasterization) { - content_is_suitable_for_gpu_rasterization_ = true; + bool content_has_slow_paths = false; + bool content_has_non_aa_paint = false; + bool did_paint_content = PaintContent( + update_layer_list, &content_has_slow_paths, &content_has_non_aa_paint); + + // |content_has_non_aa_paint| is a correctness (not performance) modifier, if + // it changes we immediately update. To prevent churn, this flag is sticky. + content_has_non_aa_paint_ |= content_has_non_aa_paint; + + // If no slow-path content has appeared for a required number of frames, + // update the flag. + if (!content_has_slow_paths) { + ++num_consecutive_frames_without_slow_paths_; + if (num_consecutive_frames_without_slow_paths_ >= + kNumFramesToConsiderBeforeRemovingSlowPathFlag) { + content_has_slow_paths_ = false; } } else { - num_consecutive_frames_suitable_for_gpu_ = 0; - content_is_suitable_for_gpu_rasterization_ = false; + num_consecutive_frames_without_slow_paths_ = 0; + content_has_slow_paths_ = true; } + return did_paint_content; } void LayerTreeHost::ApplyViewportDeltas(ScrollAndScaleSet* info) { gfx::Vector2dF inner_viewport_scroll_delta; - if (info->inner_viewport_scroll.layer_id != Layer::INVALID_ID) + if (info->inner_viewport_scroll.element_id) inner_viewport_scroll_delta = info->inner_viewport_scroll.scroll_delta; if (inner_viewport_scroll_delta.IsZero() && info->page_scale_delta == 1.f && @@ -802,7 +813,7 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) { if (root_layer_) { for (size_t i = 0; i < info->scrolls.size(); ++i) { - Layer* layer = LayerById(info->scrolls[i].layer_id); + Layer* layer = LayerByElementId(info->scrolls[i].element_id); if (!layer) continue; layer->SetScrollOffsetFromImplSide(gfx::ScrollOffsetWithDelta( @@ -909,6 +920,18 @@ LayerTreeHost::ViewportLayers::~ViewportLayers() {} void LayerTreeHost::RegisterViewportLayers(const ViewportLayers& layers) { DCHECK(!layers.inner_viewport_scroll || layers.inner_viewport_scroll != layers.outer_viewport_scroll); + // The page scale layer only affects the innter viewport scroll layer. The + // page scale layer should be sandwiched between the inner viewport scroll and + // inner viewport container layers: + // inner viewport container + // overscroll elasticity (optional) + // page scale + // inner viewport scroll + DCHECK(!layers.page_scale || + layers.inner_viewport_scroll->parent() == layers.page_scale); + DCHECK(!layers.page_scale || + layers.page_scale->parent() == layers.overscroll_elasticity || + layers.page_scale->parent() == layers.inner_viewport_container); viewport_layers_.overscroll_elasticity = layers.overscroll_elasticity; viewport_layers_.page_scale = layers.page_scale; viewport_layers_.inner_viewport_container = layers.inner_viewport_container; @@ -1043,7 +1066,8 @@ void LayerTreeHost::SetContentSourceId(uint32_t id) { SetNeedsCommit(); } -void LayerTreeHost::SetLocalSurfaceId(const LocalSurfaceId& local_surface_id) { +void LayerTreeHost::SetLocalSurfaceId( + const viz::LocalSurfaceId& local_surface_id) { if (local_surface_id_ == local_surface_id) return; local_surface_id_ = local_surface_id; @@ -1082,16 +1106,41 @@ size_t LayerTreeHost::NumLayers() const { } bool LayerTreeHost::PaintContent(const LayerList& update_layer_list, - bool* content_is_suitable_for_gpu) { + bool* content_has_slow_paths, + bool* content_has_non_aa_paint) { base::AutoReset<bool> painting(&in_paint_layer_contents_, true); bool did_paint_content = false; for (const auto& layer : update_layer_list) { did_paint_content |= layer->Update(); - *content_is_suitable_for_gpu &= layer->IsSuitableForGpuRasterization(); + *content_has_slow_paths |= layer->HasSlowPaths(); + *content_has_non_aa_paint |= layer->HasNonAAPaint(); } return did_paint_content; } +void LayerTreeHost::AddSurfaceLayerId(const viz::SurfaceId& surface_id) { + if (++surface_layer_ids_[surface_id] == 1) + needs_surface_ids_sync_ = true; +} + +void LayerTreeHost::RemoveSurfaceLayerId(const viz::SurfaceId& surface_id) { + auto iter = surface_layer_ids_.find(surface_id); + if (iter == surface_layer_ids_.end()) + return; + + if (--iter->second <= 0) { + surface_layer_ids_.erase(iter); + needs_surface_ids_sync_ = true; + } +} + +base::flat_set<viz::SurfaceId> LayerTreeHost::SurfaceLayerIds() const { + base::flat_set<viz::SurfaceId> ids; + for (auto& map_entry : surface_layer_ids_) + ids.insert(map_entry.first); + return ids; +} + void LayerTreeHost::AddLayerShouldPushProperties(Layer* layer) { layers_that_should_push_properties_.insert(layer); } @@ -1223,11 +1272,20 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) { tree_impl->set_has_ever_been_drawn(false); } +void LayerTreeHost::PushSurfaceIdsTo(LayerTreeImpl* tree_impl) { + if (needs_surface_ids_sync()) { + tree_impl->ClearSurfaceLayerIds(); + tree_impl->SetSurfaceLayerIds(SurfaceLayerIds()); + // Reset for next update + set_needs_surface_ids_sync(false); + } +} + void LayerTreeHost::PushLayerTreeHostPropertiesTo( LayerTreeHostImpl* host_impl) { host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); - host_impl->SetContentIsSuitableForGpuRasterization( - content_is_suitable_for_gpu_rasterization_); + host_impl->SetContentHasSlowPaths(content_has_slow_paths_); + host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_); RecordGpuRasterizationHistogram(host_impl); host_impl->SetViewportSize(device_viewport_size_); @@ -1320,8 +1378,7 @@ void LayerTreeHost::SetElementOpacityMutated(ElementId element_id, layer->OnOpacityAnimated(opacity); if (EffectNode* node = - property_trees_.effect_tree.UpdateNodeFromOwningLayerId( - layer->id())) { + property_trees_.effect_tree.Node(layer->effect_tree_index())) { DCHECK_EQ(layer->effect_tree_index(), node->id); if (node->opacity == opacity) return; @@ -1346,10 +1403,7 @@ void LayerTreeHost::SetElementTransformMutated( DCHECK(layer); layer->OnTransformAnimated(transform); - if (TransformNode* node = - property_trees_.transform_tree.UpdateNodeFromOwningLayerId( - layer->id())) { - DCHECK_EQ(layer->transform_tree_index(), node->id); + if (TransformNode* node = layer->GetTransformNode()) { if (node->local == transform) return; @@ -1376,79 +1430,9 @@ void LayerTreeHost::ElementIsAnimatingChanged( ElementListType list_type, const PropertyAnimationState& mask, const PropertyAnimationState& state) { - // TODO(weiliangc): Most of the code is duplicated with LayerTeeHostImpl - // version of function. Should try to share code. DCHECK_EQ(ElementListType::ACTIVE, list_type); - - for (int property = TargetProperty::FIRST_TARGET_PROPERTY; - property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) { - if (!mask.currently_running[property] && - !mask.potentially_animating[property]) - continue; - - switch (property) { - case TargetProperty::TRANSFORM: - if (TransformNode* transform_node = - property_trees()->transform_tree.FindNodeFromElementId( - element_id)) { - if (mask.currently_running[property]) - transform_node->is_currently_animating = - state.currently_running[property]; - if (mask.potentially_animating[property]) { - transform_node->has_potential_animation = - state.potentially_animating[property]; - transform_node->has_only_translation_animations = - mutator_host()->HasOnlyTranslationTransforms(element_id, - list_type); - property_trees()->transform_tree.set_needs_update(true); - } - } else { - if (state.currently_running[property] || - state.potentially_animating[property]) - DCHECK(property_trees()->needs_rebuild) - << "Attempting to animate non existent transform node"; - } - break; - case TargetProperty::OPACITY: - if (EffectNode* effect_node = - property_trees()->effect_tree.FindNodeFromElementId( - element_id)) { - if (mask.currently_running[property]) - effect_node->is_currently_animating_opacity = - state.currently_running[property]; - if (mask.potentially_animating[property]) { - effect_node->has_potential_opacity_animation = - state.potentially_animating[property]; - property_trees()->effect_tree.set_needs_update(true); - } - } else { - if (state.currently_running[property] || - state.potentially_animating[property]) - DCHECK(property_trees()->needs_rebuild) - << "Attempting to animate opacity on non existent effect node"; - } - break; - case TargetProperty::FILTER: - if (EffectNode* effect_node = - property_trees()->effect_tree.FindNodeFromElementId( - element_id)) { - if (mask.currently_running[property]) - effect_node->is_currently_animating_filter = - state.currently_running[property]; - if (mask.potentially_animating[property]) - effect_node->has_potential_filter_animation = - state.potentially_animating[property]; - } else { - if (state.currently_running[property] || - state.potentially_animating[property]) - DCHECK(property_trees()->needs_rebuild) - << "Attempting to animate filter on non existent effect node"; - } - break; - default: - break; - } - } + property_trees()->ElementIsAnimatingChanged(mutator_host(), element_id, + list_type, mask, state, true); } gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation( @@ -1459,10 +1443,10 @@ gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation( } void LayerTreeHost::QueueImageDecode( - sk_sp<const SkImage> image, + const PaintImage& image, const base::Callback<void(bool)>& callback) { TRACE_EVENT0("cc", "LayerTreeHost::QueueImageDecode"); - queued_image_decodes_.emplace_back(std::move(image), callback); + queued_image_decodes_.emplace_back(image, callback); SetNeedsCommit(); } @@ -1491,4 +1475,8 @@ void LayerTreeHost::SetHasCopyRequest(bool has_copy_request) { has_copy_request_ = has_copy_request; } +void LayerTreeHost::RequestBeginMainFrameNotExpected(bool new_state) { + proxy_->RequestBeginMainFrameNotExpected(new_state); +} + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index 51622245b1e..df5f9a4c046 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -16,6 +16,8 @@ #include <vector> #include "base/cancelable_callback.h" +#include "base/containers/flat_map.h" +#include "base/containers/flat_set.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" @@ -31,11 +33,8 @@ #include "cc/input/scrollbar.h" #include "cc/layers/layer_collections.h" #include "cc/layers/layer_list_iterator.h" -#include "cc/output/compositor_frame_sink.h" +#include "cc/output/layer_tree_frame_sink.h" #include "cc/output/swap_promise.h" -#include "cc/resources/resource_format.h" -#include "cc/surfaces/surface_reference_owner.h" -#include "cc/surfaces/surface_sequence_generator.h" #include "cc/trees/compositor_mode.h" #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/layer_tree_settings.h" @@ -43,11 +42,12 @@ #include "cc/trees/proxy.h" #include "cc/trees/swap_promise_manager.h" #include "cc/trees/target_property.h" +#include "components/viz/common/quads/resource_format.h" +#include "components/viz/common/surfaces/surface_reference_owner.h" +#include "components/viz/common/surfaces/surface_sequence_generator.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" -class SkImage; - namespace cc { class HeadsUpDisplayLayer; class Layer; @@ -65,8 +65,9 @@ class UIResourceManager; struct RenderingStats; struct ScrollAndScaleSet; -class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), - public NON_EXPORTED_BASE(MutatorHostClient) { +class CC_EXPORT LayerTreeHost + : public NON_EXPORTED_BASE(viz::SurfaceReferenceOwner), + public NON_EXPORTED_BASE(MutatorHostClient) { public: struct CC_EXPORT InitParams { LayerTreeHostClient* client = nullptr; @@ -112,9 +113,9 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), // Returns the settings used by this host. const LayerTreeSettings& GetSettings() const; - // Sets the client id used to generate the SurfaceId that uniquely identifies - // the Surfaces produced by this compositor. - void SetFrameSinkId(const FrameSinkId& frame_sink_id); + // Sets the client id used to generate the viz::SurfaceId that uniquely + // identifies the Surfaces produced by this compositor. + void SetFrameSinkId(const viz::FrameSinkId& frame_sink_id); // Sets the LayerTreeMutator interface used to directly mutate the compositor // state on the compositor thread. (Compositor-Worker) @@ -131,23 +132,23 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), // Sets whether the content is suitable to use Gpu Rasterization. void SetHasGpuRasterizationTrigger(bool has_trigger); - // Visibility and CompositorFrameSink ------------------------------- + // Visibility and LayerTreeFrameSink ------------------------------- void SetVisible(bool visible); bool IsVisible() const; - // Called in response to an CompositorFrameSink request made to the client - // using LayerTreeHostClient::RequestNewCompositorFrameSink. The client will - // be informed of the CompositorFrameSink initialization status using - // DidInitializaCompositorFrameSink or DidFailToInitializeCompositorFrameSink. + // Called in response to a LayerTreeFrameSink request made to the client + // using LayerTreeHostClient::RequestNewLayerTreeFrameSink. The client will + // be informed of the LayerTreeFrameSink initialization status using + // DidInitializaLayerTreeFrameSink or DidFailToInitializeLayerTreeFrameSink. // The request is completed when the host successfully initializes an - // CompositorFrameSink. - void SetCompositorFrameSink( - std::unique_ptr<CompositorFrameSink> compositor_frame_sink); + // LayerTreeFrameSink. + void SetLayerTreeFrameSink( + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink); // Forces the host to immediately release all references to the - // CompositorFrameSink, if any. Can be safely called any time. - std::unique_ptr<CompositorFrameSink> ReleaseCompositorFrameSink(); + // LayerTreeFrameSink, if any. Can be safely called any time. + std::unique_ptr<LayerTreeFrameSink> ReleaseLayerTreeFrameSink(); // Frame Scheduling (main and compositor frames) requests ------- @@ -325,10 +326,12 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), void SetContentSourceId(uint32_t); uint32_t content_source_id() const { return content_source_id_; } - // If this LayerTreeHost needs a valid LocalSurfaceId then commits will be - // deferred until a valid LocalSurfaceId is provided. - void SetLocalSurfaceId(const LocalSurfaceId& local_surface_id); - const LocalSurfaceId& local_surface_id() const { return local_surface_id_; } + // If this LayerTreeHost needs a valid viz::LocalSurfaceId then commits will + // be deferred until a valid viz::LocalSurfaceId is provided. + void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id); + const viz::LocalSurfaceId& local_surface_id() const { + return local_surface_id_; + } void SetRasterColorSpace(const gfx::ColorSpace& raster_color_space); const gfx::ColorSpace& raster_color_space() const { @@ -349,12 +352,17 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), bool in_update_property_trees() const { return in_update_property_trees_; } bool PaintContent(const LayerList& update_layer_list, - bool* content_is_suitable_for_gpu); + bool* content_has_slow_paths, + bool* content_has_non_aa_paint); 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 AddSurfaceLayerId(const viz::SurfaceId& surface_id); + void RemoveSurfaceLayerId(const viz::SurfaceId& surface_id); + base::flat_set<viz::SurfaceId> SurfaceLayerIds() const; + void AddLayerShouldPushProperties(Layer* layer); void RemoveLayerShouldPushProperties(Layer* layer); std::unordered_set<Layer*>& LayersThatShouldPushProperties(); @@ -370,10 +378,16 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), virtual void SetNeedsFullTreeSync(); bool needs_full_tree_sync() const { return needs_full_tree_sync_; } + bool needs_surface_ids_sync() const { return needs_surface_ids_sync_; } + void set_needs_surface_ids_sync(bool needs_surface_ids_sync) { + needs_surface_ids_sync_ = needs_surface_ids_sync; + } + void SetPropertyTreesNeedRebuild(); void PushPropertyTreesTo(LayerTreeImpl* tree_impl); void PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl); + void PushSurfaceIdsTo(LayerTreeImpl* tree_impl); void PushLayerTreeHostPropertiesTo(LayerTreeHostImpl* host_impl); MutatorHost* mutator_host() const { return mutator_host_; } @@ -406,12 +420,12 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); void WillCommit(); void CommitComplete(); - void RequestNewCompositorFrameSink(); - void DidInitializeCompositorFrameSink(); - void DidFailToInitializeCompositorFrameSink(); + void RequestNewLayerTreeFrameSink(); + void DidInitializeLayerTreeFrameSink(); + void DidFailToInitializeLayerTreeFrameSink(); virtual std::unique_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( LayerTreeHostImplClient* client); - void DidLoseCompositorFrameSink(); + void DidLoseLayerTreeFrameSink(); void DidCommitAndDrawFrame() { client_->DidCommitAndDrawFrame(); } void DidReceiveCompositorFrameAck() { client_->DidReceiveCompositorFrameAck(); @@ -444,8 +458,8 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), bool IsSingleThreaded() const; bool IsThreaded() const; - // SurfaceReferenceOwner implementation. - SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() override; + // viz::SurfaceReferenceOwner implementation. + viz::SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() override; // MutatorHostClient implementation. bool IsElementInList(ElementId element_id, @@ -475,9 +489,11 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), gfx::ScrollOffset GetScrollOffsetForAnimation( ElementId element_id) const override; - void QueueImageDecode(sk_sp<const SkImage> image, + void QueueImageDecode(const PaintImage& image, const base::Callback<void(bool)>& callback); + void RequestBeginMainFrameNotExpected(bool new_state); + protected: LayerTreeHost(InitParams* params, CompositorMode mode); @@ -513,8 +529,8 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), friend class LayerTreeHostSerializationTest; // This is the number of consecutive frames in which we want the content to be - // suitable for GPU rasterization before re-enabling it. - enum { kNumFramesToConsiderBeforeGpuRasterization = 60 }; + // free of slow-paths before toggling the flag. + enum { kNumFramesToConsiderBeforeRemovingSlowPathFlag = 60 }; void ApplyViewportDeltas(ScrollAndScaleSet* info); void RecordWheelAndTouchScrollingCount(ScrollAndScaleSet* info); @@ -539,13 +555,13 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), SwapPromiseManager swap_promise_manager_; - // |current_compositor_frame_sink_| can't be updated until we've successfully - // initialized a new CompositorFrameSink. |new_compositor_frame_sink_| - // contains the new CompositorFrameSink that is currently being initialized. - // If initialization is successful then |new_compositor_frame_sink_| replaces - // |current_compositor_frame_sink_|. - std::unique_ptr<CompositorFrameSink> new_compositor_frame_sink_; - std::unique_ptr<CompositorFrameSink> current_compositor_frame_sink_; + // |current_layer_tree_frame_sink_| can't be updated until we've successfully + // initialized a new LayerTreeFrameSink. |new_layer_tree_frame_sink_| + // contains the new LayerTreeFrameSink that is currently being initialized. + // If initialization is successful then |new_layer_tree_frame_sink_| replaces + // |current_layer_tree_frame_sink_|. + std::unique_ptr<LayerTreeFrameSink> new_layer_tree_frame_sink_; + std::unique_ptr<LayerTreeFrameSink> current_layer_tree_frame_sink_; const LayerTreeSettings settings_; LayerTreeDebugState debug_state_; @@ -553,7 +569,8 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), bool visible_ = false; bool has_gpu_rasterization_trigger_ = false; - bool content_is_suitable_for_gpu_rasterization_ = true; + bool content_has_slow_paths_ = false; + bool content_has_non_aa_paint_ = false; bool gpu_rasterization_histogram_recorded_ = false; // If set, then page scale animation has completed, but the client hasn't been @@ -569,8 +586,8 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), TaskGraphRunner* task_graph_runner_; - SurfaceSequenceGenerator surface_sequence_generator_; - uint32_t num_consecutive_frames_suitable_for_gpu_ = 0; + viz::SurfaceSequenceGenerator surface_sequence_generator_; + uint32_t num_consecutive_frames_without_slow_paths_ = 0; scoped_refptr<Layer> root_layer_; @@ -590,7 +607,7 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), gfx::ColorSpace raster_color_space_; uint32_t content_source_id_; - LocalSurfaceId local_surface_id_; + viz::LocalSurfaceId local_surface_id_; bool defer_commits_ = false; SkColor background_color_ = SK_ColorWHITE; @@ -610,10 +627,15 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), bool needs_full_tree_sync_ = true; + bool needs_surface_ids_sync_ = false; + gfx::Vector2dF elastic_overscroll_; scoped_refptr<HeadsUpDisplayLayer> hud_layer_; + // The number of SurfaceLayers that have fallback set to viz::SurfaceId. + base::flat_map<viz::SurfaceId, int> surface_layer_ids_; + // Set of layers that need to push properties. std::unordered_set<Layer*> layers_that_should_push_properties_; @@ -632,7 +654,7 @@ class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner), MutatorHost* mutator_host_; - std::vector<std::pair<sk_sp<const SkImage>, base::Callback<void(bool)>>> + std::vector<std::pair<PaintImage, base::Callback<void(bool)>>> queued_image_decodes_; 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 f54a69b0217..1b06e89d797 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -15,7 +15,6 @@ class Vector2dF; } namespace cc { -class CompositorFrameSink; struct BeginFrameArgs; class LayerTreeHostClient { @@ -48,13 +47,13 @@ class LayerTreeHostClient { virtual void RecordWheelAndTouchScrollingCount( bool has_scrolled_by_wheel, bool has_scrolled_by_touch) = 0; - // Request an CompositorFrameSink from the client. When the client has one it - // should call LayerTreeHost::SetCompositorFrameSink. This will result in - // either DidFailToInitializeCompositorFrameSink or - // DidInitializeCompositorFrameSink being called. - virtual void RequestNewCompositorFrameSink() = 0; - virtual void DidInitializeCompositorFrameSink() = 0; - virtual void DidFailToInitializeCompositorFrameSink() = 0; + // Request a LayerTreeFrameSink from the client. When the client has one it + // should call LayerTreeHost::SetLayerTreeFrameSink. This will result in + // either DidFailToInitializeLayerTreeFrameSink or + // DidInitializeLayerTreeFrameSink being called. + virtual void RequestNewLayerTreeFrameSink() = 0; + virtual void DidInitializeLayerTreeFrameSink() = 0; + virtual void DidFailToInitializeLayerTreeFrameSink() = 0; virtual void WillCommit() = 0; virtual void DidCommit() = 0; virtual void DidCommitAndDrawFrame() = 0; diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc index c7349e828b7..75ea1df5610 100644 --- a/chromium/cc/trees/layer_tree_host_common.cc +++ b/chromium/cc/trees/layer_tree_host_common.cc @@ -153,12 +153,9 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: device_scale_factor, render_surface_list) {} -LayerTreeHostCommon::ScrollUpdateInfo::ScrollUpdateInfo() - : layer_id(Layer::INVALID_ID) {} - bool LayerTreeHostCommon::ScrollUpdateInfo::operator==( const LayerTreeHostCommon::ScrollUpdateInfo& other) const { - return layer_id == other.layer_id && scroll_delta == other.scroll_delta; + return element_id == other.element_id && scroll_delta == other.scroll_delta; } LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo() @@ -304,6 +301,7 @@ static void AddSurfaceToRenderSurfaceList( // pixel-moving filters) const FilterOperations& filters = render_surface->Filters(); bool is_occlusion_immune = render_surface->HasCopyRequest() || + render_surface->ShouldCacheRenderSurface() || filters.HasReferenceFilter() || filters.HasFilterThatMovesPixels(); if (is_occlusion_immune) { @@ -361,7 +359,11 @@ static void ComputeInitialRenderSurfaceList( // it's not already been added, and add their content rect to the target // surface's accumulated content rect. for (LayerImpl* layer : *layer_tree_impl) { + DCHECK(layer); + layer->EnsureValidPropertyTreeIndices(); + layer->set_contributes_to_drawn_render_surface(false); + layer->set_raster_even_if_not_drawn(false); bool is_root = layer_tree_impl->IsRootLayer(layer); @@ -374,8 +376,8 @@ static void ComputeInitialRenderSurfaceList( 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); + layer->set_raster_even_if_not_drawn(skip_for_invertibility && + !skip_draw_properties_computation); if (skip_layer) continue; diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h index 522ef93c050..56799bf54ce 100644 --- a/chromium/cc/trees/layer_tree_host_common.h +++ b/chromium/cc/trees/layer_tree_host_common.h @@ -129,13 +129,11 @@ class CC_EXPORT LayerTreeHostCommon { const Function& function); struct CC_EXPORT ScrollUpdateInfo { - int layer_id; + ElementId element_id; // TODO(miletus): Use ScrollOffset once LayerTreeHost/Blink fully supports // fractional scroll offset. gfx::Vector2d scroll_delta; - ScrollUpdateInfo(); - bool operator==(const ScrollUpdateInfo& 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 c0b1e3254d2..b20ceedc58f 100644 --- a/chromium/cc/trees/layer_tree_host_common_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc @@ -20,9 +20,9 @@ #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/layer_tree_json_parser.h" #include "cc/test/layer_tree_test.h" -#include "cc/test/paths.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" +#include "components/viz/test/paths.h" #include "testing/perf/perf_test.h" namespace cc { @@ -41,7 +41,7 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest { void ReadTestFile(const std::string& name) { base::FilePath test_data_dir; - ASSERT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir)); + ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir)); base::FilePath json_file = test_data_dir.AppendASCII(name + ".json"); ASSERT_TRUE(base::ReadFileToString(json_file, &json_)); } diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc index 639bab1206e..e7b8525c050 100644 --- a/chromium/cc/trees/layer_tree_host_common_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc @@ -29,9 +29,9 @@ #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/test/animation_test_common.h" -#include "cc/test/fake_compositor_frame_sink.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_impl_task_runner_provider.h" +#include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_picture_layer.h" @@ -75,9 +75,10 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { const gfx::Vector2dF& delta) { if (layer_impl->layer_tree_impl() ->property_trees() - ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(), - delta)) - layer_impl->layer_tree_impl()->DidUpdateScrollOffset(layer_impl->id()); + ->scroll_tree.SetScrollOffsetDeltaForTesting( + layer_impl->element_id(), delta)) + layer_impl->layer_tree_impl()->DidUpdateScrollOffset( + layer_impl->element_id()); } static float GetMaximumAnimationScale(LayerImpl* layer_impl) { @@ -522,31 +523,25 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { LayerImpl::Create(host_impl.active_tree(), 2)); LayerImpl* scroll_layer = scroll_layer_scoped_ptr.get(); scroll_layer->SetBounds(gfx::Size(10, 20)); - std::unique_ptr<LayerImpl> clip_layer_scoped_ptr( - LayerImpl::Create(host_impl.active_tree(), 4)); - LayerImpl* clip_layer = clip_layer_scoped_ptr.get(); - scroll_layer->SetScrollClipLayer(clip_layer->id()); - clip_layer->SetBounds( + scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); + scroll_layer->SetScrollable( gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(), scroll_layer->bounds().height() + kMaxScrollOffset.y())); - scroll_layer->SetScrollClipLayer(clip_layer->id()); - SetScrollOffsetDelta(scroll_layer, kScrollDelta); - gfx::Transform impl_transform; + scroll_layer->test_properties()->AddChild(std::move(sublayer_scoped_ptr)); - LayerImpl* scroll_layer_raw_ptr = scroll_layer_scoped_ptr.get(); - clip_layer->test_properties()->AddChild(std::move(scroll_layer_scoped_ptr)); - scroll_layer_raw_ptr->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer_raw_ptr->id(), - kScrollOffset); std::unique_ptr<LayerImpl> root( LayerImpl::Create(host_impl.active_tree(), 3)); root->SetBounds(gfx::Size(3, 4)); - root->test_properties()->AddChild(std::move(clip_layer_scoped_ptr)); + root->test_properties()->AddChild(std::move(scroll_layer_scoped_ptr)); LayerImpl* root_layer = root.get(); host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); + host_impl.active_tree()->BuildPropertyTreesForTesting(); + auto& scroll_tree = host_impl.active_tree()->property_trees()->scroll_tree; + scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), + kScrollOffset); + SetScrollOffsetDelta(scroll_layer, kScrollDelta); ExecuteCalculateDrawProperties(root_layer, kDeviceScale, page_scale, scroll_layer->test_properties()->parent, @@ -1153,7 +1148,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { root->SetDrawsContent(true); root->SetBounds(gfx::Size(100, 100)); child->SetDrawsContent(true); - child->SetScrollClipLayer(root->id()); child->SetBounds(gfx::Size(100, 100)); child->SetMasksToBounds(true); @@ -1405,7 +1399,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) { 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(static_cast<RenderPassId>(root->id()), + render_surface_list.at(0)->id()); EXPECT_EQ(gfx::Rect(), root->drawable_content_rect()); } @@ -1710,8 +1705,10 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { ExecuteCalculateDrawProperties(root); 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()); + EXPECT_EQ(static_cast<uint64_t>(root->id()), + render_surface_list_impl()->at(0)->id()); + EXPECT_EQ(static_cast<uint64_t>(child->id()), + render_surface_list_impl()->at(1)->id()); } TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { @@ -1748,7 +1745,8 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { // We should cull child and grand_child from the // render_surface_list. ASSERT_EQ(1U, render_surface_list_impl()->size()); - EXPECT_EQ(root->id(), render_surface_list_impl()->at(0)->id()); + EXPECT_EQ(static_cast<uint64_t>(root->id()), + render_surface_list_impl()->at(0)->id()); } TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { @@ -3000,8 +2998,8 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, OcclusionBySiblingOfTarget) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<CompositorFrameSink> compositor_frame_sink = - FakeCompositorFrameSink::Create3d(); + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = + FakeLayerTreeFrameSink::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root = @@ -3051,10 +3049,9 @@ TEST_F(LayerTreeHostCommonTest, OcclusionBySiblingOfTarget) { root->test_properties()->AddChild(std::move(child)); host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); host_impl.SetVisible(true); - host_impl.InitializeRenderer(compositor_frame_sink.get()); + host_impl.InitializeRenderer(layer_tree_frame_sink.get()); host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - bool update_lcd_text = false; - host_impl.active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl.active_tree()->UpdateDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( GetRenderSurface(surface_ptr)->draw_transform(), translate); @@ -3075,8 +3072,8 @@ TEST_F(LayerTreeHostCommonTest, OcclusionBySiblingOfTarget) { TEST_F(LayerTreeHostCommonTest, TextureLayerSnapping) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<CompositorFrameSink> compositor_frame_sink = - FakeCompositorFrameSink::Create3d(); + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = + FakeLayerTreeFrameSink::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root = @@ -3098,10 +3095,9 @@ TEST_F(LayerTreeHostCommonTest, TextureLayerSnapping) { root->test_properties()->AddChild(std::move(child)); host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); host_impl.SetVisible(true); - host_impl.InitializeRenderer(compositor_frame_sink.get()); + host_impl.InitializeRenderer(layer_tree_frame_sink.get()); host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - bool update_lcd_text = false; - host_impl.active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl.active_tree()->UpdateDrawProperties(); EXPECT_NE(child_ptr->ScreenSpaceTransform(), fractional_translate); fractional_translate.RoundTranslationComponents(); @@ -3117,8 +3113,8 @@ TEST_F(LayerTreeHostCommonTest, OcclusionForLayerWithUninvertibleDrawTransform) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<CompositorFrameSink> compositor_frame_sink = - FakeCompositorFrameSink::Create3d(); + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = + FakeLayerTreeFrameSink::Create3d(); FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root = @@ -3161,10 +3157,9 @@ TEST_F(LayerTreeHostCommonTest, root->test_properties()->AddChild(std::move(occluding_child)); host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); host_impl.SetVisible(true); - host_impl.InitializeRenderer(compositor_frame_sink.get()); + host_impl.InitializeRenderer(layer_tree_frame_sink.get()); host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - bool update_lcd_text = false; - host_impl.active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl.active_tree()->UpdateDrawProperties(); LayerImpl* grand_child_ptr = host_impl.active_tree() ->root_layer_for_testing() @@ -4889,7 +4884,8 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { copy_grand_child_layer->test_properties()->hide_layer_and_subtree = true; copy_layer->test_properties()->copy_requests.push_back( - CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + CopyOutputRequest::CreateRequest( + base::BindOnce(&EmptyCopyOutputCallback))); RenderSurfaceList render_surface_list; LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( @@ -4906,10 +4902,14 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { // parent since it has opacity and two drawing descendants, one for the parent // since it owns a surface, and one for the copy_layer. ASSERT_EQ(4u, render_surface_list.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()); + EXPECT_EQ(static_cast<uint64_t>(root_layer->id()), + render_surface_list.at(0)->id()); + EXPECT_EQ(static_cast<uint64_t>(copy_grand_parent_layer->id()), + render_surface_list.at(1)->id()); + EXPECT_EQ(static_cast<uint64_t>(copy_parent_layer->id()), + render_surface_list.at(2)->id()); + EXPECT_EQ(static_cast<uint64_t>(copy_layer->id()), + render_surface_list.at(3)->id()); // The root render surface should have 2 contributing layers. EXPECT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); @@ -4981,7 +4981,8 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { copy_child->SetDrawsContent(true); copy_layer->test_properties()->copy_requests.push_back( - CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + CopyOutputRequest::CreateRequest( + base::BindOnce(&EmptyCopyOutputCallback))); copy_layer->test_properties()->AddChild(std::move(copy_child)); copy_parent->test_properties()->AddChild(std::move(copy_layer)); @@ -4997,7 +4998,8 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { // We should have two render surface, as the others are clipped out. ASSERT_EQ(2u, render_surface_list.size()); - EXPECT_EQ(root_layer->id(), render_surface_list.at(0)->id()); + EXPECT_EQ(static_cast<uint64_t>(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. @@ -5021,7 +5023,8 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformAndCopyRequests) { copy_layer->SetBounds(gfx::Size(100, 100)); copy_layer->SetDrawsContent(true); copy_layer->test_properties()->copy_requests.push_back( - CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + CopyOutputRequest::CreateRequest( + base::BindOnce(&EmptyCopyOutputCallback))); LayerImpl* copy_child = AddChild<LayerImpl>(copy_layer); copy_child->SetBounds(gfx::Size(100, 100)); @@ -5081,7 +5084,8 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCopyRequest) { copy_surface->test_properties()->force_render_surface = true; copy_layer->test_properties()->copy_requests.push_back( - CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + CopyOutputRequest::CreateRequest( + base::BindOnce(&EmptyCopyOutputCallback))); DCHECK(!copy_layer->test_properties()->copy_requests.empty()); ExecuteCalculateDrawProperties(root); @@ -5096,7 +5100,8 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCopyRequest) { copy_layer->SetBounds(gfx::Size(50, 50)); copy_layer->SetMasksToBounds(true); copy_layer->test_properties()->copy_requests.push_back( - CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + CopyOutputRequest::CreateRequest( + base::BindOnce(&EmptyCopyOutputCallback))); root->layer_tree_impl()->property_trees()->needs_rebuild = true; DCHECK(!copy_layer->test_properties()->copy_requests.empty()); @@ -5111,7 +5116,8 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCopyRequest) { // Case 3: When there is device scale factor. float device_scale_factor = 2.f; copy_layer->test_properties()->copy_requests.push_back( - CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + CopyOutputRequest::CreateRequest( + base::BindOnce(&EmptyCopyOutputCallback))); DCHECK(!copy_layer->test_properties()->copy_requests.empty()); ExecuteCalculateDrawProperties(root, device_scale_factor); @@ -5297,8 +5303,8 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { intervening->SetMasksToBounds(true); clip_parent->SetMasksToBounds(true); - intervening->SetScrollClipLayer(clip_parent->id()); - intervening->SetCurrentScrollOffset(gfx::ScrollOffset(3, 3)); + intervening->SetScrollable(gfx::Size(1, 1)); + intervening->SetElementId(LayerIdToElementIdForTesting(intervening->id())); gfx::Transform translation_transform; translation_transform.Translate(2, 2); @@ -5315,6 +5321,8 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { render_surface2->test_properties()->force_render_surface = true; clip_child->SetPosition(gfx::PointF(-10.f, -10.f)); clip_child->SetBounds(gfx::Size(60, 60)); + BuildPropertyTreesForTesting(); + intervening->SetCurrentScrollOffset(gfx::ScrollOffset(3, 3)); ExecuteCalculateDrawProperties(root); EXPECT_TRUE(GetRenderSurface(root)); @@ -5580,16 +5588,10 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { 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. + // A ll layers with invisible backfgaces should be checked. EXPECT_FALSE(root->should_check_backface_visibility()); - EXPECT_FALSE(child->should_check_backface_visibility()); - EXPECT_FALSE(grand_child->should_check_backface_visibility()); - // As there are no 3d rendering contexts, all layers should use their local - // transform for backface visibility. - EXPECT_TRUE(root->use_local_transform_for_backface_visibility()); - EXPECT_TRUE(child->use_local_transform_for_backface_visibility()); - EXPECT_TRUE(grand_child->use_local_transform_for_backface_visibility()); + EXPECT_TRUE(child->should_check_backface_visibility()); + EXPECT_TRUE(grand_child->should_check_backface_visibility()); gfx::Transform rotation_transform; rotation_transform.RotateAboutXAxis(180.0); @@ -5609,13 +5611,6 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { EXPECT_FALSE(root->should_check_backface_visibility()); EXPECT_TRUE(child->should_check_backface_visibility()); EXPECT_TRUE(grand_child->should_check_backface_visibility()); - // child uses its local transform for backface visibility as it is the root of - // a 3d rendering context. grand_child is in a 3d rendering context and is not - // the root, but it derives its backface visibility from its parent which uses - // its local transform. - EXPECT_TRUE(root->use_local_transform_for_backface_visibility()); - EXPECT_TRUE(child->use_local_transform_for_backface_visibility()); - EXPECT_TRUE(grand_child->use_local_transform_for_backface_visibility()); grand_child->SetUseParentBackfaceVisibility(false); grand_child->test_properties()->double_sided = false; @@ -5631,11 +5626,6 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleLayers) { EXPECT_FALSE(root->should_check_backface_visibility()); EXPECT_TRUE(child->should_check_backface_visibility()); EXPECT_TRUE(grand_child->should_check_backface_visibility()); - // grand_child is in an existing 3d rendering context, so it should not use - // local transform for backface visibility. - EXPECT_TRUE(root->use_local_transform_for_backface_visibility()); - EXPECT_TRUE(child->use_local_transform_for_backface_visibility()); - EXPECT_FALSE(grand_child->use_local_transform_for_backface_visibility()); } TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { @@ -6099,7 +6089,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { constraint.set_is_fixed_position(true); fixed->test_properties()->position_constraint = constraint; - scroller->SetScrollClipLayer(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); gfx::Transform container_transform; container_transform.Translate3d(10.0, 20.0, 0.0); @@ -6110,6 +6100,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { container->SetBounds(gfx::Size(40, 40)); container->SetDrawsContent(true); scroller->SetBounds(gfx::Size(30, 30)); + scroller->SetScrollable(container->bounds()); scroller->SetDrawsContent(true); fixed->SetBounds(gfx::Size(50, 50)); fixed->SetDrawsContent(true); @@ -6222,7 +6213,8 @@ TEST_F(LayerTreeHostCommonTest, surface->test_properties()->force_render_surface = true; container->SetBounds(gfx::Size(50, 50)); scroller->SetBounds(gfx::Size(100, 100)); - scroller->SetScrollClipLayer(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); + scroller->SetScrollable(container->bounds()); scroller->SetDrawsContent(true); gfx::Transform end_scale; @@ -6236,6 +6228,7 @@ TEST_F(LayerTreeHostCommonTest, AddAnimatedTransformToElementWithPlayer(animated_layer->element_id(), timeline_impl(), 1.0, start_operations, end_operations); + BuildPropertyTreesForTesting(); gfx::Vector2dF scroll_delta(5.f, 9.f); SetScrollOffsetDelta(scroller, scroll_delta); @@ -6264,7 +6257,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { container->AddChild(scroller); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); scroll_child->SetScrollParent(scroller.get()); gfx::Transform rotate; @@ -6272,6 +6265,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { root->SetBounds(gfx::Size(50, 50)); container->SetBounds(gfx::Size(50, 50)); scroller->SetBounds(gfx::Size(100, 100)); + scroller->SetScrollable(container->bounds()); scroller->SetPosition(gfx::PointF(10.3f, 10.3f)); scroll_child->SetBounds(gfx::Size(10, 10)); scroll_child->SetTransform(rotate); @@ -6311,13 +6305,12 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTop) { container->AddChild(scroller); scroller->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(10, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(10, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6327,6 +6320,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTop) { root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(10, 20)); @@ -6384,7 +6378,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTopScrollParent) { root->AddChild(sticky_pos); sticky_pos->SetScrollParent(scroller.get()); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); // The sticky layer has already been scrolled on the main thread side, and has // stuck. This test then checks that further changes from cc-only scrolling @@ -6393,7 +6387,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTopScrollParent) { sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(10, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(10, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6404,6 +6397,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTopScrollParent) { container->SetBounds(gfx::Size(100, 100)); container->SetPosition(gfx::PointF(50, 50)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(60, 70)); @@ -6460,13 +6454,12 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionSubpixelScroll) { container->AddChild(scroller); scroller->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; sticky_position.is_anchored_bottom = true; sticky_position.bottom_offset = 10.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 200); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 200, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6476,6 +6469,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionSubpixelScroll) { root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(100, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 200)); @@ -6506,13 +6500,12 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) { container->AddChild(scroller); scroller->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; sticky_position.is_anchored_bottom = true; sticky_position.bottom_offset = 10.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 150); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 150, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6522,6 +6515,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) { root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 150)); @@ -6574,7 +6568,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { root->AddChild(scroller); scroller->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(root->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); LayerTreeHost::ViewportLayers viewport_layers; viewport_layers.page_scale = root; viewport_layers.inner_viewport_container = root; @@ -6585,7 +6579,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { sticky_position.is_sticky = true; sticky_position.is_anchored_bottom = true; sticky_position.bottom_offset = 10.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 70); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 70, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6593,6 +6586,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { sticky_pos->SetStickyPositionConstraint(sticky_position); root->SetBounds(gfx::Size(100, 100)); + scroller->SetScrollable(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(100, 1000)); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 70)); @@ -6650,8 +6644,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { outer_clip->AddChild(outer_viewport); outer_viewport->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(root->id()); - outer_viewport->SetScrollClipLayerId(outer_clip->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); LayerTreeHost::ViewportLayers viewport_layers; viewport_layers.page_scale = root; viewport_layers.inner_viewport_container = root; @@ -6664,7 +6657,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { sticky_position.is_sticky = true; sticky_position.is_anchored_bottom = true; sticky_position.bottom_offset = 10.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 70); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 70, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6672,8 +6664,10 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { sticky_pos->SetStickyPositionConstraint(sticky_position); root->SetBounds(gfx::Size(100, 100)); + scroller->SetScrollable(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(100, 1000)); outer_clip->SetBounds(gfx::Size(100, 100)); + outer_viewport->SetScrollable(gfx::Size(100, 100)); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 70)); @@ -6733,7 +6727,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) { container->AddChild(scroller); scroller->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; @@ -6741,7 +6735,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) { sticky_position.is_anchored_right = true; sticky_position.left_offset = 10.f; sticky_position.right_offset = 10.f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(145, 0); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(145, 0, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6751,6 +6744,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) { root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(145, 0)); @@ -6838,13 +6832,12 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionMainThreadUpdates) { container->AddChild(scroller); scroller->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(10, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(10, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6854,6 +6847,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionMainThreadUpdates) { root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(10, 20)); @@ -6889,7 +6883,8 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionMainThreadUpdates) { // Now the main thread commits the new position of the sticky element. scroller->SetScrollOffset(gfx::ScrollOffset(15, 15)); - sticky_pos->SetPosition(gfx::PointF(10, 25)); + // Shift the layer by -offset_for_position_sticky. + sticky_pos->SetPosition(gfx::PointF(10, 25) - gfx::Vector2dF(0, 5)); ExecuteCalculateDrawProperties(root.get()); host()->host_impl()->CreatePendingTree(); host()->CommitAndCreatePendingTree(); @@ -6930,16 +6925,12 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionCompositedContainer) { scroller->AddChild(sticky_container); sticky_container->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); LayerStickyPositionConstraint sticky_position; sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; - // The sticky position layer is only offset by (0, 10) from its parent - // layer, this position is used to determine the offset applied by the main - // thread. - sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 10); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(20, 30, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6949,6 +6940,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionCompositedContainer) { root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_container->SetPosition(gfx::PointF(20, 20)); sticky_container->SetBounds(gfx::Size(30, 30)); sticky_pos->SetBounds(gfx::Size(10, 10)); @@ -6986,7 +6978,8 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionCompositedContainer) { // Now the main thread commits the new position of the sticky element. scroller->SetScrollOffset(gfx::ScrollOffset(0, 25)); - sticky_pos->SetPosition(gfx::PointF(0, 15)); + // Shift the layer by -offset_for_position_sticky. + sticky_pos->SetPosition(gfx::PointF(0, 15) - gfx::Vector2dF(0, 5)); ExecuteCalculateDrawProperties(root.get()); host()->host_impl()->CreatePendingTree(); host()->CommitAndCreatePendingTree(); @@ -7030,7 +7023,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledStickyBox) { container->AddChild(scroller); scroller->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); gfx::Transform t; t.Scale(2, 2); sticky_pos->SetTransform(t); @@ -7039,7 +7032,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledStickyBox) { sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 0.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -7049,6 +7041,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledStickyBox) { root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 20)); @@ -7109,7 +7102,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) { scroller->AddChild(sticky_container); sticky_container->AddChild(sticky_pos); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); gfx::Transform t; t.Scale(2, 2); sticky_container->SetTransform(t); @@ -7118,7 +7111,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) { sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 0.0f; - sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -7128,6 +7120,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) { root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(1000, 1000)); + scroller->SetScrollable(container->bounds()); sticky_container->SetBounds(gfx::Size(50, 50)); sticky_pos->SetBounds(gfx::Size(10, 10)); sticky_pos->SetPosition(gfx::PointF(0, 20)); @@ -7188,11 +7181,12 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionNested) { scroller->AddChild(outer_sticky); outer_sticky->AddChild(inner_sticky); host()->SetRootLayer(root); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); root->SetBounds(gfx::Size(100, 100)); container->SetBounds(gfx::Size(100, 100)); scroller->SetBounds(gfx::Size(100, 1000)); + scroller->SetScrollable(container->bounds()); outer_sticky->SetBounds(gfx::Size(10, 50)); outer_sticky->SetPosition(gfx::PointF(0, 50)); inner_sticky->SetBounds(gfx::Size(10, 10)); @@ -7202,7 +7196,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionNested) { outer_sticky_pos.is_sticky = true; outer_sticky_pos.is_anchored_top = true; outer_sticky_pos.top_offset = 10.0f; - outer_sticky_pos.parent_relative_sticky_box_offset = gfx::Point(0, 50); outer_sticky_pos.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 50, 10, 50); outer_sticky_pos.scroll_container_relative_containing_block_rect = @@ -7213,7 +7206,6 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionNested) { inner_sticky_pos.is_sticky = true; inner_sticky_pos.is_anchored_top = true; inner_sticky_pos.top_offset = 25.0f; - inner_sticky_pos.parent_relative_sticky_box_offset = gfx::Point(0, 0); inner_sticky_pos.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 50, 10, 10); inner_sticky_pos.scroll_container_relative_containing_block_rect = @@ -7290,12 +7282,13 @@ TEST_F(LayerTreeHostCommonTest, NonFlatContainerForFixedPosLayer) { LayerPositionConstraint fixed_position; fixed_position.set_is_fixed_position(true); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); fixed_pos->SetPositionConstraint(fixed_position); root->SetBounds(gfx::Size(50, 50)); container->SetBounds(gfx::Size(50, 50)); scroller->SetBounds(gfx::Size(50, 50)); + scroller->SetScrollable(container->bounds()); fixed_pos->SetBounds(gfx::Size(50, 50)); gfx::Transform rotate; @@ -7334,12 +7327,13 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithFixedPosChild) { LayerPositionConstraint fixed_position; fixed_position.set_is_fixed_position(true); - scroller->SetScrollClipLayerId(container->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); fixed_pos->SetPositionConstraint(fixed_position); root->SetBounds(gfx::Size(50, 50)); container->SetBounds(gfx::Size(50, 50)); scroller->SetBounds(gfx::Size(100, 100)); + scroller->SetScrollable(container->bounds()); scroller->SetPosition(gfx::PointF(10.3f, 10.3f)); fixed_pos->SetBounds(gfx::Size(10, 10)); @@ -8189,27 +8183,24 @@ TEST_F(LayerTreeHostCommonTest, ViewportBoundsDeltaAffectVisibleContentRect) { TEST_F(LayerTreeHostCommonTest, NodesAffectedByViewportBoundsDeltaGetUpdated) { scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> page_scale_layer = Layer::Create(); scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create(); scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); scoped_refptr<Layer> outer_viewport_container_layer = Layer::Create(); scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create(); root->AddChild(inner_viewport_container_layer); - inner_viewport_container_layer->AddChild(inner_viewport_scroll_layer); + inner_viewport_container_layer->AddChild(page_scale_layer); + page_scale_layer->AddChild(inner_viewport_scroll_layer); inner_viewport_scroll_layer->AddChild(outer_viewport_container_layer); outer_viewport_container_layer->AddChild(outer_viewport_scroll_layer); - inner_viewport_scroll_layer->SetScrollClipLayerId( - inner_viewport_container_layer->id()); - outer_viewport_scroll_layer->SetScrollClipLayerId( - outer_viewport_container_layer->id()); - inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); outer_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); host()->SetRootLayer(root); LayerTreeHost::ViewportLayers viewport_layers; - viewport_layers.page_scale = root; + viewport_layers.page_scale = page_scale_layer; 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; @@ -8333,7 +8324,7 @@ TEST_F(LayerTreeHostCommonTest, // 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()); + EXPECT_TRUE(animated->raster_even_if_not_drawn()); // The animated layer has a singular transform and maps to a non-empty rect in // clipped target space, so is treated as fully visible. @@ -8373,7 +8364,7 @@ TEST_F(LayerTreeHostCommonTest, // 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_TRUE(animated->raster_even_if_not_drawn()); EXPECT_EQ(gfx::Rect(120, 120), active_animated->visible_layer_rect()); } @@ -8576,8 +8567,9 @@ TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) { frame_clip->SetMasksToBounds(true); frame_clip->SetDrawsContent(true); scroller->SetBounds(gfx::Size(1000, 1000)); - scroller->SetCurrentScrollOffset(gfx::ScrollOffset(100, 100)); - scroller->SetScrollClipLayer(frame_clip->id()); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); + scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id())); + scroller->SetScrollable(frame_clip->bounds()); scroller->SetDrawsContent(true); fixed->SetPosition(gfx::PointF(100, 100)); fixed->SetBounds(gfx::Size(50, 50)); @@ -8585,6 +8577,9 @@ TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) { fixed->SetDrawsContent(true); fixed->test_properties()->force_render_surface = true; + BuildPropertyTreesForTesting(); + scroller->SetCurrentScrollOffset(gfx::ScrollOffset(100, 100)); + LayerPositionConstraint constraint; constraint.set_is_fixed_position(true); fixed->test_properties()->position_constraint = constraint; @@ -8654,6 +8649,9 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { scroll_child->SetBounds(gfx::Size(40, 40)); scroll_child->SetDrawsContent(true); scroll_parent->SetBounds(gfx::Size(30, 30)); + scroll_parent->SetScrollable(gfx::Size(50, 50)); + scroll_parent->SetElementId( + LayerIdToElementIdForTesting(scroll_parent->id())); scroll_parent->SetDrawsContent(true); scroll_child->test_properties()->scroll_parent = scroll_parent; @@ -8666,9 +8664,12 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { scroll_child->SetPosition(gfx::PointF(0, -10.f)); scroll_parent->SetCurrentScrollOffset(gfx::ScrollOffset(0.f, 10.f)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root); EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect()); + + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + ExecuteCalculateDrawProperties(root); + EXPECT_EQ(gfx::Rect(0, 10, 25, 25), scroll_child->visible_layer_rect()); } static void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {} @@ -8686,10 +8687,10 @@ TEST_F(LayerTreeHostCommonTest, HasCopyRequestsInTargetSubtree) { grandchild->AddChild(greatgrandchild); host()->SetRootLayer(root); - child1->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind(&CopyOutputCallback))); - greatgrandchild->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind(&CopyOutputCallback))); + child1->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( + base::BindOnce(&CopyOutputCallback))); + greatgrandchild->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( + base::BindOnce(&CopyOutputCallback))); child2->SetOpacity(0.f); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); @@ -8775,8 +8776,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { // Now, even though child has zero opacity, we will configure |grandchild| and // |greatgrandchild| in several ways that should force the subtree to be // processed anyhow. - grandchild->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind(&CopyOutputCallback))); + grandchild->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( + base::BindOnce(&CopyOutputCallback))); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); update_list = GetUpdateLayerList(); EXPECT_TRUE(VerifyLayerInList(grandchild, update_list)); @@ -8926,7 +8927,6 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { player.get()); player->AddAnimation(std::move(transform_animation)); grandchild_ptr->set_visible_layer_rect(gfx::Rect()); - child_ptr->SetScrollClipLayer(root_ptr->id()); root_ptr->test_properties()->transform = singular; child_ptr->test_properties()->transform = singular; root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; @@ -9099,8 +9099,8 @@ TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) { parent->AddChild(child); host()->SetRootLayer(root); - child->RequestCopyOfOutput( - CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + child->RequestCopyOfOutput(CopyOutputRequest::CreateRequest( + base::BindOnce(&EmptyCopyOutputCallback))); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); EXPECT_TRUE(root->has_copy_requests_in_target_subtree()); @@ -9172,12 +9172,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { page_scale_layer, inner_viewport_scroll_layer, outer_viewport_scroll_layer); - TransformTree& transform_tree = - root->layer_tree_impl()->property_trees()->transform_tree; - TransformNode* transform_node = - transform_tree.Node(significant_transform->transform_tree_index()); - EXPECT_EQ(transform_node->owning_layer_id, significant_transform->id()); - EXPECT_TRUE(GetRenderSurface(root)); EXPECT_EQ(GetRenderSurface(significant_transform), GetRenderSurface(root)); EXPECT_TRUE(GetRenderSurface(layer_clips_subtree)); @@ -9490,7 +9484,10 @@ TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { test_layer->test_properties()->transform = translation; test_layer->SetBounds(gfx::Size(20, 20)); test_layer->SetDrawsContent(true); - test_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 20, 20)); + + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 20, 20)); + test_layer->SetTouchActionRegion(std::move(touch_action_region)); test_layer->test_properties()->opacity = 0.f; ExecuteCalculateDrawProperties(root); @@ -9735,7 +9732,6 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { scroll_parent->test_properties()->scroll_children = base::MakeUnique<std::set<LayerImpl*>>(); scroll_parent->test_properties()->scroll_children->insert(scroll_child); - scroll_parent->SetScrollClipLayer(scroll_clip->id()); scroll_parent->SetDrawsContent(true); scroll_child->SetDrawsContent(true); @@ -9828,8 +9824,8 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { EXPECT_TRUE(property_trees->needs_rebuild); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_NE(property_trees->effect_tree.FindNodeFromOwningLayerId(child->id()), - nullptr); + EXPECT_NE(property_trees->effect_tree.Node(child->effect_tree_index()), + property_trees->effect_tree.Node(root->effect_tree_index())); // child already has an effect node. Changing its opacity shouldn't trigger // a property trees rebuild. @@ -9838,8 +9834,8 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { EXPECT_FALSE(property_trees->needs_rebuild); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_NE(property_trees->effect_tree.FindNodeFromOwningLayerId(child->id()), - nullptr); + EXPECT_NE(property_trees->effect_tree.Node(child->effect_tree_index()), + property_trees->effect_tree.Node(root->effect_tree_index())); // Changing the opacity from non-1 value to 1 should trigger a rebuild of // property trees as the effect node may no longer be needed. @@ -9848,8 +9844,8 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) { EXPECT_TRUE(property_trees->needs_rebuild); ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get()); - EXPECT_EQ(property_trees->effect_tree.FindNodeFromOwningLayerId(child->id()), - nullptr); + EXPECT_EQ(property_trees->effect_tree.Node(child->effect_tree_index()), + property_trees->effect_tree.Node(root->effect_tree_index())); } TEST_F(LayerTreeHostCommonTest, OpacityAnimationsTrackingTest) { @@ -10023,20 +10019,27 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { child9->AddChild(grand_child12); host()->SetRootLayer(root1); + root1->SetBounds(gfx::Size(1, 1)); parent2->AddMainThreadScrollingReasons( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); parent2->AddMainThreadScrollingReasons( MainThreadScrollingReason::kScrollbarScrolling); - parent2->SetScrollClipLayerId(root1->id()); + parent2->SetElementId(LayerIdToElementIdForTesting(parent2->id())); + parent2->SetScrollable(root1->bounds()); child6->AddMainThreadScrollingReasons( MainThreadScrollingReason::kScrollbarScrolling); grand_child10->AddMainThreadScrollingReasons( MainThreadScrollingReason::kScrollbarScrolling); - child7->SetScrollClipLayerId(parent3->id()); + parent3->SetBounds(gfx::Size(2, 2)); + child7->SetScrollable(parent3->bounds()); + child7->SetElementId(LayerIdToElementIdForTesting(child7->id())); child8->SetScrollParent(child7.get()); - grand_child11->SetScrollClipLayerId(parent3->id()); + child8->SetBounds(gfx::Size(3, 3)); + grand_child11->SetScrollable(child8->bounds()); + grand_child11->SetElementId( + LayerIdToElementIdForTesting(grand_child11->id())); parent5->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); parent5->SetBounds(gfx::Size(10, 10)); @@ -10059,7 +10062,6 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { ScrollNode* property_tree_root = expected_scroll_tree.Node(0); property_tree_root->id = kRootPropertyTreeNodeId; property_tree_root->parent_id = ScrollTree::kInvalidNodeId; - property_tree_root->owning_layer_id = Layer::INVALID_ID; property_tree_root->scrollable = false; property_tree_root->main_thread_scrolling_reasons = MainThreadScrollingReason::kNotScrollingOnMain; @@ -10069,22 +10071,20 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { // The node owned by root1 ScrollNode scroll_root1; scroll_root1.id = 1; - scroll_root1.owning_layer_id = root1->id(); + scroll_root1.bounds = root1->bounds(); scroll_root1.user_scrollable_horizontal = true; scroll_root1.user_scrollable_vertical = true; scroll_root1.transform_id = root1->transform_tree_index(); expected_scroll_tree.Insert(scroll_root1, 0); - expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(), - root1->id()); // The node owned by parent2 ScrollNode scroll_parent2; scroll_parent2.id = 2; - scroll_parent2.owning_layer_id = parent2->id(); + scroll_parent2.element_id = parent2->element_id(); scroll_parent2.scrollable = true; scroll_parent2.main_thread_scrolling_reasons = parent2->main_thread_scrolling_reasons(); - scroll_parent2.scroll_clip_layer_bounds = root1->bounds(); + scroll_parent2.container_bounds = root1->bounds(); scroll_parent2.bounds = parent2->bounds(); scroll_parent2.max_scroll_offset_affected_by_page_scale = true; scroll_parent2.scrolls_inner_viewport = true; @@ -10092,13 +10092,10 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { scroll_parent2.user_scrollable_vertical = true; scroll_parent2.transform_id = parent2->transform_tree_index(); expected_scroll_tree.Insert(scroll_parent2, 1); - expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(), - parent2->id()); // The node owned by child6 ScrollNode scroll_child6; scroll_child6.id = 3; - scroll_child6.owning_layer_id = child6->id(); scroll_child6.main_thread_scrolling_reasons = child6->main_thread_scrolling_reasons(); scroll_child6.should_flatten = true; @@ -10106,39 +10103,33 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { scroll_child6.user_scrollable_vertical = true; scroll_child6.transform_id = child6->transform_tree_index(); expected_scroll_tree.Insert(scroll_child6, 2); - expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(), - child6->id()); // The node owned by child7, child7 also owns a transform node ScrollNode scroll_child7; scroll_child7.id = 4; - scroll_child7.owning_layer_id = child7->id(); + scroll_child7.element_id = child7->element_id(); scroll_child7.scrollable = true; - scroll_child7.scroll_clip_layer_bounds = parent3->bounds(); + scroll_child7.container_bounds = parent3->bounds(); scroll_child7.bounds = child7->bounds(); scroll_child7.user_scrollable_horizontal = true; scroll_child7.user_scrollable_vertical = true; scroll_child7.transform_id = child7->transform_tree_index(); expected_scroll_tree.Insert(scroll_child7, 1); - expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(), - child7->id()); // The node owned by grand_child11, grand_child11 also owns a transform node ScrollNode scroll_grand_child11; scroll_grand_child11.id = 5; - scroll_grand_child11.owning_layer_id = grand_child11->id(); + scroll_grand_child11.element_id = grand_child11->element_id(); scroll_grand_child11.scrollable = true; + scroll_grand_child11.container_bounds = child8->bounds(); scroll_grand_child11.user_scrollable_horizontal = true; scroll_grand_child11.user_scrollable_vertical = true; scroll_grand_child11.transform_id = grand_child11->transform_tree_index(); expected_scroll_tree.Insert(scroll_grand_child11, 4); - expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(), - grand_child11->id()); // The node owned by parent5 ScrollNode scroll_parent5; scroll_parent5.id = 8; - scroll_parent5.owning_layer_id = parent5->id(); scroll_parent5.non_fast_scrollable_region = gfx::Rect(0, 0, 50, 50); scroll_parent5.bounds = gfx::Size(10, 10); scroll_parent5.should_flatten = true; @@ -10146,12 +10137,12 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { scroll_parent5.user_scrollable_vertical = true; scroll_parent5.transform_id = parent5->transform_tree_index(); expected_scroll_tree.Insert(scroll_parent5, 1); - expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(), - parent5->id()); - expected_scroll_tree.SetScrollOffset(parent2->id(), gfx::ScrollOffset(0, 0)); - expected_scroll_tree.SetScrollOffset(child7->id(), gfx::ScrollOffset(0, 0)); - expected_scroll_tree.SetScrollOffset(grand_child11->id(), + expected_scroll_tree.SetScrollOffset(parent2->element_id(), + gfx::ScrollOffset(0, 0)); + expected_scroll_tree.SetScrollOffset(child7->element_id(), + gfx::ScrollOffset(0, 0)); + expected_scroll_tree.SetScrollOffset(grand_child11->element_id(), gfx::ScrollOffset(0, 0)); expected_scroll_tree.set_needs_update(false); @@ -10258,5 +10249,243 @@ TEST_F(LayerTreeHostCommonTest, SurfaceContentsScaleChangeWithCopyRequestTest) { EXPECT_EQ(gfx::Rect(10, 10), test_layer->drawable_content_rect()); } +TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCacheRenderSurface) { + FakeImplTaskRunnerProvider task_runner_provider; + TestTaskGraphRunner task_graph_runner; + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); + host_impl.CreatePendingTree(); + + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.pending_tree(), 1); + root->SetBounds(gfx::Size(50, 50)); + root->SetDrawsContent(true); + LayerImpl* root_layer = root.get(); + + std::unique_ptr<LayerImpl> cache_grand_parent = + LayerImpl::Create(host_impl.pending_tree(), 2); + cache_grand_parent->SetBounds(gfx::Size(40, 40)); + cache_grand_parent->SetDrawsContent(true); + LayerImpl* cache_grand_parent_layer = cache_grand_parent.get(); + + std::unique_ptr<LayerImpl> cache_parent = + LayerImpl::Create(host_impl.pending_tree(), 3); + cache_parent->SetBounds(gfx::Size(30, 30)); + cache_parent->SetDrawsContent(true); + cache_parent->test_properties()->force_render_surface = true; + LayerImpl* cache_parent_layer = cache_parent.get(); + + std::unique_ptr<LayerImpl> cache_render_surface = + LayerImpl::Create(host_impl.pending_tree(), 4); + cache_render_surface->SetBounds(gfx::Size(20, 20)); + cache_render_surface->SetDrawsContent(true); + cache_render_surface->test_properties()->cache_render_surface = true; + LayerImpl* cache_layer = cache_render_surface.get(); + + std::unique_ptr<LayerImpl> cache_child = + LayerImpl::Create(host_impl.pending_tree(), 5); + cache_child->SetBounds(gfx::Size(20, 20)); + cache_child->SetDrawsContent(true); + LayerImpl* cache_child_layer = cache_child.get(); + + std::unique_ptr<LayerImpl> cache_grand_child = + LayerImpl::Create(host_impl.pending_tree(), 6); + cache_grand_child->SetBounds(gfx::Size(20, 20)); + cache_grand_child->SetDrawsContent(true); + LayerImpl* cache_grand_child_layer = cache_grand_child.get(); + + std::unique_ptr<LayerImpl> cache_grand_parent_sibling_before = + LayerImpl::Create(host_impl.pending_tree(), 7); + cache_grand_parent_sibling_before->SetBounds(gfx::Size(40, 40)); + cache_grand_parent_sibling_before->SetDrawsContent(true); + LayerImpl* cache_grand_parent_sibling_before_layer = + cache_grand_parent_sibling_before.get(); + + std::unique_ptr<LayerImpl> cache_grand_parent_sibling_after = + LayerImpl::Create(host_impl.pending_tree(), 8); + cache_grand_parent_sibling_after->SetBounds(gfx::Size(40, 40)); + cache_grand_parent_sibling_after->SetDrawsContent(true); + LayerImpl* cache_grand_parent_sibling_after_layer = + cache_grand_parent_sibling_after.get(); + + cache_child->test_properties()->AddChild(std::move(cache_grand_child)); + cache_render_surface->test_properties()->AddChild(std::move(cache_child)); + cache_parent->test_properties()->AddChild(std::move(cache_render_surface)); + cache_grand_parent->test_properties()->AddChild(std::move(cache_parent)); + root->test_properties()->AddChild( + std::move(cache_grand_parent_sibling_before)); + root->test_properties()->AddChild(std::move(cache_grand_parent)); + root->test_properties()->AddChild( + std::move(cache_grand_parent_sibling_after)); + host_impl.pending_tree()->SetRootLayerForTesting(std::move(root)); + + // Hide the cache_grand_parent and its subtree. But cache a render surface in + // that hidden subtree on cache_layer. Also hide the cache grand child and its + // subtree. + cache_grand_parent_layer->test_properties()->hide_layer_and_subtree = true; + cache_grand_parent_sibling_before_layer->test_properties() + ->hide_layer_and_subtree = true; + cache_grand_parent_sibling_after_layer->test_properties() + ->hide_layer_and_subtree = true; + cache_grand_child_layer->test_properties()->hide_layer_and_subtree = true; + + RenderSurfaceList render_surface_list; + LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( + root_layer, root_layer->bounds(), &render_surface_list); + inputs.can_adjust_raster_scales = true; + LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + + // We should have four render surfaces, one for the root, one for the grand + // parent since it has opacity and two drawing descendants, one for the parent + // since it owns a surface, and one for the cache_layer. + ASSERT_EQ(4u, render_surface_list.size()); + EXPECT_EQ(static_cast<uint64_t>(root_layer->id()), + render_surface_list.at(0)->id()); + EXPECT_EQ(static_cast<uint64_t>(cache_grand_parent_layer->id()), + render_surface_list.at(1)->id()); + EXPECT_EQ(static_cast<uint64_t>(cache_parent_layer->id()), + render_surface_list.at(2)->id()); + EXPECT_EQ(static_cast<uint64_t>(cache_layer->id()), + render_surface_list.at(3)->id()); + + // The root render surface should have 2 contributing layers. + EXPECT_EQ(2, GetRenderSurface(root_layer)->num_contributors()); + EXPECT_TRUE(root_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(cache_grand_parent_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(cache_grand_parent_sibling_before_layer + ->contributes_to_drawn_render_surface()); + EXPECT_FALSE(cache_grand_parent_sibling_after_layer + ->contributes_to_drawn_render_surface()); + + // Nothing actually draws into the cache parent, so only the cache_layer will + // appear in its list, since it needs to be drawn for the cache render + // surface. + ASSERT_EQ(1, GetRenderSurface(cache_parent_layer)->num_contributors()); + EXPECT_FALSE(cache_parent_layer->contributes_to_drawn_render_surface()); + + // The cache layer's render surface should have 2 contributing layers. + ASSERT_EQ(2, GetRenderSurface(cache_layer)->num_contributors()); + EXPECT_TRUE(cache_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(cache_child_layer->contributes_to_drawn_render_surface()); + EXPECT_FALSE(cache_grand_child_layer->contributes_to_drawn_render_surface()); + + // cache_grand_parent, cache_parent shouldn't be drawn because they are + // hidden, but the cache_layer and cache_child should be drawn for the cache + // render surface. cache grand child should not be drawn as its hidden even in + // the cache render surface. + EffectTree& tree = + root_layer->layer_tree_impl()->property_trees()->effect_tree; + EffectNode* node = tree.Node(cache_grand_parent_layer->effect_tree_index()); + EXPECT_FALSE(node->is_drawn); + node = tree.Node(cache_parent_layer->effect_tree_index()); + EXPECT_FALSE(node->is_drawn); + node = tree.Node(cache_layer->effect_tree_index()); + EXPECT_TRUE(node->is_drawn); + node = tree.Node(cache_child_layer->effect_tree_index()); + EXPECT_TRUE(node->is_drawn); + node = tree.Node(cache_grand_child_layer->effect_tree_index()); + EXPECT_FALSE(node->is_drawn); + + // Though cache_layer is drawn, it shouldn't contribute to drawn surface as + // its actually hidden. + EXPECT_FALSE(GetRenderSurface(cache_layer)->contributes_to_drawn_surface()); +} + +TEST_F(LayerTreeHostCommonTest, VisibleRectInNonRootCacheRenderSurface) { + LayerImpl* root = root_layer_for_testing(); + root->SetBounds(gfx::Size(50, 50)); + root->SetDrawsContent(true); + root->SetMasksToBounds(true); + + LayerImpl* cache_render_surface_layer = AddChild<LayerImpl>(root); + cache_render_surface_layer->SetBounds(gfx::Size(120, 120)); + cache_render_surface_layer->SetDrawsContent(true); + cache_render_surface_layer->test_properties()->cache_render_surface = true; + + LayerImpl* copy_layer = AddChild<LayerImpl>(cache_render_surface_layer); + copy_layer->SetBounds(gfx::Size(100, 100)); + copy_layer->SetDrawsContent(true); + copy_layer->test_properties()->force_render_surface = true; + + LayerImpl* copy_child = AddChild<LayerImpl>(copy_layer); + copy_child->SetPosition(gfx::PointF(40.f, 40.f)); + copy_child->SetBounds(gfx::Size(20, 20)); + copy_child->SetDrawsContent(true); + + LayerImpl* copy_clip = AddChild<LayerImpl>(copy_layer); + copy_clip->SetBounds(gfx::Size(55, 55)); + copy_clip->SetMasksToBounds(true); + + LayerImpl* copy_clipped_child = AddChild<LayerImpl>(copy_clip); + copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f)); + copy_clipped_child->SetBounds(gfx::Size(20, 20)); + copy_clipped_child->SetDrawsContent(true); + + LayerImpl* cache_surface = AddChild<LayerImpl>(copy_clip); + cache_surface->SetPosition(gfx::PointF(45.f, 45.f)); + cache_surface->SetBounds(gfx::Size(20, 20)); + cache_surface->SetDrawsContent(true); + + ExecuteCalculateDrawProperties(root); + EXPECT_EQ(gfx::Rect(120, 120), + cache_render_surface_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(100, 100), copy_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), copy_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(15, 15), copy_clipped_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), cache_surface->visible_layer_rect()); + + // Case 2: When the non root cache render surface layer is clipped. + cache_render_surface_layer->SetBounds(gfx::Size(50, 50)); + cache_render_surface_layer->SetMasksToBounds(true); + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + ExecuteCalculateDrawProperties(root); + EXPECT_EQ(gfx::Rect(50, 50), + cache_render_surface_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(50, 50), copy_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), copy_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), copy_clipped_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(5, 5), cache_surface->visible_layer_rect()); + + // Case 3: When there is device scale factor. + float device_scale_factor = 2.f; + ExecuteCalculateDrawProperties(root, device_scale_factor); + EXPECT_EQ(gfx::Rect(50, 50), + cache_render_surface_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(50, 50), copy_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), copy_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), copy_clipped_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(5, 5), cache_surface->visible_layer_rect()); + + // Case 4: When the non root cache render surface layer is clipped and there + // is a copy request layer beneath it. + copy_layer->test_properties()->copy_requests.push_back( + CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + DCHECK(!copy_layer->test_properties()->copy_requests.empty()); + ExecuteCalculateDrawProperties(root); + DCHECK(copy_layer->test_properties()->copy_requests.empty()); + EXPECT_EQ(gfx::Rect(50, 50), + cache_render_surface_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(100, 100), copy_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), copy_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(15, 15), copy_clipped_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), cache_surface->visible_layer_rect()); + + // Case 5: When there is another cache render surface layer under the copy + // request layer. + cache_surface->test_properties()->cache_render_surface = true; + copy_layer->test_properties()->copy_requests.push_back( + CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + DCHECK(!copy_layer->test_properties()->copy_requests.empty()); + ExecuteCalculateDrawProperties(root); + DCHECK(copy_layer->test_properties()->copy_requests.empty()); + EXPECT_EQ(gfx::Rect(50, 50), + cache_render_surface_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(100, 100), copy_layer->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), copy_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(15, 15), copy_clipped_child->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(20, 20), cache_surface->visible_layer_rect()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index 359d56d6e43..b7fd18868e5 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -48,8 +48,8 @@ #include "cc/layers/viewport.h" #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_metadata.h" -#include "cc/output/compositor_frame_sink.h" #include "cc/output/copy_output_request.h" +#include "cc/output/layer_tree_frame_sink.h" #include "cc/quads/render_pass_draw_quad.h" #include "cc/quads/shared_quad_state.h" #include "cc/quads/solid_color_draw_quad.h" @@ -161,6 +161,8 @@ void RecordCompositorSlowScrollMetric(InputHandler::ScrollInputType type, DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeDurationHistogramTimer, "Scheduling.%s.PendingTreeDuration"); +DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeRasterDurationHistogramTimer, + "Scheduling.%s.PendingTreeRasterDuration"); LayerTreeHostImpl::FrameData::FrameData() : render_surface_list(nullptr), @@ -196,9 +198,10 @@ LayerTreeHostImpl::LayerTreeHostImpl( : client_(client), task_runner_provider_(task_runner_provider), current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), - compositor_frame_sink_(nullptr), + layer_tree_frame_sink_(nullptr), need_update_gpu_rasterization_status_(false), - content_is_suitable_for_gpu_rasterization_(true), + content_has_slow_paths_(false), + content_has_non_aa_paint_(false), has_gpu_rasterization_trigger_(false), use_gpu_rasterization_(false), use_msaa_(false), @@ -237,7 +240,7 @@ LayerTreeHostImpl::LayerTreeHostImpl( id_(id), requires_high_res_to_draw_(false), is_likely_to_require_a_draw_(false), - has_valid_compositor_frame_sink_(false), + has_valid_layer_tree_frame_sink_(false), mutator_(nullptr), scroll_animating_latched_node_id_(ScrollTree::kInvalidNodeId), has_scrolled_by_wheel_(false), @@ -277,7 +280,7 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { "cc::LayerTreeHostImpl", id_); // It is released before shutdown. - DCHECK(!compositor_frame_sink_); + DCHECK(!layer_tree_frame_sink_); DCHECK(!resource_provider_); DCHECK(!resource_pool_); @@ -369,11 +372,17 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() { sync_tree()->set_needs_update_draw_properties(); // We need an update immediately post-commit to have the opportunity to create - // tilings. Because invalidations may be coming from the main thread, it's + // tilings. + sync_tree()->UpdateDrawProperties(); + // Because invalidations may be coming from the main thread, it's // safe to do an update for lcd text at this point and see if lcd text needs // to be disabled on any layers. - bool update_lcd_text = true; - sync_tree()->UpdateDrawProperties(update_lcd_text); + // It'd be ideal if this could be done earlier, but when the raster source + // is updated from the main thread during push properties, update draw + // properties has not occurred yet and so it's not clear whether or not the + // layer can or cannot use lcd text. So, this is the cleanup pass to + // determine if lcd state needs to switch due to draw properties. + sync_tree()->UpdateCanUseLCDText(); // Start working on newly created tiles immediately if needed. // TODO(vmpstr): Investigate always having PrepareTiles issue // NotifyReadyToActivate, instead of handling it here. @@ -387,6 +396,10 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() { // Scheduler to wait for ReadyToDraw signal to avoid Checkerboard. if (CommitToActiveTree()) NotifyReadyToDraw(); + } else if (!CommitToActiveTree()) { + DCHECK(!pending_tree_raster_duration_timer_); + pending_tree_raster_duration_timer_ = + base::MakeUnique<PendingTreeRasterDurationHistogramTimer>(); } } @@ -396,9 +409,9 @@ bool LayerTreeHostImpl::CanDraw() const { // client_->OnCanDrawStateChanged in the proper places and update the // NotifyIfCanDrawChanged test. - if (!compositor_frame_sink_) { + if (!layer_tree_frame_sink_) { TRACE_EVENT_INSTANT0("cc", - "LayerTreeHostImpl::CanDraw no CompositorFrameSink", + "LayerTreeHostImpl::CanDraw no LayerTreeFrameSink", TRACE_EVENT_SCOPE_THREAD); return false; } @@ -615,9 +628,10 @@ bool LayerTreeHostImpl::IsScrolledBy(LayerImpl* child, ScrollNode* ancestor) { return false; } -InputHandler::TouchStartEventListenerType -LayerTreeHostImpl::EventListenerTypeForTouchStartAt( - const gfx::Point& viewport_point) { +InputHandler::TouchStartOrMoveEventListenerType +LayerTreeHostImpl::EventListenerTypeForTouchStartOrMoveAt( + const gfx::Point& viewport_point, + TouchAction* out_touch_action) { gfx::PointF device_viewport_point = gfx::ScalePoint( gfx::PointF(viewport_point), active_tree_->device_scale_factor()); @@ -626,23 +640,33 @@ LayerTreeHostImpl::EventListenerTypeForTouchStartAt( LayerImpl* layer_impl_with_touch_handler = active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion( device_viewport_point); - if (layer_impl_with_touch_handler == NULL) - return InputHandler::TouchStartEventListenerType::NO_HANDLER; + + if (layer_impl_with_touch_handler == nullptr) { + if (out_touch_action) + *out_touch_action = kTouchActionAuto; + return InputHandler::TouchStartOrMoveEventListenerType::NO_HANDLER; + } + + if (out_touch_action) { + const auto& region = layer_impl_with_touch_handler->touch_action_region(); + gfx::Point point = gfx::ToRoundedPoint(device_viewport_point); + *out_touch_action = region.GetWhiteListedTouchAction(point); + } if (!CurrentlyScrollingNode()) - return InputHandler::TouchStartEventListenerType::HANDLER; + return InputHandler::TouchStartOrMoveEventListenerType::HANDLER; - // Check if the touch start hits on the current scrolling layer or its - // descendant. layer_impl_with_touch_handler is the layer hit by the pointer - // and has an event handler, otherwise it is null. - // We want to compare the most inner layer we are hitting on which may not - // have an event listener with the actual scrolling layer. + // Check if the touch start (or move) hits on the current scrolling layer or + // its descendant. layer_impl_with_touch_handler is the layer hit by the + // pointer and has an event handler, otherwise it is null. We want to compare + // the most inner layer we are hitting on which may not have an event listener + // with the actual scrolling layer. LayerImpl* layer_impl = active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); bool is_ancestor = IsScrolledBy(layer_impl, CurrentlyScrollingNode()); - return is_ancestor ? InputHandler::TouchStartEventListenerType:: + return is_ancestor ? InputHandler::TouchStartOrMoveEventListenerType:: HANDLER_ON_SCROLLING_LAYER - : InputHandler::TouchStartEventListenerType::HANDLER; + : InputHandler::TouchStartOrMoveEventListenerType::HANDLER; } std::unique_ptr<SwapPromiseMonitor> @@ -727,7 +751,7 @@ void LayerTreeHostImpl::FrameData::AsValueInto( DrawMode LayerTreeHostImpl::GetDrawMode() const { if (resourceless_software_draw_) { return DRAW_MODE_RESOURCELESS_SOFTWARE; - } else if (compositor_frame_sink_->context_provider()) { + } else if (layer_tree_frame_sink_->context_provider()) { return DRAW_MODE_HARDWARE; } else { return DRAW_MODE_SOFTWARE; @@ -772,7 +796,8 @@ static void AppendQuadsToFillScreen( } } -static RenderPass* FindRenderPassById(const RenderPassList& list, int id) { +static RenderPass* FindRenderPassById(const RenderPassList& list, + RenderPassId id) { auto it = std::find_if( list.begin(), list.end(), [id](const std::unique_ptr<RenderPass>& p) { return p->id == id; }); @@ -801,7 +826,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { bool hud_wants_to_draw_ = active_tree_->hud_layer() && active_tree_->hud_layer()->IsAnimatingHUDContents(); bool must_always_swap = - compositor_frame_sink_->capabilities().must_always_swap; + layer_tree_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 @@ -836,7 +861,8 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; bool should_draw_into_render_pass = is_root_surface || render_surface->contributes_to_drawn_surface() || - render_surface->HasCopyRequest(); + render_surface->HasCopyRequest() || + render_surface->ShouldCacheRenderSurface(); if (should_draw_into_render_pass) frame->render_passes.push_back(render_surface->CreateRenderPass()); } @@ -888,7 +914,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { for (EffectTreeLayerListIterator it(active_tree()); it.state() != EffectTreeLayerListIterator::State::END; ++it) { - auto target_render_pass_id = it.target_render_surface()->GetRenderPassId(); + auto target_render_pass_id = it.target_render_surface()->id(); RenderPass* target_render_pass = FindRenderPassById(frame->render_passes, target_render_pass_id); @@ -906,8 +932,10 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { } else if (it.state() == EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) { RenderSurfaceImpl* render_surface = it.current_render_surface(); - if (render_surface->contributes_to_drawn_surface()) - render_surface->AppendQuads(target_render_pass, &append_quads_data); + if (render_surface->contributes_to_drawn_surface()) { + render_surface->AppendQuads(draw_mode, target_render_pass, + &append_quads_data); + } } else if (it.state() == EffectTreeLayerListIterator::State::LAYER && !it.current_layer()->visible_layer_rect().IsEmpty()) { LayerImpl* layer = it.current_layer(); @@ -1032,7 +1060,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { // would be animating checkerboards, because failing under those conditions // triggers a new main frame, which may cause the copy request layer to be // destroyed. - // TODO(weiliangc): Test copy request w/ CompositorFrameSink recreation. Would + // TODO(weiliangc): Test copy request w/ LayerTreeFrameSink recreation. Would // trigger this DCHECK. DCHECK(!have_copy_request || draw_result == DRAW_SUCCESS); @@ -1068,18 +1096,6 @@ 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(); } @@ -1108,8 +1124,7 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { base::saturated_cast<int>(active_tree_->NumLayers()), 1, 400, 20); } - bool update_lcd_text = false; - bool ok = active_tree_->UpdateDrawProperties(update_lcd_text); + bool ok = active_tree_->UpdateDrawProperties(); DCHECK(ok) << "UpdateDrawProperties failed during draw"; // This will cause NotifyTileStateChanged() to be called for any tiles that @@ -1147,10 +1162,10 @@ void LayerTreeHostImpl::RemoveRenderPasses(FrameData* frame) { DCHECK_GE(frame->render_passes.size(), 1u); // A set of RenderPasses that we have seen. - base::flat_set<int> pass_exists; + base::flat_set<RenderPassId> pass_exists; // A set of RenderPassDrawQuads that we have seen (stored by the RenderPasses // they refer to). - base::flat_map<int, int> pass_references; + base::flat_map<RenderPassId, int> pass_references; // Iterate RenderPasses in draw order, removing empty render passes (except // the root RenderPass). @@ -1373,6 +1388,7 @@ void LayerTreeHostImpl::RequestImplSideInvalidation() { } void LayerTreeHostImpl::NotifyReadyToActivate() { + pending_tree_raster_duration_timer_.reset(); client_->NotifyReadyToActivate(); } @@ -1507,7 +1523,7 @@ void LayerTreeHostImpl::SetExternalTilePriorityConstraints( if (pending_tree_) pending_tree_->set_needs_update_draw_properties(); - // Compositor, not CompositorFrameSink, is responsible for setting damage + // Compositor, not LayerTreeFrameSink, is responsible for setting damage // and triggering redraw for constraint changes. SetFullViewportDamage(); SetNeedsRedraw(); @@ -1519,7 +1535,7 @@ void LayerTreeHostImpl::DidReceiveCompositorFrameAck() { } void LayerTreeHostImpl::ReclaimResources( - const ReturnedResourceArray& resources) { + const std::vector<ReturnedResource>& resources) { // TODO(piman): We may need to do some validation on this ack before // processing it. if (!resource_provider_) @@ -1579,7 +1595,7 @@ void LayerTreeHostImpl::OnDraw(const gfx::Transform& transform, client_->OnCanDrawStateChanged(CanDraw()); } - client_->OnDrawForCompositorFrameSink(resourceless_software_draw_); + client_->OnDrawForLayerTreeFrameSink(resourceless_software_draw_); } if (resourceless_software_draw) { @@ -1619,11 +1635,11 @@ CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { active_tree_->GetViewportSelection(&metadata.selection); - if (OuterViewportScrollLayer()) { + if (const auto* outer_viewport_scroll_node = OuterViewportScrollNode()) { metadata.root_overflow_x_hidden = - !OuterViewportScrollLayer()->user_scrollable_horizontal(); + !outer_viewport_scroll_node->user_scrollable_horizontal; metadata.root_overflow_y_hidden = - !OuterViewportScrollLayer()->user_scrollable_vertical(); + !outer_viewport_scroll_node->user_scrollable_vertical; } if (GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) { @@ -1631,26 +1647,18 @@ CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { IsActivelyScrolling() || mutator_host_->NeedsTickAnimations(); } - for (LayerImpl* surface_layer : active_tree_->SurfaceLayers()) { - SurfaceLayerImpl* surface_layer_impl = - static_cast<SurfaceLayerImpl*>(surface_layer); - if (settings_.enable_surface_synchronization) { - if (surface_layer_impl->fallback_surface_info().is_valid()) { - metadata.referenced_surfaces.push_back( - surface_layer_impl->fallback_surface_info().id()); - } - } else { - metadata.referenced_surfaces.push_back( - surface_layer_impl->primary_surface_info().id()); - } + for (auto& surface_id : active_tree_->SurfaceLayerIds()) { + metadata.referenced_surfaces.push_back(surface_id); } - if (!InnerViewportScrollLayer()) + + const auto* inner_viewport_scroll_node = InnerViewportScrollNode(); + if (!inner_viewport_scroll_node) return metadata; metadata.root_overflow_x_hidden |= - !InnerViewportScrollLayer()->user_scrollable_horizontal(); + !inner_viewport_scroll_node->user_scrollable_horizontal; metadata.root_overflow_y_hidden |= - !InnerViewportScrollLayer()->user_scrollable_vertical(); + !inner_viewport_scroll_node->user_scrollable_vertical; // TODO(miletus) : Change the metadata to hold ScrollOffset. metadata.root_scroll_offset = @@ -1676,7 +1684,7 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { } fps_counter_->SaveTimeStamp(CurrentBeginFrameArgs().frame_time, - !compositor_frame_sink_->context_provider()); + !layer_tree_frame_sink_->context_provider()); rendering_stats_instrumentation_->IncrementFrameCount(1); memory_history_->SaveEntry(tile_manager_.memory_stats_from_last_assign()); @@ -1712,8 +1720,9 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { // drawn. if (active_tree_->hud_layer()) { TRACE_EVENT0("cc", "DrawLayers.UpdateHudTexture"); - active_tree_->hud_layer()->UpdateHudTexture(draw_mode, - resource_provider_.get()); + active_tree_->hud_layer()->UpdateHudTexture( + draw_mode, resource_provider_.get(), + layer_tree_frame_sink_->context_provider()); } CompositorFrameMetadata metadata = MakeCompositorFrameMetadata(); @@ -1752,14 +1761,14 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { resource_provider_->PrepareSendToParent(resources, &compositor_frame.resource_list); 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. + // TODO(fsamuel): Once all clients get their viz::LocalSurfaceId from their + // parent, the viz::LocalSurfaceId should hang off CompositorFrameMetadata. if (settings_.enable_surface_synchronization && active_tree()->local_surface_id().is_valid()) { - compositor_frame_sink_->SetLocalSurfaceId( + layer_tree_frame_sink_->SetLocalSurfaceId( active_tree()->local_surface_id()); } - compositor_frame_sink_->SubmitCompositorFrame(std::move(compositor_frame)); + layer_tree_frame_sink_->SubmitCompositorFrame(std::move(compositor_frame)); // Clears the list of swap promises after calling DidSwap on each of them to // signal that the swap is over. @@ -1810,21 +1819,28 @@ void LayerTreeHostImpl::SetHasGpuRasterizationTrigger(bool flag) { } } -void LayerTreeHostImpl::SetContentIsSuitableForGpuRasterization(bool flag) { - if (content_is_suitable_for_gpu_rasterization_ != flag) { - content_is_suitable_for_gpu_rasterization_ = flag; +void LayerTreeHostImpl::SetContentHasSlowPaths(bool flag) { + if (content_has_slow_paths_ != flag) { + content_has_slow_paths_ = flag; + need_update_gpu_rasterization_status_ = true; + } +} + +void LayerTreeHostImpl::SetContentHasNonAAPaint(bool flag) { + if (content_has_non_aa_paint_ != flag) { + content_has_non_aa_paint_ = flag; need_update_gpu_rasterization_status_ = true; } } bool LayerTreeHostImpl::CanUseGpuRasterization() { - if (!(compositor_frame_sink_ && compositor_frame_sink_->context_provider() && - compositor_frame_sink_->worker_context_provider())) + if (!(layer_tree_frame_sink_ && layer_tree_frame_sink_->context_provider() && + layer_tree_frame_sink_->worker_context_provider())) return false; - ContextProvider* context_provider = - compositor_frame_sink_->worker_context_provider(); - ContextProvider::ScopedContextLock scoped_context(context_provider); + viz::ContextProvider* context_provider = + layer_tree_frame_sink_->worker_context_provider(); + viz::ContextProvider::ScopedContextLock scoped_context(context_provider); if (!context_provider->GrContext()) return false; @@ -1833,33 +1849,36 @@ bool LayerTreeHostImpl::CanUseGpuRasterization() { bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() { // TODO(danakj): Can we avoid having this run when there's no - // CompositorFrameSink? + // LayerTreeFrameSink? // For now just early out and leave things unchanged, we'll come back here - // when we get an CompositorFrameSink. - if (!compositor_frame_sink_) + // when we get a LayerTreeFrameSink. + if (!layer_tree_frame_sink_) return false; int requested_msaa_samples = RequestedMSAASampleCount(); int max_msaa_samples = 0; - ContextProvider* compositor_context_provider = - compositor_frame_sink_->context_provider(); + viz::ContextProvider* compositor_context_provider = + layer_tree_frame_sink_->context_provider(); bool gpu_rasterization_enabled = false; + bool supports_disable_msaa = false; if (compositor_context_provider) { const auto& caps = compositor_context_provider->ContextCapabilities(); gpu_rasterization_enabled = caps.gpu_rasterization; - if (!caps.msaa_is_slow) + supports_disable_msaa = caps.multisample_compatibility; + if (!caps.msaa_is_slow && !caps.avoid_stencil_buffers) max_msaa_samples = caps.max_samples; } bool use_gpu = false; bool use_msaa = false; - bool using_msaa_for_complex_content = - requested_msaa_samples > 0 && max_msaa_samples >= requested_msaa_samples; + bool using_msaa_for_slow_paths = + requested_msaa_samples > 0 && + max_msaa_samples >= requested_msaa_samples && + (!content_has_non_aa_paint_ || supports_disable_msaa); if (settings_.gpu_rasterization_forced) { use_gpu = true; gpu_rasterization_status_ = GpuRasterizationStatus::ON_FORCED; - use_msaa = !content_is_suitable_for_gpu_rasterization_ && - using_msaa_for_complex_content; + use_msaa = content_has_slow_paths_ && using_msaa_for_slow_paths; if (use_msaa) { gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT; } @@ -1867,8 +1886,7 @@ 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_ && - using_msaa_for_complex_content) { + } else if (content_has_slow_paths_ && using_msaa_for_slow_paths) { use_gpu = use_msaa = true; gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT; } else { @@ -1949,8 +1967,8 @@ void LayerTreeHostImpl::DidFinishImplFrame() { } void LayerTreeHostImpl::DidNotProduceFrame(const BeginFrameAck& ack) { - if (compositor_frame_sink_) - compositor_frame_sink_->DidNotProduceFrame(ack); + if (layer_tree_frame_sink_) + layer_tree_frame_sink_->DidNotProduceFrame(ack); } void LayerTreeHostImpl::UpdateViewportContainerSizes() { @@ -2003,26 +2021,44 @@ void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() { single_thread_synchronous_task_graph_runner_->RunUntilIdle(); } -void LayerTreeHostImpl::DidLoseCompositorFrameSink() { +void LayerTreeHostImpl::DidLoseLayerTreeFrameSink() { if (resource_provider_) - resource_provider_->DidLoseContextProvider(); - has_valid_compositor_frame_sink_ = false; - client_->DidLoseCompositorFrameSinkOnImplThread(); + resource_provider_->DidLoseVulkanContextProvider(); + has_valid_layer_tree_frame_sink_ = false; + client_->DidLoseLayerTreeFrameSinkOnImplThread(); } bool LayerTreeHostImpl::HaveRootScrollLayer() const { return !!InnerViewportScrollLayer(); } +LayerImpl* LayerTreeHostImpl::InnerViewportContainerLayer() const { + return active_tree_->InnerViewportContainerLayer(); +} + LayerImpl* LayerTreeHostImpl::InnerViewportScrollLayer() const { return active_tree_->InnerViewportScrollLayer(); } +ScrollNode* LayerTreeHostImpl::InnerViewportScrollNode() const { + const auto* inner_viewport_scroll_layer = InnerViewportScrollLayer(); + if (!inner_viewport_scroll_layer) + return nullptr; + ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; + return scroll_tree.Node(inner_viewport_scroll_layer->scroll_tree_index()); +} + +LayerImpl* LayerTreeHostImpl::OuterViewportContainerLayer() const { + return active_tree_->OuterViewportContainerLayer(); +} + LayerImpl* LayerTreeHostImpl::OuterViewportScrollLayer() const { return active_tree_->OuterViewportScrollLayer(); } ScrollNode* LayerTreeHostImpl::OuterViewportScrollNode() const { + // TODO(pdr): Refactor this to work like InnerViewportScrollNode and access + // OuterViewportScrollLayer instead of MainScrollLayer. if (!viewport()->MainScrollLayer()) return nullptr; ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; @@ -2103,6 +2139,12 @@ void LayerTreeHostImpl::ActivateSyncTree() { // Reset will call the destructor and log the timer histogram. pending_tree_duration_timer_.reset(); + // In most cases, this will be reset in NotifyReadyToActivate, since we + // activate the pending tree only when its ready. But an activation may be + // forced, in the case of a context loss for instance, so reset it here as + // well. + pending_tree_raster_duration_timer_.reset(); + // Process any requests in the UI resource queue. The request queue is // given in LayerTreeHost::FinishCommitOnImplThread. This must take place // before the swap. @@ -2246,6 +2288,10 @@ void LayerTreeHostImpl::ReleaseTileResources() { pending_tree_->ReleaseTileResources(); if (recycle_tree_) recycle_tree_->ReleaseTileResources(); + + // Need to update tiles again in order to kick of raster work for all the + // tiles that are dropped here. + active_tree_->set_needs_update_draw_properties(); } void LayerTreeHostImpl::RecreateTileResources() { @@ -2262,13 +2308,13 @@ void LayerTreeHostImpl::CreateTileManagerResources() { if (use_gpu_rasterization_) { image_decode_cache_ = base::MakeUnique<GpuImageDecodeCache>( - compositor_frame_sink_->worker_context_provider(), - settings_.renderer_settings.preferred_tile_format, + layer_tree_frame_sink_->worker_context_provider(), + settings_.preferred_tile_format, settings_.decoded_image_working_set_budget_bytes, settings_.decoded_image_cache_budget_bytes); } else { image_decode_cache_ = base::MakeUnique<SoftwareImageDecodeCache>( - settings_.renderer_settings.preferred_tile_format, + settings_.preferred_tile_format, settings_.decoded_image_working_set_budget_bytes); } @@ -2300,8 +2346,8 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( // resolved. CHECK(resource_provider_); - ContextProvider* compositor_context_provider = - compositor_frame_sink_->context_provider(); + viz::ContextProvider* compositor_context_provider = + layer_tree_frame_sink_->context_provider(); if (!compositor_context_provider) { *resource_pool = ResourcePool::Create(resource_provider_.get(), GetTaskRunner(), @@ -2314,8 +2360,8 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( return; } - ContextProvider* worker_context_provider = - compositor_frame_sink_->worker_context_provider(); + viz::ContextProvider* worker_context_provider = + layer_tree_frame_sink_->worker_context_provider(); if (use_gpu_rasterization_) { DCHECK(worker_context_provider); @@ -2330,7 +2376,7 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( *raster_buffer_provider = base::MakeUnique<GpuRasterBufferProvider>( compositor_context_provider, worker_context_provider, resource_provider_.get(), settings_.use_distance_field_text, - msaa_sample_count, settings_.renderer_settings.preferred_tile_format, + msaa_sample_count, settings_.preferred_tile_format, settings_.async_worker_context_enabled); return; } @@ -2352,8 +2398,7 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( settings_.disallow_non_exact_resource_reuse); *raster_buffer_provider = ZeroCopyRasterBufferProvider::Create( - resource_provider_.get(), - settings_.renderer_settings.preferred_tile_format); + resource_provider_.get(), settings_.preferred_tile_format); return; } @@ -2371,8 +2416,7 @@ void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider( GetTaskRunner(), compositor_context_provider, worker_context_provider, resource_provider_.get(), max_copy_texture_chromium_size, settings_.use_partial_raster, settings_.max_staging_buffer_usage_in_bytes, - settings_.renderer_settings.preferred_tile_format, - settings_.async_worker_context_enabled); + settings_.preferred_tile_format, settings_.async_worker_context_enabled); } void LayerTreeHostImpl::SetLayerTreeMutator( @@ -2390,11 +2434,12 @@ LayerImpl* LayerTreeHostImpl::ViewportMainScrollLayer() { } void LayerTreeHostImpl::QueueImageDecode( - sk_sp<const SkImage> image, + const PaintImage& image, const base::Callback<void(bool)>& embedder_callback) { decoded_image_tracker_.QueueImageDecode( - std::move(image), base::Bind(&LayerTreeHostImpl::ImageDecodeFinished, - base::Unretained(this), embedder_callback)); + image, base::Bind(&LayerTreeHostImpl::ImageDecodeFinished, + base::Unretained(this), embedder_callback)); + tile_manager_.checker_image_tracker().DisallowCheckeringForImage(image); } void LayerTreeHostImpl::ImageDecodeFinished( @@ -2402,7 +2447,7 @@ void LayerTreeHostImpl::ImageDecodeFinished( bool decode_succeeded) { completed_image_decode_callbacks_.emplace_back( base::Bind(embedder_callback, decode_succeeded)); - client_->SetNeedsCommitOnImplThread(); + client_->NotifyImageDecodeRequestFinished(); } std::vector<base::Closure> @@ -2438,26 +2483,26 @@ void LayerTreeHostImpl::CleanUpTileManagerAndUIResources() { // We've potentially just freed a large number of resources on our various // contexts. Flushing now helps ensure these are cleaned up quickly // preventing driver cache growth. See crbug.com/643251 - if (compositor_frame_sink_) { - if (auto* compositor_context = compositor_frame_sink_->context_provider()) + if (layer_tree_frame_sink_) { + if (auto* compositor_context = layer_tree_frame_sink_->context_provider()) compositor_context->ContextGL()->ShallowFlushCHROMIUM(); if (auto* worker_context = - compositor_frame_sink_->worker_context_provider()) { - ContextProvider::ScopedContextLock hold(worker_context); + layer_tree_frame_sink_->worker_context_provider()) { + viz::ContextProvider::ScopedContextLock hold(worker_context); worker_context->ContextGL()->ShallowFlushCHROMIUM(); } } } -void LayerTreeHostImpl::ReleaseCompositorFrameSink() { - TRACE_EVENT0("cc", "LayerTreeHostImpl::ReleaseCompositorFrameSink"); +void LayerTreeHostImpl::ReleaseLayerTreeFrameSink() { + TRACE_EVENT0("cc", "LayerTreeHostImpl::ReleaseLayerTreeFrameSink"); - if (!compositor_frame_sink_) { - DCHECK(!has_valid_compositor_frame_sink_); + if (!layer_tree_frame_sink_) { + DCHECK(!has_valid_layer_tree_frame_sink_); return; } - has_valid_compositor_frame_sink_ = false; + has_valid_layer_tree_frame_sink_ = false; // Since we will create a new resource provider, we cannot continue to use // the old resources (i.e. render_surfaces and texture IDs). Clear them @@ -2468,27 +2513,27 @@ void LayerTreeHostImpl::ReleaseCompositorFrameSink() { CleanUpTileManagerAndUIResources(); resource_provider_ = nullptr; - // Release any context visibility before we destroy the CompositorFrameSink. + // Release any context visibility before we destroy the LayerTreeFrameSink. SetContextVisibility(false); - // Detach from the old CompositorFrameSink and reset |compositor_frame_sink_| + // Detach from the old LayerTreeFrameSink and reset |layer_tree_frame_sink_| // pointer as this surface is going to be destroyed independent of if binding - // the new CompositorFrameSink succeeds or not. - compositor_frame_sink_->DetachFromClient(); - compositor_frame_sink_ = nullptr; + // the new LayerTreeFrameSink succeeds or not. + layer_tree_frame_sink_->DetachFromClient(); + layer_tree_frame_sink_ = nullptr; - // We don't know if the next CompositorFrameSink will support GPU + // We don't know if the next LayerTreeFrameSink will support GPU // rasterization. Make sure to clear the flag so that we force a // re-computation. use_gpu_rasterization_ = false; } bool LayerTreeHostImpl::InitializeRenderer( - CompositorFrameSink* compositor_frame_sink) { + LayerTreeFrameSink* layer_tree_frame_sink) { TRACE_EVENT0("cc", "LayerTreeHostImpl::InitializeRenderer"); - ReleaseCompositorFrameSink(); - if (!compositor_frame_sink->BindToClient(this)) { + ReleaseLayerTreeFrameSink(); + if (!layer_tree_frame_sink->BindToClient(this)) { // Avoid recreating tree resources because we might not have enough // information to do this yet (eg. we don't have a TileManager at this // point). @@ -2498,28 +2543,26 @@ bool LayerTreeHostImpl::InitializeRenderer( // When using software compositing, change to the limits specified for it. // Since this is a one way trip, we don't need to worry about going back to // GPU compositing. - if (!compositor_frame_sink->context_provider()) + if (!layer_tree_frame_sink->context_provider()) SetMemoryPolicy(settings_.software_memory_policy); - compositor_frame_sink_ = compositor_frame_sink; - has_valid_compositor_frame_sink_ = true; + layer_tree_frame_sink_ = layer_tree_frame_sink; + has_valid_layer_tree_frame_sink_ = true; resource_provider_ = base::MakeUnique<ResourceProvider>( - compositor_frame_sink_->context_provider(), - compositor_frame_sink_->shared_bitmap_manager(), - compositor_frame_sink_->gpu_memory_buffer_manager(), + layer_tree_frame_sink_->context_provider(), + layer_tree_frame_sink_->shared_bitmap_manager(), + layer_tree_frame_sink_->gpu_memory_buffer_manager(), task_runner_provider_->blocking_main_thread_task_runner(), - settings_.renderer_settings.texture_id_allocation_chunk_size, - compositor_frame_sink_->capabilities().delegated_sync_points_required, - settings_.renderer_settings.use_gpu_memory_buffer_resources, + layer_tree_frame_sink_->capabilities().delegated_sync_points_required, settings_.enable_color_correct_rasterization, - settings_.renderer_settings.buffer_to_texture_target_map); + settings_.resource_settings); // Since the new context may be capable of MSAA, update status here. We don't // need to check the return value since we are recreating all resources // already. UpdateGpuRasterizationStatus(); - // See note in LayerTreeImpl::UpdateDrawProperties, new CompositorFrameSink + // See note in LayerTreeImpl::UpdateDrawProperties, new LayerTreeFrameSink // means a new max texture size which affects draw properties. Also, if the // draw properties were up to date, layers still lost resources and we need to // UpdateDrawProperties() after calling RecreateTreeResources(). @@ -2772,6 +2815,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( MainThreadScrollingReason::kNotScrollingOnMain; if (!scrolling_node) { scroll_status.thread = SCROLL_IGNORED; + if (settings_.is_layer_tree_for_subframe) + scroll_status.thread = SCROLL_UNKNOWN; scroll_status.main_thread_scrolling_reasons = MainThreadScrollingReason::kNoScrollingLayer; return scroll_status; @@ -2790,6 +2835,15 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( // scroll customization callbacks are invoked. DistributeScrollDelta(scroll_state); + // If the CurrentlyScrollingNode doesn't exist after distributing scroll + // delta, no scroller can scroll in the given delta hint direction(s). + if (!active_tree_->CurrentlyScrollingNode()) { + scroll_status.thread = InputHandler::SCROLL_IGNORED; + scroll_status.main_thread_scrolling_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; + return scroll_status; + } + client_->RenewTreePriority(); RecordCompositorSlowScrollMetric(type, CC_THREAD); @@ -2849,16 +2903,18 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( (settings_.is_layer_tree_for_subframe || (!scrolling_node->scrolls_outer_viewport && !scrolling_node->scrolls_inner_viewport))) { + const auto& container_bounds = scrolling_node->container_bounds; + int size = container_bounds.GetCheckedArea().ValueOrDefault( + std::numeric_limits<int>::max()); + DCHECK_GT(size, 0); if (IsWheelBasedScroll(type)) { - UMA_HISTOGRAM_CUSTOM_COUNTS( - "Event.Scroll.ScrollerSize.OnScroll_Wheel", - scrolling_node->scroll_clip_layer_bounds.GetArea(), 1, - kScrollerSizeLargestBucket, kScrollerSizeBucketCount); + UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Scroll.ScrollerSize.OnScroll_Wheel", + size, 1, kScrollerSizeLargestBucket, + kScrollerSizeBucketCount); } else { - UMA_HISTOGRAM_CUSTOM_COUNTS( - "Event.Scroll.ScrollerSize.OnScroll_Touch", - scrolling_node->scroll_clip_layer_bounds.GetArea(), 1, - kScrollerSizeLargestBucket, kScrollerSizeBucketCount); + UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Scroll.ScrollerSize.OnScroll_Touch", + size, 1, kScrollerSizeLargestBucket, + kScrollerSizeBucketCount); } } } @@ -2916,7 +2972,7 @@ bool LayerTreeHostImpl::IsInitialScrollHitTestReliable( } InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( - const gfx::Point& viewport_point) { + ScrollState* scroll_state) { InputHandler::ScrollStatus scroll_status; scroll_status.main_thread_scrolling_reasons = MainThreadScrollingReason::kNotScrollingOnMain; @@ -2934,16 +2990,12 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin( } return scroll_status; } - ScrollStateData scroll_state_data; - scroll_state_data.position_x = viewport_point.x(); - scroll_state_data.position_y = viewport_point.y(); - ScrollState scroll_state(scroll_state_data); // ScrollAnimated is used for animated wheel scrolls. We find the first layer // that can scroll and set up an animation of its scroll offset. Note that // this does not currently go through the scroll customization machinery // that ScrollBy uses for non-animated wheel scrolls. - scroll_status = ScrollBegin(&scroll_state, WHEEL); + scroll_status = ScrollBegin(scroll_state, WHEEL); if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { scroll_animating_latched_node_id_ = ScrollTree::kInvalidNodeId; ScrollStateData scroll_state_end_data; @@ -2968,7 +3020,7 @@ gfx::Vector2dF LayerTreeHostImpl::ComputeScrollDelta( adjusted_scroll.set_y(0); gfx::ScrollOffset old_offset = - scroll_tree.current_scroll_offset(scroll_node->owning_layer_id); + scroll_tree.current_scroll_offset(scroll_node->element_id); gfx::ScrollOffset new_offset = scroll_tree.ClampScrollOffsetToLimits( old_offset + gfx::ScrollOffset(adjusted_scroll), scroll_node); @@ -2992,13 +3044,9 @@ bool LayerTreeHostImpl::ScrollAnimationCreate(ScrollNode* scroll_node, scroll_tree.set_currently_scrolling_node(scroll_node->id); gfx::ScrollOffset current_offset = - scroll_tree.current_scroll_offset(scroll_node->owning_layer_id); + scroll_tree.current_scroll_offset(scroll_node->element_id); gfx::ScrollOffset target_offset = scroll_tree.ClampScrollOffsetToLimits( current_offset + gfx::ScrollOffset(delta), scroll_node); - DCHECK_EQ( - ElementId( - 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 @@ -3014,6 +3062,22 @@ bool LayerTreeHostImpl::ScrollAnimationCreate(ScrollNode* scroll_node, return true; } +static bool CanPropagate(ScrollNode* scroll_node, float x, float y) { + // ScrollBoundaryBehavior may have different values on x-axis and y-axis. + // We need to find out the dominant axis of user's intended scroll to decide + // which node's ScrollBoundaryBehavior should be applied, i.e. which the + // scroll should be propagated from this node given its relevant* + // ScrollBoundaryBehavior value. * relevant here depends on the dominant + // axis of scroll gesture. + bool x_dominant = std::abs(x) > std::abs(y); + return (x_dominant && + scroll_node->scroll_boundary_behavior.x == + ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeAuto) || + (!x_dominant && + scroll_node->scroll_boundary_behavior.y == + ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeAuto); +} + InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( const gfx::Point& viewport_point, const gfx::Vector2dF& scroll_delta, @@ -3102,6 +3166,9 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( } pending_delta -= scroll_delta; + + if (!CanPropagate(scroll_node, pending_delta.x(), pending_delta.y())) + break; } } scroll_state.set_is_ending(true); @@ -3117,15 +3184,17 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( return scroll_status; } -gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta( - ScrollNode* scroll_node, +bool LayerTreeHostImpl::CalculateLocalScrollDeltaAndStartPoint( + const ScrollNode& scroll_node, const gfx::PointF& viewport_point, const gfx::Vector2dF& viewport_delta, - ScrollTree* scroll_tree) { + const ScrollTree& scroll_tree, + gfx::Vector2dF* out_local_scroll_delta, + gfx::PointF* out_local_start_point /*= nullptr*/) { // Layers with non-invertible screen space transforms should not have passed // the scroll hit test in the first place. const gfx::Transform screen_space_transform = - scroll_tree->ScreenSpaceTransform(scroll_node->id); + scroll_tree.ScreenSpaceTransform(scroll_node.id); DCHECK(screen_space_transform.IsInvertible()); gfx::Transform inverse_screen_space_transform( gfx::Transform::kSkipInitialization); @@ -3143,28 +3212,45 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta( gfx::Vector2dF screen_space_delta = viewport_delta; screen_space_delta.Scale(scale_from_viewport_to_screen_space); - // First project the scroll start and end points to local layer space to find - // the scroll delta in layer coordinates. + // Project the scroll start and end points to local layer space to find the + // scroll delta in layer coordinates. bool start_clipped, end_clipped; gfx::PointF screen_space_end_point = screen_space_point + screen_space_delta; gfx::PointF local_start_point = MathUtil::ProjectPoint( inverse_screen_space_transform, screen_space_point, &start_clipped); gfx::PointF local_end_point = MathUtil::ProjectPoint( inverse_screen_space_transform, screen_space_end_point, &end_clipped); + DCHECK(out_local_scroll_delta); + *out_local_scroll_delta = local_end_point - local_start_point; + + if (out_local_start_point) + *out_local_start_point = local_start_point; - // In general scroll point coordinates should not get clipped. - DCHECK(!start_clipped); - DCHECK(!end_clipped); if (start_clipped || end_clipped) + return false; + + return true; +} + +gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta( + ScrollNode* scroll_node, + const gfx::PointF& viewport_point, + const gfx::Vector2dF& viewport_delta, + ScrollTree* scroll_tree) { + gfx::PointF local_start_point; + gfx::Vector2dF local_scroll_delta; + if (!CalculateLocalScrollDeltaAndStartPoint( + *scroll_node, viewport_point, viewport_delta, *scroll_tree, + &local_scroll_delta, &local_start_point)) { return gfx::Vector2dF(); + } // Apply the scroll delta. gfx::ScrollOffset previous_offset = - scroll_tree->current_scroll_offset(scroll_node->owning_layer_id); - scroll_tree->ScrollBy(scroll_node, local_end_point - local_start_point, - active_tree()); + scroll_tree->current_scroll_offset(scroll_node->element_id); + scroll_tree->ScrollBy(scroll_node, local_scroll_delta, active_tree()); gfx::ScrollOffset scrolled = - scroll_tree->current_scroll_offset(scroll_node->owning_layer_id) - + scroll_tree->current_scroll_offset(scroll_node->element_id) - previous_offset; // Get the end point in the layer's content space so we can apply its @@ -3173,11 +3259,17 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta( local_start_point + gfx::Vector2dF(scrolled.x(), scrolled.y()); // Calculate the applied scroll delta in viewport space coordinates. + bool end_clipped; + const gfx::Transform screen_space_transform = + scroll_tree->ScreenSpaceTransform(scroll_node->id); gfx::PointF actual_screen_space_end_point = MathUtil::MapPoint( screen_space_transform, actual_local_end_point, &end_clipped); DCHECK(!end_clipped); if (end_clipped) return gfx::Vector2dF(); + + float scale_from_viewport_to_screen_space = + active_tree_->device_scale_factor(); gfx::PointF actual_viewport_end_point = gfx::ScalePoint( actual_screen_space_end_point, 1.f / scale_from_viewport_to_screen_space); return actual_viewport_end_point - viewport_point; @@ -3190,12 +3282,12 @@ static gfx::Vector2dF ScrollNodeWithLocalDelta( LayerTreeImpl* layer_tree_impl) { ScrollTree& scroll_tree = layer_tree_impl->property_trees()->scroll_tree; gfx::ScrollOffset previous_offset = - scroll_tree.current_scroll_offset(scroll_node->owning_layer_id); + scroll_tree.current_scroll_offset(scroll_node->element_id); gfx::Vector2dF delta = local_delta; delta.Scale(1.f / page_scale_factor); scroll_tree.ScrollBy(scroll_node, delta, layer_tree_impl); gfx::ScrollOffset scrolled = - scroll_tree.current_scroll_offset(scroll_node->owning_layer_id) - + scroll_tree.current_scroll_offset(scroll_node->element_id) - previous_offset; gfx::Vector2dF consumed_scroll(scrolled.x(), scrolled.y()); consumed_scroll.Scale(page_scale_factor); @@ -3308,7 +3400,10 @@ void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) { std::list<ScrollNode*> current_scroll_chain; ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); - ScrollNode* viewport_scroll_node = OuterViewportScrollNode(); + ScrollNode* viewport_scroll_node = + viewport()->MainScrollLayer() + ? scroll_tree.Node(viewport()->MainScrollLayer()->scroll_tree_index()) + : nullptr; if (scroll_node) { // TODO(bokan): The loop checks for a null parent but don't we still want to // distribute to the root scroll node? @@ -3326,14 +3421,60 @@ void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) { if (!scroll_node->scrollable) continue; - current_scroll_chain.push_front(scroll_node); + if (CanConsumeDelta(scroll_node, *scroll_state)) + current_scroll_chain.push_front(scroll_node); + + float delta_x = scroll_state->is_beginning() + ? scroll_state->delta_x_hint() + : scroll_state->delta_x(); + float delta_y = scroll_state->is_beginning() + ? scroll_state->delta_y_hint() + : scroll_state->delta_y(); + + if (!CanPropagate(scroll_node, delta_x, delta_y)) + break; } } + active_tree_->SetCurrentlyScrollingNode( + current_scroll_chain.empty() ? nullptr : current_scroll_chain.back()); scroll_state->set_scroll_chain_and_layer_tree(current_scroll_chain, active_tree()); scroll_state->DistributeToScrollChainDescendant(); } +bool LayerTreeHostImpl::CanConsumeDelta(ScrollNode* scroll_node, + const ScrollState& scroll_state) { + DCHECK(scroll_node); + gfx::Vector2dF delta_to_scroll; + if (scroll_state.is_beginning()) { + delta_to_scroll = gfx::Vector2dF(scroll_state.delta_x_hint(), + scroll_state.delta_y_hint()); + } else { + delta_to_scroll = + gfx::Vector2dF(scroll_state.delta_x(), scroll_state.delta_y()); + } + + if (delta_to_scroll == gfx::Vector2dF()) + return true; + + ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; + if (scroll_state.is_direct_manipulation()) { + gfx::Vector2dF local_scroll_delta; + if (!CalculateLocalScrollDeltaAndStartPoint( + *scroll_node, + gfx::PointF(scroll_state.position_x(), scroll_state.position_y()), + delta_to_scroll, scroll_tree, &local_scroll_delta)) { + return false; + } + delta_to_scroll = local_scroll_delta; + } + + if (ComputeScrollDelta(scroll_node, delta_to_scroll) != gfx::Vector2dF()) + return true; + + return false; +} + InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( ScrollState* scroll_state) { DCHECK(scroll_state); @@ -3393,10 +3534,10 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( scroll_state->delta_y()); // When inner viewport is unscrollable, disable overscrolls. - if (InnerViewportScrollLayer()) { - if (!InnerViewportScrollLayer()->user_scrollable_horizontal()) + if (const auto* inner_viewport_scroll_node = InnerViewportScrollNode()) { + if (!inner_viewport_scroll_node->user_scrollable_horizontal) unused_root_delta.set_x(0); - if (!InnerViewportScrollLayer()->user_scrollable_vertical()) + if (!inner_viewport_scroll_node->user_scrollable_vertical) unused_root_delta.set_y(0); } @@ -3604,13 +3745,13 @@ static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, if (tree_impl->LayerListIsEmpty()) return; - int inner_viewport_layer_id = + ElementId inner_viewport_scroll_element_id = tree_impl->InnerViewportScrollLayer() - ? tree_impl->InnerViewportScrollLayer()->id() - : Layer::INVALID_ID; + ? tree_impl->InnerViewportScrollLayer()->element_id() + : ElementId(); tree_impl->property_trees()->scroll_tree.CollectScrollDeltas( - scroll_info, inner_viewport_layer_id); + scroll_info, inner_viewport_scroll_element_id); } static void CollectScrollbarUpdates( @@ -3931,20 +4072,20 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid, if (id) DeleteUIResource(uid); - if (!has_valid_compositor_frame_sink_) { + if (!has_valid_layer_tree_frame_sink_) { evicted_ui_resources_.insert(uid); return; } - ResourceFormat format = resource_provider_->best_texture_format(); + viz::ResourceFormat format = resource_provider_->best_texture_format(); switch (bitmap.GetFormat()) { case UIResourceBitmap::RGBA8: break; case UIResourceBitmap::ALPHA_8: - format = ALPHA_8; + format = viz::ALPHA_8; break; case UIResourceBitmap::ETC1: - format = ETC1; + format = viz::ETC1; break; } @@ -4017,7 +4158,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid, void LayerTreeHostImpl::DeleteUIResource(UIResourceId uid) { ResourceId id = ResourceIdForUIResource(uid); if (id) { - if (has_valid_compositor_frame_sink_) + if (has_valid_layer_tree_frame_sink_) resource_provider_->DeleteResource(id); ui_resource_map_.erase(uid); } @@ -4109,11 +4250,6 @@ bool LayerTreeHostImpl::ScrollAnimationUpdateTarget( ScrollNode* scroll_node, const gfx::Vector2dF& scroll_delta, base::TimeDelta delayed_by) { - DCHECK_EQ( - ElementId( - active_tree()->LayerById(scroll_node->owning_layer_id)->element_id()), - scroll_node->element_id); - return mutator_host_->ImplOnlyScrollAnimationUpdateTarget( scroll_node->element_id, scroll_delta, active_tree_->property_trees()->scroll_tree.MaxScrollOffset( @@ -4148,14 +4284,13 @@ void LayerTreeHostImpl::SetTreeLayerScrollOffsetMutated( if (!tree) return; - const int layer_id = tree->LayerIdByElementId(element_id); PropertyTrees* property_trees = tree->property_trees(); DCHECK_EQ(1u, property_trees->element_id_to_scroll_node_index.count(element_id)); const int scroll_node_index = property_trees->element_id_to_scroll_node_index[element_id]; property_trees->scroll_tree.OnScrollOffsetAnimated( - layer_id, scroll_node_index, scroll_offset, tree); + element_id, scroll_node_index, scroll_offset, tree); // Run mutation callbacks to respond to updated scroll offset. Mutate(CurrentBeginFrameArgs().frame_time); } @@ -4228,69 +4363,13 @@ void LayerTreeHostImpl::ElementIsAnimatingChanged( ElementListType list_type, const PropertyAnimationState& mask, const PropertyAnimationState& state) { - // TODO(weiliangc): Most of the code is duplicated with LayerTeeHost version - // of function. Should try to share code. LayerTreeImpl* tree = list_type == ElementListType::ACTIVE ? active_tree() : pending_tree(); - if (!tree) - return; - PropertyTrees* property_trees = tree->property_trees(); - - for (int property = TargetProperty::FIRST_TARGET_PROPERTY; - property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) { - if (!mask.currently_running[property] && - !mask.potentially_animating[property]) - continue; - - switch (property) { - case TargetProperty::TRANSFORM: - if (TransformNode* transform_node = - property_trees->transform_tree.FindNodeFromElementId( - element_id)) { - if (mask.currently_running[property]) - transform_node->is_currently_animating = - state.currently_running[property]; - if (mask.potentially_animating[property]) { - transform_node->has_potential_animation = - state.potentially_animating[property]; - transform_node->has_only_translation_animations = - mutator_host()->HasOnlyTranslationTransforms(element_id, - list_type); - property_trees->transform_tree.set_needs_update(true); - tree->set_needs_update_draw_properties(); - } - } - break; - case TargetProperty::OPACITY: - if (EffectNode* effect_node = - property_trees->effect_tree.FindNodeFromElementId(element_id)) { - if (mask.currently_running[property]) - effect_node->is_currently_animating_opacity = - state.currently_running[property]; - if (mask.potentially_animating[property]) { - effect_node->has_potential_opacity_animation = - state.potentially_animating[property]; - property_trees->effect_tree.set_needs_update(true); - } - } - break; - case TargetProperty::FILTER: - if (EffectNode* effect_node = - property_trees->effect_tree.FindNodeFromElementId(element_id)) { - if (mask.currently_running[property]) - effect_node->is_currently_animating_filter = - state.currently_running[property]; - if (mask.potentially_animating[property]) - effect_node->has_potential_filter_animation = - state.potentially_animating[property]; - // Filter animation changes only the node, and the subtree does not - // care. There is no need to request update on property trees here. - } - break; - default: - break; - } - } + // TODO(wkorman): Explore enabling DCHECK in ElementIsAnimatingChanged() + // below. Currently enabling causes batch of unit test failures. + if (tree && tree->property_trees()->ElementIsAnimatingChanged( + mutator_host(), element_id, list_type, mask, state, false)) + tree->set_needs_update_draw_properties(); } void LayerTreeHostImpl::ScrollOffsetAnimationFinished() { @@ -4323,13 +4402,13 @@ bool LayerTreeHostImpl::CommitToActiveTree() const { } void LayerTreeHostImpl::SetContextVisibility(bool is_visible) { - if (!compositor_frame_sink_) + if (!layer_tree_frame_sink_) return; // Update the compositor context. If we are already in the correct visibility // state, skip. This can happen if we transition invisible/visible rapidly, // before we get a chance to go invisible in NotifyAllTileTasksComplete. - auto* compositor_context = compositor_frame_sink_->context_provider(); + auto* compositor_context = layer_tree_frame_sink_->context_provider(); if (compositor_context && is_visible != !!compositor_context_visibility_) { if (is_visible) { compositor_context_visibility_ = @@ -4343,9 +4422,9 @@ void LayerTreeHostImpl::SetContextVisibility(bool is_visible) { // Update the worker context. If we are already in the correct visibility // state, skip. This can happen if we transition invisible/visible rapidly, // before we get a chance to go invisible in NotifyAllTileTasksComplete. - auto* worker_context = compositor_frame_sink_->worker_context_provider(); + auto* worker_context = layer_tree_frame_sink_->worker_context_provider(); if (worker_context && is_visible != !!worker_context_visibility_) { - ContextProvider::ScopedContextLock hold(worker_context); + viz::ContextProvider::ScopedContextLock hold(worker_context); if (is_visible) { worker_context_visibility_ = worker_context->CacheController()->ClientBecameVisible(); diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index b8553cb323b..c1a39201c7e 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -26,8 +26,7 @@ #include "cc/input/scrollbar_animation_controller.h" #include "cc/layers/layer_collections.h" #include "cc/output/begin_frame_args.h" -#include "cc/output/compositor_frame_sink_client.h" -#include "cc/output/context_cache_controller.h" +#include "cc/output/layer_tree_frame_sink_client.h" #include "cc/output/managed_memory_policy.h" #include "cc/quads/render_pass.h" #include "cc/resources/resource_provider.h" @@ -36,8 +35,6 @@ #include "cc/scheduler/commit_earlyout_reason.h" #include "cc/scheduler/draw_result.h" #include "cc/scheduler/video_frame_controller.h" -#include "cc/surfaces/local_surface_id.h" -#include "cc/surfaces/surface_id.h" #include "cc/tiles/decoded_image_tracker.h" #include "cc/tiles/image_decode_cache.h" #include "cc/tiles/tile_manager.h" @@ -45,6 +42,9 @@ #include "cc/trees/layer_tree_settings.h" #include "cc/trees/mutator_host_client.h" #include "cc/trees/task_runner_provider.h" +#include "components/viz/common/gpu/context_cache_controller.h" +#include "components/viz/common/surfaces/local_surface_id.h" +#include "components/viz/common/surfaces/surface_id.h" #include "ui/gfx/geometry/rect.h" namespace gfx { @@ -55,7 +55,7 @@ namespace cc { class BrowserControlsOffsetManager; class CompositorFrameMetadata; -class CompositorFrameSink; +class LayerTreeFrameSink; class DebugRectHistory; class EvictionTilePriorityQueue; class FrameRateCounter; @@ -66,6 +66,7 @@ class MutatorEvents; class MutatorHost; class PageScaleAnimation; class PendingTreeDurationHistogramTimer; +class PendingTreeRasterDurationHistogramTimer; class RasterTilePriorityQueue; class RasterBufferProvider; class RenderingStatsInstrumentation; @@ -97,7 +98,7 @@ enum class ImplThreadPhase { // LayerTreeHost->Proxy callback interface. class LayerTreeHostImplClient { public: - virtual void DidLoseCompositorFrameSinkOnImplThread() = 0; + virtual void DidLoseLayerTreeFrameSinkOnImplThread() = 0; virtual void SetBeginFrameSource(BeginFrameSource* source) = 0; virtual void DidReceiveCompositorFrameAckOnImplThread() = 0; virtual void OnCanDrawStateChanged(bool can_draw) = 0; @@ -124,10 +125,13 @@ class LayerTreeHostImplClient { virtual void DidCompletePageScaleAnimationOnImplThread() = 0; // Called when output surface asks for a draw. - virtual void OnDrawForCompositorFrameSink( - bool resourceless_software_draw) = 0; + virtual void OnDrawForLayerTreeFrameSink(bool resourceless_software_draw) = 0; virtual void NeedsImplSideInvalidation() = 0; + // Called when a requested image decode completes. + virtual void NotifyImageDecodeRequestFinished() = 0; + + virtual void RequestBeginMainFrameNotExpected(bool new_state) = 0; protected: virtual ~LayerTreeHostImplClient() {} @@ -138,7 +142,7 @@ class LayerTreeHostImplClient { class CC_EXPORT LayerTreeHostImpl : public InputHandler, public TileManagerClient, - public CompositorFrameSinkClient, + public LayerTreeFrameSinkClient, public BrowserControlsOffsetManagerClient, public ScrollbarAnimationControllerClient, public VideoFrameControllerClient, @@ -166,7 +170,7 @@ class CC_EXPORT LayerTreeHostImpl InputHandler::ScrollStatus RootScrollBegin( ScrollState* scroll_state, InputHandler::ScrollInputType type) override; - ScrollStatus ScrollAnimatedBegin(const gfx::Point& viewport_point) override; + ScrollStatus ScrollAnimatedBegin(ScrollState* scroll_state) override; InputHandler::ScrollStatus ScrollAnimated( const gfx::Point& viewport_point, const gfx::Vector2dF& scroll_delta, @@ -199,8 +203,10 @@ class CC_EXPORT LayerTreeHostImpl InputHandler::ScrollInputType type) const override; EventListenerProperties GetEventListenerProperties( EventListenerClass event_class) const override; - InputHandler::TouchStartEventListenerType EventListenerTypeForTouchStartAt( - const gfx::Point& viewport_port) override; + InputHandler::TouchStartOrMoveEventListenerType + EventListenerTypeForTouchStartOrMoveAt( + const gfx::Point& viewport_port, + TouchAction* out_touch_action) override; std::unique_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( ui::LatencyInfo* latency) override; ScrollElasticityHelper* CreateScrollElasticityHelper() override; @@ -228,7 +234,7 @@ class CC_EXPORT LayerTreeHostImpl ~FrameData(); void AsValueInto(base::trace_event::TracedValue* value) const; - std::vector<SurfaceId> activation_dependencies; + std::vector<viz::SurfaceId> activation_dependencies; std::vector<gfx::Rect> occluding_screen_space_rects; std::vector<gfx::Rect> non_occluding_screen_space_rects; RenderPassList render_passes; @@ -361,14 +367,15 @@ class CC_EXPORT LayerTreeHostImpl void AddVideoFrameController(VideoFrameController* controller) override; void RemoveVideoFrameController(VideoFrameController* controller) override; - // CompositorFrameSinkClient implementation. + // LayerTreeFrameSinkClient implementation. void SetBeginFrameSource(BeginFrameSource* source) override; void SetExternalTilePriorityConstraints( const gfx::Rect& viewport_rect, const gfx::Transform& transform) override; - void DidLoseCompositorFrameSink() override; + void DidLoseLayerTreeFrameSink() override; void DidReceiveCompositorFrameAck() override; - void ReclaimResources(const ReturnedResourceArray& resources) override; + void ReclaimResources( + const std::vector<ReturnedResource>& resources) override; void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override; void SetTreeActivationCallback(const base::Closure& callback) override; void OnDraw(const gfx::Transform& transform, @@ -384,21 +391,22 @@ class CC_EXPORT LayerTreeHostImpl // Implementation. int id() const { return id_; } bool CanDraw() const; - CompositorFrameSink* compositor_frame_sink() const { - return compositor_frame_sink_; + LayerTreeFrameSink* layer_tree_frame_sink() const { + return layer_tree_frame_sink_; } - void ReleaseCompositorFrameSink(); + void ReleaseLayerTreeFrameSink(); std::string LayerTreeAsJson() const; int RequestedMSAASampleCount() const; // TODO(danakj): Rename this, there is no renderer. - virtual bool InitializeRenderer(CompositorFrameSink* compositor_frame_sink); + virtual bool InitializeRenderer(LayerTreeFrameSink* layer_tree_frame_sink); TileManager* tile_manager() { return &tile_manager_; } void SetHasGpuRasterizationTrigger(bool flag); - void SetContentIsSuitableForGpuRasterization(bool flag); + void SetContentHasSlowPaths(bool flag); + void SetContentHasNonAAPaint(bool flag); bool CanUseGpuRasterization(); bool use_gpu_rasterization() const { return use_gpu_rasterization_; } bool use_msaa() const { return use_msaa_; } @@ -434,7 +442,10 @@ class CC_EXPORT LayerTreeHostImpl virtual void ActivateSyncTree(); // Shortcuts to layers/nodes on the active tree. + LayerImpl* InnerViewportContainerLayer() const; LayerImpl* InnerViewportScrollLayer() const; + ScrollNode* InnerViewportScrollNode() const; + LayerImpl* OuterViewportContainerLayer() const; LayerImpl* OuterViewportScrollLayer() const; ScrollNode* OuterViewportScrollNode() const; ScrollNode* CurrentlyScrollingNode(); @@ -465,11 +476,6 @@ class CC_EXPORT LayerTreeHostImpl std::unique_ptr<BeginFrameCallbackList> ProcessLayerTreeMutations(); std::unique_ptr<ScrollAndScaleSet> ProcessScrollDeltas(); - - void set_max_memory_needed_bytes(size_t bytes) { - max_memory_needed_bytes_ = bytes; - } - FrameRateCounter* fps_counter() { return fps_counter_.get(); } MemoryHistory* memory_history() { return memory_history_.get(); } DebugRectHistory* debug_rect_history() { return debug_rect_history_.get(); } @@ -600,7 +606,7 @@ class CC_EXPORT LayerTreeHostImpl LayerImpl* ViewportMainScrollLayer(); - void QueueImageDecode(sk_sp<const SkImage> image, + void QueueImageDecode(const PaintImage& image, const base::Callback<void(bool)>& embedder_callback); std::vector<base::Closure> TakeCompletedImageDecodeCallbacks(); @@ -633,6 +639,16 @@ class CC_EXPORT LayerTreeHostImpl BeginFrameTracker current_begin_frame_tracker_; private: + // Transforms viewport start point and scroll delta to local start point and + // local delta, respectively. If the transformation of either the start or end + // point of a scroll is clipped, the function returns false. + bool CalculateLocalScrollDeltaAndStartPoint( + const ScrollNode& scroll_node, + const gfx::PointF& viewport_point, + const gfx::Vector2dF& viewport_delta, + const ScrollTree& scroll_tree, + gfx::Vector2dF* out_local_scroll_delta, + gfx::PointF* out_local_start_point = nullptr); gfx::Vector2dF ScrollNodeWithViewportSpaceDelta( ScrollNode* scroll_node, const gfx::PointF& viewport_point, @@ -664,6 +680,8 @@ class CC_EXPORT LayerTreeHostImpl InputHandler::ScrollInputType type); bool IsInitialScrollHitTestReliable(LayerImpl* layer, const gfx::PointF&); void DistributeScrollDelta(ScrollState* scroll_state); + bool CanConsumeDelta(ScrollNode* scroll_node, + const ScrollState& scroll_state); bool AnimatePageScale(base::TimeTicks monotonic_time); bool AnimateScrollbars(base::TimeTicks monotonic_time); @@ -726,22 +744,23 @@ class CC_EXPORT LayerTreeHostImpl // request queue. std::set<UIResourceId> evicted_ui_resources_; - CompositorFrameSink* compositor_frame_sink_; + LayerTreeFrameSink* layer_tree_frame_sink_; - LocalSurfaceId local_surface_id_; + viz::LocalSurfaceId local_surface_id_; // The following scoped variables must not outlive the - // |compositor_frame_sink_|. - // These should be transfered to ContextCacheController's + // |layer_tree_frame_sink_|. + // These should be transfered to viz::ContextCacheController's // ClientBecameNotVisible() before the output surface is destroyed. - std::unique_ptr<ContextCacheController::ScopedVisibility> + std::unique_ptr<viz::ContextCacheController::ScopedVisibility> compositor_context_visibility_; - std::unique_ptr<ContextCacheController::ScopedVisibility> + std::unique_ptr<viz::ContextCacheController::ScopedVisibility> worker_context_visibility_; std::unique_ptr<ResourceProvider> resource_provider_; bool need_update_gpu_rasterization_status_; - bool content_is_suitable_for_gpu_rasterization_; + bool content_has_slow_paths_; + bool content_has_non_aa_paint_; bool has_gpu_rasterization_trigger_; bool use_gpu_rasterization_; bool use_msaa_; @@ -812,7 +831,7 @@ class CC_EXPORT LayerTreeHostImpl // overridden. gfx::Size device_viewport_size_; - // Optional top-level constraints that can be set by the CompositorFrameSink. + // Optional top-level constraints that can be set by the LayerTreeFrameSink. // - external_transform_ applies a transform above the root layer // - external_viewport_ is used DrawProperties, tile management and // glViewport/window projection matrix. @@ -851,9 +870,9 @@ class CC_EXPORT LayerTreeHostImpl bool requires_high_res_to_draw_; bool is_likely_to_require_a_draw_; - // TODO(danakj): Delete the compositor frame sink and all resources when + // TODO(danakj): Delete the LayerTreeFrameSink and all resources when // it's lost instead of having this bool. - bool has_valid_compositor_frame_sink_; + bool has_valid_layer_tree_frame_sink_; std::unique_ptr<Viewport> viewport_; @@ -861,6 +880,8 @@ class CC_EXPORT LayerTreeHostImpl std::unique_ptr<PendingTreeDurationHistogramTimer> pending_tree_duration_timer_; + std::unique_ptr<PendingTreeRasterDurationHistogramTimer> + pending_tree_raster_duration_timer_; // The id of the scroll node to which scroll animations must latch. // This gets reset at ScrollAnimatedBegin, and updated the first time that a diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index e8eba4fd251..82dd789b309 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -49,7 +49,7 @@ #include "cc/resources/ui_resource_manager.h" #include "cc/test/animation_test_common.h" #include "cc/test/begin_frame_args_test.h" -#include "cc/test/fake_compositor_frame_sink.h" +#include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_mask_layer_impl.h" #include "cc/test/fake_output_surface.h" @@ -61,7 +61,6 @@ #include "cc/test/layer_test_common.h" #include "cc/test/layer_tree_test.h" #include "cc/test/skia_common.h" -#include "cc/test/test_compositor_frame_sink.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/effect_node.h" @@ -71,6 +70,7 @@ #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" #include "media/base/media.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -95,16 +95,17 @@ using media::VideoFrame; namespace cc { namespace { -SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id, uint32_t local_id) { - return SurfaceId( - frame_sink_id, - LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u))); +viz::SurfaceId MakeSurfaceId(const viz::FrameSinkId& frame_sink_id, + uint32_t local_id) { + return viz::SurfaceId( + frame_sink_id, viz::LocalSurfaceId( + local_id, base::UnguessableToken::Deserialize(0, 1u))); } struct TestFrameData : public LayerTreeHostImpl::FrameData { TestFrameData() { // Set ack to something valid, so DCHECKs don't complain. - begin_frame_ack = BeginFrameAck(0, 1, 1, true); + begin_frame_ack = BeginFrameAck(0, 1, true); } }; @@ -130,22 +131,22 @@ class LayerTreeHostImplTest : public testing::Test, 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 = - DefaultBufferToTextureTargetMapForTesting(); + settings.resource_settings.texture_id_allocation_chunk_size = 1; + settings.resource_settings.buffer_to_texture_target_map = + viz::DefaultBufferToTextureTargetMapForTesting(); return settings; } void SetUp() override { - CreateHostImpl(DefaultSettings(), CreateCompositorFrameSink()); + CreateHostImpl(DefaultSettings(), CreateLayerTreeFrameSink()); } void TearDown() override { if (host_impl_) - host_impl_->ReleaseCompositorFrameSink(); + host_impl_->ReleaseLayerTreeFrameSink(); } - void DidLoseCompositorFrameSinkOnImplThread() override {} + void DidLoseLayerTreeFrameSinkOnImplThread() override {} void SetBeginFrameSource(BeginFrameSource* source) override {} void DidReceiveCompositorFrameAckOnImplThread() override {} void OnCanDrawStateChanged(bool can_draw) override { @@ -180,7 +181,7 @@ class LayerTreeHostImplTest : public testing::Test, void DidCompletePageScaleAnimationOnImplThread() override { did_complete_page_scale_animation_ = true; } - void OnDrawForCompositorFrameSink(bool resourceless_software_draw) override { + void OnDrawForLayerTreeFrameSink(bool resourceless_software_draw) override { std::unique_ptr<TestFrameData> frame(new TestFrameData); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(frame.get())); last_on_draw_render_passes_.clear(); @@ -192,6 +193,8 @@ class LayerTreeHostImplTest : public testing::Test, void NeedsImplSideInvalidation() override { did_request_impl_side_invalidation_ = true; } + void NotifyImageDecodeRequestFinished() override {} + void RequestBeginMainFrameNotExpected(bool new_state) override {} void set_reduce_memory_result(bool reduce_memory_result) { reduce_memory_result_ = reduce_memory_result; @@ -199,9 +202,9 @@ class LayerTreeHostImplTest : public testing::Test, virtual bool CreateHostImpl( const LayerTreeSettings& settings, - std::unique_ptr<CompositorFrameSink> compositor_frame_sink) { + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) { return CreateHostImplWithTaskRunnerProvider( - settings, std::move(compositor_frame_sink), &task_runner_provider_); + settings, std::move(layer_tree_frame_sink), &task_runner_provider_); } AnimationHost* GetImplAnimationHost() const { @@ -210,10 +213,10 @@ class LayerTreeHostImplTest : public testing::Test, virtual bool CreateHostImplWithTaskRunnerProvider( const LayerTreeSettings& settings, - std::unique_ptr<CompositorFrameSink> compositor_frame_sink, + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink, TaskRunnerProvider* task_runner_provider) { if (host_impl_) - host_impl_->ReleaseCompositorFrameSink(); + host_impl_->ReleaseLayerTreeFrameSink(); host_impl_.reset(); InitializeImageWorker(settings); host_impl_ = LayerTreeHostImpl::Create( @@ -221,9 +224,9 @@ class LayerTreeHostImplTest : public testing::Test, &task_graph_runner_, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, image_worker_ ? image_worker_->task_runner() : nullptr); - compositor_frame_sink_ = std::move(compositor_frame_sink); + layer_tree_frame_sink_ = std::move(layer_tree_frame_sink); host_impl_->SetVisible(true); - bool init = host_impl_->InitializeRenderer(compositor_frame_sink_.get()); + bool init = host_impl_->InitializeRenderer(layer_tree_frame_sink_.get()); host_impl_->SetViewportSize(gfx::Size(10, 10)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); // Set the BeginFrameArgs so that methods which use it are able to. @@ -249,10 +252,10 @@ class LayerTreeHostImplTest : public testing::Test, } static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) { - gfx::ScrollOffset delta = - layer_impl->layer_tree_impl() - ->property_trees() - ->scroll_tree.GetScrollOffsetDeltaForTesting(layer_impl->id()); + gfx::ScrollOffset delta = layer_impl->layer_tree_impl() + ->property_trees() + ->scroll_tree.GetScrollOffsetDeltaForTesting( + layer_impl->element_id()); return gfx::Vector2dF(delta.x(), delta.y()); } @@ -263,12 +266,12 @@ class LayerTreeHostImplTest : public testing::Test, static ::testing::AssertionResult ScrollInfoContains( const ScrollAndScaleSet& scroll_info, - int id, + ElementId id, const gfx::Vector2d& scroll_delta) { int times_encountered = 0; for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) { - if (scroll_info.scrolls[i].layer_id != id) + if (scroll_info.scrolls[i].element_id != id) continue; if (scroll_delta != scroll_info.scrolls[i].scroll_delta) { @@ -279,7 +282,7 @@ class LayerTreeHostImplTest : public testing::Test, times_encountered++; } - if (id == scroll_info.inner_viewport_scroll.layer_id) { + if (id == scroll_info.inner_viewport_scroll.element_id) { if (scroll_delta != scroll_info.inner_viewport_scroll.scroll_delta) { return ::testing::AssertionFailure() << "Expected " << scroll_delta.ToString() << ", not " @@ -289,15 +292,15 @@ class LayerTreeHostImplTest : public testing::Test, } if (times_encountered != 1) - return ::testing::AssertionFailure() << "No layer found with id " << id; + return ::testing::AssertionFailure() << "No scroll found with id " << id; return ::testing::AssertionSuccess(); } - static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) { + static void ExpectNone(const ScrollAndScaleSet& scroll_info, ElementId id) { int times_encountered = 0; for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) { - if (scroll_info.scrolls[i].layer_id != id) + if (scroll_info.scrolls[i].element_id != id) continue; times_encountered++; } @@ -332,18 +335,19 @@ class LayerTreeHostImplTest : public testing::Test, true; inner_scroll->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(), - gfx::ScrollOffset()); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + inner_scroll->element_id(), gfx::ScrollOffset()); std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); - inner_clip->SetBounds( - gfx::Size(content_size.width() / 2, content_size.height() / 2)); + gfx::Size viewport_scroll_bounds = + gfx::Size(content_size.width() / 2, content_size.height() / 2); + inner_clip->SetBounds(viewport_scroll_bounds); std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); - inner_scroll->SetScrollClipLayer(inner_clip->id()); + inner_scroll->SetScrollable(viewport_scroll_bounds); inner_scroll->SetElementId( LayerIdToElementIdForTesting(inner_scroll->id())); inner_scroll->SetBounds(content_size); @@ -357,13 +361,13 @@ class LayerTreeHostImplTest : public testing::Test, std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); - outer_scroll->SetScrollClipLayer(outer_clip->id()); + outer_scroll->SetScrollable(content_size); outer_scroll->SetElementId( LayerIdToElementIdForTesting(outer_scroll->id())); outer_scroll->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(), - gfx::ScrollOffset()); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + outer_scroll->element_id(), gfx::ScrollOffset()); outer_scroll->SetBounds(content_size); outer_scroll->SetPosition(gfx::PointF()); @@ -401,6 +405,80 @@ class LayerTreeHostImplTest : public testing::Test, return scroll_layer; } + void CreateAndTestNonScrollableLayers(const bool& transparent_layer) { + LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); + gfx::Size content_size = gfx::Size(360, 600); + gfx::Size scroll_content_size = gfx::Size(345, 3800); + gfx::Size scrollbar_size = gfx::Size(15, 600); + + host_impl_->SetViewportSize(content_size); + std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); + root->SetBounds(content_size); + root->SetPosition(gfx::PointF()); + + std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); + scroll->SetBounds(scroll_content_size); + scroll->SetScrollable(content_size); + scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); + scroll->SetDrawsContent(true); + + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = + SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10, + 0, false, true); + scrollbar->SetBounds(scrollbar_size); + scrollbar->SetPosition(gfx::PointF(345, 0)); + scrollbar->SetScrollElementId(scroll->element_id()); + scrollbar->SetDrawsContent(true); + scrollbar->test_properties()->opacity = 1.f; + + std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5); + squash1->SetBounds(gfx::Size(140, 300)); + squash1->SetPosition(gfx::PointF(220, 0)); + if (transparent_layer) { + // In the it is a transparent layer but should still participate + // in hit testing. + squash1->test_properties()->opacity = 0.0f; + squash1->SetShouldHitTest(true); + } else { + squash1->SetDrawsContent(true); + } + + std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6); + squash2->SetBounds(gfx::Size(140, 300)); + squash2->SetPosition(gfx::PointF(220, 300)); + squash2->SetDrawsContent(true); + + scroll->test_properties()->AddChild(std::move(squash2)); + root->test_properties()->AddChild(std::move(scroll)); + root->test_properties()->AddChild(std::move(scrollbar)); + root->test_properties()->AddChild(std::move(squash1)); + + layer_tree_impl->SetRootLayerForTesting(std::move(root)); + layer_tree_impl->BuildPropertyTreesForTesting(); + layer_tree_impl->DidBecomeActive(); + + // The point hits squash1 layer and also scroll layer, because scroll layer + // is not an ancestor of squash1 layer, we cannot scroll on impl thread. + InputHandler::ScrollStatus status = host_impl_->ScrollBegin( + BeginState(gfx::Point(230, 150)).get(), InputHandler::WHEEL); + ASSERT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread); + ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_scrolling_reasons); + + // The point hits squash1 layer and also scrollbar layer. + status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(), + InputHandler::WHEEL); + ASSERT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread); + ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest, + status.main_thread_scrolling_reasons); + + // The point hits squash2 layer and also scroll layer, because scroll layer + // is an ancestor of squash2 layer, we should scroll on impl. + status = host_impl_->ScrollBegin(BeginState(gfx::Point(230, 450)).get(), + InputHandler::WHEEL); + ASSERT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); + } + // Sets up a typical virtual viewport setup with one child content layer. // Returns a pointer to the content layer. LayerImpl* CreateBasicVirtualViewportLayers(const gfx::Size& viewport_size, @@ -415,6 +493,7 @@ class LayerTreeHostImplTest : public testing::Test, ->children.back(); content_layer->SetBounds(content_size); host_impl_->OuterViewportScrollLayer()->SetBounds(content_size); + host_impl_->OuterViewportScrollLayer()->SetScrollable(viewport_size); LayerImpl* outer_clip = host_impl_->OuterViewportScrollLayer()->test_properties()->parent; @@ -426,6 +505,7 @@ class LayerTreeHostImplTest : public testing::Test, ->parent; inner_clip_layer->SetBounds(viewport_size); host_impl_->InnerViewportScrollLayer()->SetBounds(viewport_size); + host_impl_->InnerViewportScrollLayer()->SetScrollable(viewport_size); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -436,17 +516,15 @@ class LayerTreeHostImplTest : public testing::Test, } std::unique_ptr<LayerImpl> CreateScrollableLayer(int id, - const gfx::Size& size, - LayerImpl* clip_layer) { - DCHECK(clip_layer); - DCHECK(id != clip_layer->id()); + const gfx::Size& size) { std::unique_ptr<LayerImpl> layer = LayerImpl::Create(host_impl_->active_tree(), id); - layer->SetScrollClipLayer(clip_layer->id()); layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); layer->SetDrawsContent(true); layer->SetBounds(size); - clip_layer->SetBounds(gfx::Size(size.width() / 2, size.height() / 2)); + gfx::Size scroll_container_bounds = + gfx::Size(size.width() / 2, size.height() / 2); + layer->SetScrollable(scroll_container_bounds); return layer; } @@ -500,8 +578,8 @@ class LayerTreeHostImplTest : public testing::Test, scoped_refptr<AnimationTimeline> timeline() { return timeline_; } protected: - virtual std::unique_ptr<CompositorFrameSink> CreateCompositorFrameSink() { - return FakeCompositorFrameSink::Create3dForGpuRasterization(); + virtual std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() { + return FakeLayerTreeFrameSink::Create3dForGpuRasterization(); } void DrawOneFrame() { @@ -514,9 +592,10 @@ class LayerTreeHostImplTest : public testing::Test, const gfx::Vector2dF& delta) { if (layer_impl->layer_tree_impl() ->property_trees() - ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(), - delta)) - layer_impl->layer_tree_impl()->DidUpdateScrollOffset(layer_impl->id()); + ->scroll_tree.SetScrollOffsetDeltaForTesting( + layer_impl->element_id(), delta)) + layer_impl->layer_tree_impl()->DidUpdateScrollOffset( + layer_impl->element_id()); } void BeginImplFrameAndAnimate(BeginFrameArgs begin_frame_args, @@ -541,7 +620,7 @@ class LayerTreeHostImplTest : public testing::Test, DebugScopedSetMainThreadBlocked always_main_thread_blocked_; TestTaskGraphRunner task_graph_runner_; - std::unique_ptr<CompositorFrameSink> compositor_frame_sink_; + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink_; std::unique_ptr<LayerTreeHostImpl> host_impl_; FakeRenderingStatsInstrumentation stats_instrumentation_; bool on_can_draw_state_changed_called_; @@ -565,7 +644,7 @@ class LayerTreeHostImplTest : public testing::Test, class LayerTreeHostImplTimelinesTest : public LayerTreeHostImplTest { public: void SetUp() override { - CreateHostImpl(DefaultSettings(), CreateCompositorFrameSink()); + CreateHostImpl(DefaultSettings(), CreateLayerTreeFrameSink()); } }; @@ -659,7 +738,7 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { } TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { - CreateHostImpl(DefaultSettings(), FakeCompositorFrameSink::CreateSoftware()); + CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::CreateSoftware()); SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -667,18 +746,17 @@ TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { host_impl_->SetViewportSize(gfx::Size()); EXPECT_FALSE(host_impl_->CanDraw()); - FakeCompositorFrameSink* fake_compositor_frame_sink = - static_cast<FakeCompositorFrameSink*>( - host_impl_->compositor_frame_sink()); - EXPECT_EQ(fake_compositor_frame_sink->num_sent_frames(), 0u); + auto* fake_layer_tree_frame_sink = + static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); + EXPECT_EQ(fake_layer_tree_frame_sink->num_sent_frames(), 0u); gfx::Transform identity; gfx::Rect viewport(100, 100); const bool resourceless_software_draw = true; host_impl_->OnDraw(identity, viewport, resourceless_software_draw); - ASSERT_EQ(fake_compositor_frame_sink->num_sent_frames(), 1u); + ASSERT_EQ(fake_layer_tree_frame_sink->num_sent_frames(), 1u); EXPECT_EQ( gfx::SizeF(100.f, 100.f), - fake_compositor_frame_sink->last_sent_frame()->metadata.root_layer_size); + fake_layer_tree_frame_sink->last_sent_frame()->metadata.root_layer_size); } TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { @@ -728,20 +806,17 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { gfx::ScrollOffset scroll_offset(20, 30); gfx::Vector2d scroll_delta(11, -15); - auto root_clip_owned = LayerImpl::Create(host_impl_->active_tree(), 2); - auto* root_clip = root_clip_owned.get(); auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1); auto* root = root_owned.get(); - root_clip->SetBounds(gfx::Size(10, 10)); - root_clip->test_properties()->AddChild(std::move(root_owned)); root->SetBounds(gfx::Size(110, 110)); - root->SetScrollClipLayer(root_clip->id()); + root->SetScrollable(gfx::Size(10, 10)); root->SetElementId(LayerIdToElementIdForTesting(root->id())); root->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->id(), scroll_offset); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip_owned)); + ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->element_id(), + scroll_offset); + host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_owned)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); std::unique_ptr<ScrollAndScaleSet> scroll_info; @@ -749,18 +824,19 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { root->ScrollBy(scroll_delta); scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(scroll_info->scrolls.size(), 1u); - EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(), scroll_delta)); + EXPECT_TRUE( + ScrollInfoContains(*scroll_info, root->element_id(), scroll_delta)); gfx::Vector2d scroll_delta2(-5, 27); root->ScrollBy(scroll_delta2); scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(scroll_info->scrolls.size(), 1u); - EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->element_id(), scroll_delta + scroll_delta2)); root->ScrollBy(gfx::Vector2d()); scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->element_id(), scroll_delta + scroll_delta2)); } @@ -774,20 +850,14 @@ TEST_F(LayerTreeHostImplTest, ScrollerSizeOfCCScrollingHistogramRecordingTest) { 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->SetScrollable(gfx::Size(100, 100)); 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)); + outer_viewport_scroll_layer->test_properties()->AddChild(std::move(child)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); base::HistogramTester histogram_tester; @@ -886,7 +956,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { // Initialization will fail. EXPECT_FALSE(CreateHostImpl( DefaultSettings(), - FakeCompositorFrameSink::Create3d(std::move(context_owned)))); + FakeLayerTreeFrameSink::Create3d(std::move(context_owned)))); SetupScrollAndContentsLayers(gfx::Size(100, 100)); @@ -921,8 +991,8 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { host_impl_->ScrollEnd(EndState().get()); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE( - ScrollInfoContains(*scroll_info, scroll_layer->id(), scroll_delta)); + EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), + scroll_delta)); } TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { @@ -965,9 +1035,15 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { } // Touch handler regions determine whether touch events block scroll. - root->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100)); - EXPECT_EQ(InputHandler::TouchStartEventListenerType::HANDLER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(10, 10))); + TouchAction touch_action; + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionPanLeft, gfx::Rect(0, 0, 100, 100)); + touch_action_region.Union(kTouchActionPanRight, gfx::Rect(25, 25, 100, 100)); + root->SetTouchActionRegion(std::move(touch_action_region)); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType::HANDLER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(10, 10), &touch_action)); + EXPECT_EQ(kTouchActionPanLeft, touch_action); // But they don't influence the actual handling of the scroll gestures. InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -977,14 +1053,21 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { status.main_thread_scrolling_reasons); host_impl_->ScrollEnd(EndState().get()); - EXPECT_EQ(InputHandler::TouchStartEventListenerType::HANDLER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(10, 30))); - root->SetTouchEventHandlerRegion(gfx::Rect()); - EXPECT_EQ(InputHandler::TouchStartEventListenerType::NO_HANDLER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(10, 30))); - child->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50)); - EXPECT_EQ(InputHandler::TouchStartEventListenerType::HANDLER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(10, 30))); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType::HANDLER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(10, 30), &touch_action)); + root->SetTouchActionRegion(TouchActionRegion()); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType::NO_HANDLER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(10, 30), &touch_action)); + EXPECT_EQ(kTouchActionAuto, touch_action); + touch_action_region = TouchActionRegion(); + touch_action_region.Union(kTouchActionPanX, gfx::Rect(0, 0, 50, 50)); + child->SetTouchActionRegion(std::move(touch_action_region)); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType::HANDLER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(10, 30), &touch_action)); + EXPECT_EQ(kTouchActionPanX, touch_action); } TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) { @@ -1086,75 +1169,12 @@ TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { } TEST_F(LayerTreeHostImplTest, ScrollWithOverlappingNonScrollableLayer) { - LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - gfx::Size content_size = gfx::Size(360, 600); - gfx::Size scroll_content_size = gfx::Size(345, 3800); - gfx::Size scrollbar_size = gfx::Size(15, 600); - - host_impl_->SetViewportSize(content_size); - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(content_size); - root->SetPosition(gfx::PointF()); - - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2); - clip->SetBounds(content_size); - clip->SetPosition(gfx::PointF()); - - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); - scroll->SetBounds(scroll_content_size); - scroll->SetScrollClipLayer(clip->id()); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, 10, 0, - false, true); - scrollbar->SetBounds(scrollbar_size); - scrollbar->SetPosition(gfx::PointF(345, 0)); - scrollbar->SetScrollElementId(scroll->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->test_properties()->opacity = 1.f; - - std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5); - squash1->SetBounds(gfx::Size(140, 300)); - squash1->SetPosition(gfx::PointF(220, 0)); - squash1->SetDrawsContent(true); - - std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6); - squash2->SetBounds(gfx::Size(140, 300)); - squash2->SetPosition(gfx::PointF(220, 300)); - squash2->SetDrawsContent(true); - - scroll->test_properties()->AddChild(std::move(squash2)); - clip->test_properties()->AddChild(std::move(scroll)); - clip->test_properties()->AddChild(std::move(scrollbar)); - clip->test_properties()->AddChild(std::move(squash1)); - root->test_properties()->AddChild(std::move(clip)); - - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); - layer_tree_impl->DidBecomeActive(); - - // The point hits squash1 layer and also scroll layer, because scroll layer is - // not an ancestor of squash1 layer, we cannot scroll on impl thread. - InputHandler::ScrollStatus status = host_impl_->ScrollBegin( - BeginState(gfx::Point(230, 150)).get(), InputHandler::WHEEL); - EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread); - EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, - status.main_thread_scrolling_reasons); - - // The point hits squash1 layer and also scrollbar layer. - status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(), - InputHandler::WHEEL); - EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread); - EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest, - status.main_thread_scrolling_reasons); + CreateAndTestNonScrollableLayers(false); +} - // The point hits squash2 layer and also scroll layer, because scroll layer is - // an ancestor of squash2 layer, we should scroll on impl. - status = host_impl_->ScrollBegin(BeginState(gfx::Point(230, 450)).get(), - InputHandler::WHEEL); - EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); +TEST_F(LayerTreeHostImplTest, + ScrollWithOverlappingTransparentNonScrollableLayer) { + CreateAndTestNonScrollableLayers(true); } TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { @@ -1168,13 +1188,9 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { root->SetBounds(content_size); root->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 2); - clip->SetBounds(content_size); - clip->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); scroll->SetBounds(scroll_content_size); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(content_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); @@ -1194,8 +1210,7 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { scroll->test_properties()->AddChild(std::move(drawn_scrollbar)); scroll->test_properties()->AddChild(std::move(squash)); - clip->test_properties()->AddChild(std::move(scroll)); - root->test_properties()->AddChild(std::move(clip)); + root->test_properties()->AddChild(std::move(scroll)); layer_tree_impl->SetRootLayerForTesting(std::move(root)); layer_tree_impl->BuildPropertyTreesForTesting(); @@ -1410,6 +1425,120 @@ TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { .did_scroll); } +TEST_F(LayerTreeHostImplTest, ScrollBoundaryBehaviorPreventsPropagation) { + LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); + host_impl_->SetViewportSize(gfx::Size(100, 100)); + + gfx::Size overflow_size(400, 400); + ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); + LayerImpl* overflow = scroll_layer->test_properties()->children[0]; + overflow->SetBounds(overflow_size); + overflow->SetScrollable(gfx::Size(100, 100)); + overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); + overflow->layer_tree_impl() + ->property_trees() + ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), + gfx::ScrollOffset()); + overflow->SetPosition(gfx::PointF(40, 40)); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(30, 30)); + + DrawFrame(); + gfx::Point scroll_position(50, 50); + + // ScrollBoundaryBehaviorTypeAuto shouldn't prevent scroll propagation. + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) + .thread); + EXPECT_VECTOR_EQ(gfx::Vector2dF(30, 30), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->CurrentScrollOffset()); + + gfx::Vector2dF x_dominant_delta(-10, -5); + gfx::Vector2dF y_dominant_delta(-5, -10); + host_impl_->ScrollBy(UpdateState(scroll_position, x_dominant_delta).get()); + host_impl_->ScrollEnd(EndState().get()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 25), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + overflow->test_properties()->scroll_boundary_behavior = + ScrollBoundaryBehavior( + ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeNone, + ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeAuto); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + DrawFrame(); + + // ScrollBoundaryBehaviorNone on x should prevent x-dominant-scroll + // propagation. + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) + .thread); + EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 25), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + host_impl_->ScrollBy(UpdateState(scroll_position, x_dominant_delta).get()); + host_impl_->ScrollEnd(EndState().get()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 25), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + // ScrollBoundaryBehaviorNone on x shouldn't prevent y-dominant-scroll + // propagation. + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) + .thread); + EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 25), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + host_impl_->ScrollBy(UpdateState(scroll_position, y_dominant_delta).get()); + host_impl_->ScrollEnd(EndState().get()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(15, 15), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + overflow->test_properties()->scroll_boundary_behavior = + ScrollBoundaryBehavior( + ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeAuto, + ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeNone); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + DrawFrame(); + + // ScrollBoundaryBehaviorNone on y shouldn't prevent x-dominant-scroll + // propagation. + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) + .thread); + EXPECT_VECTOR_EQ(gfx::Vector2dF(15, 15), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + host_impl_->ScrollBy(UpdateState(scroll_position, x_dominant_delta).get()); + host_impl_->ScrollEnd(EndState().get()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + // ScrollBoundaryBehaviorNone on y should prevent y-dominant-scroll + // propagation. + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL) + .thread); + EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + host_impl_->ScrollBy(UpdateState(scroll_position, y_dominant_delta).get()); + host_impl_->ScrollEnd(EndState().get()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10), scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); +} + TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); host_impl_->SetViewportSize(gfx::Size(100, 100)); @@ -1418,12 +1547,11 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); LayerImpl* overflow = scroll_layer->test_properties()->children[0]; overflow->SetBounds(overflow_size); - overflow->SetScrollClipLayer( - scroll_layer->test_properties()->parent->test_properties()->parent->id()); + overflow->SetScrollable(gfx::Size(100, 100)); overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); overflow->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), gfx::ScrollOffset()); overflow->SetPosition(gfx::PointF()); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -1445,7 +1573,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset()); - overflow->set_user_scrollable_horizontal(false); + overflow->test_properties()->user_scrollable_horizontal = false; host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -1463,7 +1591,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset()); - overflow->set_user_scrollable_vertical(false); + overflow->test_properties()->user_scrollable_vertical = false; host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -1605,7 +1733,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingActiveTree) { TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { FakeImplTaskRunnerProvider provider(nullptr); CreateHostImplWithTaskRunnerProvider(DefaultSettings(), - CreateCompositorFrameSink(), &provider); + CreateLayerTreeFrameSink(), &provider); EXPECT_TRUE(host_impl_->CommitToActiveTree()); host_impl_->SetViewportSize(gfx::Size(50, 50)); @@ -1647,7 +1775,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { EXPECT_FALSE(did_request_commit_); // Delete the LayerTreeHostImpl before the TaskRunnerProvider goes away. - host_impl_->ReleaseCompositorFrameSink(); + host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; } @@ -1735,7 +1863,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { DrawFrame(); EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); - LayerImpl* container_layer = scroll_layer->scroll_clip_layer(); + LayerImpl* container_layer = host_impl_->InnerViewportContainerLayer(); EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); float min_page_scale = 1.f, max_page_scale = 4.f; @@ -1797,14 +1925,14 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), scroll_layer->id(), + *scroll_info.get(), scroll_layer->element_id(), gfx::Vector2d(0, scroll_delta.y() / page_scale_delta))); } } TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) { LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.25f, 4.f); const gfx::Size content_size(1000, 1000); @@ -1863,7 +1991,7 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) { // dropped. crbug.com/539334. TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) { LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); const gfx::Size content_size(1000, 1000); @@ -1912,7 +2040,7 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) { // to the outer viewport. TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) { LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); const gfx::Size content_size(1000, 1000); @@ -1966,7 +2094,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) { // should assume the user means to scroll into the edge of the screen. TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); const gfx::Size content_size(1000, 1000); @@ -2101,6 +2229,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) { TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { ui::LatencyInfo latency_info; + latency_info.set_trace_id(5); latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 1234); std::unique_ptr<SwapPromise> swap_promise( @@ -2136,19 +2265,15 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { LayerImpl* child; LayerImpl* child_clip; - std::unique_ptr<LayerImpl> scroll_parent_clip = - LayerImpl::Create(host_impl_->active_tree(), 6); std::unique_ptr<LayerImpl> scroll_parent = - CreateScrollableLayer(7, gfx::Size(10, 10), scroll_parent_clip.get()); + CreateScrollableLayer(7, gfx::Size(10, 10)); parent = scroll_parent.get(); - scroll_parent_clip->test_properties()->AddChild(std::move(scroll_parent)); - - viewport_scroll->test_properties()->AddChild(std::move(scroll_parent_clip)); + viewport_scroll->test_properties()->AddChild(std::move(scroll_parent)); std::unique_ptr<LayerImpl> scroll_child_clip = LayerImpl::Create(host_impl_->active_tree(), 8); std::unique_ptr<LayerImpl> scroll_child = - CreateScrollableLayer(9, gfx::Size(10, 10), scroll_child_clip.get()); + CreateScrollableLayer(9, gfx::Size(10, 10)); child = scroll_child.get(); scroll_child->SetPosition(gfx::PointF(20.f, 20.f)); scroll_child_clip->test_properties()->AddChild(std::move(scroll_child)); @@ -2278,7 +2403,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer->id(), gfx::ScrollOffset(50, 50)); + scroll_layer->element_id(), gfx::ScrollOffset(50, 50)); float page_scale_delta = 0.1f; host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), @@ -2306,7 +2431,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer->id(), gfx::ScrollOffset(20, 20)); + scroll_layer->element_id(), gfx::ScrollOffset(20, 20)); float page_scale_delta = 1.f; host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(), @@ -2334,7 +2459,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer->id(), gfx::ScrollOffset(20, 20)); + scroll_layer->element_id(), gfx::ScrollOffset(20, 20)); float page_scale_delta = 1.f; host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(), @@ -2350,7 +2475,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); - EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), gfx::Vector2d(-10, -10))); } @@ -2363,8 +2488,8 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { ->scroll_tree.CollectScrollDeltasForTesting(); scroll_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(), - gfx::ScrollOffset(0, 0)); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + scroll_layer->element_id(), gfx::ScrollOffset(0, 0)); host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), InputHandler::TOUCHSCREEN); @@ -2384,7 +2509,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, 2.f); - EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), gfx::Vector2d(10, 10))); } } @@ -2415,7 +2540,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer->id(), gfx::ScrollOffset(50, 50)); + scroll_layer->element_id(), gfx::ScrollOffset(50, 50)); did_request_redraw_ = false; did_request_next_frame_ = false; @@ -2461,7 +2586,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, 2); - EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), gfx::Vector2d(-50, -50))); } @@ -2476,7 +2601,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer->id(), gfx::ScrollOffset(50, 50)); + scroll_layer->element_id(), gfx::ScrollOffset(50, 50)); did_request_redraw_ = false; did_request_next_frame_ = false; @@ -2514,7 +2639,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale); // Pushed to (0,0) via clamping against contents layer size. - EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), gfx::Vector2d(-50, -50))); } } @@ -2545,7 +2670,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer->id(), gfx::ScrollOffset(50, 50)); + scroll_layer->element_id(), gfx::ScrollOffset(50, 50)); host_impl_->active_tree()->SetPendingPageScaleAnimation( std::unique_ptr<PendingPageScaleAnimation>( @@ -2575,7 +2700,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, 1); - ExpectNone(*scroll_info, scroll_layer->id()); + ExpectNone(*scroll_info, scroll_layer->element_id()); } } @@ -2610,7 +2735,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { scroll_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), gfx::ScrollOffset(50, 50)); // Make sure TakePageScaleAnimation works properly. @@ -2700,7 +2825,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, target_scale); - EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), gfx::Vector2d(-50, -50))); } @@ -2724,7 +2849,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); scroll_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), gfx::ScrollOffset(50, 50)); did_complete_page_scale_animation_ = false; @@ -2762,7 +2887,7 @@ TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) { DrawFrame(); LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - LayerImpl* inner_container = inner_scroll->scroll_clip_layer(); + LayerImpl* inner_container = host_impl_->InnerViewportContainerLayer(); DCHECK(inner_scroll); DCHECK(inner_container); EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset()); @@ -2814,7 +2939,7 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { protected: void SetupLayers(LayerTreeSettings settings) { - host_impl_->ReleaseCompositorFrameSink(); + host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; gfx::Size content_size(100, 100); @@ -2824,9 +2949,9 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { settings, this, &task_runner_provider_, &task_graph_runner_, &stats_instrumentation_); host_impl_ = base::WrapUnique(host_impl_override_time); - compositor_frame_sink_ = CreateCompositorFrameSink(); + layer_tree_frame_sink_ = CreateLayerTreeFrameSink(); host_impl_->SetVisible(true); - host_impl_->InitializeRenderer(compositor_frame_sink_.get()); + host_impl_->InitializeRenderer(layer_tree_frame_sink_.get()); SetupScrollAndContentsLayers(content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f); @@ -2985,10 +3110,10 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { if (host_impl_->active_tree() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - host_impl_->InnerViewportScrollLayer()->id(), + host_impl_->InnerViewportScrollLayer()->element_id(), gfx::ScrollOffset(5, 5))) host_impl_->active_tree()->DidUpdateScrollOffset( - host_impl_->InnerViewportScrollLayer()->id()); + host_impl_->InnerViewportScrollLayer()->element_id()); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); EXPECT_EQ(base::TimeDelta(), requested_animation_delay_); @@ -3036,7 +3161,7 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { // If no animator is set, scrollbar won't show and no animation is expected. bool expecting_animations = animator != LayerTreeSettings::NO_ANIMATOR; - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->CreatePendingTree(); CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size); std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = @@ -3129,7 +3254,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) { settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); gfx::Size content_size(100, 100); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->CreatePendingTree(); CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size); std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = @@ -3196,21 +3321,24 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) { TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) { LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); gfx::Size inner_viewport_size(315, 200); gfx::Size outer_viewport_size(300, 200); gfx::Size content_size(1000, 1000); const int horiz_id = 11; - const int child_clip_id = 14; const int child_scroll_id = 15; CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( inner_viewport_size); + host_impl_->active_tree()->InnerViewportScrollLayer()->SetScrollable( + inner_viewport_size); host_impl_->active_tree()->OuterViewportContainerLayer()->SetBounds( outer_viewport_size); + host_impl_->active_tree()->OuterViewportScrollLayer()->SetScrollable( + outer_viewport_size); LayerImpl* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); std::unique_ptr<SolidColorScrollbarLayerImpl> horiz_scrollbar = @@ -3219,12 +3347,13 @@ TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) { std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); child->SetBounds(content_size); - std::unique_ptr<LayerImpl> child_clip = - LayerImpl::Create(host_impl_->active_tree(), child_clip_id); child->SetBounds(inner_viewport_size); horiz_scrollbar->SetScrollElementId(root_scroll->element_id()); + host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); + host_impl_->active_tree()->UpdateScrollbarGeometries(); + EXPECT_EQ(300, horiz_scrollbar->clip_layer_length()); } @@ -3233,7 +3362,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { settings.scrollbar_animator = LayerTreeSettings::ANDROID_OVERLAY; settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); gfx::Size viewport_size(300, 200); gfx::Size content_size(1000, 1000); @@ -3242,7 +3371,6 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { const int horiz_1_id = 11; const int vert_2_id = 12; const int horiz_2_id = 13; - const int child_clip_id = 14; const int child_scroll_id = 15; CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); @@ -3254,36 +3382,28 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { 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]); + auto* vert_1_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( + container->test_properties()->children[1]); container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( host_impl_->active_tree(), horiz_1_id, HORIZONTAL, 5, 5, true, true)); - SolidColorScrollbarLayerImpl* horiz_1_scrollbar = - static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[2]); + auto* horiz_1_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( + container->test_properties()->children[2]); container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( host_impl_->active_tree(), vert_2_id, VERTICAL, 5, 5, true, true)); - SolidColorScrollbarLayerImpl* vert_2_scrollbar = - static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[3]); + auto* vert_2_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( + container->test_properties()->children[3]); container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( host_impl_->active_tree(), horiz_2_id, HORIZONTAL, 5, 5, true, true)); - SolidColorScrollbarLayerImpl* horiz_2_scrollbar = - static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[4]); + auto* horiz_2_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( + container->test_properties()->children[4]); std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->SetBounds(content_size); - std::unique_ptr<LayerImpl> child_clip = - LayerImpl::Create(host_impl_->active_tree(), child_clip_id); child->SetBounds(viewport_size); LayerImpl* child_ptr = child.get(); - LayerImpl* child_clip_ptr = child_clip.get(); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -3309,11 +3429,10 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { animation_task_ = base::Closure(); // Check scrollbar registration on a sublayer. - child->SetScrollClipLayer(child_clip->id()); + child->SetScrollable(viewport_size); 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)); + root_scroll->test_properties()->AddChild(std::move(child)); EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( child_scroll_element_id)); @@ -3329,8 +3448,9 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { // 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)); + child_ptr->SetBounds(gfx::Size(200, 200)); child_ptr->set_needs_show_scrollbars(true); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain(); EXPECT_FALSE(animation_task_.Equals(base::Closure())); animation_task_ = base::Closure(); @@ -3363,6 +3483,72 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { EXPECT_TRUE(animation_task_.Equals(base::Closure())); } +TEST_F(LayerTreeHostImplTest, ScrollBeforeMouseMove) { + LayerTreeSettings settings = DefaultSettings(); + settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY; + settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); + settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + + gfx::Size viewport_size(300, 200); + gfx::Size content_size(1000, 1000); + + CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); + auto* container = host_impl_->active_tree()->InnerViewportContainerLayer(); + container->SetBounds(viewport_size); + auto* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); + + container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( + host_impl_->active_tree(), 10, VERTICAL, 5, 0, false, true)); + auto* vert_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( + container->test_properties()->children[1]); + + vert_scrollbar->SetScrollElementId(root_scroll->element_id()); + vert_scrollbar->SetBounds(gfx::Size(10, 200)); + vert_scrollbar->SetPosition(gfx::PointF(300, 0)); + vert_scrollbar->test_properties()->opacity_can_animate = true; + vert_scrollbar->SetCurrentPos(0); + + host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); + host_impl_->active_tree()->UpdateScrollbarGeometries(); + + EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); + auto* scrollbar_controller = + host_impl_->ScrollbarAnimationControllerForElementId( + root_scroll->element_id()); + + const float kDistanceToTriggerThumb = + SingleScrollbarAnimationControllerThinning:: + kMouseMoveDistanceToTriggerExpand; + + // Move the mouse near the thumb in the top position. + auto near_thumb_at_top = gfx::Point(300, -kDistanceToTriggerThumb + 1); + host_impl_->MouseMoveAt(near_thumb_at_top); + EXPECT_TRUE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL)); + + // Move the mouse away from the thumb. + host_impl_->MouseMoveAt(gfx::Point(300, -kDistanceToTriggerThumb - 1)); + EXPECT_FALSE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL)); + + // Scroll the page down which moves the thumb down. + host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 100)).get()); + host_impl_->ScrollEnd(EndState().get()); + + // Move the mouse near the thumb in the top position. + host_impl_->MouseMoveAt(near_thumb_at_top); + EXPECT_FALSE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL)); + + // Scroll the page up which moves the thumb back up. + host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, -100)).get()); + host_impl_->ScrollEnd(EndState().get()); + + // Move the mouse near the thumb in the top position. + host_impl_->MouseMoveAt(near_thumb_at_top); + EXPECT_TRUE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL)); +} + void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( float device_scale_factor) { LayerTreeSettings settings = DefaultSettings(); @@ -3376,7 +3562,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( gfx::Size content_size(1000, 1000); gfx::Size scrollbar_size(gfx::Size(15, viewport_size.height())); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor); host_impl_->SetViewportSize(device_viewport_size); @@ -3392,7 +3578,9 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( scrollbar->SetScrollElementId(root_scroll->element_id()); scrollbar->SetDrawsContent(true); scrollbar->SetBounds(scrollbar_size); - scrollbar->SetTouchEventHandlerRegion(gfx::Rect(scrollbar_size)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size)); + scrollbar->SetTouchActionRegion(touch_action_region); host_impl_->active_tree() ->InnerViewportContainerLayer() ->test_properties() @@ -3401,7 +3589,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); - host_impl_->active_tree()->UpdateDrawProperties(false); + host_impl_->active_tree()->UpdateDrawProperties(); ScrollbarAnimationController* scrollbar_animation_controller = host_impl_->ScrollbarAnimationControllerForElementId( @@ -3462,13 +3650,15 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { host_impl_->SetViewportSize(gfx::Size(50, 50)); LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - std::vector<SurfaceId> primary_surfaces = { - MakeSurfaceId(FrameSinkId(1, 1), 1), MakeSurfaceId(FrameSinkId(2, 2), 2), - MakeSurfaceId(FrameSinkId(3, 3), 3)}; + std::vector<viz::SurfaceId> primary_surfaces = { + MakeSurfaceId(viz::FrameSinkId(1, 1), 1), + MakeSurfaceId(viz::FrameSinkId(2, 2), 2), + MakeSurfaceId(viz::FrameSinkId(3, 3), 3)}; - std::vector<SurfaceId> fallback_surfaces = { - MakeSurfaceId(FrameSinkId(4, 4), 1), MakeSurfaceId(FrameSinkId(4, 4), 2), - MakeSurfaceId(FrameSinkId(4, 4), 3)}; + std::vector<viz::SurfaceId> fallback_surfaces = { + MakeSurfaceId(viz::FrameSinkId(4, 4), 1), + MakeSurfaceId(viz::FrameSinkId(4, 4), 2), + MakeSurfaceId(viz::FrameSinkId(4, 4), 3)}; for (size_t i = 0; i < primary_surfaces.size(); ++i) { std::unique_ptr<SurfaceLayerImpl> child = @@ -3477,22 +3667,27 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); child->SetPrimarySurfaceInfo( - SurfaceInfo(primary_surfaces[i], 1.f /* device_scale_factor */, - gfx::Size(10, 10) /* size_in_pixels */)); + viz::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 */)); + viz::SurfaceInfo(fallback_surfaces[i], 1.f /* device_scale_factor */, + gfx::Size(10, 10) /* size_in_pixels */)); root->test_properties()->AddChild(std::move(child)); } + base::flat_set<viz::SurfaceId> fallback_surfaces_set; + for (size_t i = 0; i < fallback_surfaces.size(); ++i) { + fallback_surfaces_set.insert(fallback_surfaces[i]); + } + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + host_impl_->active_tree()->SetSurfaceLayerIds(fallback_surfaces_set); DrawFrame(); - FakeCompositorFrameSink* fake_compositor_frame_sink = - static_cast<FakeCompositorFrameSink*>( - host_impl_->compositor_frame_sink()); + auto* fake_layer_tree_frame_sink = + static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); const CompositorFrameMetadata& metadata = - fake_compositor_frame_sink->last_sent_frame()->metadata; + fake_layer_tree_frame_sink->last_sent_frame()->metadata; EXPECT_THAT( metadata.activation_dependencies, testing::UnorderedElementsAre(primary_surfaces[0], primary_surfaces[1])); @@ -3544,7 +3739,9 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { { host_impl_->active_tree() ->OuterViewportScrollLayer() - ->set_user_scrollable_horizontal(false); + ->test_properties() + ->user_scrollable_horizontal = false; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); CompositorFrameMetadata metadata = host_impl_->MakeCompositorFrameMetadata(); EXPECT_TRUE(metadata.root_overflow_x_hidden); @@ -3552,7 +3749,9 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { host_impl_->active_tree() ->OuterViewportScrollLayer() - ->set_user_scrollable_vertical(false); + ->test_properties() + ->user_scrollable_vertical = false; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); metadata = host_impl_->MakeCompositorFrameMetadata(); EXPECT_TRUE(metadata.root_overflow_x_hidden); EXPECT_TRUE(metadata.root_overflow_y_hidden); @@ -3562,10 +3761,13 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { { host_impl_->active_tree() ->OuterViewportScrollLayer() - ->set_user_scrollable_horizontal(true); + ->test_properties() + ->user_scrollable_horizontal = true; host_impl_->active_tree() ->OuterViewportScrollLayer() - ->set_user_scrollable_vertical(true); + ->test_properties() + ->user_scrollable_vertical = true; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); CompositorFrameMetadata metadata = host_impl_->MakeCompositorFrameMetadata(); EXPECT_FALSE(metadata.root_overflow_x_hidden); @@ -3577,7 +3779,9 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { { host_impl_->active_tree() ->InnerViewportScrollLayer() - ->set_user_scrollable_horizontal(false); + ->test_properties() + ->user_scrollable_horizontal = false; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); CompositorFrameMetadata metadata = host_impl_->MakeCompositorFrameMetadata(); EXPECT_TRUE(metadata.root_overflow_x_hidden); @@ -3585,7 +3789,9 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { host_impl_->active_tree() ->InnerViewportScrollLayer() - ->set_user_scrollable_vertical(false); + ->test_properties() + ->user_scrollable_vertical = false; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); metadata = host_impl_->MakeCompositorFrameMetadata(); EXPECT_TRUE(metadata.root_overflow_x_hidden); EXPECT_TRUE(metadata.root_overflow_y_hidden); @@ -3665,7 +3871,7 @@ class DidDrawCheckLayer : public LayerImpl { void AddCopyRequest() { test_properties()->copy_requests.push_back( - CopyOutputRequest::CreateRequest(base::Bind(&IgnoreResult))); + CopyOutputRequest::CreateRequest(base::BindOnce(&IgnoreResult))); } protected: @@ -3692,13 +3898,13 @@ TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) { // will be masked out by the root layer's bounds. host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - DidDrawCheckLayer* root = + auto* root = static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); root->test_properties()->AddChild( DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); root->test_properties()->force_render_surface = true; - DidDrawCheckLayer* layer = + auto* layer = static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -3736,13 +3942,13 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { // will be masked out by the root layer's bounds. host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - DidDrawCheckLayer* root = + auto* root = static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); root->SetMasksToBounds(true); root->test_properties()->force_render_surface = true; root->test_properties()->AddChild( DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - DidDrawCheckLayer* layer = + auto* layer = static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); // Ensure visible_layer_rect for layer is empty. layer->SetPosition(gfx::PointF(100.f, 100.f)); @@ -3787,18 +3993,18 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - DidDrawCheckLayer* root = + auto* root = static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); root->test_properties()->AddChild( DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - DidDrawCheckLayer* occluded_layer = + auto* occluded_layer = static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); root->test_properties()->AddChild( DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); root->test_properties()->force_render_surface = true; - DidDrawCheckLayer* top_layer = + auto* top_layer = static_cast<DidDrawCheckLayer*>(root->test_properties()->children[1]); // This layer covers the occluded_layer above. Make this layer large so it can // occlude. @@ -3826,18 +4032,18 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - DidDrawCheckLayer* root = + auto* root = static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); root->test_properties()->AddChild( DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); root->test_properties()->force_render_surface = true; - DidDrawCheckLayer* layer1 = + auto* layer1 = static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); layer1->test_properties()->AddChild( DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); - DidDrawCheckLayer* layer2 = + auto* layer2 = static_cast<DidDrawCheckLayer*>(layer1->test_properties()->children[0]); layer1->test_properties()->force_render_surface = true; @@ -3933,7 +4139,7 @@ static void CreateLayerFromState( root->layer_tree_impl(), layer_id++, state.has_missing_tile, state.has_incomplete_tile, state.is_animating, root->layer_tree_impl()->resource_provider(), timeline)); - DidDrawCheckLayer* layer = + auto* layer = static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); if (state.has_copy_request) layer->AddCopyRequest(); @@ -4012,7 +4218,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) { host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - DidDrawCheckLayer* root = + auto* root = static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); root->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -4053,7 +4259,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsAndFails) { TEST_F(LayerTreeHostImplTest, PrepareToDrawWhenDrawAndSwapFullViewportEveryFrame) { - CreateHostImpl(DefaultSettings(), FakeCompositorFrameSink::CreateSoftware()); + CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::CreateSoftware()); const gfx::Transform external_transform; const gfx::Rect external_viewport; @@ -4080,7 +4286,7 @@ TEST_F(LayerTreeHostImplTest, host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>( + auto* root = static_cast<DidDrawCheckLayer*>( host_impl_->active_tree()->root_layer_for_testing()); root->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -4116,7 +4322,6 @@ TEST_F(LayerTreeHostImplTest, TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetScrollClipLayer(Layer::INVALID_ID); root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -4149,8 +4354,8 @@ TEST_F(LayerTreeHostImplTest, ClampingAfterActivation) { host_impl_->pending_tree()->OuterViewportScrollLayer(); pending_outer_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(pending_outer_layer->id(), - pending_scroll); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + pending_outer_layer->element_id(), pending_scroll); host_impl_->ActivateSyncTree(); // Scrolloffsets on the active tree will be clamped after activation. @@ -4171,9 +4376,9 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { bool CreateHostImpl( const LayerTreeSettings& settings, - std::unique_ptr<CompositorFrameSink> compositor_frame_sink) override { + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) override { bool init = LayerTreeHostImplTest::CreateHostImpl( - settings, std::move(compositor_frame_sink)); + settings, std::move(layer_tree_frame_sink)); if (init) { host_impl_->active_tree()->set_top_controls_height(top_controls_height_); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); @@ -4187,7 +4392,7 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { const gfx::Size& outer_viewport_size, const gfx::Size& scroll_layer_size) { settings_ = DefaultSettings(); - CreateHostImpl(settings_, CreateCompositorFrameSink()); + CreateHostImpl(settings_, CreateLayerTreeFrameSink()); SetupBrowserControlsAndScrollLayerWithVirtualViewport( host_impl_->active_tree(), inner_viewport_size, outer_viewport_size, scroll_layer_size); @@ -4212,7 +4417,7 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(tree_impl, 5); root_clip->SetBounds(inner_viewport_size); - root->SetScrollClipLayer(root_clip->id()); + root->SetScrollable(inner_viewport_size); root->SetElementId(LayerIdToElementIdForTesting(root->id())); root->SetBounds(outer_viewport_size); root->SetPosition(gfx::PointF()); @@ -4220,7 +4425,7 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { root_clip->test_properties()->force_render_surface = true; root->test_properties()->is_container_for_fixed_position_layers = true; outer_clip->SetBounds(outer_viewport_size); - outer_scroll->SetScrollClipLayer(outer_clip->id()); + outer_scroll->SetScrollable(outer_viewport_size); outer_scroll->SetElementId( LayerIdToElementIdForTesting(outer_scroll->id())); outer_scroll->SetBounds(scroll_layer_size); @@ -4337,6 +4542,100 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->ScrollEnd(EndState().get()); } +// Tests that browser controls affect the position of horizontal scrollbars. +TEST_F(LayerTreeHostImplBrowserControlsTest, + HidingBrowserControlsAdjustsScrollbarPosition) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( + gfx::Size(50, 50), gfx::Size(50, 50), gfx::Size(50, 50)); + + LayerTreeImpl* active_tree = host_impl_->active_tree(); + + // Create a horizontal scrollbar. + const int scrollbar_id = 23; + gfx::Size scrollbar_size(gfx::Size(50, 15)); + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = + SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), + scrollbar_id, HORIZONTAL, 3, 20, + false, true); + scrollbar->SetScrollElementId( + host_impl_->OuterViewportScrollLayer()->element_id()); + scrollbar->SetDrawsContent(true); + scrollbar->SetBounds(scrollbar_size); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size)); + scrollbar->SetTouchActionRegion(touch_action_region); + scrollbar->SetCurrentPos(0); + scrollbar->SetPosition(gfx::PointF(0, 35)); + host_impl_->active_tree() + ->InnerViewportContainerLayer() + ->test_properties() + ->AddChild(std::move(scrollbar)); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + host_impl_->active_tree()->UpdateScrollbarGeometries(); + + DrawFrame(); + + LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); + LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); + auto* scrollbar_layer = static_cast<SolidColorScrollbarLayerImpl*>( + active_tree->LayerById(scrollbar_id)); + + // The browser controls should start off showing so the viewport should be + // shrunk. + EXPECT_EQ(gfx::Size(50, 50), inner_container->bounds()); + EXPECT_EQ(gfx::Size(50, 50), outer_container->bounds()); + EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize()); + EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); + EXPECT_EQ(gfx::Rect(20, 0, 10, 3), scrollbar_layer->ComputeThumbQuadRect()); + + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(gfx::Point()).get(), + InputHandler::TOUCHSCREEN) + .thread); + + host_impl_->browser_controls_manager()->ScrollBegin(); + + // Hide the browser controls by a bit, the scrollable size should increase but + // the actual content bounds shouldn't. + { + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + host_impl_->active_tree()->UpdateScrollbarGeometries(); + ASSERT_EQ(gfx::Size(50, 75), inner_container->bounds()); + ASSERT_EQ(gfx::Size(50, 75), outer_container->bounds()); + EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize()); + EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); + EXPECT_EQ(gfx::Rect(20, 25, 10, 3), + scrollbar_layer->ComputeThumbQuadRect()); + } + + // Fully hide the browser controls. + { + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + host_impl_->active_tree()->UpdateScrollbarGeometries(); + ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); + ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); + EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); + EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); + EXPECT_EQ(gfx::Rect(20, 50, 10, 3), + scrollbar_layer->ComputeThumbQuadRect()); + } + + // Additional scrolling shouldn't have any effect. + { + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); + ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); + EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); + EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); + EXPECT_EQ(gfx::Rect(20, 50, 10, 3), + scrollbar_layer->ComputeThumbQuadRect()); + } + + host_impl_->browser_controls_manager()->ScrollEnd(); + host_impl_->ScrollEnd(EndState().get()); +} + TEST_F(LayerTreeHostImplBrowserControlsTest, ScrollBrowserControlsByFractionalAmount) { SetupBrowserControlsAndScrollLayerWithVirtualViewport( @@ -4571,27 +4870,23 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, 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(sub_content_layer_size); - child->SetScrollClipLayer(child_clip->id()); + child->SetScrollable(sub_content_layer_size); child->SetElementId(LayerIdToElementIdForTesting(child->id())); child->SetBounds(sub_content_size); child->SetPosition(gfx::PointF()); child->SetDrawsContent(true); child->test_properties()->is_container_for_fixed_position_layers = true; - // scroll child to limit - SetScrollOffsetDelta(child.get(), gfx::Vector2dF(0, 100.f)); - child_clip->test_properties()->AddChild(std::move(child)); - outer_viewport_scroll_layer->test_properties()->AddChild( - std::move(child_clip)); + LayerImpl* child_ptr = child.get(); + outer_viewport_scroll_layer->test_properties()->AddChild(std::move(child)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); + // Scroll child to the limit. + SetScrollOffsetDelta(child_ptr, gfx::Vector2dF(0, 100.f)); + // Scroll 25px to hide browser controls gfx::Vector2dF scroll_delta(0.f, 25.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -4614,7 +4909,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, TEST_F(LayerTreeHostImplBrowserControlsTest, PositionBrowserControlsExplicitly) { settings_ = DefaultSettings(); - CreateHostImpl(settings_, CreateCompositorFrameSink()); + CreateHostImpl(settings_, CreateLayerTreeFrameSink()); SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); @@ -4649,7 +4944,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // change after the activation. TEST_F(LayerTreeHostImplBrowserControlsTest, ApplyDeltaOnTreeActivation) { settings_ = DefaultSettings(); - CreateHostImpl(settings_, CreateCompositorFrameSink()); + CreateHostImpl(settings_, CreateLayerTreeFrameSink()); SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); @@ -4699,7 +4994,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, ApplyDeltaOnTreeActivation) { TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsLayoutHeightChanged) { settings_ = DefaultSettings(); - CreateHostImpl(settings_, CreateCompositorFrameSink()); + CreateHostImpl(settings_, CreateLayerTreeFrameSink()); SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); @@ -4938,7 +5233,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, TEST_F(LayerTreeHostImplBrowserControlsTest, ScrollNonScrollableRootWithBrowserControls) { settings_ = DefaultSettings(); - CreateHostImpl(settings_, CreateCompositorFrameSink()); + CreateHostImpl(settings_, CreateLayerTreeFrameSink()); SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); @@ -5100,7 +5395,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, { host_impl_->pending_tree() ->property_trees() - ->scroll_tree.SetScrollOffsetDeltaForTesting(outer_scroll->id(), + ->scroll_tree.SetScrollOffsetDeltaForTesting(outer_scroll->element_id(), gfx::Vector2dF(0, 1050)); host_impl_->ActivateSyncTree(); @@ -5122,19 +5417,19 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { content_layer->SetPosition(gfx::PointF()); content_layer->SetBounds(contents_size); - LayerImpl* scroll_clip_layer = + LayerImpl* scroll_container_layer = CreateBasicVirtualViewportLayers(surface_size, surface_size); std::unique_ptr<LayerImpl> scroll_layer = LayerImpl::Create(host_impl_->active_tree(), 12); - scroll_layer->SetScrollClipLayer(scroll_clip_layer->id()); + scroll_layer->SetScrollable(surface_size); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); scroll_layer->SetBounds(contents_size); scroll_layer->SetPosition(gfx::PointF()); scroll_layer->test_properties()->AddChild(std::move(content_layer)); - scroll_clip_layer->test_properties()->AddChild(std::move(scroll_layer)); + scroll_container_layer->test_properties()->AddChild(std::move(scroll_layer)); - scroll_clip_layer->test_properties()->force_render_surface = true; + scroll_container_layer->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(surface_size); @@ -5158,8 +5453,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { LayerImpl* root = CreateBasicVirtualViewportLayers(surface_size, surface_size); - root->test_properties()->AddChild( - CreateScrollableLayer(12, contents_size, root)); + root->test_properties()->AddChild(CreateScrollableLayer(12, contents_size)); root->test_properties()->force_render_surface = true; host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -5181,8 +5475,7 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { gfx::Size surface_size(10, 10); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->AddChild( - CreateScrollableLayer(2, surface_size, root.get())); + root->test_properties()->AddChild(CreateScrollableLayer(2, surface_size)); root->test_properties()->force_render_surface = true; host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -5207,8 +5500,7 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); root->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, surface_size, root.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); gfx::Transform matrix; matrix.RotateAboutXAxis(180.0); @@ -5236,23 +5528,17 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> clip_layer = - LayerImpl::Create(host_impl_->active_tree(), 3); std::unique_ptr<LayerImpl> content_layer = - CreateScrollableLayer(1, surface_size, clip_layer.get()); + CreateScrollableLayer(1, surface_size); content_layer->set_main_thread_scrolling_reasons( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); - content_layer->SetScrollClipLayer(Layer::INVALID_ID); // Note: we can use the same clip layer for both since both calls to // CreateScrollableLayer() use the same surface size. std::unique_ptr<LayerImpl> scroll_layer = - CreateScrollableLayer(2, surface_size, clip_layer.get()); + CreateScrollableLayer(2, surface_size); scroll_layer->test_properties()->AddChild(std::move(content_layer)); - clip_layer->test_properties()->AddChild(std::move(scroll_layer)); - clip_layer->test_properties()->force_render_surface = true; - - host_impl_->active_tree()->SetRootLayerForTesting(std::move(clip_layer)); + host_impl_->active_tree()->SetRootLayerForTesting(std::move(scroll_layer)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(surface_size); @@ -5274,23 +5560,18 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { SetupScrollAndContentsLayers(viewport_size); // Setup the layers so that the outer viewport is scrollable. - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->parent->SetBounds(viewport_size); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds( - gfx::Size(40, 40)); + host_impl_->InnerViewportScrollLayer()->test_properties()->parent->SetBounds( + viewport_size); + host_impl_->OuterViewportScrollLayer()->SetBounds(gfx::Size(40, 40)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); DrawFrame(); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); - EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds()); + LayerImpl* root_container = host_impl_->OuterViewportContainerLayer(); + EXPECT_EQ(viewport_size, root_container->bounds()); gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta = scroll_delta; + LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -5305,7 +5586,8 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(), + LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); // The scroll range should also have been updated. @@ -5323,25 +5605,20 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { SetupScrollAndContentsLayers(viewport_size); // Setup the layers so that the outer viewport is scrollable. - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->parent->SetBounds(viewport_size); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds( - gfx::Size(40, 40)); + host_impl_->InnerViewportScrollLayer()->test_properties()->parent->SetBounds( + viewport_size); + host_impl_->OuterViewportScrollLayer()->SetBounds(gfx::Size(40, 40)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); - EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds()); + LayerImpl* root_container = host_impl_->OuterViewportContainerLayer(); + EXPECT_EQ(viewport_size, root_container->bounds()); gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta = scroll_delta; + LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -5364,7 +5641,8 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { // The scroll delta is not scaled because the main thread did not scale. std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(), + LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); // The scroll range should also have been updated. @@ -5395,7 +5673,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { std::unique_ptr<LayerImpl> scrollable_child_clip = LayerImpl::Create(host_impl_->active_tree(), 6); std::unique_ptr<LayerImpl> scrollable_child = - CreateScrollableLayer(7, surface_size, scrollable_child_clip.get()); + CreateScrollableLayer(7, surface_size); scrollable_child_clip->test_properties()->AddChild( std::move(scrollable_child)); child->test_properties()->AddChild(std::move(scrollable_child_clip)); @@ -5463,7 +5741,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); // The scroll range should not have changed. @@ -5485,10 +5763,9 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { root->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(13, content_size, root); + CreateScrollableLayer(13, content_size); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(12, content_size, root); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); @@ -5499,11 +5776,11 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { grand_child_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(), - gfx::ScrollOffset(0, 5)); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + grand_child_layer->element_id(), gfx::ScrollOffset(0, 5)); child_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(3, 0)); host_impl_->SetViewportSize(surface_size); @@ -5526,11 +5803,12 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { ->root_layer_for_testing() ->test_properties() ->children[0]; - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), + grand_child_layer->element_id(), gfx::Vector2d(0, -5))); // The child should not have scrolled. - ExpectNone(*scroll_info.get(), child->id()); + ExpectNone(*scroll_info.get(), child->element_id()); } } @@ -5550,10 +5828,9 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { root->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(13, content_size, root); + CreateScrollableLayer(13, content_size); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(12, content_size, root); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); @@ -5565,11 +5842,11 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { grand_child_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(), - gfx::ScrollOffset(0, 30)); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + grand_child_layer->element_id(), gfx::ScrollOffset(0, 30)); child_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(0, 50)); host_impl_->SetViewportSize(surface_size); @@ -5631,7 +5908,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { host_impl_->DidFinishImplFrame(); // Tear down the LayerTreeHostImpl before the InputHandlerClient. - host_impl_->ReleaseCompositorFrameSink(); + host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; } @@ -5648,23 +5925,21 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(host_impl_->active_tree(), kViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scrolling = CreateScrollableLayer( - kViewportScrollLayerId, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scrolling = + CreateScrollableLayer(kViewportScrollLayerId, surface_size); root_scrolling->test_properties()->is_container_for_fixed_position_layers = true; std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(5, surface_size, root_clip.get()); + CreateScrollableLayer(5, surface_size); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(4, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(4, surface_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); LayerImpl* child_layer = child.get(); root_scrolling->test_properties()->AddChild(std::move(child)); root_clip->test_properties()->AddChild(std::move(root_scrolling)); - EXPECT_EQ(viewport_size, root_clip->bounds()); root_ptr->test_properties()->AddChild(std::move(root_clip)); host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); @@ -5678,11 +5953,11 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { grand_child_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(), - gfx::ScrollOffset(0, 2)); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + grand_child_layer->element_id(), gfx::ScrollOffset(0, 2)); child_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(0, 3)); DrawFrame(); @@ -5709,11 +5984,11 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { ->test_properties() ->children[0]; LayerImpl* grand_child = child->test_properties()->children[0]; - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(), - gfx::Vector2d(0, -2))); + EXPECT_TRUE(ScrollInfoContains( + *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, -2))); // The child should not have scrolled. - ExpectNone(*scroll_info.get(), child->id()); + ExpectNone(*scroll_info.get(), child->element_id()); // The next time we scroll we should only scroll the parent. scroll_delta = gfx::Vector2d(0, -3); @@ -5732,12 +6007,12 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { scroll_info = host_impl_->ProcessScrollDeltas(); // The child should have scrolled up to its limit. - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(), gfx::Vector2d(0, -3))); // The grand child should not have scrolled. - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(), - gfx::Vector2d(0, -2))); + EXPECT_TRUE(ScrollInfoContains( + *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, -2))); // After scrolling the parent, another scroll on the opposite direction // should still scroll the child. @@ -5757,11 +6032,11 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { scroll_info = host_impl_->ProcessScrollDeltas(); // The grand child should have scrolled. - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(), - gfx::Vector2d(0, 5))); + EXPECT_TRUE(ScrollInfoContains( + *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, 5))); // The child should not have scrolled. - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(), gfx::Vector2d(0, -3))); // Scrolling should be adjusted from viewport space. @@ -5782,8 +6057,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { scroll_info = host_impl_->ProcessScrollDeltas(); // Should have scrolled by half the amount in layer space (5 - 2/2) - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(), - gfx::Vector2d(0, 4))); + EXPECT_TRUE(ScrollInfoContains( + *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, 4))); } } TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { @@ -5799,16 +6074,17 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { 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( - kViewportClipLayerId, content_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scroll = + CreateScrollableLayer(kViewportClipLayerId, content_size); // 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( - kViewportScrollLayerId, content_size, root_scroll.get()); + std::unique_ptr<LayerImpl> child = + CreateScrollableLayer(kViewportScrollLayerId, content_size); child->test_properties()->is_container_for_fixed_position_layers = true; root_scroll->SetBounds(content_size); + child->SetScrollable(content_size); - int root_scroll_id = root_scroll->id(); + ElementId root_scroll_id = root_scroll->element_id(); root_scroll->test_properties()->AddChild(std::move(child)); root_clip->test_properties()->AddChild(std::move(root_scroll)); root_ptr->test_properties()->AddChild(std::move(root_clip)); @@ -5855,12 +6131,12 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); - std::unique_ptr<LayerImpl> inner_scroll = CreateScrollableLayer( - kInnerViewportScrollLayerId, surface_size, inner_clip.get()); + std::unique_ptr<LayerImpl> inner_scroll = + CreateScrollableLayer(kInnerViewportScrollLayerId, surface_size); std::unique_ptr<LayerImpl> outer_clip = LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId); - std::unique_ptr<LayerImpl> outer_scroll = CreateScrollableLayer( - kOuterViewportScrollLayerId, surface_size, outer_clip.get()); + std::unique_ptr<LayerImpl> outer_scroll = + CreateScrollableLayer(kOuterViewportScrollLayerId, surface_size); inner_clip->test_properties()->force_render_surface = true; inner_scroll->test_properties()->is_container_for_fixed_position_layers = true; @@ -5897,12 +6173,12 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { LayerImpl::Create(host_impl_->active_tree(), 4); std::unique_ptr<LayerImpl> inner_clip2 = LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId2); - std::unique_ptr<LayerImpl> inner_scroll2 = CreateScrollableLayer( - kInnerViewportScrollLayerId2, surface_size, inner_clip2.get()); + std::unique_ptr<LayerImpl> inner_scroll2 = + CreateScrollableLayer(kInnerViewportScrollLayerId2, surface_size); std::unique_ptr<LayerImpl> outer_clip2 = LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId2); - std::unique_ptr<LayerImpl> outer_scroll2 = CreateScrollableLayer( - kOuterViewportScrollLayerId2, surface_size, outer_clip2.get()); + std::unique_ptr<LayerImpl> outer_scroll2 = + CreateScrollableLayer(kOuterViewportScrollLayerId2, surface_size); inner_scroll2->test_properties()->is_container_for_fixed_position_layers = true; outer_scroll2->test_properties()->is_container_for_fixed_position_layers = @@ -5961,7 +6237,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { // The layer should have scrolled down in its local coordinates. std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(), gfx::Vector2d(0, gesture_scroll_delta.x()))); // Reset and scroll down with the wheel. @@ -5977,7 +6253,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { // The layer should have scrolled down in its local coordinates. scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(), wheel_scroll_delta)); } @@ -5990,8 +6266,8 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { // Create a child layer that is rotated to a non-axis-aligned angle. std::unique_ptr<LayerImpl> clip_layer = LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer( - child_layer_id, scroll_layer->bounds(), clip_layer.get()); + std::unique_ptr<LayerImpl> child = + CreateScrollableLayer(child_layer_id, scroll_layer->bounds()); gfx::Transform rotate_transform; rotate_transform.Translate(-50.0, -50.0); rotate_transform.Rotate(child_layer_angle); @@ -5999,8 +6275,10 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { clip_layer->test_properties()->transform = rotate_transform; // Only allow vertical scrolling. - clip_layer->SetBounds( - gfx::Size(child->bounds().width(), child->bounds().height() / 2)); + gfx::Size scroll_container_bounds = + gfx::Size(child->bounds().width(), child->bounds().height() / 2); + clip_layer->SetBounds(scroll_container_bounds); + child->SetScrollable(scroll_container_bounds); // The rotation depends on the layer's transform origin, and the child layer // is a different size than the clip, so make sure the clip layer's origin // lines up over the child. @@ -6008,9 +6286,12 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f); LayerImpl* child_ptr = child.get(); clip_layer->test_properties()->AddChild(std::move(child)); + // TODO(pdr): Shouldn't clip_layer be scroll_layer's parent? scroll_layer->test_properties()->AddChild(std::move(clip_layer)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); + ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id); + gfx::Size surface_size(50, 50); host_impl_->SetViewportSize(surface_size); DrawFrame(); @@ -6032,7 +6313,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { std::cos(MathUtil::Deg2Rad(child_layer_angle))); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id, + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id, expected_scroll_delta)); // The root scroll layer should not have scrolled, because the input delta @@ -6051,17 +6332,18 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); - // The child layer shouldn't have scrolled. + // The child layer should have scrolled down in its local coordinates an + // amount proportional to the angle between it and the input scroll delta. gfx::Vector2d expected_scroll_delta( 0, -gesture_scroll_delta.x() * std::sin(MathUtil::Deg2Rad(child_layer_angle))); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id, + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id, expected_scroll_delta)); // The root scroll layer shouldn't have scrolled. - ExpectNone(*scroll_info.get(), scroll_layer->id()); + ExpectNone(*scroll_info.get(), scroll_layer->element_id()); } } @@ -6075,8 +6357,8 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { // Create a child layer that is rotated on its x axis, with perspective. std::unique_ptr<LayerImpl> clip_layer = LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer( - child_layer_id, scroll_layer->bounds(), clip_layer.get()); + std::unique_ptr<LayerImpl> child = + CreateScrollableLayer(child_layer_id, scroll_layer->bounds()); LayerImpl* child_ptr = child.get(); gfx::Transform perspective_transform; perspective_transform.Translate(-50.0, -50.0); @@ -6136,7 +6418,8 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { host_impl_->ScrollEnd(EndState().get()); scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id, + ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id); + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id, expected_scroll_deltas[i])); // The root scroll layer should not have scrolled, because the input delta @@ -6174,7 +6457,7 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { // amount. std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(), gfx::Vector2d(0, scroll_delta.y() / scale))); // Reset and scroll down with the wheel. @@ -6190,7 +6473,7 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { // It should apply the scale factor to the scroll delta for the wheel event. scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(), wheel_scroll_delta)); } @@ -6199,8 +6482,11 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) { int height = 20; int scale = 3; SetupScrollAndContentsLayers(gfx::Size(width, height)); + gfx::Size container_bounds = gfx::Size(width * scale - 1, height * scale); host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - gfx::Size(width * scale - 1, height * scale)); + container_bounds); + host_impl_->active_tree()->InnerViewportScrollLayer()->SetScrollable( + container_bounds); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->SetDeviceScaleFactor(scale); @@ -6219,6 +6505,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { LayerImpl* clip_layer = scroll_layer->test_properties()->parent->test_properties()->parent; clip_layer->SetBounds(gfx::Size(10, 20)); + scroll_layer->SetScrollable(gfx::Size(10, 20)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->BindToClient(&scroll_watcher, false); @@ -6226,7 +6513,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { gfx::Vector2dF initial_scroll_delta(10.f, 10.f); scroll_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), gfx::ScrollOffset()); SetScrollOffsetDelta(scroll_layer, initial_scroll_delta); @@ -6310,7 +6597,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { EXPECT_EQ(gfx::SizeF(new_size), scroll_watcher.scrollable_size()); // Tear down the LayerTreeHostImpl before the InputHandlerClient. - host_impl_->ReleaseCompositorFrameSink(); + host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; } @@ -6331,6 +6618,7 @@ TEST_F(LayerTreeHostImplTest, LayerImpl* clip_layer = scroll_layer->test_properties()->parent->test_properties()->parent; clip_layer->SetBounds(gfx::Size(10, 20)); + scroll_layer->SetScrollable(gfx::Size(10, 20)); scroll_layer->SetDrawsContent(true); // Draw first frame to clear any pending draws and check scroll. @@ -6493,14 +6781,13 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root = CreateScrollableLayer( - kInnerViewportScrollLayerId, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> root = + CreateScrollableLayer(kInnerViewportScrollLayerId, surface_size); std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(3, surface_size, root_clip.get()); + CreateScrollableLayer(3, surface_size); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, surface_size, root_clip.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); @@ -6518,12 +6805,12 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { child_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(0, 3)); grand_child_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(), - gfx::ScrollOffset(0, 2)); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + grand_child_layer->element_id(), gfx::ScrollOffset(0, 2)); host_impl_->SetViewportSize(surface_size); DrawFrame(); @@ -6626,13 +6913,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) { TEST_F(LayerTreeHostImplTest, OverscrollAlways) { InputHandlerScrollResult scroll_result; LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(50, 50)); LayerImpl* clip_layer = scroll_layer->test_properties()->parent->test_properties()->parent; clip_layer->SetBounds(gfx::Size(50, 50)); + scroll_layer->SetScrollable(gfx::Size(50, 50)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(gfx::Size(50, 50)); @@ -6730,7 +7018,7 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) { InputHandlerScrollResult scroll_result; LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); const gfx::Size content_size(50, 50); const gfx::Size viewport_size(50, 50); @@ -6790,20 +7078,15 @@ TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) { // passing through the outer viewport still scroll correctly and affect // browser controls. { - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10); - clip->SetBounds(viewport_size); - clip->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(viewport_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); scroll_layer = scroll.get(); - clip->test_properties()->AddChild(std::move(scroll)); - inner_scroll_layer->test_properties()->AddChild(std::move(clip)); + inner_scroll_layer->test_properties()->AddChild(std::move(scroll)); // Move the outer viewport layer away so that scrolls won't target it. host_impl_->active_tree()->OuterViewportContainerLayer()->SetPosition( @@ -6881,35 +7164,23 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) { // with another scrolling div inside it. Set the outer "div" to be the outer // viewport. { - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10); - clip->SetBounds(content_size); - clip->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(content_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); - std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 12); - clip2->SetBounds(gfx::Size(300, 300)); - clip2->SetPosition(gfx::PointF()); - clip2->SetDrawsContent(true); - std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 13); scroll2->SetBounds(gfx::Size(500, 500)); - scroll2->SetScrollClipLayer(clip2->id()); + scroll2->SetScrollable(gfx::Size(300, 300)); scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id())); scroll2->SetDrawsContent(true); scroll_layer = scroll.get(); child_scroll_layer = scroll2.get(); - clip2->test_properties()->AddChild(std::move(scroll2)); - scroll->test_properties()->AddChild(std::move(clip2)); - - clip->test_properties()->AddChild(std::move(scroll)); - content_layer->test_properties()->AddChild(std::move(clip)); + scroll->test_properties()->AddChild(std::move(scroll2)); + content_layer->test_properties()->AddChild(std::move(scroll)); LayerTreeImpl::ViewportLayerIds viewport_ids; viewport_ids.page_scale = layer_tree_impl->PageScaleLayer()->id(); viewport_ids.inner_viewport_scroll = inner_scroll_layer->id(); @@ -7016,36 +7287,26 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) { // set as the outer viewport. Add a sibling scrolling layer that isn't a child // of the outer viewport scroll layer. { - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10); - clip->SetBounds(content_size); - clip->SetPosition(gfx::PointF(100, 100)); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); scroll->SetBounds(gfx::Size(1200, 1200)); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(content_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); outer_scroll_layer = scroll.get(); - clip->test_properties()->AddChild(std::move(scroll)); - content_layer->test_properties()->AddChild(std::move(clip)); + content_layer->test_properties()->AddChild(std::move(scroll)); // Create the non-descendant. - std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 14); - clip2->SetBounds(gfx::Size(600, 600)); - clip2->SetPosition(gfx::PointF()); - std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 15); scroll2->SetBounds(gfx::Size(1200, 1200)); - scroll2->SetScrollClipLayer(clip2->id()); + scroll2->SetScrollable(gfx::Size(600, 600)); scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id())); scroll2->SetDrawsContent(true); sibling_scroll_layer = scroll2.get(); - clip2->test_properties()->AddChild(std::move(scroll2)); - content_layer->test_properties()->AddChild(std::move(clip2)); + content_layer->test_properties()->AddChild(std::move(scroll2)); LayerImpl* inner_container = host_impl_->active_tree()->InnerViewportContainerLayer(); @@ -7180,7 +7441,7 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) { TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) { InputHandlerScrollResult scroll_result; LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); const gfx::Size content_size(50, 50); const gfx::Size viewport_size(50, 50); @@ -7281,7 +7542,7 @@ class BlendStateCheckLayer : public LayerImpl { resource_id_(resource_provider->CreateResource( gfx::Size(1, 1), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - RGBA_8888, + viz::RGBA_8888, gfx::ColorSpace())) { resource_provider->AllocateForTesting(resource_id_); SetBounds(gfx::Size(10, 10)); @@ -7311,7 +7572,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { root->test_properties()->AddChild(BlendStateCheckLayer::Create( host_impl_->active_tree(), 2, host_impl_->resource_provider())); - BlendStateCheckLayer* layer1 = + auto* layer1 = static_cast<BlendStateCheckLayer*>(root->test_properties()->children[0]); layer1->SetPosition(gfx::PointF(2.f, 2.f)); @@ -7364,7 +7625,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->test_properties()->AddChild(BlendStateCheckLayer::Create( host_impl_->active_tree(), 3, host_impl_->resource_provider())); - BlendStateCheckLayer* layer2 = static_cast<BlendStateCheckLayer*>( + auto* layer2 = static_cast<BlendStateCheckLayer*>( layer1->test_properties()->children[0]); layer2->SetPosition(gfx::PointF(4.f, 4.f)); @@ -7569,12 +7830,12 @@ TEST_F(LayerTreeHostImplTest, MayContainVideo) { int layer_id = 1; host_impl_->active_tree()->SetRootLayerForTesting( DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); - DidDrawCheckLayer* root = + auto* root = static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); root->test_properties()->AddChild( DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); - DidDrawCheckLayer* video_layer = + auto* video_layer = static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); video_layer->set_may_contain_video(true); EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get())); @@ -7582,7 +7843,7 @@ TEST_F(LayerTreeHostImplTest, MayContainVideo) { // Test with the video layer occluded. root->test_properties()->AddChild( DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); - DidDrawCheckLayer* large_layer = + auto* large_layer = static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); large_layer->SetBounds(big_size); large_layer->SetContentsOpaque(true); @@ -7608,11 +7869,11 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { child_(NULL), did_activate_pending_tree_(false) {} - std::unique_ptr<CompositorFrameSink> CreateFakeCompositorFrameSink( + std::unique_ptr<LayerTreeFrameSink> CreateFakeLayerTreeFrameSink( bool software) { if (software) - return FakeCompositorFrameSink::CreateSoftware(); - return FakeCompositorFrameSink::Create3d(); + return FakeLayerTreeFrameSink::CreateSoftware(); + return FakeLayerTreeFrameSink::Create3d(); } void SetupActiveTreeLayers() { @@ -7829,7 +8090,7 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) { viewport_size_ = gfx::Size(1000, 1000); bool software = false; - CreateHostImpl(DefaultSettings(), CreateFakeCompositorFrameSink(software)); + CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); SetupActiveTreeLayers(); @@ -7843,7 +8104,7 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) { viewport_size_ = gfx::Size(1000, 1000); bool software = false; - CreateHostImpl(DefaultSettings(), CreateFakeCompositorFrameSink(software)); + CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); host_impl_->active_tree()->SetDeviceScaleFactor(2.f); host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); @@ -7858,7 +8119,7 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) { viewport_size_ = gfx::Size(1000, 1000); bool software = true; - CreateHostImpl(DefaultSettings(), CreateFakeCompositorFrameSink(software)); + CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); // Pending tree to force active_tree size invalid. Not used otherwise. host_impl_->CreatePendingTree(); @@ -7875,7 +8136,7 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) { viewport_size_ = gfx::Size(1000, 1000); bool software = true; - CreateHostImpl(DefaultSettings(), CreateFakeCompositorFrameSink(software)); + CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); // Set larger viewport and activate it to active tree. host_impl_->CreatePendingTree(); @@ -7909,30 +8170,30 @@ class FakeDrawableLayerImpl : public LayerImpl { : LayerImpl(tree_impl, id) {} }; -// Make sure damage tracking propagates all the way to the graphics context, -// where it should request to swap only the sub-buffer that is damaged. +// Make sure damage tracking propagates all the way to the CompositorFrame +// submitted to the LayerTreeFrameSink, where it should request to swap only +// the sub-buffer that is damaged. TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { scoped_refptr<TestContextProvider> context_provider( TestContextProvider::Create()); context_provider->BindToCurrentThread(); context_provider->TestContext3d()->set_have_post_sub_buffer(true); - std::unique_ptr<FakeCompositorFrameSink> compositor_frame_sink( - FakeCompositorFrameSink::Create3d(context_provider)); - FakeCompositorFrameSink* fake_compositor_frame_sink = - compositor_frame_sink.get(); + std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink( + FakeLayerTreeFrameSink::Create3d(context_provider)); + FakeLayerTreeFrameSink* fake_layer_tree_frame_sink = + layer_tree_frame_sink.get(); // This test creates its own LayerTreeHostImpl, so // that we can force partial swap enabled. LayerTreeSettings settings = DefaultSettings(); - settings.renderer_settings.partial_swap_enabled = true; std::unique_ptr<LayerTreeHostImpl> layer_tree_host_impl = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr); layer_tree_host_impl->SetVisible(true); - layer_tree_host_impl->InitializeRenderer(compositor_frame_sink.get()); + layer_tree_host_impl->InitializeRenderer(layer_tree_frame_sink.get()); layer_tree_host_impl->WillBeginImplFrame( CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2)); layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500)); @@ -7959,7 +8220,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { layer_tree_host_impl->DidDrawAllLayers(frame); gfx::Rect expected_swap_rect(500, 500); EXPECT_EQ(expected_swap_rect.ToString(), - fake_compositor_frame_sink->last_swap_rect().ToString()); + fake_layer_tree_frame_sink->last_swap_rect().ToString()); // Second frame, only the damaged area should get swapped. Damage should be // the union of old and new child rects: gfx::Rect(26, 28). @@ -7980,7 +8241,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { expected_swap_rect = gfx::Rect(26, 28); EXPECT_EQ(expected_swap_rect.ToString(), - fake_compositor_frame_sink->last_swap_rect().ToString()); + fake_layer_tree_frame_sink->last_swap_rect().ToString()); layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10)); // This will damage everything. @@ -7993,9 +8254,9 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { expected_swap_rect = gfx::Rect(10, 10); EXPECT_EQ(expected_swap_rect.ToString(), - fake_compositor_frame_sink->last_swap_rect().ToString()); + fake_layer_tree_frame_sink->last_swap_rect().ToString()); - layer_tree_host_impl->ReleaseCompositorFrameSink(); + layer_tree_host_impl->ReleaseLayerTreeFrameSink(); } TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { @@ -8047,145 +8308,13 @@ class FakeLayerWithQuads : public LayerImpl { : LayerImpl(tree_impl, id) {} }; -static std::unique_ptr<LayerTreeHostImpl> SetupLayersForOpacity( - LayerTreeSettings settings, - bool partial_swap, - LayerTreeHostImplClient* client, - TaskRunnerProvider* task_runner_provider, - TaskGraphRunner* task_graph_runner, - RenderingStatsInstrumentation* stats_instrumentation, - CompositorFrameSink* compositor_frame_sink) { - settings.renderer_settings.partial_swap_enabled = partial_swap; - std::unique_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create( - settings, client, task_runner_provider, stats_instrumentation, - task_graph_runner, AnimationHost::CreateForTesting(ThreadInstance::IMPL), - 0, nullptr); - my_host_impl->SetVisible(true); - my_host_impl->InitializeRenderer(compositor_frame_sink); - my_host_impl->WillBeginImplFrame( - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2)); - my_host_impl->SetViewportSize(gfx::Size(100, 100)); - - /* - Layers are created as follows: - - +--------------------+ - | 1 | - | +-----------+ | - | | 2 | | - | | +-------------------+ - | | | 3 | - | | +-------------------+ - | | | | - | +-----------+ | - | | - | | - +--------------------+ - - Layers 1, 2 have render surfaces - */ - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(my_host_impl->active_tree(), 1); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(my_host_impl->active_tree(), 2); - std::unique_ptr<LayerImpl> grand_child = - FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3); - - gfx::Rect root_rect(0, 0, 100, 100); - gfx::Rect child_rect(10, 10, 50, 50); - gfx::Rect grand_child_rect(5, 5, 150, 150); - - root->test_properties()->force_render_surface = true; - root->SetPosition(gfx::PointF(root_rect.origin())); - root->SetBounds(root_rect.size()); - root->draw_properties().visible_layer_rect = root_rect; - root->SetDrawsContent(false); - - child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y())); - child->test_properties()->opacity = 0.5f; - child->SetBounds(gfx::Size(child_rect.width(), child_rect.height())); - child->draw_properties().visible_layer_rect = child_rect; - child->SetDrawsContent(false); - child->test_properties()->force_render_surface = true; - - grand_child->SetPosition(gfx::PointF(grand_child_rect.origin())); - grand_child->SetBounds(grand_child_rect.size()); - grand_child->draw_properties().visible_layer_rect = grand_child_rect; - grand_child->SetDrawsContent(true); - - child->test_properties()->AddChild(std::move(grand_child)); - root->test_properties()->AddChild(std::move(child)); - - my_host_impl->active_tree()->SetRootLayerForTesting(std::move(root)); - my_host_impl->active_tree()->BuildPropertyTreesForTesting(); - return my_host_impl; -} - -TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) { - TestTaskGraphRunner task_graph_runner; - scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); - provider->BindToCurrentThread(); - provider->TestContext3d()->set_have_post_sub_buffer(true); - std::unique_ptr<CompositorFrameSink> compositor_frame_sink( - FakeCompositorFrameSink::Create3d(provider)); - std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity( - DefaultSettings(), true, this, &task_runner_provider_, &task_graph_runner, - &stats_instrumentation_, compositor_frame_sink.get()); - { - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame)); - - // Verify all quads have been computed - ASSERT_EQ(2U, frame.render_passes.size()); - ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size()); - ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size()); - EXPECT_EQ(DrawQuad::SOLID_COLOR, - frame.render_passes[0]->quad_list.front()->material); - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list.front()->material); - - my_host_impl->DrawLayers(&frame); - my_host_impl->DidDrawAllLayers(frame); - } - my_host_impl->ReleaseCompositorFrameSink(); -} - -TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) { - TestTaskGraphRunner task_graph_runner; - scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); - provider->BindToCurrentThread(); - provider->TestContext3d()->set_have_post_sub_buffer(true); - std::unique_ptr<CompositorFrameSink> compositor_frame_sink( - FakeCompositorFrameSink::Create3d(provider)); - std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity( - DefaultSettings(), false, this, &task_runner_provider_, - &task_graph_runner, &stats_instrumentation_, compositor_frame_sink.get()); - { - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame)); - - // Verify all quads have been computed - ASSERT_EQ(2U, frame.render_passes.size()); - ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size()); - ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size()); - EXPECT_EQ(DrawQuad::SOLID_COLOR, - frame.render_passes[0]->quad_list.front()->material); - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list.front()->material); - - my_host_impl->DrawLayers(&frame); - my_host_impl->DidDrawAllLayers(frame); - } - my_host_impl->ReleaseCompositorFrameSink(); -} - TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); TestWebGraphicsContext3D* context3d = context.get(); - std::unique_ptr<CompositorFrameSink> compositor_frame_sink( - FakeCompositorFrameSink::Create3d(std::move(context))); - CreateHostImpl(DefaultSettings(), std::move(compositor_frame_sink)); + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink( + FakeLayerTreeFrameSink::Create3d(std::move(context))); + CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink)); std::unique_ptr<LayerImpl> root_layer = LayerImpl::Create(host_impl_->active_tree(), 1); @@ -8262,8 +8391,8 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest { protected: - std::unique_ptr<CompositorFrameSink> CreateCompositorFrameSink() override { - return FakeCompositorFrameSink::Create3d(); + std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() override { + return FakeLayerTreeFrameSink::Create3d(); } void DrawFrameAndTestDamage(const gfx::Rect& expected_damage) { @@ -8388,19 +8517,18 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { root->SetBounds(root_size); gfx::ScrollOffset scroll_offset(100000, 0); - scrolling_layer->SetScrollClipLayer(root->id()); + scrolling_layer->SetScrollable(content_layer_bounds); scrolling_layer->SetElementId( LayerIdToElementIdForTesting(scrolling_layer->id())); host_impl_->pending_tree()->BuildPropertyTreesForTesting(); scrolling_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(scrolling_layer->id(), - scroll_offset); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + scrolling_layer->element_id(), scroll_offset); host_impl_->ActivateSyncTree(); - bool update_lcd_text = false; - host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl_->active_tree()->UpdateDrawProperties(); ASSERT_EQ(1u, host_impl_->active_tree()->GetRenderSurfaceList().size()); TestFrameData frame; @@ -8443,7 +8571,7 @@ TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { host_impl_->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); } - host_impl_->ReclaimResources(ReturnedResourceArray()); + host_impl_->ReclaimResources(std::vector<ReturnedResource>()); host_impl_->DidReceiveCompositorFrameAck(); EXPECT_EQ(acks_received_, 1); } @@ -8468,7 +8596,7 @@ TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) { set_reduce_memory_result(false); EXPECT_TRUE(CreateHostImpl(DefaultSettings(), - FakeCompositorFrameSink::CreateSoftware())); + FakeLayerTreeFrameSink::CreateSoftware())); const gfx::Transform external_transform; const gfx::Rect external_viewport; @@ -8500,7 +8628,7 @@ TEST_F(LayerTreeHostImplTest, // Checks that we use the memory limits provided. TEST_F(LayerTreeHostImplTest, MemoryLimits) { - host_impl_->ReleaseCompositorFrameSink(); + host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; const size_t kGpuByteLimit = 1234321; @@ -8534,10 +8662,10 @@ TEST_F(LayerTreeHostImplTest, MemoryLimits) { AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr); // Gpu compositing. - compositor_frame_sink_ = - FakeCompositorFrameSink::Create3d(TestWebGraphicsContext3D::Create()); + layer_tree_frame_sink_ = + FakeLayerTreeFrameSink::Create3d(TestWebGraphicsContext3D::Create()); host_impl_->SetVisible(true); - host_impl_->InitializeRenderer(compositor_frame_sink_.get()); + host_impl_->InitializeRenderer(layer_tree_frame_sink_.get()); { const auto& state = host_impl_->global_tile_state(); EXPECT_EQ(kGpuByteLimit, state.hard_memory_limit_in_bytes); @@ -8563,9 +8691,9 @@ TEST_F(LayerTreeHostImplTest, MemoryLimits) { } // Software compositing. - host_impl_->ReleaseCompositorFrameSink(); - compositor_frame_sink_ = FakeCompositorFrameSink::CreateSoftware(); - host_impl_->InitializeRenderer(compositor_frame_sink_.get()); + host_impl_->ReleaseLayerTreeFrameSink(); + layer_tree_frame_sink_ = FakeLayerTreeFrameSink::CreateSoftware(); + host_impl_->InitializeRenderer(layer_tree_frame_sink_.get()); { const auto& state = host_impl_->global_tile_state(); EXPECT_EQ(kSoftwareByteLimit, state.hard_memory_limit_in_bytes); @@ -8651,16 +8779,19 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { host_impl_->ResetRequiresHighResToDraw(); - host_impl_->SetContentIsSuitableForGpuRasterization(true); + host_impl_->SetContentHasSlowPaths(false); host_impl_->SetHasGpuRasterizationTrigger(false); host_impl_->CommitComplete(); EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); + host_impl_->NotifyReadyToActivate(); host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); + host_impl_->NotifyReadyToActivate(); host_impl_->SetHasGpuRasterizationTrigger(false); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); + host_impl_->NotifyReadyToActivate(); host_impl_->ResetRequiresHighResToDraw(); @@ -8668,6 +8799,7 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); + host_impl_->NotifyReadyToActivate(); } class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest { @@ -8676,9 +8808,9 @@ class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest { fake_host_impl_ = new FakeLayerTreeHostImpl( LayerTreeSettings(), &task_runner_provider_, &task_graph_runner_); host_impl_.reset(fake_host_impl_); - compositor_frame_sink_ = CreateCompositorFrameSink(); + layer_tree_frame_sink_ = CreateLayerTreeFrameSink(); host_impl_->SetVisible(true); - host_impl_->InitializeRenderer(compositor_frame_sink_.get()); + host_impl_->InitializeRenderer(layer_tree_frame_sink_.get()); host_impl_->SetViewportSize(gfx::Size(10, 10)); } @@ -8697,9 +8829,9 @@ TEST_F(LayerTreeHostImplTest, UIResourceManagement) { std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); TestWebGraphicsContext3D* context3d = context.get(); - std::unique_ptr<FakeCompositorFrameSink> compositor_frame_sink = - FakeCompositorFrameSink::Create3d(); - CreateHostImpl(DefaultSettings(), std::move(compositor_frame_sink)); + std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink = + FakeLayerTreeFrameSink::Create3d(); + CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink)); EXPECT_EQ(0u, context3d->NumTextures()); @@ -8741,7 +8873,7 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { std::unique_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); TestWebGraphicsContext3D* context3d = context.get(); - CreateHostImpl(DefaultSettings(), FakeCompositorFrameSink::Create3d()); + CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::Create3d()); EXPECT_EQ(0u, context3d->NumTextures()); @@ -8751,7 +8883,7 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { // correct width/height are passed directly to UIResourceBitmap. SkImageInfo info = SkImageInfo::Make(4, 2, kAlpha_8_SkColorType, kPremul_SkAlphaType); - sk_sp<SkPixelRef> pixel_ref(SkMallocPixelRef::MakeAllocate(info, 0, 0)); + sk_sp<SkPixelRef> pixel_ref(SkMallocPixelRef::MakeAllocate(info, 0)); pixel_ref->setImmutable(); UIResourceBitmap bitmap(std::move(pixel_ref), size); UIResourceId ui_resource_id = 1; @@ -8764,49 +8896,51 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { void ShutdownReleasesContext_Callback( std::unique_ptr<CopyOutputResult> result) {} -class FrameSinkClient : public TestCompositorFrameSinkClient { +class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient { public: explicit FrameSinkClient( - scoped_refptr<ContextProvider> display_context_provider) + scoped_refptr<viz::ContextProvider> display_context_provider) : display_context_provider_(std::move(display_context_provider)) {} std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { return FakeOutputSurface::Create3d(std::move(display_context_provider_)); } void DisplayReceivedLocalSurfaceId( - const LocalSurfaceId& local_surface_id) override {} + const viz::LocalSurfaceId& local_surface_id) override {} void DisplayReceivedCompositorFrame(const CompositorFrame& frame) override {} void DisplayWillDrawAndSwap(bool will_draw_and_swap, const RenderPassList& render_passes) override {} void DisplayDidDrawAndSwap() override {} private: - scoped_refptr<ContextProvider> display_context_provider_; + scoped_refptr<viz::ContextProvider> display_context_provider_; }; TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); - FrameSinkClient test_client_(context_provider); + FrameSinkClient test_client(context_provider); constexpr bool synchronous_composite = true; constexpr bool disable_display_vsync = false; - auto compositor_frame_sink = base::MakeUnique<TestCompositorFrameSink>( + constexpr double refresh_rate = 60.0; + auto layer_tree_frame_sink = base::MakeUnique<viz::TestLayerTreeFrameSink>( context_provider, TestContextProvider::CreateWorker(), nullptr, nullptr, - RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(), - synchronous_composite, disable_display_vsync); - compositor_frame_sink->SetClient(&test_client_); + viz::RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(), + synchronous_composite, disable_display_vsync, refresh_rate); + layer_tree_frame_sink->SetClient(&test_client); - CreateHostImpl(DefaultSettings(), std::move(compositor_frame_sink)); + CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink)); SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); root->test_properties()->copy_requests.push_back( CopyOutputRequest::CreateRequest( - base::Bind(&ShutdownReleasesContext_Callback))); + base::BindOnce(&ShutdownReleasesContext_Callback))); host_impl_->active_tree()->BuildPropertyTreesForTesting(); TestFrameData frame; @@ -8814,12 +8948,12 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { host_impl_->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); - // The CopyOutputResult's callback has a ref on the ContextProvider and a + // The CopyOutputResult's callback has a ref on the viz::ContextProvider and a // texture in a texture mailbox. EXPECT_FALSE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); - host_impl_->ReleaseCompositorFrameSink(); + host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; // The CopyOutputResult's callback was cancelled, the CopyOutputResult @@ -8842,14 +8976,13 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scroll = CreateScrollableLayer( - kInnerViewportScrollLayerId, content_size, root_clip.get()); + std::unique_ptr<LayerImpl> root_scroll = + CreateScrollableLayer(kInnerViewportScrollLayerId, content_size); root_scroll->test_properties()->is_container_for_fixed_position_layers = true; - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, content_size, root_clip.get()); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size); root_scroll->test_properties()->AddChild(std::move(child)); - int root_id = root_scroll->id(); + ElementId root_id = root_scroll->element_id(); root_clip->test_properties()->AddChild(std::move(root_scroll)); root_ptr->test_properties()->AddChild(std::move(root_clip)); @@ -8897,17 +9030,17 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { root->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> root_scrolling_owned = - CreateScrollableLayer(12, surface_size, root); + CreateScrollableLayer(12, surface_size); auto* root_scrolling = root_scrolling_owned.get(); root->test_properties()->AddChild(std::move(root_scrolling_owned)); std::unique_ptr<LayerImpl> child_owned = - CreateScrollableLayer(13, surface_size, root); + CreateScrollableLayer(13, surface_size); auto* child = child_owned.get(); root_scrolling->test_properties()->AddChild(std::move(child_owned)); std::unique_ptr<LayerImpl> grand_child_owned = - CreateScrollableLayer(14, surface_size, root); + CreateScrollableLayer(14, surface_size); auto* grand_child = grand_child_owned.get(); child->test_properties()->AddChild(std::move(grand_child_owned)); @@ -8916,11 +9049,11 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { child->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(child->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(child->element_id(), gfx::ScrollOffset(0, 4)); grand_child->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child->element_id(), gfx::ScrollOffset(0, 2)); host_impl_->SetViewportSize(surface_size); @@ -8941,8 +9074,10 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { // The grand child should have scrolled up to its limit. scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(1u, scroll_info->scrolls.size()); + ElementId grand_child_scroll_id = + LayerIdToElementIdForTesting(grand_child->id()); EXPECT_TRUE( - ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta)); + ScrollInfoContains(*scroll_info, grand_child_scroll_id, scroll_delta)); EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, grand_child->scroll_tree_index()); @@ -8953,8 +9088,8 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(1u, scroll_info->scrolls.size()); EXPECT_TRUE( - ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta)); - ExpectNone(*scroll_info, child->id()); + ScrollInfoContains(*scroll_info, grand_child_scroll_id, scroll_delta)); + ExpectNone(*scroll_info, child->element_id()); EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, grand_child->scroll_tree_index()); @@ -8970,8 +9105,8 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(1u, scroll_info->scrolls.size()); EXPECT_TRUE( - ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta)); - ExpectNone(*scroll_info, child->id()); + ScrollInfoContains(*scroll_info, grand_child_scroll_id, scroll_delta)); + ExpectNone(*scroll_info, child->element_id()); // As the locked layer is at it's limit, no further scrolling can occur. EXPECT_FALSE( @@ -8991,10 +9126,9 @@ TEST_F(LayerTreeHostImplTest, WheelFlingShouldntBubble) { CreateBasicVirtualViewportLayers(surface_size, surface_size); root_clip->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> root_scroll = - CreateScrollableLayer(11, content_size, root_clip); - int root_scroll_id = root_scroll->id(); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(12, content_size, root_clip); + CreateScrollableLayer(11, content_size); + ElementId root_scroll_id = root_scroll->element_id(); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); root_scroll->test_properties()->AddChild(std::move(child)); root_clip->test_properties()->AddChild(std::move(root_scroll)); @@ -9088,8 +9222,8 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id); int child_scroll_layer_id = 8; - std::unique_ptr<LayerImpl> child_scroll = CreateScrollableLayer( - child_scroll_layer_id, content_size, child_scroll_clip.get()); + std::unique_ptr<LayerImpl> child_scroll = + CreateScrollableLayer(child_scroll_layer_id, content_size); child_scroll->SetPosition(gfx::PointF(10.f, 10.f)); @@ -9111,15 +9245,13 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) { gfx::Size content_size(100, 100); SetupScrollAndContentsLayers(content_size); - LayerImpl* root = host_impl_->active_tree()->LayerById(1); - int scroll_layer_id = 2; LayerImpl* scroll_layer = host_impl_->active_tree()->LayerById(scroll_layer_id); int child_scroll_layer_id = 7; std::unique_ptr<LayerImpl> child_scroll = - CreateScrollableLayer(child_scroll_layer_id, content_size, root); + CreateScrollableLayer(child_scroll_layer_id, content_size); child_scroll->SetDrawsContent(false); scroll_layer->test_properties()->AddChild(std::move(child_scroll)); @@ -9152,11 +9284,11 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - FakeCompositorFrameSink* fake_compositor_frame_sink = - static_cast<FakeCompositorFrameSink*>( - host_impl_->compositor_frame_sink()); + auto* fake_layer_tree_frame_sink = + static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); ui::LatencyInfo latency_info; + latency_info.set_trace_id(5); latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0); std::unique_ptr<SwapPromise> swap_promise( @@ -9170,7 +9302,7 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { host_impl_->DidDrawAllLayers(frame); const std::vector<ui::LatencyInfo>& metadata_latency_after = - fake_compositor_frame_sink->last_sent_frame()->metadata.latency_info; + fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; EXPECT_EQ(1u, metadata_latency_after.size()); EXPECT_TRUE(metadata_latency_after[0].FindLatency( ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL)); @@ -9189,9 +9321,8 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { host_impl_->active_tree()->BuildPropertyTreesForTesting(); // Ensure the default frame selection bounds are empty. - FakeCompositorFrameSink* fake_compositor_frame_sink = - static_cast<FakeCompositorFrameSink*>( - host_impl_->compositor_frame_sink()); + auto* fake_layer_tree_frame_sink = + static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); // Plumb the layer-local selection bounds. gfx::Point selection_top(5, 0); @@ -9215,7 +9346,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { // Ensure the selection bounds have propagated to the frame metadata. const Selection<gfx::SelectionBound>& selection_after = - fake_compositor_frame_sink->last_sent_frame()->metadata.selection; + fake_layer_tree_frame_sink->last_sent_frame()->metadata.selection; EXPECT_EQ(selection.start.type, selection_after.start.type()); EXPECT_EQ(selection.end.type, selection_after.end.type()); EXPECT_EQ(gfx::PointF(selection_bottom), selection_after.start.edge_bottom()); @@ -9354,7 +9485,7 @@ class LayerTreeHostImplWithBrowserControlsTest : public LayerTreeHostImplTest { public: void SetUp() override { LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->set_top_controls_height(top_controls_height_); host_impl_->sync_tree()->set_top_controls_height(top_controls_height_); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); @@ -9370,7 +9501,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, NoIdleAnimations) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); scroll_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), gfx::ScrollOffset(0, 10)); BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2); @@ -9411,7 +9542,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); scroll_layer->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(), + ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), gfx::ScrollOffset(0, 10)); host_impl_->DidChangeBrowserControlsPosition(); EXPECT_TRUE(did_request_next_frame_); @@ -9628,7 +9759,8 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer->id(), gfx::ScrollOffset(0, initial_scroll_offset)); + scroll_layer->element_id(), + gfx::ScrollOffset(0, initial_scroll_offset)); DrawFrame(); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -9705,7 +9837,8 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - scroll_layer->id(), gfx::ScrollOffset(0, initial_scroll_offset)); + scroll_layer->element_id(), + gfx::ScrollOffset(0, initial_scroll_offset)); DrawFrame(); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -9878,7 +10011,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); scroll->SetBounds(scroll_content_size); - scroll->SetScrollClipLayer(clip->id()); + scroll->SetScrollable(root_layer_size); scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); scroll->SetDrawsContent(true); @@ -9936,8 +10069,8 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { true; inner_scroll->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(), - gfx::ScrollOffset()); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + inner_scroll->element_id(), gfx::ScrollOffset()); std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); @@ -9946,7 +10079,7 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { std::unique_ptr<LayerImpl> page_scale = LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); - inner_scroll->SetScrollClipLayer(inner_clip->id()); + inner_scroll->SetScrollable(inner_viewport); inner_scroll->SetElementId( LayerIdToElementIdForTesting(inner_scroll->id())); inner_scroll->SetBounds(outer_viewport); @@ -9960,13 +10093,13 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { std::unique_ptr<LayerImpl> outer_scroll = LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); - outer_scroll->SetScrollClipLayer(outer_clip->id()); + outer_scroll->SetScrollable(outer_viewport); outer_scroll->SetElementId( LayerIdToElementIdForTesting(outer_scroll->id())); outer_scroll->layer_tree_impl() ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(), - gfx::ScrollOffset()); + ->scroll_tree.UpdateScrollOffsetBaseForTesting( + outer_scroll->element_id(), gfx::ScrollOffset()); outer_scroll->SetBounds(content_size); outer_scroll->SetPosition(gfx::PointF()); @@ -10172,13 +10305,14 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(10, outer_viewport, outer_scroll); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport); LayerImpl* child_scroll = child.get(); outer_scroll->test_properties()->children[0]->test_properties()->AddChild( std::move(child)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); + ElementId child_scroll_id = LayerIdToElementIdForTesting(child_scroll->id()); + DrawFrame(); { std::unique_ptr<ScrollAndScaleSet> scroll_info; @@ -10199,7 +10333,7 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(1u, scroll_info->scrolls.size()); EXPECT_TRUE( - ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta)); + ScrollInfoContains(*scroll_info, child_scroll_id, scroll_delta)); EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, child_scroll->scroll_tree_index()); @@ -10218,8 +10352,8 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(1u, scroll_info->scrolls.size()); EXPECT_TRUE( - ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta)); - ExpectNone(*scroll_info, inner_scroll->id()); + ScrollInfoContains(*scroll_info, child_scroll_id, scroll_delta)); + ExpectNone(*scroll_info, inner_scroll->element_id()); // As the locked layer is at its limit, no further scrolling can occur. EXPECT_FALSE( @@ -10243,8 +10377,7 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(10, outer_viewport, outer_scroll); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport); LayerImpl* child_scroll = child.get(); outer_scroll->test_properties()->children[0]->test_properties()->AddChild( std::move(child)); @@ -10279,8 +10412,8 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); // Make inner viewport unscrollable. LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - inner_scroll->set_user_scrollable_horizontal(false); - inner_scroll->set_user_scrollable_vertical(false); + inner_scroll->test_properties()->user_scrollable_horizontal = false; + inner_scroll->test_properties()->user_scrollable_vertical = false; host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -10306,7 +10439,7 @@ class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest { void SetUp() override { LayerTreeSettings settings = DefaultSettings(); settings.max_memory_for_prepaint_percentage = 50; - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); } }; @@ -10420,14 +10553,13 @@ TEST_F(LayerTreeHostImplTest, TouchInsideFlingLayer) { root->test_properties()->force_render_surface = true; // A div layer which has an event handler. - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(26, surface_size, root); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(26, surface_size); LayerImpl* child_layer = child.get(); // The layer tree should create a layer for the div layer, which is the // actual scrolling layer. std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(27, content_size, root); + CreateScrollableLayer(27, content_size); LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); @@ -10439,12 +10571,17 @@ TEST_F(LayerTreeHostImplTest, TouchInsideFlingLayer) { DrawFrame(); { + TouchAction touch_action; // Touch on a layer which does not have a handler will return kNone. - EXPECT_EQ(InputHandler::TouchStartEventListenerType::NO_HANDLER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(10, 10))); - child_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100)); - EXPECT_EQ(InputHandler::TouchStartEventListenerType::HANDLER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(10, 10))); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType::NO_HANDLER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(10, 10), &touch_action)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 100, 100)); + child_layer->SetTouchActionRegion(touch_action_region); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType::HANDLER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(10, 10), &touch_action)); // Flinging the grand_child layer. EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -10457,9 +10594,10 @@ TEST_F(LayerTreeHostImplTest, TouchInsideFlingLayer) { host_impl_->CurrentlyScrollingNode()->id); // Touch on the grand_child layer, which is an active fling layer, the touch // event handler will force to be passive. - EXPECT_EQ( - InputHandler::TouchStartEventListenerType::HANDLER_ON_SCROLLING_LAYER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(70, 80))); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType:: + HANDLER_ON_SCROLLING_LAYER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(70, 80), &touch_action)); } } @@ -10476,19 +10614,18 @@ TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) { root->test_properties()->force_render_surface = true; // A div layer which has an event handler. - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(26, surface_size, root); + std::unique_ptr<LayerImpl> child = CreateScrollableLayer(26, surface_size); LayerImpl* child_layer = child.get(); // The layer tree should create a layer for the div layer, which is the // actual scrolling layer. std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(27, content_size, root); + CreateScrollableLayer(27, content_size); LayerImpl* grand_child_layer = grand_child.get(); // A child scrollable layer inside grand_child_layer. std::unique_ptr<LayerImpl> great_grand_child = - CreateScrollableLayer(28, inner_size, root); + CreateScrollableLayer(28, inner_size); LayerImpl* great_grand_child_layer = great_grand_child.get(); grand_child->test_properties()->AddChild(std::move(great_grand_child)); @@ -10501,8 +10638,12 @@ TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) { DrawFrame(); { - child_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100)); - grand_child_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 100, 100)); + child_layer->SetTouchActionRegion(std::move(touch_action_region)); + touch_action_region = TouchActionRegion(); + touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 50, 50)); + grand_child_layer->SetTouchActionRegion(std::move(touch_action_region)); // Flinging the grand_child layer. EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -10515,14 +10656,17 @@ TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) { host_impl_->CurrentlyScrollingNode()->id); // Touch on the grand_child layer, which is an active fling layer, the touch // event handler will force to be passive. - EXPECT_EQ( - InputHandler::TouchStartEventListenerType::HANDLER_ON_SCROLLING_LAYER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(70, 80))); + TouchAction touch_action; + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType:: + HANDLER_ON_SCROLLING_LAYER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(70, 80), &touch_action)); // Touch on the great_grand_child_layer layer, which is the child of the // active fling layer, the touch event handler will force to be passive. - EXPECT_EQ( - InputHandler::TouchStartEventListenerType::HANDLER_ON_SCROLLING_LAYER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(20, 30))); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType:: + HANDLER_ON_SCROLLING_LAYER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(20, 30), &touch_action)); // Now flinging on the great_grand_child_layer. EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -10535,15 +10679,16 @@ TEST_F(LayerTreeHostImplTest, TouchInsideOrOutsideFlingLayer) { EXPECT_EQ(great_grand_child_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); // Touch on the child layer, the touch event handler will be blocked. - EXPECT_EQ(InputHandler::TouchStartEventListenerType::HANDLER, - host_impl_->EventListenerTypeForTouchStartAt(gfx::Point(60, 60))); + EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType::HANDLER, + host_impl_->EventListenerTypeForTouchStartOrMoveAt( + gfx::Point(60, 60), &touch_action)); } } class ResourcelessSoftwareLayerTreeHostImplTest : public LayerTreeHostImplTest { protected: - std::unique_ptr<CompositorFrameSink> CreateCompositorFrameSink() override { - return FakeCompositorFrameSink::Create3d(); + std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() override { + return FakeLayerTreeFrameSink::Create3d(); } }; @@ -10616,22 +10761,21 @@ TEST_F(LayerTreeHostImplTest, ExternalTileConstraintReflectedInPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); const gfx::Size layer_size(100, 100); host_impl_->SetViewportSize(layer_size); - bool update_lcd_text = false; // Set up active and pending tree. host_impl_->CreatePendingTree(); host_impl_->pending_tree()->SetRootLayerForTesting( LayerImpl::Create(host_impl_->pending_tree(), 1)); host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - host_impl_->pending_tree()->UpdateDrawProperties(update_lcd_text); + host_impl_->pending_tree()->UpdateDrawProperties(); host_impl_->ActivateSyncTree(); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl_->active_tree()->UpdateDrawProperties(); host_impl_->CreatePendingTree(); - host_impl_->pending_tree()->UpdateDrawProperties(update_lcd_text); - host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl_->pending_tree()->UpdateDrawProperties(); + host_impl_->active_tree()->UpdateDrawProperties(); EXPECT_FALSE(host_impl_->pending_tree()->needs_update_draw_properties()); EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties()); @@ -10654,10 +10798,8 @@ TEST_F(LayerTreeHostImplTest, ExternalViewportAffectsVisibleRects) { ->test_properties() ->children[0]; - bool update_lcd_text = false; - host_impl_->SetViewportSize(gfx::Size(90, 90)); - host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl_->active_tree()->UpdateDrawProperties(); EXPECT_EQ(gfx::Rect(90, 90), content_layer->visible_layer_rect()); gfx::Transform external_transform; @@ -10687,10 +10829,8 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsVisibleRects) { ->test_properties() ->children[0]; - bool update_lcd_text = false; - host_impl_->SetViewportSize(gfx::Size(50, 50)); - host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl_->active_tree()->UpdateDrawProperties(); EXPECT_EQ(gfx::Rect(50, 50), content_layer->visible_layer_rect()); gfx::Transform external_transform; @@ -10735,10 +10875,8 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { test_layer->test_properties()->transform = perspective_transform; host_impl_->active_tree()->BuildPropertyTreesForTesting(); - bool update_lcd_text = false; - host_impl_->SetViewportSize(gfx::Size(50, 50)); - host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); + host_impl_->active_tree()->UpdateDrawProperties(); EffectNode* node = host_impl_->active_tree()->property_trees()->effect_tree.Node( test_layer->effect_tree_index()); @@ -10848,12 +10986,14 @@ TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) { const gfx::Size viewport_size(50, 100); CreateBasicVirtualViewportLayers(viewport_size, content_size); - EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, - host_impl_->ScrollAnimatedBegin(gfx::Point()).thread); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollAnimatedBegin(BeginState(gfx::Point()).get()).thread); // The second ScrollAnimatedBegin should not get ignored. - EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, - host_impl_->ScrollAnimatedBegin(gfx::Point()).thread); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollAnimatedBegin(BeginState(gfx::Point()).get()).thread); } // Verfify that a smooth scroll animation doesn't jump when UpdateTarget gets @@ -11283,8 +11423,12 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) { const gfx::Size viewport_size(500, 500); CreateBasicVirtualViewportLayers(viewport_size, content_size); - host_impl_->OuterViewportScrollLayer()->set_user_scrollable_vertical(true); - host_impl_->OuterViewportScrollLayer()->set_user_scrollable_horizontal(false); + host_impl_->OuterViewportScrollLayer() + ->test_properties() + ->user_scrollable_vertical = true; + host_impl_->OuterViewportScrollLayer() + ->test_properties() + ->user_scrollable_horizontal = false; host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -11425,7 +11569,7 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) { Occlusion(), true); host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer)); - FakePictureLayerImpl* root_layer = static_cast<FakePictureLayerImpl*>( + auto* root_layer = static_cast<FakePictureLayerImpl*>( host_impl_->pending_tree()->root_layer_for_testing()); root_layer->set_has_valid_tile_priorities(true); @@ -11523,7 +11667,7 @@ TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) { class LayerTreeHostImplCountingLostSurfaces : public LayerTreeHostImplTest { public: LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {} - void DidLoseCompositorFrameSinkOnImplThread() override { + void DidLoseLayerTreeFrameSinkOnImplThread() override { num_lost_surfaces_++; } @@ -11536,13 +11680,13 @@ TEST_F(LayerTreeHostImplCountingLostSurfaces, TwiceLostSurface) { // we go from having a valid output surface to not having a valid output // surface. EXPECT_EQ(0, num_lost_surfaces_); - host_impl_->DidLoseCompositorFrameSink(); + host_impl_->DidLoseLayerTreeFrameSink(); EXPECT_EQ(1, num_lost_surfaces_); - host_impl_->DidLoseCompositorFrameSink(); + host_impl_->DidLoseLayerTreeFrameSink(); EXPECT_LE(1, num_lost_surfaces_); } -size_t CountRenderPassesWithId(const RenderPassList& list, int id) { +size_t CountRenderPassesWithId(const RenderPassList& list, RenderPassId id) { return std::count_if( list.begin(), list.end(), [id](const std::unique_ptr<RenderPass>& p) { return p->id == id; }); @@ -11579,10 +11723,10 @@ TEST_F(LayerTreeHostImplTest, RemoveUnreferencedRenderPass) { // But pass2 is not referenced by pass1. So pass2 and pass3 should be culled. FakeLayerTreeHostImpl::RemoveRenderPasses(&frame); EXPECT_EQ(1u, frame.render_passes.size()); - EXPECT_EQ(1u, CountRenderPassesWithId(frame.render_passes, 1)); - EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 2)); - EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 3)); - EXPECT_EQ(1, frame.render_passes[0]->id); + EXPECT_EQ(1u, CountRenderPassesWithId(frame.render_passes, 1u)); + EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 2u)); + EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 3u)); + EXPECT_EQ(1u, frame.render_passes[0]->id); } TEST_F(LayerTreeHostImplTest, RemoveEmptyRenderPass) { @@ -11618,10 +11762,10 @@ TEST_F(LayerTreeHostImplTest, RemoveEmptyRenderPass) { // should be removed. FakeLayerTreeHostImpl::RemoveRenderPasses(&frame); EXPECT_EQ(1u, frame.render_passes.size()); - EXPECT_EQ(1u, CountRenderPassesWithId(frame.render_passes, 1)); - EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 2)); - EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 3)); - EXPECT_EQ(1, frame.render_passes[0]->id); + EXPECT_EQ(1u, CountRenderPassesWithId(frame.render_passes, 1u)); + EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 2u)); + EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 3u)); + EXPECT_EQ(1u, frame.render_passes[0]->id); // The RenderPassDrawQuad should be removed from pass1. EXPECT_EQ(1u, pass1->quad_list.size()); EXPECT_EQ(DrawQuad::SOLID_COLOR, pass1->quad_list.ElementAt(0)->material); @@ -11656,10 +11800,10 @@ TEST_F(LayerTreeHostImplTest, DoNotRemoveEmptyRootRenderPass) { // not be removed. FakeLayerTreeHostImpl::RemoveRenderPasses(&frame); EXPECT_EQ(1u, frame.render_passes.size()); - EXPECT_EQ(1u, CountRenderPassesWithId(frame.render_passes, 1)); - EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 2)); - EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 3)); - EXPECT_EQ(1, frame.render_passes[0]->id); + EXPECT_EQ(1u, CountRenderPassesWithId(frame.render_passes, 1u)); + EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 2u)); + EXPECT_EQ(0u, CountRenderPassesWithId(frame.render_passes, 3u)); + EXPECT_EQ(1u, frame.render_passes[0]->id); // The RenderPassDrawQuad should be removed from pass1. EXPECT_EQ(0u, pass1->quad_list.size()); } @@ -11738,17 +11882,19 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) { TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusTrigger) { // Set initial state, before varying GPU rasterization trigger. host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->SetContentIsSuitableForGpuRasterization(true); + host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, host_impl_->gpu_rasterization_status()); EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + host_impl_->NotifyReadyToActivate(); // Toggle the trigger on. host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + host_impl_->NotifyReadyToActivate(); // And off. host_impl_->SetHasGpuRasterizationTrigger(false); @@ -11756,41 +11902,45 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusTrigger) { EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, host_impl_->gpu_rasterization_status()); EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + host_impl_->NotifyReadyToActivate(); } -// Tests that SetContentIsSuitableForGpuRasterization behaves as expected. -TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSuitability) { +// Tests that SetContentHasSlowPaths behaves as expected. +TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSlowPaths) { 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( + EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeLayerTreeFrameSink::Create3d( std::move(context_with_msaa)))); - // Set initial state, before varying GPU rasterization suitability. + // Set initial state, with slow paths on. host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_msaa()); + host_impl_->NotifyReadyToActivate(); - // Toggle suitability on. - host_impl_->SetContentIsSuitableForGpuRasterization(true); + // Toggle slow paths off. + host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_FALSE(host_impl_->use_msaa()); + host_impl_->NotifyReadyToActivate(); - // And off. - host_impl_->SetContentIsSuitableForGpuRasterization(false); + // And on. + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_TRUE(host_impl_->use_msaa()); + host_impl_->NotifyReadyToActivate(); } // Tests that SetDeviceScaleFactor correctly impacts GPU rasterization. @@ -11802,15 +11952,16 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) { context_with_msaa->set_gpu_rasterization(true); LayerTreeSettings msaaSettings = DefaultSettings(); msaaSettings.gpu_rasterization_msaa_sample_count = -1; - EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeCompositorFrameSink::Create3d( + EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeLayerTreeFrameSink::Create3d( std::move(context_with_msaa)))); // Set initial state, before varying scale factor. host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + host_impl_->NotifyReadyToActivate(); // Set device scale factor to 2, which lowers the required MSAA samples from // 8 to 4. @@ -11820,6 +11971,7 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) { host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_TRUE(host_impl_->use_msaa()); + host_impl_->NotifyReadyToActivate(); // Set device scale factor back to 1. host_impl_->active_tree()->SetDeviceScaleFactor(1.0f); @@ -11827,6 +11979,7 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) { EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_FALSE(host_impl_->use_msaa()); + host_impl_->NotifyReadyToActivate(); } // Tests that explicit MSAA sample count correctly impacts GPU rasterization. @@ -11838,11 +11991,11 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusExplicitMSAACount) { context_with_msaa->set_gpu_rasterization(true); LayerTreeSettings msaaSettings = DefaultSettings(); msaaSettings.gpu_rasterization_msaa_sample_count = 4; - EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeCompositorFrameSink::Create3d( + EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeLayerTreeFrameSink::Create3d( std::move(context_with_msaa)))); host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); @@ -11853,8 +12006,8 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusExplicitMSAACount) { class GpuRasterizationDisabledLayerTreeHostImplTest : public LayerTreeHostImplTest { public: - std::unique_ptr<CompositorFrameSink> CreateCompositorFrameSink() override { - return FakeCompositorFrameSink::Create3d(); + std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() override { + return FakeLayerTreeFrameSink::Create3d(); } }; @@ -11863,9 +12016,9 @@ TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest, GpuRasterizationStatusOverrides) { // GPU rasterization explicitly disabled. LayerTreeSettings settings = DefaultSettings(); - EXPECT_TRUE(CreateHostImpl(settings, FakeCompositorFrameSink::Create3d())); + EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d())); host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(true); + host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, host_impl_->gpu_rasterization_status()); @@ -11873,10 +12026,10 @@ TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest, // GPU rasterization explicitly forced. settings.gpu_rasterization_forced = true; - EXPECT_TRUE(CreateHostImpl(settings, FakeCompositorFrameSink::Create3d())); + EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d())); host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON_FORCED, host_impl_->gpu_rasterization_status()); @@ -11885,42 +12038,128 @@ TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest, class MsaaIsSlowLayerTreeHostImplTest : public LayerTreeHostImplTest { public: - void CreateHostImplWithMsaaIsSlow(bool msaa_is_slow) { + void CreateHostImplWithCaps(bool msaa_is_slow, bool avoid_stencil_buffers) { LayerTreeSettings settings = DefaultSettings(); settings.gpu_rasterization_msaa_sample_count = 4; auto context_provider = TestContextProvider::Create(); context_provider->UnboundTestContext3d()->SetMaxSamples(4); context_provider->UnboundTestContext3d()->set_msaa_is_slow(msaa_is_slow); context_provider->UnboundTestContext3d()->set_gpu_rasterization(true); - auto msaa_is_normal_compositor_frame_sink = - FakeCompositorFrameSink::Create3d(context_provider); + context_provider->UnboundTestContext3d()->set_avoid_stencil_buffers( + avoid_stencil_buffers); + auto msaa_is_normal_layer_tree_frame_sink = + FakeLayerTreeFrameSink::Create3d(context_provider); EXPECT_TRUE(CreateHostImpl( - settings, std::move(msaa_is_normal_compositor_frame_sink))); + settings, std::move(msaa_is_normal_layer_tree_frame_sink))); } }; TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { - // Ensure that without the msaa_is_slow cap we raster unsuitable content with - // msaa. - CreateHostImplWithMsaaIsSlow(false); + // Ensure that without the msaa_is_slow or avoid_stencil_buffers caps + // we raster slow paths with msaa. + CreateHostImplWithCaps(false, false); host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); - // Ensure that with the msaa_is_slow cap we don't raster unsuitable content - // with msaa (we'll still use GPU raster, though). - CreateHostImplWithMsaaIsSlow(true); + // Ensure that with either msaa_is_slow or avoid_stencil_buffers caps + // we don't raster slow paths with msaa (we'll still use GPU raster, though). + // msaa_is_slow = true, avoid_stencil_buffers = false + CreateHostImplWithCaps(true, false); host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + EXPECT_FALSE(host_impl_->use_msaa()); + + // msaa_is_slow = false, avoid_stencil_buffers = true + CreateHostImplWithCaps(false, true); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + EXPECT_FALSE(host_impl_->use_msaa()); + + // msaa_is_slow = true, avoid_stencil_buffers = true + CreateHostImplWithCaps(true, true); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_FALSE(host_impl_->use_msaa()); } +class MsaaCompatibilityLayerTreeHostImplTest : public LayerTreeHostImplTest { + public: + void CreateHostImplWithMultisampleCompatibility( + bool support_multisample_compatibility) { + LayerTreeSettings settings = DefaultSettings(); + settings.gpu_rasterization_msaa_sample_count = 4; + auto context_provider = TestContextProvider::Create(); + context_provider->UnboundTestContext3d()->SetMaxSamples(4); + context_provider->UnboundTestContext3d() + ->set_support_multisample_compatibility( + support_multisample_compatibility); + context_provider->UnboundTestContext3d()->set_gpu_rasterization(true); + auto msaa_is_normal_layer_tree_frame_sink = + FakeLayerTreeFrameSink::Create3d(context_provider); + EXPECT_TRUE(CreateHostImpl( + settings, std::move(msaa_is_normal_layer_tree_frame_sink))); + } +}; + +TEST_F(MsaaCompatibilityLayerTreeHostImplTest, + GpuRasterizationStatusNonAAPaint) { + // Ensure that without non-aa paint and without multisample compatibility, we + // raster slow paths with msaa. + CreateHostImplWithMultisampleCompatibility(false); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->SetContentHasNonAAPaint(false); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + + // Ensure that without non-aa paint and with multisample compatibility, we + // raster slow paths with msaa. + CreateHostImplWithMultisampleCompatibility(true); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->SetContentHasNonAAPaint(false); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + + // Ensure that with non-aa paint and without multisample compatibility, we do + // not raster slow paths with msaa. + CreateHostImplWithMultisampleCompatibility(false); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->SetContentHasNonAAPaint(true); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + + // Ensure that with non-aa paint and with multisample compatibility, we raster + // slow paths with msaa. + CreateHostImplWithMultisampleCompatibility(true); + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); + host_impl_->SetContentHasNonAAPaint(true); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); +} + TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { // Check page scale factor update in property trees when an update is made // on the active tree. @@ -11949,14 +12188,14 @@ TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { EXPECT_EQ(pending_tree_node->post_local_scale_factor, 1.f); EXPECT_EQ(host_impl_->pending_tree()->current_page_scale_factor(), 2.f); - host_impl_->pending_tree()->UpdateDrawProperties(false); + host_impl_->pending_tree()->UpdateDrawProperties(); pending_tree_node = host_impl_->pending_tree()->property_trees()->transform_tree.Node( page_scale_layer->transform_tree_index()); EXPECT_EQ(pending_tree_node->post_local_scale_factor, 2.f); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->UpdateDrawProperties(false); + host_impl_->active_tree()->UpdateDrawProperties(); active_tree_node = host_impl_->active_tree()->property_trees()->transform_tree.Node( page_scale_layer->transform_tree_index()); @@ -12015,7 +12254,7 @@ TEST_F(LayerTreeHostImplTest, JitterTest) { UpdateState(gfx::Point(), gfx::Vector2dF(0, scroll)).get()); accumulated_scroll += scroll; host_impl_->ScrollEnd(EndState().get()); - host_impl_->active_tree()->UpdateDrawProperties(false); + host_impl_->active_tree()->UpdateDrawProperties(); host_impl_->CreatePendingTree(); host_impl_->pending_tree()->set_source_frame_number(i + 1); @@ -12045,15 +12284,15 @@ TEST_F(LayerTreeHostImplTest, JitterTest) { gfx::ScrollOffset pending_base = pending_tree->property_trees() ->scroll_tree.GetScrollOffsetBaseForTesting( - last_scrolled_layer->id()); + last_scrolled_layer->element_id()); pending_tree->BuildPropertyTreesForTesting(); pending_tree->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - last_scrolled_layer->id(), pending_base); + last_scrolled_layer->element_id(), pending_base); pending_tree->LayerById(content_layer->id())->SetNeedsPushProperties(); pending_tree->set_needs_update_draw_properties(); - pending_tree->UpdateDrawProperties(false); + pending_tree->UpdateDrawProperties(); float jitter = LayerTreeHostCommon::CalculateLayerJitter(content_layer); // There should not be any jitter measured till we hit the fixed point hits // threshold. @@ -12063,13 +12302,11 @@ TEST_F(LayerTreeHostImplTest, JitterTest) { } } -// Checks that if we lose a GPU raster enabled CompositorFrameSink and replace -// it -// with a software CompositorFrameSink, LayerTreeHostImpl correctly re-computes -// GPU -// rasterization status. -TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnCompositorFrameSinkChange) { - host_impl_->ReleaseCompositorFrameSink(); +// Checks that if we lose a GPU raster enabled LayerTreeFrameSink and replace +// it with a software LayerTreeFrameSink, LayerTreeHostImpl correctly +// re-computes GPU rasterization status. +TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnLayerTreeFrameSinkChange) { + host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; LayerTreeSettings settings = DefaultSettings(); @@ -12082,14 +12319,14 @@ TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnCompositorFrameSinkChange) { host_impl_->SetVisible(true); // InitializeRenderer with a gpu-raster enabled output surface. - auto gpu_raster_compositor_frame_sink = - FakeCompositorFrameSink::Create3d(TestWebGraphicsContext3D::Create()); - host_impl_->InitializeRenderer(gpu_raster_compositor_frame_sink.get()); + auto gpu_raster_layer_tree_frame_sink = + FakeLayerTreeFrameSink::Create3d(TestWebGraphicsContext3D::Create()); + host_impl_->InitializeRenderer(gpu_raster_layer_tree_frame_sink.get()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); // Re-initialize with a software output surface. - compositor_frame_sink_ = FakeCompositorFrameSink::CreateSoftware(); - host_impl_->InitializeRenderer(compositor_frame_sink_.get()); + layer_tree_frame_sink_ = FakeLayerTreeFrameSink::CreateSoftware(); + host_impl_->InitializeRenderer(layer_tree_frame_sink_.get()); EXPECT_FALSE(host_impl_->use_gpu_rasterization()); } @@ -12108,10 +12345,9 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( const int scrollbar_1_id = 10; const int scrollbar_2_id = 11; - const int child_clip_id = 12; const int child_scroll_id = 13; - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); host_impl_->SetViewportSize(viewport_size); CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); @@ -12133,7 +12369,9 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( 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)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1)); + scrollbar_1->SetTouchActionRegion(touch_action_region); scrollbar_1->SetCurrentPos(0); scrollbar_1->SetPosition(gfx::PointF(0, 0)); host_impl_->active_tree() @@ -12142,10 +12380,11 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( ->AddChild(std::move(scrollbar_1)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); + host_impl_->active_tree()->UpdateScrollbarGeometries(); host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); - host_impl_->active_tree()->UpdateDrawProperties(false); + host_impl_->active_tree()->UpdateDrawProperties(); ScrollbarAnimationController* scrollbar_1_animation_controller = host_impl_->ScrollbarAnimationControllerForElementId( @@ -12223,14 +12462,12 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 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 = LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); child->SetPosition(gfx::PointF(50, 50)); child->SetBounds(child_layer_size); child->SetDrawsContent(true); - child->SetScrollClipLayer(child_clip_id); + child->SetScrollable(gfx::Size(100, 100)); child->SetElementId(LayerIdToElementIdForTesting(child->id())); ElementId child_element_id = child->element_id(); @@ -12246,10 +12483,10 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( scrollbar_2->SetPosition(gfx::PointF(0, 0)); child->test_properties()->AddChild(std::move(scrollbar_2)); - child_clip->test_properties()->AddChild(std::move(child)); - root_scroll->test_properties()->AddChild(std::move(child_clip)); + root_scroll->test_properties()->AddChild(std::move(child)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); + host_impl_->active_tree()->UpdateScrollbarGeometries(); host_impl_->active_tree()->DidBecomeActive(); ScrollbarAnimationController* scrollbar_2_animation_controller = @@ -12353,7 +12590,7 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { settings.enable_checker_imaging = true; settings.default_tile_size = gfx::Size(256, 256); settings.max_untiled_layer_size = gfx::Size(256, 256); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); gfx::Size layer_size = gfx::Size(750, 750); std::unique_ptr<FakeRecordingSource> recording_source = @@ -12370,9 +12607,8 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { recording_source->add_draw_rect_with_flags(gfx::Rect(0, 510, 200, 400), non_solid_flags); recording_source->Rerecord(); - scoped_refptr<FakeRasterSource> raster_source = - FakeRasterSource::CreateFromRecordingSource(recording_source.get(), - false); + scoped_refptr<RasterSource> raster_source = + recording_source->CreateRasterSource(); // Create the pending tree. host_impl_->BeginCommit(); @@ -12381,8 +12617,7 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { pending_tree->SetRootLayerForTesting( FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 1, raster_source)); - FakePictureLayerImpl* root = - static_cast<FakePictureLayerImpl*>(*pending_tree->begin()); + auto* root = static_cast<FakePictureLayerImpl*>(*pending_tree->begin()); root->SetBounds(layer_size); root->SetDrawsContent(true); pending_tree->BuildPropertyTreesForTesting(); @@ -12425,16 +12660,187 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { TEST_F(LayerTreeHostImplTest, RasterColorSpaceNoColorCorrection) { LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); EXPECT_FALSE(host_impl_->GetRasterColorSpace().IsValid()); } TEST_F(LayerTreeHostImplTest, RasterColorSpace) { LayerTreeSettings settings = DefaultSettings(); settings.enable_color_correct_rasterization = true; - CreateHostImpl(settings, CreateCompositorFrameSink()); + CreateHostImpl(settings, CreateLayerTreeFrameSink()); EXPECT_EQ(host_impl_->GetRasterColorSpace(), gfx::ColorSpace::CreateSRGB()); } +TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { + gfx::Size layer_bounds(500, 500); + + host_impl_->SetViewportSize(layer_bounds); + host_impl_->CreatePendingTree(); + std::unique_ptr<LayerImpl> scoped_root = + LayerImpl::Create(host_impl_->pending_tree(), 1); + scoped_root->SetBounds(layer_bounds); + LayerImpl* root = scoped_root.get(); + host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); + + scoped_refptr<FakeRasterSource> raster_source( + FakeRasterSource::CreateFilled(layer_bounds)); + std::unique_ptr<FakePictureLayerImpl> scoped_animated_transform_layer = + FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), + 2, raster_source); + scoped_animated_transform_layer->SetBounds(layer_bounds); + scoped_animated_transform_layer->SetDrawsContent(true); + gfx::Transform singular; + singular.Scale3d(6.f, 6.f, 0.f); + scoped_animated_transform_layer->test_properties()->transform = singular; + FakePictureLayerImpl* animated_transform_layer = + scoped_animated_transform_layer.get(); + root->test_properties()->AddChild(std::move(scoped_animated_transform_layer)); + + // A layer with a non-invertible transform is not drawn or rasterized. Since + // this layer is not rasterized, we shouldn't be creating any tilings for it. + host_impl_->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + EXPECT_FALSE(animated_transform_layer->HasValidTilePriorities()); + EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 0u); + host_impl_->pending_tree()->UpdateDrawProperties(); + EXPECT_FALSE(animated_transform_layer->raster_even_if_not_drawn()); + EXPECT_FALSE(animated_transform_layer->contributes_to_drawn_render_surface()); + EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 0u); + + // Now add a transform animation to this layer. While we don't drawn layers + // with non-invertible transforms, we still raster them if there is a + // transform animation. + host_impl_->pending_tree()->SetElementIdsForTesting(); + TransformOperations start_transform_operations; + start_transform_operations.AppendMatrix(singular); + TransformOperations end_transform_operations; + AddAnimatedTransformToElementWithPlayer( + animated_transform_layer->element_id(), timeline(), 10.0, + start_transform_operations, end_transform_operations); + + // The layer is still not drawn, but it will be rasterized. Since the layer is + // rasterized, we should be creating tilings for it in UpdateDrawProperties. + // However, none of these tiles should be required for activation. + host_impl_->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + host_impl_->pending_tree()->UpdateDrawProperties(); + EXPECT_TRUE(animated_transform_layer->raster_even_if_not_drawn()); + EXPECT_FALSE(animated_transform_layer->contributes_to_drawn_render_surface()); + EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 1u); + EXPECT_FALSE(animated_transform_layer->tilings() + ->tiling_at(0) + ->can_require_tiles_for_activation()); +} + +TEST_F(LayerTreeHostImplTest, RasterTilePrioritizationForNonDrawingLayers) { + gfx::Size layer_bounds(500, 500); + + host_impl_->SetViewportSize(layer_bounds); + host_impl_->CreatePendingTree(); + std::unique_ptr<LayerImpl> scoped_root = + LayerImpl::Create(host_impl_->pending_tree(), 1); + scoped_root->SetBounds(layer_bounds); + LayerImpl* root = scoped_root.get(); + host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); + + scoped_refptr<FakeRasterSource> raster_source( + FakeRasterSource::CreateFilled(layer_bounds)); + + std::unique_ptr<FakePictureLayerImpl> scoped_hidden_layer = + FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), + 2, raster_source); + scoped_hidden_layer->SetBounds(layer_bounds); + scoped_hidden_layer->SetDrawsContent(true); + scoped_hidden_layer->set_contributes_to_drawn_render_surface(true); + FakePictureLayerImpl* hidden_layer = scoped_hidden_layer.get(); + root->test_properties()->AddChild(std::move(scoped_hidden_layer)); + + std::unique_ptr<FakePictureLayerImpl> scoped_drawing_layer = + FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), + 3, raster_source); + scoped_drawing_layer->SetBounds(layer_bounds); + scoped_drawing_layer->SetDrawsContent(true); + scoped_drawing_layer->set_contributes_to_drawn_render_surface(true); + FakePictureLayerImpl* drawing_layer = scoped_drawing_layer.get(); + root->test_properties()->AddChild(std::move(scoped_drawing_layer)); + + gfx::Rect layer_rect(0, 0, 500, 500); + gfx::Rect empty_rect(0, 0, 0, 0); + host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + + hidden_layer->tilings()->AddTiling(gfx::AxisTransform2d(), raster_source); + PictureLayerTiling* hidden_tiling = hidden_layer->tilings()->tiling_at(0); + hidden_tiling->set_resolution(TileResolution::LOW_RESOLUTION); + hidden_tiling->CreateAllTilesForTesting(); + hidden_tiling->SetTilePriorityRectsForTesting( + layer_rect, // Visible rect. + layer_rect, // Skewport rect. + layer_rect, // Soon rect. + layer_rect); // Eventually rect. + + drawing_layer->tilings()->AddTiling(gfx::AxisTransform2d(), raster_source); + PictureLayerTiling* drawing_tiling = drawing_layer->tilings()->tiling_at(0); + drawing_tiling->set_resolution(TileResolution::HIGH_RESOLUTION); + drawing_tiling->CreateAllTilesForTesting(); + drawing_tiling->SetTilePriorityRectsForTesting( + layer_rect, // Visible rect. + layer_rect, // Skewport rect. + layer_rect, // Soon rect. + layer_rect); // Eventually rect. + + // Both layers are drawn. Since the hidden layer has a low resolution tiling, + // in smoothness priority mode its tile is higher priority. + std::unique_ptr<RasterTilePriorityQueue> queue = + host_impl_->BuildRasterQueue(TreePriority::SMOOTHNESS_TAKES_PRIORITY, + RasterTilePriorityQueue::Type::ALL); + EXPECT_EQ(queue->Top().tile()->layer_id(), 2); + + // Hide the hidden layer and set it to so it still rasters. Now the drawing + // layer should be prioritized over the hidden layer. + hidden_layer->set_contributes_to_drawn_render_surface(false); + hidden_layer->set_raster_even_if_not_drawn(true); + queue = host_impl_->BuildRasterQueue(TreePriority::SMOOTHNESS_TAKES_PRIORITY, + RasterTilePriorityQueue::Type::ALL); + EXPECT_EQ(queue->Top().tile()->layer_id(), 3); +} + +TEST_F(LayerTreeHostImplTest, DrawAfterDroppingTileResources) { + LayerTreeSettings settings = DefaultSettings(); + settings.using_synchronous_renderer_compositor = true; + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + host_impl_->CreatePendingTree(); + + gfx::Size bounds(100, 100); + scoped_refptr<FakeRasterSource> raster_source( + FakeRasterSource::CreateFilled(bounds)); + { + std::unique_ptr<FakePictureLayerImpl> scoped_layer = + FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), + 1, raster_source); + scoped_layer->SetBounds(bounds); + scoped_layer->SetDrawsContent(true); + host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_layer)); + } + host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + host_impl_->ActivateSyncTree(); + + FakePictureLayerImpl* layer = static_cast<FakePictureLayerImpl*>( + host_impl_->active_tree()->FindActiveTreeLayerById(1)); + + DrawFrame(); + EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties()); + EXPECT_LT(0.f, layer->raster_page_scale()); + EXPECT_GT(layer->tilings()->num_tilings(), 0u); + + const ManagedMemoryPolicy policy = host_impl_->ActualManagedMemoryPolicy(); + const ManagedMemoryPolicy zero_policy(0u); + host_impl_->SetMemoryPolicy(zero_policy); + EXPECT_EQ(0.f, layer->raster_page_scale()); + EXPECT_EQ(layer->tilings()->num_tilings(), 0u); + + host_impl_->SetMemoryPolicy(policy); + DrawFrame(); + EXPECT_LT(0.f, layer->raster_page_scale()); + EXPECT_GT(layer->tilings()->num_tilings(), 0u); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc index 7649a527fa2..85072682853 100644 --- a/chromium/cc/trees/layer_tree_host_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_perftest.cc @@ -18,13 +18,13 @@ #include "cc/layers/solid_color_layer.h" #include "cc/layers/texture_layer.h" #include "cc/resources/single_release_callback.h" -#include "cc/resources/texture_mailbox.h" #include "cc/test/fake_content_layer_client.h" #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 "components/viz/common/quads/texture_mailbox.h" +#include "components/viz/test/paths.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" #include "testing/perf/perf_test.h" namespace cc { @@ -46,18 +46,20 @@ class LayerTreeHostPerfTest : public LayerTreeTest { measure_commit_cost_(false) { } - std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::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>( + return base::MakeUnique<viz::TestLayerTreeFrameSink>( 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); + shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings, + ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync, + refresh_rate); } void BeginTest() override { @@ -136,7 +138,7 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { void ReadTestFile(const std::string& name) { base::FilePath test_data_dir; - ASSERT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir)); + ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir)); base::FilePath json_file = test_data_dir.AppendASCII(name + ".json"); ASSERT_TRUE(base::ReadFileToString(json_file, &json_)); } @@ -322,7 +324,7 @@ class BrowserCompositorInvalidateLayerTreePerfTest gpu::CommandBufferId::FromUnsafeValue(1), next_fence_sync_); next_sync_token.SetVerifyFlush(); - TextureMailbox mailbox(gpu_mailbox, next_sync_token, GL_TEXTURE_2D); + viz::TextureMailbox mailbox(gpu_mailbox, next_sync_token, GL_TEXTURE_2D); next_fence_sync_++; tab_contents_->SetTextureMailbox(mailbox, std::move(callback)); @@ -346,7 +348,7 @@ class BrowserCompositorInvalidateLayerTreePerfTest } void CleanUpAndEndTestOnMainThread() { - tab_contents_->SetTextureMailbox(TextureMailbox(), nullptr); + tab_contents_->SetTextureMailbox(viz::TextureMailbox(), nullptr); // ReleaseMailbox will end the test when we get the last mailbox back. } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc index 656d2922e02..d01351fc5bc 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc @@ -9,6 +9,7 @@ #include "cc/paint/paint_image.h" #include "cc/test/layer_tree_pixel_resource_test.h" #include "cc/test/pixel_comparator.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkSurface.h" @@ -67,13 +68,21 @@ class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest { pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true)); } - void InitializeSettings(LayerTreeSettings* settings) override { - settings->renderer_settings.force_antialiasing = force_antialiasing_; - settings->renderer_settings.force_blending_with_shaders = + protected: + std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { + viz::RendererSettings modified_renderer_settings = renderer_settings; + modified_renderer_settings.force_antialiasing = force_antialiasing_; + modified_renderer_settings.force_blending_with_shaders = force_blending_with_shaders_; + return LayerTreeHostPixelResourceTest::CreateLayerTreeFrameSink( + modified_renderer_settings, refresh_rate, compositor_context_provider, + worker_context_provider); } - protected: void RunBlendingWithRootPixelTestType(PixelResourceTestCase type) { const int kLaneWidth = 2; const int kLaneHeight = kLaneWidth; diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc index 1f5f2b7361a..5f24e1ac321 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -36,7 +36,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) { background->AddChild(blur); FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(2.f)); + filters.Append(FilterOperation::CreateBlurFilter( + 2.f, SkBlurImageFilter::kClamp_TileMode)); blur->SetBackgroundFilters(filters); #if defined(OS_WIN) @@ -77,12 +78,13 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) { background->AddChild(blur); FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(5.f)); + filters.Append(FilterOperation::CreateBlurFilter( + 5.f, SkBlurImageFilter::kClamp_TileMode)); blur->SetBackgroundFilters(filters); #if defined(OS_WIN) - // Windows has 5.6075% pixels by at most 2: crbug.com/259922 - float percentage_pixels_large_error = 5.7f; + // Windows has 5.9325% pixels by at most 2: crbug.com/259922 + float percentage_pixels_large_error = 6.0f; float percentage_pixels_small_error = 0.0f; float average_error_allowed_in_bad_pixels = 2.f; int large_error_allowed = 2; @@ -138,7 +140,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) { blur->SetTransform(blur_transform); FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(2.f)); + filters.Append(FilterOperation::CreateBlurFilter( + 2.f, SkBlurImageFilter::kClamp_TileMode)); blur->SetBackgroundFilters(filters); #if defined(OS_WIN) @@ -478,7 +481,8 @@ class ImageBackgroundFilter : public LayerTreeHostFiltersPixelTest { // Add a blur filter to the blue layer. FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(5.0f)); + filters.Append(FilterOperation::CreateBlurFilter( + 5.0f, SkBlurImageFilter::kClamp_TileMode)); filter->SetBackgroundFilters(filters); // Allow some fuzziness so that this doesn't fail when Skia makes minor @@ -935,7 +939,8 @@ class BlurFilterWithClip : public LayerTreeHostFiltersPixelTest { filter_layer->AddChild(child4); FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(2.f)); + filters.Append(FilterOperation::CreateBlurFilter( + 2.f, SkBlurImageFilter::kClamp_TileMode)); filter_layer->SetFilters(filters); // Force the allocation a larger textures. diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc index 1d1d70b2cdd..1e7cf22ded1 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -9,10 +9,9 @@ #include "cc/layers/picture_image_layer.h" #include "cc/layers/picture_layer.h" #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/paint/paint_op_buffer.h" #include "cc/test/fake_picture_layer.h" #include "cc/test/layer_tree_pixel_resource_test.h" #include "cc/test/pixel_comparator.h" @@ -40,31 +39,29 @@ class MaskContentLayerClient : public ContentLayerClient { scoped_refptr<DisplayItemList> PaintContentsToDisplayList( PaintingControlSetting picture_control) override { - PaintRecorder recorder; - PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(PaintableRegion())); + auto display_list = make_scoped_refptr(new DisplayItemList); + PaintOpBuffer* buffer = display_list->StartPaint(); + + buffer->push<SaveOp>(); + buffer->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()), + SkClipOp::kIntersect, false); + SkColor color = SK_ColorTRANSPARENT; + buffer->push<DrawColorOp>(color, SkBlendMode::kSrc); PaintFlags flags; flags.setStyle(PaintFlags::kStroke_Style); flags.setStrokeWidth(SkIntToScalar(2)); flags.setColor(SK_ColorWHITE); - canvas->clear(SK_ColorTRANSPARENT); gfx::Rect inset_rect(bounds_); while (!inset_rect.IsEmpty()) { inset_rect.Inset(3, 3, 2, 2); - canvas->drawRect( - SkRect::MakeXYWH(inset_rect.x(), inset_rect.y(), inset_rect.width(), - inset_rect.height()), - flags); + buffer->push<DrawRectOp>(gfx::RectToSkRect(inset_rect), flags); inset_rect.Inset(3, 3, 2, 2); } - auto display_list = make_scoped_refptr(new DisplayItemList); - display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( - PaintableRegion(), recorder.finishRecordingAsPicture(), - gfx::RectToSkRect(PaintableRegion())); - + buffer->push<RestoreOp>(); + display_list->EndPaintOfUnpaired(PaintableRegion()); display_list->Finalize(); return display_list; } @@ -152,41 +149,6 @@ 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); @@ -221,30 +183,35 @@ class CheckerContentLayerClient : public ContentLayerClient { gfx::Rect PaintableRegion() override { return gfx::Rect(bounds_); } scoped_refptr<DisplayItemList> PaintContentsToDisplayList( PaintingControlSetting picture_control) override { - PaintRecorder recorder; - PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(PaintableRegion())); + auto display_list = make_scoped_refptr(new DisplayItemList); + PaintOpBuffer* buffer = display_list->StartPaint(); + + buffer->push<SaveOp>(); + buffer->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()), + SkClipOp::kIntersect, false); + SkColor color = SK_ColorTRANSPARENT; + buffer->push<DrawColorOp>(color, SkBlendMode::kSrc); PaintFlags flags; flags.setStyle(PaintFlags::kStroke_Style); flags.setStrokeWidth(SkIntToScalar(4)); flags.setColor(color_); - canvas->clear(SK_ColorTRANSPARENT); if (vertical_) { for (int i = 4; i < bounds_.width(); i += 16) { - canvas->drawLine(i, 0, i, bounds_.height(), flags); + gfx::PointF p1(i, 0.f); + gfx::PointF p2(i, bounds_.height()); + buffer->push<DrawLineOp>(p1.x(), p1.y(), p2.x(), p2.y(), flags); } } else { for (int i = 4; i < bounds_.height(); i += 16) { - canvas->drawLine(0, i, bounds_.width(), i, flags); + gfx::PointF p1(0.f, i); + gfx::PointF p2(bounds_.width(), i); + buffer->push<DrawLineOp>(p1.x(), p1.y(), p2.x(), p2.y(), flags); } } - auto display_list = make_scoped_refptr(new DisplayItemList); - display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( - PaintableRegion(), recorder.finishRecordingAsPicture(), - gfx::RectToSkRect(PaintableRegion())); - + buffer->push<RestoreOp>(); + display_list->EndPaintOfUnpaired(PaintableRegion()); display_list->Finalize(); return display_list; } @@ -265,22 +232,23 @@ class CircleContentLayerClient : public ContentLayerClient { gfx::Rect PaintableRegion() override { return gfx::Rect(bounds_); } scoped_refptr<DisplayItemList> PaintContentsToDisplayList( PaintingControlSetting picture_control) override { - PaintRecorder recorder; - PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(PaintableRegion())); + auto display_list = make_scoped_refptr(new DisplayItemList); + PaintOpBuffer* buffer = display_list->StartPaint(); + + buffer->push<SaveOp>(); + buffer->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()), + SkClipOp::kIntersect, false); + SkColor color = SK_ColorTRANSPARENT; + buffer->push<DrawColorOp>(color, SkBlendMode::kSrc); PaintFlags flags; flags.setStyle(PaintFlags::kFill_Style); flags.setColor(SK_ColorWHITE); - canvas->clear(SK_ColorTRANSPARENT); - canvas->drawCircle(bounds_.width() / 2, bounds_.height() / 2, - bounds_.width() / 4, flags); - - auto display_list = make_scoped_refptr(new DisplayItemList); - display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( - PaintableRegion(), recorder.finishRecordingAsPicture(), - gfx::RectToSkRect(PaintableRegion())); + buffer->push<DrawCircleOp>(bounds_.width() / 2.f, bounds_.height() / 2.f, + bounds_.width() / 4.f, flags); + buffer->push<RestoreOp>(); + display_list->EndPaintOfUnpaired(PaintableRegion()); display_list->Finalize(); return display_list; } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc index d920a3e84e7..189da3b652c 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc @@ -10,9 +10,9 @@ #include "cc/test/fake_picture_layer.h" #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/layer_tree_pixel_test.h" -#include "cc/test/paths.h" #include "cc/test/solid_color_content_layer_client.h" #include "cc/trees/layer_tree_impl.h" +#include "components/viz/test/paths.h" #if !defined(OS_ANDROID) @@ -64,20 +64,20 @@ class LayerTreeHostReadbackPixelTest std::unique_ptr<CopyOutputRequest> request; if (readback_type_ == READBACK_BITMAP) { - request = CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, - base::Unretained(this))); + request = CopyOutputRequest::CreateBitmapRequest(base::BindOnce( + &LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, + base::Unretained(this))); } else { DCHECK_EQ(readback_type_, READBACK_DEFAULT); if (test_type_ == PIXEL_TEST_SOFTWARE) { - request = CopyOutputRequest::CreateRequest( - base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, - base::Unretained(this))); + request = CopyOutputRequest::CreateRequest(base::BindOnce( + &LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, + base::Unretained(this))); } else { DCHECK_EQ(test_type_, PIXEL_TEST_GL); - request = CopyOutputRequest::CreateRequest( - base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture, - base::Unretained(this))); + request = CopyOutputRequest::CreateRequest(base::BindOnce( + &LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture, + base::Unretained(this))); } } @@ -115,7 +115,7 @@ class LayerTreeHostReadbackPixelTest EXPECT_TRUE(task_runner_provider()->IsMainThread()); EXPECT_TRUE(result->HasTexture()); - TextureMailbox texture_mailbox; + viz::TextureMailbox texture_mailbox; std::unique_ptr<SingleReleaseCallback> release_callback; result->TakeTexture(&texture_mailbox, &release_callback); EXPECT_TRUE(texture_mailbox.IsValid()); @@ -290,7 +290,7 @@ TEST_P(LayerTreeHostReadbackPixelTest, hidden_target->AddChild(blue); hidden_target->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&IgnoreReadbackResult))); + base::BindOnce(&IgnoreReadbackResult))); RunReadbackTest(GetParam().pixel_test_type, GetParam().readback_type, background, base::FilePath(FILE_PATH_LITERAL("black.png"))); } @@ -415,7 +415,7 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackNonRootOrFirstLayer) { scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); blue->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&IgnoreReadbackResult))); + base::BindOnce(&IgnoreReadbackResult))); background->AddChild(blue); RunReadbackTestWithReadbackTarget( @@ -435,7 +435,7 @@ TEST_P(LayerTreeHostReadbackPixelTest, MultipleReadbacksOnLayer) { CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&IgnoreReadbackResult))); + base::BindOnce(&IgnoreReadbackResult))); RunReadbackTestWithReadbackTarget( GetParam().pixel_test_type, GetParam().readback_type, background, diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc index e2fc6d64670..2617a122e5e 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -8,12 +8,10 @@ #include "cc/layers/picture_layer.h" #include "cc/output/copy_output_request.h" #include "cc/paint/display_item_list.h" -#include "cc/paint/drawing_display_item.h" -#include "cc/paint/paint_canvas.h" #include "cc/paint/paint_flags.h" -#include "cc/paint/paint_recorder.h" +#include "cc/paint/paint_op_buffer.h" #include "cc/test/layer_tree_pixel_test.h" -#include "cc/test/test_compositor_frame_sink.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" #include "gpu/command_buffer/client/gles2_interface.h" #if !defined(OS_ANDROID) @@ -111,9 +109,8 @@ class BlueYellowClient : public ContentLayerClient { PaintingControlSetting painting_status) override { auto display_list = make_scoped_refptr(new DisplayItemList); - PaintRecorder recorder; - PaintCanvas* canvas = - recorder.beginRecording(gfx::RectToSkRect(PaintableRegion())); + PaintOpBuffer* buffer = display_list->StartPaint(); + gfx::Rect top(0, 0, size_.width(), size_.height() / 2); gfx::Rect bottom(0, size_.height() / 2, size_.width(), size_.height() / 2); @@ -124,13 +121,11 @@ class BlueYellowClient : public ContentLayerClient { flags.setStyle(PaintFlags::kFill_Style); flags.setColor(SK_ColorBLUE); - canvas->drawRect(gfx::RectToSkRect(blue_rect), flags); + buffer->push<DrawRectOp>(gfx::RectToSkRect(blue_rect), flags); flags.setColor(SK_ColorYELLOW); - canvas->drawRect(gfx::RectToSkRect(yellow_rect), flags); + buffer->push<DrawRectOp>(gfx::RectToSkRect(yellow_rect), flags); - display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( - PaintableRegion(), recorder.finishRecordingAsPicture(), - gfx::RectToSkRect(PaintableRegion())); + display_list->EndPaintOfUnpaired(PaintableRegion()); display_list->Finalize(); return display_list; } @@ -182,12 +177,12 @@ class LayerTreeHostTilesTestPartialInvalidation void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override { // Issue a GL finish before preparing tiles to ensure resources become // available for use in a timely manner. Needed for the one-copy path. - ContextProvider* context_provider = - host_impl->compositor_frame_sink()->worker_context_provider(); + viz::ContextProvider* context_provider = + host_impl->layer_tree_frame_sink()->worker_context_provider(); if (!context_provider) return; - ContextProvider::ScopedContextLock lock(context_provider); + viz::ContextProvider::ScopedContextLock lock(context_provider); lock.ContextGL()->Finish(); } diff --git a/chromium/cc/trees/layer_tree_host_single_thread_client.h b/chromium/cc/trees/layer_tree_host_single_thread_client.h index 00cc3dbaec8..416b5de8bd6 100644 --- a/chromium/cc/trees/layer_tree_host_single_thread_client.h +++ b/chromium/cc/trees/layer_tree_host_single_thread_client.h @@ -22,10 +22,10 @@ class LayerTreeHostSingleThreadClient { // limiting. virtual void DidSubmitCompositorFrame() = 0; - // Called when the active CompositorFrameSink is lost and needs to be + // Called when the active LayerTreeFrameSink is lost and needs to be // replaced. This allows the embedder to schedule a composite which will - // run the machinery to acquire a new CompositorFrameSink. - virtual void DidLoseCompositorFrameSink() = 0; + // run the machinery to acquire a new LayerTreeFrameSink. + virtual void DidLoseLayerTreeFrameSink() = 0; protected: virtual ~LayerTreeHostSingleThreadClient() {} diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index 9a657f521e4..0e49545ae71 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -52,7 +52,6 @@ #include "cc/test/push_properties_counting_layer_impl.h" #include "cc/test/render_pass_test_utils.h" #include "cc/test/skia_common.h" -#include "cc/test/test_compositor_frame_sink.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/clip_node.h" #include "cc/trees/effect_node.h" @@ -64,6 +63,7 @@ #include "cc/trees/single_thread_proxy.h" #include "cc/trees/swap_promise_manager.h" #include "cc/trees/transform_node.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/khronos/GLES2/gl2.h" @@ -441,16 +441,18 @@ SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawVisibility); class LayerTreeHostContextCacheTest : public LayerTreeHostTest { public: - std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { - // Create the main ContextProvider with a MockContextSupport. + std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { + // Create the main viz::ContextProvider with a MockContextSupport. auto main_support = base::MakeUnique<MockContextSupport>(); mock_main_context_support_ = main_support.get(); auto test_main_context_provider = TestContextProvider::Create( TestWebGraphicsContext3D::Create(), std::move(main_support)); - // Create the main ContextProvider with a MockContextSupport. + // Create the main viz::ContextProvider with a MockContextSupport. auto worker_support = base::MakeUnique<MockContextSupport>(); mock_worker_context_support_ = worker_support.get(); auto test_worker_context_provider = TestContextProvider::Create( @@ -464,8 +466,8 @@ class LayerTreeHostContextCacheTest : public LayerTreeHostTest { EXPECT_CALL(*mock_worker_context_support_, SetAggressivelyFreeResources(false)); - return LayerTreeHostTest::CreateCompositorFrameSink( - std::move(test_main_context_provider), + return LayerTreeHostTest::CreateLayerTreeFrameSink( + renderer_settings, refresh_rate, std::move(test_main_context_provider), std::move(test_worker_context_provider)); } @@ -577,13 +579,13 @@ class LayerTreeHostFreeContextResourcesOnDestroy SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostFreeContextResourcesOnDestroy); // Test if the LTH successfully frees and stops freeing context resources -// when the CompositorFrameSink is lost and recreated. -class LayerTreeHostCacheBehaviorOnCompositorFrameSinkRecreated +// when the LayerTreeFrameSink is lost and recreated. +class LayerTreeHostCacheBehaviorOnLayerTreeFrameSinkRecreated : public LayerTreeHostContextCacheTest { public: void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, const BeginFrameArgs& args) override { - // This code is run once, to trigger recreation of our CompositorFrameSink. + // This code is run once, to trigger recreation of our LayerTreeFrameSink. if (test_state_ != TestState::INIT) return; @@ -591,18 +593,18 @@ class LayerTreeHostCacheBehaviorOnCompositorFrameSinkRecreated Mock::VerifyAndClearExpectations(mock_main_context_support_); Mock::VerifyAndClearExpectations(mock_worker_context_support_); - // CompositorFrameSink lost expectations. + // LayerTreeFrameSink lost expectations. EXPECT_CALL(*mock_worker_context_support_, SetAggressivelyFreeResources(true)); EXPECT_CALL(*mock_main_context_support_, SetAggressivelyFreeResources(true)); - host_impl->DidLoseCompositorFrameSink(); + host_impl->DidLoseLayerTreeFrameSink(); test_state_ = TestState::RECREATED; } void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, bool success) override { - // This is run after we have recreated our CompositorFrameSink. + // This is run after we have recreated our LayerTreeFrameSink. if (test_state_ != TestState::RECREATED) return; @@ -625,7 +627,7 @@ class LayerTreeHostCacheBehaviorOnCompositorFrameSinkRecreated }; SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostCacheBehaviorOnCompositorFrameSinkRecreated); + LayerTreeHostCacheBehaviorOnLayerTreeFrameSinkRecreated); // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1 // draw with frame 0. @@ -811,80 +813,76 @@ class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest { break; case 2: // child_ should create a scroll node. - child_->SetScrollClipLayerId(root_->id()); + child_->SetScrollable(gfx::Size(1, 1)); break; case 3: // child_ should create a clip node. child_->SetMasksToBounds(true); break; case 4: - // child_ should not create any property tree node. + // child_ should only create the scroll-related nodes. child_->SetMasksToBounds(false); child_->SetForceRenderSurfaceForTesting(false); - child_->SetScrollClipLayerId(Layer::INVALID_ID); + // Should have no effect because empty bounds do not prevent scrolling. + child_->SetScrollable(gfx::Size(0, 0)); } } void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { PropertyTrees* property_trees = impl->sync_tree()->property_trees(); const TransformNode* root_transform_node = - property_trees->transform_tree.FindNodeFromOwningLayerId(root_->id()); + property_trees->transform_tree.Node(root_->transform_tree_index()); const TransformNode* child_transform_node = - property_trees->transform_tree.FindNodeFromOwningLayerId(child_->id()); + property_trees->transform_tree.Node(child_->transform_tree_index()); const EffectNode* root_effect_node = - property_trees->effect_tree.FindNodeFromOwningLayerId(root_->id()); + property_trees->effect_tree.Node(root_->effect_tree_index()); const EffectNode* child_effect_node = - property_trees->effect_tree.FindNodeFromOwningLayerId(child_->id()); + property_trees->effect_tree.Node(child_->effect_tree_index()); const ClipNode* root_clip_node = - property_trees->clip_tree.FindNodeFromOwningLayerId(root_->id()); + property_trees->clip_tree.Node(root_->clip_tree_index()); const ClipNode* child_clip_node = - property_trees->clip_tree.FindNodeFromOwningLayerId(child_->id()); + property_trees->clip_tree.Node(child_->clip_tree_index()); const ScrollNode* root_scroll_node = - property_trees->scroll_tree.FindNodeFromOwningLayerId(root_->id()); + property_trees->scroll_tree.Node(root_->scroll_tree_index()); const ScrollNode* child_scroll_node = - property_trees->scroll_tree.FindNodeFromOwningLayerId(child_->id()); + property_trees->scroll_tree.Node(child_->scroll_tree_index()); switch (impl->sync_tree()->source_frame_number()) { case 0: // root_ should create transform, scroll and effect tree nodes but not // a clip node. - EXPECT_NE(root_transform_node, nullptr); - EXPECT_EQ(root_transform_node->id, root_->transform_tree_index()); - EXPECT_NE(root_effect_node, nullptr); - EXPECT_EQ(root_effect_node->id, root_->effect_tree_index()); - EXPECT_NE(root_scroll_node, nullptr); - EXPECT_EQ(root_scroll_node->id, root_->scroll_tree_index()); - EXPECT_EQ(root_clip_node, nullptr); - EXPECT_EQ(child_transform_node, nullptr); - EXPECT_EQ(child_effect_node, nullptr); - EXPECT_EQ(child_clip_node, nullptr); - EXPECT_EQ(child_scroll_node, nullptr); + EXPECT_NE(nullptr, root_transform_node); + EXPECT_NE(nullptr, root_effect_node); + EXPECT_NE(nullptr, root_scroll_node); + EXPECT_NE(nullptr, root_clip_node); + EXPECT_EQ(root_transform_node, child_transform_node); + EXPECT_EQ(child_effect_node, root_effect_node); + EXPECT_EQ(root_clip_node, child_clip_node); + EXPECT_EQ(root_scroll_node, child_scroll_node); + break; case 1: // child_ should create a transfrom, effect nodes but not a scroll, clip // node. - EXPECT_NE(child_transform_node, nullptr); - EXPECT_EQ(child_transform_node->id, child_->transform_tree_index()); - EXPECT_NE(child_effect_node, nullptr); - EXPECT_EQ(child_effect_node->id, child_->effect_tree_index()); - EXPECT_EQ(child_clip_node, nullptr); - EXPECT_EQ(child_scroll_node, nullptr); + EXPECT_NE(root_transform_node, child_transform_node); + EXPECT_NE(child_effect_node, root_effect_node); + EXPECT_EQ(root_clip_node, child_clip_node); + EXPECT_EQ(root_scroll_node, child_scroll_node); + break; case 2: // child_ should create a scroll node. - EXPECT_NE(child_scroll_node, nullptr); - EXPECT_EQ(child_scroll_node->id, child_->scroll_tree_index()); + EXPECT_NE(root_scroll_node, child_scroll_node); break; case 3: // child_ should create a clip node. - EXPECT_NE(child_clip_node, nullptr); - EXPECT_EQ(child_clip_node->id, child_->clip_tree_index()); + EXPECT_NE(root_clip_node, child_clip_node); break; case 4: - // child_ should not create any property tree nodes. - EXPECT_EQ(child_transform_node, nullptr); - EXPECT_EQ(child_effect_node, nullptr); - EXPECT_EQ(child_clip_node, nullptr); - EXPECT_EQ(child_scroll_node, nullptr); + // child_ should only create the scroll-related nodes. + EXPECT_EQ(child_transform_node->id, child_scroll_node->transform_id); + EXPECT_EQ(child_effect_node, root_effect_node); + EXPECT_EQ(root_clip_node, child_clip_node); + EXPECT_NE(root_scroll_node, child_scroll_node); EndTest(); break; } @@ -1688,6 +1686,7 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(10, 10)); child_layer_ = make_scoped_refptr(new UpdateCountingLayer); + child_layer_->SetBounds(gfx::Size(10, 10)); mask_layer_ = make_scoped_refptr(new UpdateCountingLayer); mask_layer_->SetBounds(gfx::Size(10, 10)); child_layer_->SetMaskLayer(mask_layer_.get()); @@ -2732,6 +2731,65 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { // Single thread proxy does not support impl-side page scale changes. MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation); +class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest { + protected: + ViewportDeltasAppliedDuringPinch() : sent_gesture_(false) {} + + void SetupTree() override { + scoped_refptr<Layer> root_clip = Layer::Create(); + root_clip->SetBounds(gfx::Size(500, 500)); + scoped_refptr<Layer> page_scale_layer = Layer::Create(); + page_scale_layer->SetBounds(gfx::Size(500, 500)); + + scoped_refptr<Layer> pinch = Layer::Create(); + pinch->SetBounds(gfx::Size(500, 500)); + pinch->SetScrollable(gfx::Size(200, 200)); + pinch->SetIsContainerForFixedPositionLayers(true); + page_scale_layer->AddChild(pinch); + root_clip->AddChild(page_scale_layer); + + 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(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + if (!sent_gesture_) { + host_impl->PinchGestureBegin(); + host_impl->PinchGestureUpdate(2, gfx::Point(100, 100)); + host_impl->PinchGestureEnd(); + sent_gesture_ = true; + } + } + + void ApplyViewportDeltas(const gfx::Vector2dF& inner, + const gfx::Vector2dF& outer, + const gfx::Vector2dF& elastic_overscroll_delta, + float scale_delta, + float top_controls_delta) override { + EXPECT_TRUE(sent_gesture_); + EXPECT_EQ(gfx::Vector2dF(50, 50), inner); + EXPECT_EQ(2, scale_delta); + + auto* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer(); + EXPECT_EQ(gfx::ScrollOffset(50, 50), scroll_layer->scroll_offset()); + EndTest(); + } + + void AfterTest() override { EXPECT_TRUE(sent_gesture_); } + + bool sent_gesture_; +}; + +MULTI_THREAD_TEST_F(ViewportDeltasAppliedDuringPinch); + class LayerTreeHostTestSetVisible : public LayerTreeHostTest { public: LayerTreeHostTestSetVisible() : num_draws_(0) {} @@ -3202,25 +3260,25 @@ class LayerTreeHostTestLCDChange : public LayerTreeHostTest { // The first draw. EXPECT_EQ(1, num_tiles_rastered_); EXPECT_TRUE(can_use_lcd_text); - EXPECT_TRUE(root_layer->RasterSourceUsesLCDText()); + EXPECT_TRUE(root_layer->RasterSourceUsesLCDTextForTesting()); break; case 1: // Nothing changed on the layer. EXPECT_EQ(1, num_tiles_rastered_); EXPECT_TRUE(can_use_lcd_text); - EXPECT_TRUE(root_layer->RasterSourceUsesLCDText()); + EXPECT_TRUE(root_layer->RasterSourceUsesLCDTextForTesting()); break; case 2: // LCD text was disabled; it should be re-rastered with LCD text off. EXPECT_EQ(2, num_tiles_rastered_); EXPECT_FALSE(can_use_lcd_text); - EXPECT_FALSE(root_layer->RasterSourceUsesLCDText()); + EXPECT_FALSE(root_layer->RasterSourceUsesLCDTextForTesting()); break; case 3: // LCD text was enabled, but it's sticky and stays off. EXPECT_EQ(2, num_tiles_rastered_); EXPECT_TRUE(can_use_lcd_text); - EXPECT_FALSE(root_layer->RasterSourceUsesLCDText()); + EXPECT_FALSE(root_layer->RasterSourceUsesLCDTextForTesting()); break; } } @@ -3302,28 +3360,30 @@ class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { int commit_complete_count_; }; -class OnDrawCompositorFrameSink : public TestCompositorFrameSink { +class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink { public: - explicit OnDrawCompositorFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider, - SharedBitmapManager* shared_bitmap_manager, + OnDrawLayerTreeFrameSink( + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider, + viz::SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - const RendererSettings& renderer_settings, + const viz::RendererSettings& renderer_settings, base::SingleThreadTaskRunner* task_runner, bool synchronous_composite, + double refresh_rate, base::Closure invalidate_callback) - : TestCompositorFrameSink(std::move(compositor_context_provider), - std::move(worker_context_provider), - shared_bitmap_manager, - gpu_memory_buffer_manager, - renderer_settings, - task_runner, - synchronous_composite, - false /* disable_display_vsync */), + : TestLayerTreeFrameSink(std::move(compositor_context_provider), + std::move(worker_context_provider), + shared_bitmap_manager, + gpu_memory_buffer_manager, + renderer_settings, + task_runner, + synchronous_composite, + false /* disable_display_vsync */, + refresh_rate), invalidate_callback_(std::move(invalidate_callback)) {} - // TestCompositorFrameSink overrides. + // TestLayerTreeFrameSink overrides. void Invalidate() override { invalidate_callback_.Run(); } void OnDraw(bool resourceless_software_draw) { @@ -3344,20 +3404,21 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor settings->using_synchronous_renderer_compositor = true; } - std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { auto on_draw_callback = base::Bind( &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor:: CallOnDraw, base::Unretained(this)); - auto frame_sink = base::MakeUnique<OnDrawCompositorFrameSink>( + auto frame_sink = base::MakeUnique<OnDrawLayerTreeFrameSink>( compositor_context_provider, std::move(worker_context_provider), - shared_bitmap_manager(), gpu_memory_buffer_manager(), - layer_tree_host()->GetSettings().renderer_settings, - ImplThreadTaskRunner(), false /* synchronous_composite */, + shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings, + ImplThreadTaskRunner(), false /* synchronous_composite */, refresh_rate, std::move(on_draw_callback)); - compositor_frame_sink_ = frame_sink.get(); + layer_tree_frame_sink_ = frame_sink.get(); return std::move(frame_sink); } @@ -3367,13 +3428,13 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor // surface. But it needs to be done on a new stack frame. bool resourceless_software_draw = false; ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&OnDrawCompositorFrameSink::OnDraw, - base::Unretained(compositor_frame_sink_), + FROM_HERE, base::BindOnce(&OnDrawLayerTreeFrameSink::OnDraw, + base::Unretained(layer_tree_frame_sink_), resourceless_software_draw)); } } - OnDrawCompositorFrameSink* compositor_frame_sink_ = nullptr; + OnDrawLayerTreeFrameSink* layer_tree_frame_sink_ = nullptr; }; MULTI_THREAD_TEST_F( @@ -3460,7 +3521,7 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest { LayerTreeHostTestUIResource() : num_ui_resources_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { - settings->renderer_settings.texture_id_allocation_chunk_size = 1; + settings->resource_settings.texture_id_allocation_chunk_size = 1; } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -3501,7 +3562,7 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest { void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { auto* context = static_cast<TestContextProvider*>( - impl->compositor_frame_sink()->context_provider()) + impl->layer_tree_frame_sink()->context_provider()) ->TestContext3d(); int frame = impl->active_tree()->source_frame_number(); @@ -4706,8 +4767,8 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); scoped_refptr<Layer> page_scale_layer = Layer::Create(); scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); - inner_viewport_scroll_layer->SetScrollClipLayerId( - inner_viewport_container_layer->id()); + inner_viewport_scroll_layer->SetScrollable( + inner_viewport_container_layer->bounds()); inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true); root_layer_->AddChild(inner_viewport_container_layer); @@ -5398,14 +5459,14 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_TRUE(layer_->IsSuitableForGpuRasterization()); + EXPECT_FALSE(layer_->HasSlowPaths()); EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_TRUE(layer_->IsSuitableForGpuRasterization()); + EXPECT_FALSE(layer_->HasSlowPaths()); EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); @@ -5449,14 +5510,14 @@ class LayerTreeHostTestEmptyLayerGpuRasterization : public LayerTreeHostTest { } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_TRUE(layer_->IsSuitableForGpuRasterization()); + EXPECT_FALSE(layer_->HasSlowPaths()); EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_TRUE(layer_->IsSuitableForGpuRasterization()); + EXPECT_FALSE(layer_->HasSlowPaths()); EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); @@ -5474,20 +5535,20 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestEmptyLayerGpuRasterization); class LayerTreeHostWithGpuRasterizationTest : public LayerTreeHostTest { protected: - std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { auto context = TestWebGraphicsContext3D::Create(); + context->SetMaxSamples(4); + context->set_support_multisample_compatibility(false); context->set_gpu_rasterization(true); auto context_provider = TestContextProvider::Create(std::move(context)); - return LayerTreeHostTest::CreateCompositorFrameSink( - std::move(context_provider), std::move(worker_context_provider)); + return LayerTreeHostTest::CreateLayerTreeFrameSink( + renderer_settings, refresh_rate, std::move(context_provider), + std::move(worker_context_provider)); } -}; - -class LayerTreeHostTestGpuRasterizationEnabled - : public LayerTreeHostWithGpuRasterizationTest { - protected: void SetupTree() override { LayerTreeHostTest::SetupTree(); @@ -5505,6 +5566,14 @@ class LayerTreeHostTestGpuRasterizationEnabled layer_client_.set_bounds(layer_->bounds()); } + FakeContentLayerClient layer_client_; + FakePictureLayer* layer_; + FakeRecordingSource* recording_source_; +}; + +class LayerTreeHostTestGpuRasterizationEnabled + : public LayerTreeHostWithGpuRasterizationTest { + protected: void BeginTest() override { // Verify default value. EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); @@ -5514,26 +5583,26 @@ class LayerTreeHostTestGpuRasterizationEnabled EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is relevant as well. - layer_->set_force_unsuitable_for_gpu_rasterization(true); + layer_->set_force_content_has_slow_paths(true); // Veto will take effect when layers are updated. // The results will be verified after commit is completed below. - // Since we are manually marking the source as unsuitable, + // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. layer_->SetNeedsDisplay(); PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - // Ensure the suitability bit sticks. - EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); + // Ensure the slow path bit sticks. + EXPECT_TRUE(layer_->HasSlowPaths()); 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_TRUE(layer_->HasSlowPaths()); EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); @@ -5541,10 +5610,6 @@ class LayerTreeHostTestGpuRasterizationEnabled } void AfterTest() override {} - - FakeContentLayerClient layer_client_; - FakePictureLayer* layer_; - FakeRecordingSource* recording_source_; }; MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); @@ -5556,36 +5621,6 @@ class LayerTreeHostTestGpuRasterizationReenabled 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(); - - std::unique_ptr<FakeRecordingSource> recording_source( - new FakeRecordingSource); - recording_source_ = recording_source.get(); - - scoped_refptr<FakePictureLayer> layer = - FakePictureLayer::CreateWithRecordingSource( - &layer_client_, std::move(recording_source)); - layer_ = layer.get(); - layer->SetBounds(gfx::Size(10, 10)); - layer->SetIsDrawable(true); - layer_tree_host()->root_layer()->AddChild(layer); - layer_client_.set_bounds(layer_->bounds()); - } - void BeginTest() override { // Verify default value. EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); @@ -5595,11 +5630,11 @@ class LayerTreeHostTestGpuRasterizationReenabled EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is relevant as well. - layer_->set_force_unsuitable_for_gpu_rasterization(true); + layer_->set_force_content_has_slow_paths(true); // Veto will take effect when layers are updated. // The results will be verified after commit is completed below. - // Since we are manually marking the source as unsuitable, + // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. layer_->SetNeedsDisplay(); PostSetNeedsCommitToMainThread(); @@ -5616,13 +5651,13 @@ class LayerTreeHostTestGpuRasterizationReenabled ++num_commits_; switch (num_commits_) { case 1: - layer_->set_force_unsuitable_for_gpu_rasterization(false); + layer_->set_force_content_has_slow_paths(false); break; case 30: - layer_->set_force_unsuitable_for_gpu_rasterization(true); + layer_->set_force_content_has_slow_paths(true); break; case 31: - layer_->set_force_unsuitable_for_gpu_rasterization(false); + layer_->set_force_content_has_slow_paths(false); break; case 90: expected_use_msaa_ = false; @@ -5635,15 +5670,67 @@ class LayerTreeHostTestGpuRasterizationReenabled void AfterTest() override {} - FakeContentLayerClient layer_client_; - FakePictureLayer* layer_; - FakeRecordingSource* recording_source_; int num_commits_ = 0; bool expected_use_msaa_ = true; }; MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationReenabled); +class LayerTreeHostTestGpuRasterizationNonAASticky + : public LayerTreeHostWithGpuRasterizationTest { + protected: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->gpu_rasterization_msaa_sample_count = 4; + } + + void BeginTest() override { + // Verify default value. + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); + + // Gpu rasterization trigger is relevant. + layer_tree_host()->SetHasGpuRasterizationTrigger(true); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); + + // Start without slow paths, but no non-aa paint. + layer_->set_force_content_has_slow_paths(true); + layer_->set_force_content_has_non_aa_paint(false); + + // The results will be verified after commit is completed below. + layer_->SetNeedsDisplay(); + PostSetNeedsCommitToMainThread(); + } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + SCOPED_TRACE(base::StringPrintf("commit %d", num_commits_)); + if (expected_use_msaa_) { + EXPECT_TRUE(host_impl->use_msaa()); + } else { + EXPECT_FALSE(host_impl->use_msaa()); + } + + ++num_commits_; + switch (num_commits_) { + case 30: + layer_->set_force_content_has_non_aa_paint(true); + expected_use_msaa_ = false; + break; + case 31: + layer_->set_force_content_has_non_aa_paint(false); + break; + } + PostSetNeedsCommitToMainThread(); + if (num_commits_ > 100) + EndTest(); + } + + void AfterTest() override {} + + int num_commits_ = 0; + bool expected_use_msaa_ = true; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationNonAASticky); + class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { protected: void InitializeSettings(LayerTreeSettings* settings) override { @@ -5678,26 +5765,26 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is irrelevant as well. - layer_->set_force_unsuitable_for_gpu_rasterization(true); + layer_->set_force_content_has_slow_paths(true); // Veto will take effect when layers are updated. // The results will be verified after commit is completed below. - // Since we are manually marking the source as unsuitable, + // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. layer_->SetNeedsDisplay(); PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - // Ensure the suitability bit sticks. - EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); + // Ensure the slow-paths bit sticks. + EXPECT_TRUE(layer_->HasSlowPaths()); EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_FALSE(layer_->IsSuitableForGpuRasterization()); + EXPECT_TRUE(layer_->HasSlowPaths()); EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); @@ -5721,7 +5808,13 @@ class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame() : will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {} - void BeginTest() override { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { + // Test terminates when a main frame is no longer expected so request that + // this message is actually sent. + layer_tree_host()->RequestBeginMainFrameNotExpected(true); + + PostSetNeedsCommitToMainThread(); + } void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, const BeginFrameArgs& args) override { @@ -5795,6 +5888,9 @@ class LayerTreeHostTestBeginMainFrameTimeIsAlsoImplTime : impl_frame_args_(), will_begin_impl_frame_count_(0) {} void BeginTest() override { + // Test terminates when a main frame is no longer expected so request that + // this message is actually sent. + layer_tree_host()->RequestBeginMainFrameNotExpected(true); // Kick off the test with a commit. PostSetNeedsCommitToMainThread(); } @@ -5969,18 +6065,20 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise settings->use_zero_copy = true; } - std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { constexpr bool disable_display_vsync = false; bool synchronous_composite = !HasImplThread() && !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; - return base::MakeUnique<TestCompositorFrameSink>( + return base::MakeUnique<viz::TestLayerTreeFrameSink>( 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); + shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings, + ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync, + refresh_rate); } void BeginTest() override { @@ -6114,7 +6212,7 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { scoped_refptr<Layer> pinch = Layer::Create(); pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollClipLayerId(root_clip->id()); + pinch->SetScrollable(gfx::Size(500, 500)); pinch->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); @@ -6295,7 +6393,8 @@ class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy : public LayerTreeHostTestCrispUpAfterPinchEnds { protected: std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { scoped_refptr<TestContextProvider> display_context_provider = TestContextProvider::Create(); TestWebGraphicsContext3D* context3d = @@ -6421,7 +6520,7 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles scoped_refptr<Layer> pinch = Layer::Create(); pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollClipLayerId(root_clip->id()); + pinch->SetScrollable(gfx::Size(500, 500)); pinch->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch); root_clip->AddChild(page_scale_layer); @@ -6753,7 +6852,7 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest { switch (layer_tree_host()->SourceFrameNumber()) { case 1: child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(CopyOutputCallback))); + base::BindOnce(CopyOutputCallback))); transform.Scale(2.0, 2.0); child->SetTransform(transform); break; @@ -6827,7 +6926,7 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin CreateVirtualViewportLayers(root.get(), outer_viewport_scroll_layer, gfx::Size(50, 50), gfx::Size(50, 50), layer_tree_host()); - outer_viewport_scroll_layer->scroll_clip_layer()->SetMasksToBounds(true); + layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true); outer_viewport_scroll_layer->AddChild(content_layer); client_.set_bounds(root->bounds()); @@ -6919,12 +7018,12 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { content_layer->AddChild(content_child_layer); std::unique_ptr<RecordingSource> recording_source = - FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100)); + FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(50, 50)); PaintFlags paint1, paint2; static_cast<FakeRecordingSource*>(recording_source.get()) - ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1); + ->add_draw_rect_with_flags(gfx::Rect(0, 0, 50, 40), paint1); static_cast<FakeRecordingSource*>(recording_source.get()) - ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2); + ->add_draw_rect_with_flags(gfx::Rect(0, 40, 50, 10), paint2); client_.set_fill_with_nonsolid_color(true); static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord(); @@ -6951,7 +7050,7 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { content_child_layer->SetBounds(child_size); content_child_layer->SetPosition(gfx::PointF(20.f, 0.f)); - gfx::Size mask_size(100, 100); + gfx::Size mask_size(50, 50); mask_layer->SetBounds(mask_size); mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK); mask_layer_id_ = mask_layer->id(); @@ -7169,131 +7268,6 @@ class LayerTreeTestMultiTextureMaskLayerWithScaling SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMultiTextureMaskLayerWithScaling); -class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest { - protected: - void SetupTree() override { - // The mask layer has bounds 100x100 but is attached to a layer with bounds - // 50x50. - - 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(50, 50); - content_layer->SetBounds(layer_size); - - gfx::Size mask_size(100, 100); - mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK); - - 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); - - EXPECT_EQ(DrawQuad::RENDER_PASS, root_pass->quad_list.front()->material); - const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front()); - switch (host_impl->active_tree()->source_frame_number()) { - case 0: - // Check that the mask fills the surface. - EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), - render_pass_quad->rect.ToString()); - if (host_impl->settings().enable_mask_tiling) { - EXPECT_EQ(gfx::RectF(0.f, 0.f, 50.f / 128.f, 50.f / 128.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); - } else { - EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); - } - break; - case 1: - // Applying a DSF should change the render surface size, but won't - // affect which part of the mask is used. - EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), - render_pass_quad->rect.ToString()); - if (host_impl->settings().enable_mask_tiling) { - EXPECT_EQ(gfx::RectF(0.f, 0.f, 50.f / 128.f, 50.f / 128.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); - } else { - EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); - } - EndTest(); - break; - } - return draw_result; - } - - void DidCommit() override { - switch (layer_tree_host()->SourceFrameNumber()) { - case 1: - gfx::Size double_root_size(200, 200); - layer_tree_host()->SetViewportSize(double_root_size); - layer_tree_host()->SetDeviceScaleFactor(2.f); - break; - } - } - - void AfterTest() override {} - - FakeContentLayerClient client_; -}; - -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 { @@ -7376,37 +7350,36 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest { // -root // -pre page scale // -page scale - // -page scale child1 + // -inner viewport scroll // -page scale grandchild - // -page scale child2 // -post page scale scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> pre_page_scale = Layer::Create(); scoped_refptr<Layer> page_scale = Layer::Create(); - scoped_refptr<Layer> page_scale_child1 = Layer::Create(); + scoped_refptr<Layer> inner_viewport_scroll = Layer::Create(); scoped_refptr<Layer> page_scale_grandchild = Layer::Create(); - scoped_refptr<Layer> page_scale_child2 = Layer::Create(); scoped_refptr<Layer> post_page_scale = Layer::Create(); root->AddChild(pre_page_scale); root->AddChild(page_scale); root->AddChild(post_page_scale); - page_scale->AddChild(page_scale_child1); - page_scale->AddChild(page_scale_child2); - page_scale_child1->AddChild(page_scale_grandchild); + page_scale->AddChild(inner_viewport_scroll); + inner_viewport_scroll->AddChild(page_scale_grandchild); + inner_viewport_scroll->SetIsContainerForFixedPositionLayers(true); layer_tree_host()->SetRootLayer(root); LayerTreeTest::SetupTree(); LayerTreeHost::ViewportLayers viewport_layers; + viewport_layers.inner_viewport_container = root; viewport_layers.page_scale = page_scale; + viewport_layers.inner_viewport_scroll = inner_viewport_scroll; layer_tree_host()->RegisterViewportLayers(viewport_layers); affected_by_page_scale_.push_back(page_scale->id()); - affected_by_page_scale_.push_back(page_scale_child1->id()); - affected_by_page_scale_.push_back(page_scale_child2->id()); + affected_by_page_scale_.push_back(inner_viewport_scroll->id()); affected_by_page_scale_.push_back(page_scale_grandchild->id()); not_affected_by_page_scale_.push_back(root->id()); @@ -7483,7 +7456,7 @@ class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest { }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor); -// Makes sure that LocalSurfaceId is propagated to the CompositorFrameSink. +// Makes sure that viz::LocalSurfaceId is propagated to the LayerTreeFrameSink. class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest { protected: void InitializeSettings(LayerTreeSettings* settings) override { @@ -7505,15 +7478,15 @@ class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest { } void DisplayReceivedLocalSurfaceIdOnThread( - const LocalSurfaceId& local_surface_id) override { + const viz::LocalSurfaceId& local_surface_id) override { EXPECT_EQ(expected_local_surface_id_, local_surface_id); EndTest(); } void AfterTest() override {} - LocalSurfaceId expected_local_surface_id_; - LocalSurfaceIdAllocator allocator_; + viz::LocalSurfaceId expected_local_surface_id_; + viz::LocalSurfaceIdAllocator allocator_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId); @@ -7569,10 +7542,10 @@ class GpuRasterizationSucceedsWithLargeImage : public LayerTreeHostTest { // this here to ensure that our otuput surface exists. // Retrieve max texture size from Skia. - ContextProvider* context_provider = - host_impl->compositor_frame_sink()->context_provider(); + viz::ContextProvider* context_provider = + host_impl->layer_tree_frame_sink()->context_provider(); ASSERT_TRUE(context_provider); - ContextProvider::ScopedContextLock context_lock(context_provider); + viz::ContextProvider::ScopedContextLock context_lock(context_provider); GrContext* gr_context = context_provider->GrContext(); ASSERT_TRUE(gr_context); @@ -7701,45 +7674,19 @@ class LayerTreeHostTestContentSourceId : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContentSourceId); -class LayerTreeHostTestBeginFrameSequenceNumbers : public LayerTreeHostTest { +class LayerTreeHostTestBeginFrameAcks : public LayerTreeHostTest { protected: void BeginTest() override { PostSetNeedsCommitToMainThread(); } void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl, const BeginFrameArgs& args) override { - // First BeginFrame will block activation, second one unblocks. - impl->BlockNotifyReadyToActivateForTesting(false); - EXPECT_TRUE(args.IsValid()); current_begin_frame_args_ = args; } - void BeginMainFrame(const BeginFrameArgs& args) override { - EXPECT_TRUE(args.IsValid()); - if (!current_begin_main_frame_args_.IsValid()) - current_begin_main_frame_args_ = args; - } - - void BeginCommitOnThread(LayerTreeHostImpl* impl) override { - current_begin_main_frame_args_on_impl_ = current_begin_main_frame_args_; - // Request another subsequent commit. That way, the first commit's - // latest_confirmed_sequence_number should stay at the first BeginFrame's - // sequence number. - PostSetNeedsCommitToMainThread(); - } - - void WillCommitCompleteOnThread(LayerTreeHostImpl* impl) override { - // Defer current commit's activation until second BeginFrame. - impl->BlockNotifyReadyToActivateForTesting(true); - } - DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - // We should only draw in second BeginFrame. - EXPECT_TRUE(current_begin_main_frame_args_on_impl_.IsValid()); - EXPECT_LT(current_begin_main_frame_args_on_impl_.sequence_number, - current_begin_frame_args_.sequence_number); frame_data_ = frame_data; return draw_result; } @@ -7750,10 +7697,8 @@ class LayerTreeHostTestBeginFrameSequenceNumbers : public LayerTreeHostTest { return; compositor_frame_submitted_ = true; - EXPECT_EQ(BeginFrameAck( - current_begin_frame_args_.source_id, - current_begin_frame_args_.sequence_number, - current_begin_main_frame_args_on_impl_.sequence_number, true), + EXPECT_EQ(BeginFrameAck(current_begin_frame_args_.source_id, + current_begin_frame_args_.sequence_number, true), frame.metadata.begin_frame_ack); } @@ -7764,10 +7709,8 @@ class LayerTreeHostTestBeginFrameSequenceNumbers : public LayerTreeHostTest { EXPECT_TRUE(frame_data_); EXPECT_TRUE(compositor_frame_submitted_); - EXPECT_EQ(BeginFrameAck( - current_begin_frame_args_.source_id, - current_begin_frame_args_.sequence_number, - current_begin_main_frame_args_on_impl_.sequence_number, true), + EXPECT_EQ(BeginFrameAck(current_begin_frame_args_.source_id, + current_begin_frame_args_.sequence_number, true), frame_data_->begin_frame_ack); EndTest(); } @@ -7778,29 +7721,51 @@ class LayerTreeHostTestBeginFrameSequenceNumbers : public LayerTreeHostTest { bool compositor_frame_submitted_ = false; bool layers_drawn_ = false; BeginFrameArgs current_begin_frame_args_; - BeginFrameArgs current_begin_main_frame_args_; - BeginFrameArgs current_begin_main_frame_args_on_impl_; LayerTreeHostImpl::FrameData* frame_data_; }; -MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestBeginFrameSequenceNumbers); +MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestBeginFrameAcks); class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest { protected: void BeginTest() override { PostSetNeedsCommitToMainThread(); } + void InitializeSettings(LayerTreeSettings* settings) override { + settings->enable_checker_imaging = true; + } + void WillBeginMainFrame() override { if (!first_) return; first_ = false; - sk_sp<const SkImage> image = CreateDiscardableImage(gfx::Size(10, 10)); + image_ = DrawImage(PaintImage(PaintImage::GetNextId(), + CreateDiscardableImage(gfx::Size(400, 400))), + SkIRect::MakeWH(400, 400), kNone_SkFilterQuality, + SkMatrix::I(), gfx::ColorSpace()); auto callback = base::Bind(&LayerTreeHostTestQueueImageDecode::ImageDecodeFinished, base::Unretained(this)); // Schedule the decode twice for the same image. - layer_tree_host()->QueueImageDecode(image, callback); - layer_tree_host()->QueueImageDecode(image, callback); + layer_tree_host()->QueueImageDecode(image_.paint_image(), callback); + layer_tree_host()->QueueImageDecode(image_.paint_image(), callback); + } + + void ReadyToCommitOnThread(LayerTreeHostImpl* impl) override { + if (one_commit_done_) + return; + EXPECT_TRUE( + impl->tile_manager()->checker_image_tracker().ShouldCheckerImage( + image_, WhichTree::PENDING_TREE)); + // Reset the tracker as if it has never seen this image. + impl->tile_manager()->checker_image_tracker().ClearTracker(true); + } + + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { + one_commit_done_ = true; + EXPECT_FALSE( + impl->tile_manager()->checker_image_tracker().ShouldCheckerImage( + image_, WhichTree::PENDING_TREE)); } void ImageDecodeFinished(bool decode_succeeded) { @@ -7815,7 +7780,9 @@ class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest { private: bool first_ = true; + bool one_commit_done_ = false; int finished_decode_count_ = 0; + DrawImage image_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestQueueImageDecode); @@ -7830,7 +7797,7 @@ class LayerTreeHostTestQueueImageDecodeNonLazy : public LayerTreeHostTest { first_ = false; bitmap_.allocN32Pixels(10, 10); - sk_sp<const SkImage> image = SkImage::MakeFromBitmap(bitmap_); + PaintImage image(PaintImage::GetNextId(), SkImage::MakeFromBitmap(bitmap_)); auto callback = base::Bind( &LayerTreeHostTestQueueImageDecodeNonLazy::ImageDecodeFinished, base::Unretained(this)); @@ -7888,7 +7855,7 @@ class LayerTreeHostTestHudLayerWithLayerLists : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHudLayerWithLayerLists); // Verifies that LayerTreeHostClient does not receive frame acks from a released -// CompositorFrameSink. +// LayerTreeFrameSink. class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest { protected: void SetupTree() override { @@ -7914,14 +7881,14 @@ class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest { void WillReceiveCompositorFrameAck() { switch (layer_tree_host()->SourceFrameNumber()) { case 1: - // For the first commit, don't release the CompositorFrameSink. We must + // For the first commit, don't release the LayerTreeFrameSink. We must // receive the ack later on. break; case 2: - // Release the CompositorFrameSink for the second commit. We'll later + // Release the LayerTreeFrameSink for the second commit. We'll later // check that the ack is discarded. layer_tree_host()->SetVisible(false); - layer_tree_host()->ReleaseCompositorFrameSink(); + layer_tree_host()->ReleaseLayerTreeFrameSink(); break; default: NOTREACHED(); @@ -7944,13 +7911,13 @@ class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest { void CheckFrameAck() { switch (layer_tree_host()->SourceFrameNumber()) { case 1: - // CompositorFrameSink was not released. We must receive the ack. + // LayerTreeFrameSink 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. + // LayerTreeFrameSink was released. The ack must be discarded. EXPECT_FALSE(received_ack_); EndTest(); break; diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc index b9fa010f632..1574fb29875 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -724,7 +724,7 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated LayerTreeHostAnimationTest::SetupTree(); scroll_layer_ = FakePictureLayer::Create(&client_); - scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); + scroll_layer_->SetScrollable(gfx::Size(100, 100)); scroll_layer_->SetBounds(gfx::Size(1000, 1000)); client_.set_bounds(scroll_layer_->bounds()); scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); @@ -785,7 +785,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationTakeover scroll_layer_->SetBounds(gfx::Size(10000, 10000)); client_.set_bounds(scroll_layer_->bounds()); scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); - scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); + scroll_layer_->SetScrollable(gfx::Size(10, 10)); layer_tree_host()->root_layer()->AddChild(scroll_layer_); AttachPlayersToTimeline(); @@ -845,7 +845,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted scroll_layer_->SetBounds(gfx::Size(10000, 10000)); client_.set_bounds(scroll_layer_->bounds()); scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); - scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); + scroll_layer_->SetScrollable(gfx::Size(10, 10)); layer_tree_host()->root_layer()->AddChild(scroll_layer_); AttachPlayersToTimeline(); @@ -951,7 +951,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval LayerTreeHostAnimationTest::SetupTree(); scroll_layer_ = FakePictureLayer::Create(&client_); - scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); + scroll_layer_->SetScrollable(gfx::Size(100, 100)); scroll_layer_->SetBounds(gfx::Size(10000, 10000)); client_.set_bounds(scroll_layer_->bounds()); scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0)); diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc index 0828b107c44..2e4ca84fc16 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc @@ -9,8 +9,8 @@ #include "cc/test/fake_picture_layer.h" #include "cc/test/layer_tree_test.h" #include "cc/test/skia_common.h" -#include "cc/test/test_compositor_frame_sink.h" #include "cc/trees/layer_tree_impl.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" namespace cc { namespace { @@ -46,15 +46,6 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest { LayerTreeTest::SetupTree(); } - void FlushImageDecodeTasks() { - CompletionEvent completion_event; - image_worker_task_runner()->PostTask( - FROM_HERE, - base::BindOnce([](CompletionEvent* event) { event->Signal(); }, - base::Unretained(&completion_event))); - completion_event.Wait(); - } - private: // Accessed only on the main thread. FakeContentLayerClient content_layer_client_; @@ -73,26 +64,24 @@ class LayerTreeHostCheckerImagingTestMergeWithMainFrame } } - void ReadyToCommitOnThread(LayerTreeHostImpl* host_impl) override { - if (num_of_commits_ == 1) { - // Send the blocked invalidation request before notifying that we're ready - // to commit, since the invalidation will be merged with the commit. - host_impl->BlockImplSideInvalidationRequestsForTesting(false); - } + void DidReceiveImplSideInvalidationRequest( + LayerTreeHostImpl* host_impl) override { + if (invalidation_requested_) + return; + invalidation_requested_ = true; + + // Request a commit. + host_impl->SetNeedsCommit(); } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { switch (++num_of_commits_) { - case 1: { - // The first commit has happened. Run all tasks on the image worker to - // ensure that the decode completion triggers an impl-side invalidation - // request. - FlushImageDecodeTasks(); - - // Block notifying the scheduler of this request until we get a commit. + case 1: + // Block notifying the scheduler of this request until we've had a + // chance to make sure that the decode work was scheduled, flushed and + // the commit requested after it is received. host_impl->BlockImplSideInvalidationRequestsForTesting(true); - host_impl->SetNeedsCommit(); - } break; + break; case 2: { // Ensure that the expected tiles are invalidated on the sync tree. PictureLayerImpl* sync_layer_impl = static_cast<PictureLayerImpl*>( @@ -102,7 +91,9 @@ class LayerTreeHostCheckerImagingTestMergeWithMainFrame ->FindTilingWithResolution(TileResolution::HIGH_RESOLUTION); for (int i = 0; i < 4; i++) { + SCOPED_TRACE(i); for (int j = 0; j < 2; j++) { + SCOPED_TRACE(j); Tile* tile = sync_tiling->TileAt(i, j) ? sync_tiling->TileAt(i, j) : nullptr; @@ -110,10 +101,12 @@ class LayerTreeHostCheckerImagingTestMergeWithMainFrame // exist and have a raster task. If its the active tree, then only // the invalidated tiles have a raster task. if (i < 3) { + ASSERT_TRUE(tile); EXPECT_TRUE(tile->HasRasterTask()); } else if (host_impl->pending_tree()) { EXPECT_EQ(tile, nullptr); } else { + ASSERT_TRUE(tile); EXPECT_FALSE(tile->HasRasterTask()); } } @@ -127,7 +120,9 @@ class LayerTreeHostCheckerImagingTestMergeWithMainFrame void AfterTest() override { EXPECT_EQ(num_of_commits_, 2); } + // Use only on impl thread. int num_of_commits_ = 0; + bool invalidation_requested_ = false; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -158,10 +153,12 @@ class LayerTreeHostCheckerImagingTestImplSideTree // exist and have a raster task. If its the active tree, then only // the invalidated tiles have a raster task. if (i < 2) { + ASSERT_TRUE(tile); EXPECT_TRUE(tile->HasRasterTask()); } else if (host_impl->pending_tree()) { EXPECT_EQ(tile, nullptr); } else { + ASSERT_TRUE(tile); EXPECT_FALSE(tile->HasRasterTask()); } } diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc index d1337cb9904..6ad849225fe 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_context.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc @@ -29,7 +29,6 @@ #include "cc/test/fake_video_frame_provider.h" #include "cc/test/layer_tree_test.h" #include "cc/test/render_pass_test_utils.h" -#include "cc/test/test_compositor_frame_sink.h" #include "cc/test/test_context_provider.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" @@ -37,6 +36,7 @@ #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" #include "gpu/GLES2/gl2extchromium.h" #include "media/base/media.h" @@ -60,12 +60,12 @@ class LayerTreeHostContextTest : public LayerTreeTest { committed_at_least_once_(false), context_should_support_io_surface_(false), fallback_context_works_(false), - async_compositor_frame_sink_creation_(false) { + async_layer_tree_frame_sink_creation_(false) { media::InitializeMediaLibrary(); } void LoseContext() { - // CreateDisplayCompositorFrameSink happens on a different thread, so lock + // CreateDisplayLayerTreeFrameSink happens on a different thread, so lock // context3d_ to make sure we don't set it to null after recreating it // there. base::AutoLock lock(context3d_lock_); @@ -77,9 +77,11 @@ class LayerTreeHostContextTest : public LayerTreeTest { context3d_ = nullptr; } - std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { + std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { base::AutoLock lock(context3d_lock_); std::unique_ptr<TestWebGraphicsContext3D> compositor_context3d = @@ -97,7 +99,8 @@ class LayerTreeHostContextTest : public LayerTreeTest { GL_INNOCENT_CONTEXT_RESET_ARB); } - return LayerTreeTest::CreateCompositorFrameSink( + return LayerTreeTest::CreateLayerTreeFrameSink( + renderer_settings, refresh_rate, TestContextProvider::Create(std::move(compositor_context3d)), std::move(worker_context_provider)); } @@ -136,7 +139,7 @@ class LayerTreeHostContextTest : public LayerTreeTest { times_to_fail_recreate_ = 0; } - void DidFailToInitializeCompositorFrameSink() override { + void DidFailToInitializeLayerTreeFrameSink() override { ++times_create_failed_; } @@ -149,7 +152,7 @@ class LayerTreeHostContextTest : public LayerTreeTest { protected: // Protects use of context3d_ so LoseContext and - // CreateDisplayCompositorFrameSink can both use it on different threads. + // CreateDisplayLayerTreeFrameSink can both use it on different threads. base::Lock context3d_lock_; TestWebGraphicsContext3D* context3d_; @@ -162,7 +165,7 @@ class LayerTreeHostContextTest : public LayerTreeTest { bool committed_at_least_once_; bool context_should_support_io_surface_; bool fallback_context_works_; - bool async_compositor_frame_sink_creation_; + bool async_layer_tree_frame_sink_creation_; }; class LayerTreeHostContextTestLostContextSucceeds @@ -178,23 +181,23 @@ class LayerTreeHostContextTestLostContextSucceeds void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void RequestNewCompositorFrameSink() override { - if (async_compositor_frame_sink_creation_) { + void RequestNewLayerTreeFrameSink() override { + if (async_layer_tree_frame_sink_creation_) { MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&LayerTreeHostContextTestLostContextSucceeds:: - AsyncRequestNewCompositorFrameSink, + AsyncRequestNewLayerTreeFrameSink, base::Unretained(this))); } else { - AsyncRequestNewCompositorFrameSink(); + AsyncRequestNewLayerTreeFrameSink(); } } - void AsyncRequestNewCompositorFrameSink() { - LayerTreeHostContextTest::RequestNewCompositorFrameSink(); + void AsyncRequestNewLayerTreeFrameSink() { + LayerTreeHostContextTest::RequestNewLayerTreeFrameSink(); } - void DidInitializeCompositorFrameSink() override { + void DidInitializeLayerTreeFrameSink() override { if (first_initialized_) ++num_losses_; else @@ -237,35 +240,35 @@ class LayerTreeHostContextTestLostContextSucceeds 0, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works - false, // async_compositor_frame_sink_creation + false, // async_layer_tree_frame_sink_creation }, { 0, // times_to_lose_during_commit 1, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works - false, // async_compositor_frame_sink_creation + false, // async_layer_tree_frame_sink_creation }, { 1, // times_to_lose_during_commit 0, // times_to_lose_during_draw 3, // times_to_fail_recreate false, // fallback_context_works - false, // async_compositor_frame_sink_creation + false, // async_layer_tree_frame_sink_creation }, { 0, // times_to_lose_during_commit 1, // times_to_lose_during_draw 3, // times_to_fail_recreate false, // fallback_context_works - false, // async_compositor_frame_sink_creation + false, // async_layer_tree_frame_sink_creation }, { 0, // times_to_lose_during_commit 1, // times_to_lose_during_draw 3, // times_to_fail_recreate false, // fallback_context_works - true, // async_compositor_frame_sink_creation + true, // async_layer_tree_frame_sink_creation }, // Losing the context and recreating it any number of times should // succeed. @@ -274,28 +277,28 @@ class LayerTreeHostContextTestLostContextSucceeds 0, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works - false, // async_compositor_frame_sink_creation + false, // async_layer_tree_frame_sink_creation }, { 0, // times_to_lose_during_commit 10, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works - false, // async_compositor_frame_sink_creation + false, // async_layer_tree_frame_sink_creation }, { 10, // times_to_lose_during_commit 0, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works - true, // async_compositor_frame_sink_creation + true, // async_layer_tree_frame_sink_creation }, { 0, // times_to_lose_during_commit 10, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works - true, // async_compositor_frame_sink_creation + true, // async_layer_tree_frame_sink_creation }, // Losing the context, failing to reinitialize it, and making a fallback // context should work. @@ -304,14 +307,14 @@ class LayerTreeHostContextTestLostContextSucceeds 1, // times_to_lose_during_draw 0, // times_to_fail_recreate true, // fallback_context_works - false, // async_compositor_frame_sink_creation + false, // async_layer_tree_frame_sink_creation }, { 0, // times_to_lose_during_commit 1, // times_to_lose_during_draw 0, // times_to_fail_recreate true, // fallback_context_works - true, // async_compositor_frame_sink_creation + true, // async_layer_tree_frame_sink_creation }, }; @@ -327,8 +330,8 @@ class LayerTreeHostContextTestLostContextSucceeds times_to_lose_during_draw_ = kTests[test_case_].times_to_lose_during_draw; times_to_fail_recreate_ = kTests[test_case_].times_to_fail_recreate; fallback_context_works_ = kTests[test_case_].fallback_context_works; - async_compositor_frame_sink_creation_ = - kTests[test_case_].async_compositor_frame_sink_creation; + async_layer_tree_frame_sink_creation_ = + kTests[test_case_].async_layer_tree_frame_sink_creation; ++test_case_; return true; } @@ -338,7 +341,7 @@ class LayerTreeHostContextTestLostContextSucceeds int times_to_lose_during_draw; int times_to_fail_recreate; bool fallback_context_works; - bool async_compositor_frame_sink_creation; + bool async_layer_tree_frame_sink_creation; }; protected: @@ -349,12 +352,13 @@ class LayerTreeHostContextTestLostContextSucceeds bool first_initialized_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds); +// Disabled because of crbug.com/736392 +// SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds); -class LayerTreeHostClientNotVisibleDoesNotCreateCompositorFrameSink +class LayerTreeHostClientNotVisibleDoesNotCreateLayerTreeFrameSink : public LayerTreeHostContextTest { public: - LayerTreeHostClientNotVisibleDoesNotCreateCompositorFrameSink() + LayerTreeHostClientNotVisibleDoesNotCreateLayerTreeFrameSink() : LayerTreeHostContextTest() {} void WillBeginTest() override { @@ -367,60 +371,60 @@ class LayerTreeHostClientNotVisibleDoesNotCreateCompositorFrameSink EndTest(); } - void RequestNewCompositorFrameSink() override { - ADD_FAILURE() << "RequestNewCompositorFrameSink() should not be called"; + void RequestNewLayerTreeFrameSink() override { + ADD_FAILURE() << "RequestNewLayerTreeFrameSink() should not be called"; } - void DidInitializeCompositorFrameSink() override { EXPECT_TRUE(false); } + void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); } void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostClientNotVisibleDoesNotCreateCompositorFrameSink); + LayerTreeHostClientNotVisibleDoesNotCreateLayerTreeFrameSink); -// This tests the CompositorFrameSink release logic in the following sequence. -// SetUp LTH and create and init CompositorFrameSink. +// This tests the LayerTreeFrameSink release logic in the following sequence. +// SetUp LTH and create and init LayerTreeFrameSink. // LTH::SetVisible(false); -// LTH::ReleaseCompositorFrameSink(); +// LTH::ReleaseLayerTreeFrameSink(); // ... // LTH::SetVisible(true); -// Create and init new CompositorFrameSink -class LayerTreeHostClientTakeAwayCompositorFrameSink +// Create and init new LayerTreeFrameSink +class LayerTreeHostClientTakeAwayLayerTreeFrameSink : public LayerTreeHostContextTest { public: - LayerTreeHostClientTakeAwayCompositorFrameSink() + LayerTreeHostClientTakeAwayLayerTreeFrameSink() : LayerTreeHostContextTest(), setos_counter_(0) {} void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void RequestNewCompositorFrameSink() override { + void RequestNewLayerTreeFrameSink() override { if (layer_tree_host()->IsVisible()) { setos_counter_++; - LayerTreeHostContextTest::RequestNewCompositorFrameSink(); + LayerTreeHostContextTest::RequestNewLayerTreeFrameSink(); } } - void HideAndReleaseCompositorFrameSink() { + void HideAndReleaseLayerTreeFrameSink() { EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread()); layer_tree_host()->SetVisible(false); - std::unique_ptr<CompositorFrameSink> surface = - layer_tree_host()->ReleaseCompositorFrameSink(); + std::unique_ptr<LayerTreeFrameSink> surface = + layer_tree_host()->ReleaseLayerTreeFrameSink(); CHECK(surface); MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce( - &LayerTreeHostClientTakeAwayCompositorFrameSink::MakeVisible, + &LayerTreeHostClientTakeAwayLayerTreeFrameSink::MakeVisible, base::Unretained(this))); } - void DidInitializeCompositorFrameSink() override { + void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(layer_tree_host()->IsVisible()); if (setos_counter_ == 1) { MainThreadTaskRunner()->PostTask( FROM_HERE, - base::BindOnce(&LayerTreeHostClientTakeAwayCompositorFrameSink:: - HideAndReleaseCompositorFrameSink, + base::BindOnce(&LayerTreeHostClientTakeAwayLayerTreeFrameSink:: + HideAndReleaseLayerTreeFrameSink, base::Unretained(this))); } else { EndTest(); @@ -437,12 +441,12 @@ class LayerTreeHostClientTakeAwayCompositorFrameSink int setos_counter_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostClientTakeAwayCompositorFrameSink); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostClientTakeAwayLayerTreeFrameSink); -class MultipleCompositeDoesNotCreateCompositorFrameSink +class MultipleCompositeDoesNotCreateLayerTreeFrameSink : public LayerTreeHostContextTest { public: - MultipleCompositeDoesNotCreateCompositorFrameSink() + MultipleCompositeDoesNotCreateLayerTreeFrameSink() : LayerTreeHostContextTest(), request_count_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { @@ -450,7 +454,7 @@ class MultipleCompositeDoesNotCreateCompositorFrameSink settings->use_zero_copy = true; } - void RequestNewCompositorFrameSink() override { + void RequestNewLayerTreeFrameSink() override { EXPECT_GE(1, ++request_count_); EndTest(); } @@ -460,7 +464,7 @@ class MultipleCompositeDoesNotCreateCompositorFrameSink layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(2)); } - void DidInitializeCompositorFrameSink() override { EXPECT_TRUE(false); } + void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); } void AfterTest() override {} @@ -468,15 +472,15 @@ class MultipleCompositeDoesNotCreateCompositorFrameSink }; // This test uses Composite() which only exists for single thread. -SINGLE_THREAD_TEST_F(MultipleCompositeDoesNotCreateCompositorFrameSink); +SINGLE_THREAD_TEST_F(MultipleCompositeDoesNotCreateLayerTreeFrameSink); // This test makes sure that once a SingleThreadProxy issues a -// DidFailToInitializeCompositorFrameSink, that future Composite calls will not +// DidFailToInitializeLayerTreeFrameSink, that future Composite calls will not // trigger additional requests for output surfaces. -class FailedCreateDoesNotCreateExtraCompositorFrameSink +class FailedCreateDoesNotCreateExtraLayerTreeFrameSink : public LayerTreeHostContextTest { public: - FailedCreateDoesNotCreateExtraCompositorFrameSink() + FailedCreateDoesNotCreateExtraLayerTreeFrameSink() : LayerTreeHostContextTest(), num_requests_(0), has_failed_(false) { times_to_fail_create_ = 1; } @@ -486,16 +490,16 @@ class FailedCreateDoesNotCreateExtraCompositorFrameSink settings->use_zero_copy = true; } - void RequestNewCompositorFrameSink() override { + void RequestNewLayerTreeFrameSink() override { num_requests_++; // There should be one initial request and then one request from - // the LayerTreeTest test hooks DidFailToInitializeCompositorFrameSink + // the LayerTreeTest test hooks DidFailToInitializeLayerTreeFrameSink // (which is hard to skip). This second request is just ignored and is test // cruft. EXPECT_LE(num_requests_, 2); if (num_requests_ > 1) return; - LayerTreeHostContextTest::RequestNewCompositorFrameSink(); + LayerTreeHostContextTest::RequestNewLayerTreeFrameSink(); } void BeginTest() override { @@ -510,10 +514,10 @@ class FailedCreateDoesNotCreateExtraCompositorFrameSink EndTest(); } - void DidInitializeCompositorFrameSink() override { EXPECT_TRUE(false); } + void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); } - void DidFailToInitializeCompositorFrameSink() override { - LayerTreeHostContextTest::DidFailToInitializeCompositorFrameSink(); + void DidFailToInitializeLayerTreeFrameSink() override { + LayerTreeHostContextTest::DidFailToInitializeLayerTreeFrameSink(); EXPECT_FALSE(has_failed_); has_failed_ = true; } @@ -525,12 +529,12 @@ class FailedCreateDoesNotCreateExtraCompositorFrameSink }; // This test uses Composite() which only exists for single thread. -SINGLE_THREAD_TEST_F(FailedCreateDoesNotCreateExtraCompositorFrameSink); +SINGLE_THREAD_TEST_F(FailedCreateDoesNotCreateExtraLayerTreeFrameSink); -class LayerTreeHostContextTestCommitAfterDelayedCompositorFrameSink +class LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink : public LayerTreeHostContextTest { public: - LayerTreeHostContextTestCommitAfterDelayedCompositorFrameSink() + LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink() : LayerTreeHostContextTest(), creating_output_(false) {} void InitializeSettings(LayerTreeSettings* settings) override { @@ -538,18 +542,18 @@ class LayerTreeHostContextTestCommitAfterDelayedCompositorFrameSink settings->use_zero_copy = true; } - void RequestNewCompositorFrameSink() override { + void RequestNewLayerTreeFrameSink() override { MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce( - &LayerTreeHostContextTestCommitAfterDelayedCompositorFrameSink:: - CreateAndSetCompositorFrameSink, + &LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink:: + CreateAndSetLayerTreeFrameSink, base::Unretained(this))); } - void CreateAndSetCompositorFrameSink() { + void CreateAndSetLayerTreeFrameSink() { creating_output_ = true; - LayerTreeHostContextTest::RequestNewCompositorFrameSink(); + LayerTreeHostContextTest::RequestNewLayerTreeFrameSink(); } void BeginTest() override { @@ -568,7 +572,7 @@ class LayerTreeHostContextTestCommitAfterDelayedCompositorFrameSink // This test uses Composite() which only exists for single thread. SINGLE_THREAD_TEST_F( - LayerTreeHostContextTestCommitAfterDelayedCompositorFrameSink); + LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink); class LayerTreeHostContextTestAvoidUnnecessaryComposite : public LayerTreeHostContextTest { @@ -581,8 +585,8 @@ class LayerTreeHostContextTestAvoidUnnecessaryComposite settings->use_zero_copy = true; } - void RequestNewCompositorFrameSink() override { - LayerTreeHostContextTest::RequestNewCompositorFrameSink(); + void RequestNewLayerTreeFrameSink() override { + LayerTreeHostContextTest::RequestNewLayerTreeFrameSink(); EndTest(); } @@ -653,17 +657,17 @@ class LayerTreeHostContextTestLostContextSucceedsWithContent SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostContextTestLostContextSucceedsWithContent); -class LayerTreeHostContextTestCreateCompositorFrameSinkFailsOnce +class LayerTreeHostContextTestCreateLayerTreeFrameSinkFailsOnce : public LayerTreeHostContextTest { public: - LayerTreeHostContextTestCreateCompositorFrameSinkFailsOnce() + LayerTreeHostContextTestCreateLayerTreeFrameSinkFailsOnce() : times_to_fail_(1), times_initialized_(0) { times_to_fail_create_ = times_to_fail_; } void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void DidInitializeCompositorFrameSink() override { times_initialized_++; } + void DidInitializeLayerTreeFrameSink() override { times_initialized_++; } void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { EndTest(); } @@ -678,7 +682,7 @@ class LayerTreeHostContextTestCreateCompositorFrameSinkFailsOnce }; SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostContextTestCreateCompositorFrameSinkFailsOnce); + LayerTreeHostContextTestCreateLayerTreeFrameSinkFailsOnce); class LayerTreeHostContextTestLostContextAndEvictTextures : public LayerTreeHostContextTest { @@ -758,7 +762,7 @@ class LayerTreeHostContextTestLostContextAndEvictTextures EndTest(); } - void DidInitializeCompositorFrameSink() override {} + void DidInitializeLayerTreeFrameSink() override {} void AfterTest() override {} @@ -884,8 +888,8 @@ class LayerTreeHostContextTestDontUseLostResources gpu::gles2::GLES2Interface* gl = child_context_provider_->ContextGL(); ResourceId resource = child_resource_provider_->CreateResource( - gfx::Size(4, 4), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, - gfx::ColorSpace()); + gfx::Size(4, 4), ResourceProvider::TEXTURE_HINT_IMMUTABLE, + viz::RGBA_8888, gfx::ColorSpace()); ResourceProvider::ScopedWriteLockGL lock(child_resource_provider_.get(), resource, false); @@ -911,7 +915,7 @@ class LayerTreeHostContextTestDontUseLostResources texture->SetBounds(gfx::Size(10, 10)); texture->SetIsDrawable(true); texture->SetTextureMailbox( - TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D), + viz::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D), SingleReleaseCallback::Create( base::Bind(&LayerTreeHostContextTestDontUseLostResources:: EmptyReleaseCallback))); @@ -999,26 +1003,28 @@ class LayerTreeHostContextTestDontUseLostResources DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame, DrawResult draw_result) override { - if (host_impl->active_tree()->source_frame_number() == 2) { - // Lose the context during draw on the second commit. This will cause - // a third commit to recover. - context3d_->set_times_bind_texture_succeeds(0); - } return draw_result; } - void RequestNewCompositorFrameSink() override { + void RequestNewLayerTreeFrameSink() override { // This will get called twice: - // First when we create the initial CompositorFrameSink... + // First when we create the initial LayerTreeFrameSink... if (layer_tree_host()->SourceFrameNumber() > 0) { // ... and then again after we forced the context to be lost. lost_context_ = true; } - LayerTreeHostContextTest::RequestNewCompositorFrameSink(); + LayerTreeHostContextTest::RequestNewLayerTreeFrameSink(); } void DidCommitAndDrawFrame() override { ASSERT_TRUE(layer_tree_host()->hud_layer()); + + if (layer_tree_host()->SourceFrameNumber() == 2) { + // Lose the context after draw on the second commit. This will cause + // a third commit to recover. + context3d_->set_times_bind_texture_succeeds(0); + } + // End the test once we know the 3nd frame drew. if (layer_tree_host()->SourceFrameNumber() < 5) { layer_tree_host()->root_layer()->SetNeedsDisplay(); @@ -1035,7 +1041,7 @@ class LayerTreeHostContextTestDontUseLostResources bool lost_context_; scoped_refptr<TestContextProvider> child_context_provider_; - std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; + std::unique_ptr<viz::SharedBitmapManager> shared_bitmap_manager_; std::unique_ptr<ResourceProvider> child_resource_provider_; scoped_refptr<VideoFrame> color_video_frame_; @@ -1074,7 +1080,7 @@ class LayerTreeHostContextTestImplSidePainting void AfterTest() override {} - void DidInitializeCompositorFrameSink() override { EndTest(); } + void DidInitializeLayerTreeFrameSink() override { EndTest(); } private: FakeContentLayerClient client_; @@ -1131,7 +1137,7 @@ class UIResourceLostTest : public LayerTreeHostContextTest { public: UIResourceLostTest() : time_step_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { - settings->renderer_settings.texture_id_allocation_chunk_size = 1; + settings->resource_settings.texture_id_allocation_chunk_size = 1; } void BeginTest() override { PostSetNeedsCommitToMainThread(); } void AfterTest() override {} @@ -1571,11 +1577,11 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame // After the first frame, we will lose the context and then not start // allowing commits until that happens. The 2nd frame should not happen - // before DidInitializeCompositorFrameSink occurs. + // before DidInitializeLayerTreeFrameSink occurs. lost_ = true; } - void DidInitializeCompositorFrameSink() override { + void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(lost_); lost_ = false; } @@ -1621,8 +1627,8 @@ class LayerTreeHostContextTestLoseWorkerContextDuringPrepareTiles void BeginTest() override { PostSetNeedsCommitToMainThread(); } void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override { - ContextProvider::ScopedContextLock scoped_context( - host_impl->compositor_frame_sink()->worker_context_provider()); + viz::ContextProvider::ScopedContextLock scoped_context( + host_impl->layer_tree_frame_sink()->worker_context_provider()); gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc index 7805b3d76cf..d4122f0b0a4 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc @@ -12,13 +12,12 @@ #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/output/direct_renderer.h" -#include "cc/surfaces/display.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_picture_layer.h" #include "cc/test/layer_tree_test.h" -#include "cc/test/test_compositor_frame_sink.h" #include "cc/trees/layer_tree_impl.h" +#include "components/viz/test/test_layer_tree_frame_sink.h" #include "gpu/GLES2/gl2extchromium.h" namespace cc { @@ -64,9 +63,9 @@ class LayerTreeHostCopyRequestTestMultipleRequests switch (frame) { case 1: child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests:: - CopyOutputCallback, - base::Unretained(this), 0))); + base::BindOnce(&LayerTreeHostCopyRequestTestMultipleRequests:: + CopyOutputCallback, + base::Unretained(this), 0))); EXPECT_EQ(0u, callbacks_.size()); break; case 2: @@ -81,17 +80,17 @@ class LayerTreeHostCopyRequestTestMultipleRequests EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString()); child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests:: - CopyOutputCallback, - base::Unretained(this), 1))); + base::BindOnce(&LayerTreeHostCopyRequestTestMultipleRequests:: + CopyOutputCallback, + base::Unretained(this), 1))); root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests:: - CopyOutputCallback, - base::Unretained(this), 2))); + base::BindOnce(&LayerTreeHostCopyRequestTestMultipleRequests:: + CopyOutputCallback, + base::Unretained(this), 2))); grand_child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests:: - CopyOutputCallback, - base::Unretained(this), 3))); + base::BindOnce(&LayerTreeHostCopyRequestTestMultipleRequests:: + CopyOutputCallback, + base::Unretained(this), 3))); EXPECT_EQ(1u, callbacks_.size()); break; case 4: @@ -130,7 +129,8 @@ class LayerTreeHostCopyRequestTestMultipleRequests void AfterTest() override { EXPECT_EQ(4u, callbacks_.size()); } std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { if (!use_gl_renderer_) { return FakeOutputSurface::CreateSoftware( base::WrapUnique(new SoftwareOutputDevice)); @@ -219,8 +219,8 @@ class LayerTreeHostCopyRequestCompletionCausesCommit switch (frame) { case 1: layer_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostCopyRequestCompletionCausesCommit:: - CopyOutputCallback))); + base::BindOnce(&LayerTreeHostCopyRequestCompletionCausesCommit:: + CopyOutputCallback))); break; case 2: // This commit is triggered by the copy request. @@ -275,11 +275,11 @@ class LayerTreeHostCopyRequestTestLayerDestroyed switch (frame) { case 1: main_destroyed_->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind( + CopyOutputRequest::CreateBitmapRequest(base::BindOnce( &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback, base::Unretained(this)))); impl_destroyed_->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind( + CopyOutputRequest::CreateBitmapRequest(base::BindOnce( &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback, base::Unretained(this)))); EXPECT_EQ(0, callback_count_); @@ -366,7 +366,7 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree void AddCopyRequest(Layer* layer) { layer->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind( + CopyOutputRequest::CreateBitmapRequest(base::BindOnce( &LayerTreeHostCopyRequestTestInHiddenSubtree::CopyOutputCallback, base::Unretained(this)))); } @@ -464,11 +464,13 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest client_.set_bounds(root_->bounds()); } - std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( - scoped_refptr<ContextProvider> compositor_context_provider, - scoped_refptr<ContextProvider> worker_context_provider) override { - auto frame_sink = LayerTreeHostCopyRequestTest::CreateCompositorFrameSink( - std::move(compositor_context_provider), + std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink( + const viz::RendererSettings& renderer_settings, + double refresh_rate, + scoped_refptr<viz::ContextProvider> compositor_context_provider, + scoped_refptr<viz::ContextProvider> worker_context_provider) override { + auto frame_sink = LayerTreeHostCopyRequestTest::CreateLayerTreeFrameSink( + renderer_settings, refresh_rate, std::move(compositor_context_provider), std::move(worker_context_provider)); frame_sink_ = frame_sink.get(); return frame_sink; @@ -478,9 +480,9 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest PostSetNeedsCommitToMainThread(); copy_layer_->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind( + CopyOutputRequest::CreateBitmapRequest(base::BindOnce( &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest:: - CopyOutputCallback, + CopyOutputCallback, base::Unretained(this)))); } @@ -532,9 +534,9 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest void AfterTest() override { EXPECT_TRUE(did_swap_); } - int parent_render_pass_id = 0; - int copy_layer_render_pass_id = 0; - TestCompositorFrameSink* frame_sink_ = nullptr; + RenderPassId parent_render_pass_id = 0; + RenderPassId copy_layer_render_pass_id = 0; + viz::TestLayerTreeFrameSink* frame_sink_ = nullptr; bool did_swap_ = false; FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; @@ -571,9 +573,10 @@ class LayerTreeHostCopyRequestTestClippedOut void BeginTest() override { PostSetNeedsCommitToMainThread(); - copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostCopyRequestTestClippedOut::CopyOutputCallback, - base::Unretained(this)))); + copy_layer_->RequestCopyOfOutput( + CopyOutputRequest::CreateBitmapRequest(base::BindOnce( + &LayerTreeHostCopyRequestTestClippedOut::CopyOutputCallback, + base::Unretained(this)))); } void CopyOutputCallback(std::unique_ptr<CopyOutputResult> result) { @@ -626,7 +629,7 @@ class LayerTreeHostCopyRequestTestScaledLayer PostSetNeedsCommitToMainThread(); std::unique_ptr<CopyOutputRequest> request = - CopyOutputRequest::CreateBitmapRequest(base::Bind( + CopyOutputRequest::CreateBitmapRequest(base::BindOnce( &LayerTreeHostCopyRequestTestScaledLayer::CopyOutputCallback, base::Unretained(this))); request->set_area(gfx::Rect(5, 5)); @@ -668,7 +671,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw void AddCopyRequest(Layer* layer) { layer->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind( + CopyOutputRequest::CreateBitmapRequest(base::BindOnce( &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback, base::Unretained(this)))); } @@ -737,7 +740,8 @@ class LayerTreeHostCopyRequestTestDeleteTexture : public LayerTreeHostCopyRequestTest { protected: std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { display_context_provider_ = TestContextProvider::Create(); display_context_provider_->BindToCurrentThread(); return FakeOutputSurface::Create3d(display_context_provider_); @@ -774,9 +778,9 @@ class LayerTreeHostCopyRequestTestDeleteTexture void InsertCopyRequest() { copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateRequest( - base::Bind(&LayerTreeHostCopyRequestTestDeleteTexture:: - ReceiveCopyRequestOutputAndCommit, - base::Unretained(this)))); + base::BindOnce(&LayerTreeHostCopyRequestTestDeleteTexture:: + ReceiveCopyRequestOutputAndCommit, + base::Unretained(this)))); } void DestroyCopyResultAndCheckNumTextures() { @@ -859,15 +863,16 @@ class LayerTreeHostCopyRequestTestCountTextures protected: void InitializeSettings(LayerTreeSettings* settings) override { // Always allocate only a single texture at a time through ResourceProvider. - settings->renderer_settings.texture_id_allocation_chunk_size = 1; + settings->resource_settings.texture_id_allocation_chunk_size = 1; } std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<ContextProvider> compositor_context_provider) override { + scoped_refptr<viz::ContextProvider> compositor_context_provider) + override { // These tests expect the LayerTreeHostImpl to share a context with // the Display so that sync points are not needed and the texture counts // are visible together. - // Since this test does not override CreateCompositorFrameSink, the + // Since this test does not override CreateLayerTreeFrameSink, the // |compositor_context_provider| will be a TestContextProvider. display_context_provider_ = static_cast<TestContextProvider*>(compositor_context_provider.get()); @@ -963,7 +968,7 @@ class LayerTreeHostCopyRequestTestCreatesTexture void RequestCopy(Layer* layer) override { // Request a normal texture copy. This should create a new texture. copy_layer_->RequestCopyOfOutput( - CopyOutputRequest::CreateRequest(base::Bind( + CopyOutputRequest::CreateRequest(base::BindOnce( &LayerTreeHostCopyRequestTestCreatesTexture::CopyOutputCallback, base::Unretained(this)))); } @@ -972,7 +977,7 @@ class LayerTreeHostCopyRequestTestCreatesTexture EXPECT_FALSE(result->IsEmpty()); EXPECT_TRUE(result->HasTexture()); - TextureMailbox mailbox; + viz::TextureMailbox mailbox; result->TakeTexture(&mailbox, &release_); EXPECT_TRUE(release_); } @@ -1004,7 +1009,7 @@ class LayerTreeHostCopyRequestTestProvideTexture EXPECT_FALSE(result->IsEmpty()); EXPECT_TRUE(result->HasTexture()); - TextureMailbox mailbox; + viz::TextureMailbox mailbox; std::unique_ptr<SingleReleaseCallback> release; result->TakeTexture(&mailbox, &release); EXPECT_FALSE(release); @@ -1014,7 +1019,7 @@ class LayerTreeHostCopyRequestTestProvideTexture // Request a copy to a provided texture. This should not create a new // texture. std::unique_ptr<CopyOutputRequest> request = - CopyOutputRequest::CreateRequest(base::Bind( + CopyOutputRequest::CreateRequest(base::BindOnce( &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback, base::Unretained(this))); @@ -1027,7 +1032,7 @@ class LayerTreeHostCopyRequestTestProvideTexture gl->GenSyncTokenCHROMIUM(fence_sync, sync_token_.GetData()); request->SetTextureMailbox( - TextureMailbox(mailbox, sync_token_, GL_TEXTURE_2D)); + viz::TextureMailbox(mailbox, sync_token_, GL_TEXTURE_2D)); EXPECT_TRUE(request->has_texture_mailbox()); copy_layer_->RequestCopyOfOutput(std::move(request)); @@ -1035,7 +1040,7 @@ class LayerTreeHostCopyRequestTestProvideTexture void AfterTest() override { // Expect the compositor to have waited for the sync point in the provided - // TextureMailbox. + // viz::TextureMailbox. EXPECT_EQ(sync_token_, waited_sync_token_after_readback_); // Except the copy to have *not* made another texture. EXPECT_EQ(num_textures_without_readback_, num_textures_with_readback_); @@ -1089,9 +1094,9 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy // drawing to take place. std::unique_ptr<CopyOutputRequest> request = CopyOutputRequest::CreateRequest( - base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy:: - CopyOutputCallback, - base::Unretained(this))); + base::BindOnce(&LayerTreeHostCopyRequestTestDestroyBeforeCopy:: + CopyOutputCallback, + base::Unretained(this))); copy_layer_->RequestCopyOfOutput(std::move(request)); layer_tree_host()->SetViewportSize(gfx::Size()); @@ -1167,9 +1172,9 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy // drawing to take place. std::unique_ptr<CopyOutputRequest> request = CopyOutputRequest::CreateRequest( - base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy:: - CopyOutputCallback, - base::Unretained(this))); + base::BindOnce(&LayerTreeHostCopyRequestTestShutdownBeforeCopy:: + CopyOutputCallback, + base::Unretained(this))); copy_layer_->RequestCopyOfOutput(std::move(request)); layer_tree_host()->SetViewportSize(gfx::Size()); @@ -1226,7 +1231,7 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest // Send a copy request after the first commit. if (layer_tree_host()->SourceFrameNumber() == 1) { child_->RequestCopyOfOutput( - CopyOutputRequest::CreateBitmapRequest(base::Bind( + CopyOutputRequest::CreateBitmapRequest(base::BindOnce( &LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest:: CopyOutputCallback, base::Unretained(this)))); diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc index 578324f785e..34950c6e58f 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc @@ -339,19 +339,14 @@ class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest { root_layer->SetMasksToBounds(true); layer_tree_host()->SetRootLayer(root_layer); - 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_->SetScrollable(root_layer->bounds()); content_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); content_layer_->SetBounds(gfx::Size(100, 200)); content_layer_->SetIsDrawable(true); - scroll_clip_layer->SetBounds( - gfx::Size(content_layer_->bounds().width() - 30, - content_layer_->bounds().height() - 50)); - scroll_clip_layer->AddChild(content_layer_); - root_layer->AddChild(scroll_clip_layer); + root_layer->AddChild(content_layer_); scoped_refptr<Layer> scrollbar_layer = FakePaintedScrollbarLayer::Create( false, true, content_layer_->element_id()); diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc index e4fefef207c..65796622aba 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc @@ -224,7 +224,7 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree // picture_'s transform is going to be changing on the compositor thread, so // force it to have a transform node by making it scrollable. - picture_->SetScrollClipLayerId(root->id()); + picture_->SetScrollable(root->bounds()); layer_tree_host()->SetRootLayer(root); LayerTreeHostPictureTest::SetupTree(); @@ -412,7 +412,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale pinch_ = Layer::Create(); pinch_->SetBounds(gfx::Size(500, 500)); - pinch_->SetScrollClipLayerId(root_clip->id()); + pinch_->SetScrollable(root_clip->bounds()); pinch_->SetIsContainerForFixedPositionLayers(true); page_scale_layer->AddChild(pinch_); root_clip->AddChild(page_scale_layer); diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc index e9a1e5d6b2e..767c4e20341 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc @@ -94,10 +94,8 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { num_scrolls_(0) {} void BeginTest() override { - outer_viewport_container_layer_id_ = layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() - ->id(); + outer_viewport_container_layer_id_ = + layer_tree_host()->outer_viewport_container_layer()->id(); layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( initial_scroll_); layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( @@ -125,7 +123,6 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); - scroll_layer->SetScrollClipLayer(outer_viewport_container_layer_id_); scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); scroll_layer->ScrollBy(scroll_amount_); @@ -134,14 +131,14 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { case 0: EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); PostSetNeedsCommitToMainThread(); break; case 1: EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); EndTest(); break; @@ -206,9 +203,9 @@ class LayerTreeHostScrollTestScrollMultipleRedraw scroll_layer->ScrollBy(scroll_amount_); EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); - EXPECT_VECTOR_EQ(initial_scroll_, - ScrollTreeForLayer(scroll_layer) - ->GetScrollOffsetBaseForTesting(scroll_layer->id())); + EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) + ->GetScrollOffsetBaseForTesting( + scroll_layer->element_id())); PostSetNeedsRedrawToMainThread(); } else if (impl->active_tree()->source_frame_number() == 0 && impl->SourceAnimationFrameNumberForTesting() == 2) { @@ -348,9 +345,10 @@ class LayerTreeHostScrollTestScrollAbortedCommit EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer)); root_scroll_layer->ScrollBy(impl_scroll_); EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer)); - EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(root_scroll_layer) - ->GetScrollOffsetBaseForTesting( - root_scroll_layer->id())); + EXPECT_VECTOR_EQ( + initial_scroll_, + ScrollTreeForLayer(root_scroll_layer) + ->GetScrollOffsetBaseForTesting(root_scroll_layer->element_id())); EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta()); EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); @@ -371,7 +369,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_), ScrollTreeForLayer(root_scroll_layer) - ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + ->GetScrollOffsetBaseForTesting(root_scroll_layer->element_id())); EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta()); EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor()); @@ -395,7 +393,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, delta), ScrollTreeForLayer(root_scroll_layer) - ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + ->GetScrollOffsetBaseForTesting(root_scroll_layer->element_id())); } else if (impl->active_tree()->source_frame_number() == 2 && impl->SourceAnimationFrameNumberForTesting() == 4) { // Final draw after the second aborted commit. @@ -405,7 +403,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, delta), ScrollTreeForLayer(root_scroll_layer) - ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + ->GetScrollOffsetBaseForTesting(root_scroll_layer->element_id())); EndTest(); } else { // Commit for source frame 3 is aborted. @@ -462,7 +460,7 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ( gfx::Vector2d(0, 0), ScrollTreeForLayer(scroll_layer) - ->GetScrollOffsetBaseForTesting(scroll_layer->id())); + ->GetScrollOffsetBaseForTesting(scroll_layer->element_id())); EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), ScrollDelta(scroll_layer)); PostSetNeedsCommitToMainThread(); break; @@ -470,7 +468,7 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ( gfx::ToFlooredVector2d(scroll_amount_), ScrollTreeForLayer(scroll_layer) - ->GetScrollOffsetBaseForTesting(scroll_layer->id())); + ->GetScrollOffsetBaseForTesting(scroll_layer->element_id())); EXPECT_VECTOR_EQ(gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f), ScrollDelta(scroll_layer)); PostSetNeedsCommitToMainThread(); @@ -479,7 +477,7 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ( gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_), ScrollTreeForLayer(scroll_layer) - ->GetScrollOffsetBaseForTesting(scroll_layer->id())); + ->GetScrollOffsetBaseForTesting(scroll_layer->element_id())); EXPECT_VECTOR_EQ( gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f), ScrollDelta(scroll_layer)); @@ -504,15 +502,12 @@ class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest { void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() + ->outer_viewport_container_layer() ->SetForceRenderSurfaceForTesting(true); gfx::Transform translate; translate.Translate(0.25f, 0.f); - layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() - ->SetTransform(translate); + layer_tree_host()->outer_viewport_container_layer()->SetTransform( + translate); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f); } @@ -597,11 +592,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { child_layer_->SetPosition(gfx::PointF(60.f, 5.f)); } - scoped_refptr<Layer> outer_container_layer = - layer_tree_host()->outer_viewport_scroll_layer()->parent(); - child_layer_->SetIsDrawable(true); - child_layer_->SetScrollClipLayerId(outer_container_layer->id()); + child_layer_->SetScrollable(root_layer->bounds()); child_layer_->SetElementId( LayerIdToElementIdForTesting(child_layer_->id())); child_layer_->SetBounds(root_scroll_layer_->bounds()); @@ -715,7 +707,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ(initial_offset_, ScrollTreeForLayer(expected_scroll_layer_impl) ->GetScrollOffsetBaseForTesting( - expected_scroll_layer_impl->id())); + expected_scroll_layer_impl->element_id())); EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(expected_scroll_layer_impl)); break; @@ -735,7 +727,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ(javascript_scroll_, ScrollTreeForLayer(expected_scroll_layer_impl) ->GetScrollOffsetBaseForTesting( - expected_scroll_layer_impl->id())); + expected_scroll_layer_impl->element_id())); EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(expected_scroll_layer_impl)); break; @@ -746,7 +738,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_), ScrollTreeForLayer(expected_scroll_layer_impl) ->GetScrollOffsetBaseForTesting( - expected_scroll_layer_impl->id())); + expected_scroll_layer_impl->element_id())); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(expected_scroll_layer_impl)); @@ -887,9 +879,10 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); scroll_layer->ScrollBy(impl_thread_scroll1_); - EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) - ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + EXPECT_VECTOR_EQ( + initial_scroll_, + ScrollTreeForLayer(scroll_layer) + ->GetScrollOffsetBaseForTesting(scroll_layer->element_id())); EXPECT_VECTOR_EQ(impl_thread_scroll1_, ScrollDelta(scroll_layer)); PostSetNeedsCommitToMainThread(); @@ -901,9 +894,10 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1); scroll_layer->ScrollBy(impl_thread_scroll2_); - EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) - ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + EXPECT_VECTOR_EQ( + initial_scroll_, + ScrollTreeForLayer(scroll_layer) + ->GetScrollOffsetBaseForTesting(scroll_layer->element_id())); EXPECT_VECTOR_EQ(impl_thread_scroll1_ + impl_thread_scroll2_, ScrollDelta(scroll_layer)); @@ -913,7 +907,8 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { gfx::ScrollOffsetWithDelta( initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_), ScrollTreeForLayer(pending_scroll_layer) - ->GetScrollOffsetBaseForTesting(pending_scroll_layer->id())); + ->GetScrollOffsetBaseForTesting( + pending_scroll_layer->element_id())); EXPECT_VECTOR_EQ(impl_thread_scroll2_, ScrollDelta(pending_scroll_layer)); } @@ -924,7 +919,7 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { gfx::ScrollOffsetWithDelta( initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_), ScrollTreeForLayer(scroll_layer) - ->GetScrollOffsetBaseForTesting(scroll_layer->id())); + ->GetScrollOffsetBaseForTesting(scroll_layer->element_id())); EXPECT_VECTOR_EQ(impl_thread_scroll2_, ScrollDelta(scroll_layer)); EndTest(); break; @@ -1011,27 +1006,27 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { ASSERT_TRUE(pending_scroll_layer); switch (impl->pending_tree()->source_frame_number()) { case 0: - EXPECT_VECTOR_EQ( - initial_scroll_, - ScrollTreeForLayer(pending_scroll_layer) - ->GetScrollOffsetBaseForTesting(pending_scroll_layer->id())); + EXPECT_VECTOR_EQ(initial_scroll_, + ScrollTreeForLayer(pending_scroll_layer) + ->GetScrollOffsetBaseForTesting( + pending_scroll_layer->element_id())); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(pending_scroll_layer)); EXPECT_FALSE(active_root); break; case 1: // Even though the scroll happened during the commit, both layers // should have the appropriate scroll delta. - EXPECT_VECTOR_EQ( - initial_scroll_, - ScrollTreeForLayer(pending_scroll_layer) - ->GetScrollOffsetBaseForTesting(pending_scroll_layer->id())); + EXPECT_VECTOR_EQ(initial_scroll_, + ScrollTreeForLayer(pending_scroll_layer) + ->GetScrollOffsetBaseForTesting( + pending_scroll_layer->element_id())); EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(pending_scroll_layer)); ASSERT_TRUE(active_root); - EXPECT_VECTOR_EQ( - initial_scroll_, - ScrollTreeForLayer(active_scroll_layer) - ->GetScrollOffsetBaseForTesting(active_scroll_layer->id())); + EXPECT_VECTOR_EQ(initial_scroll_, + ScrollTreeForLayer(active_scroll_layer) + ->GetScrollOffsetBaseForTesting( + active_scroll_layer->element_id())); EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(active_scroll_layer)); break; case 2: @@ -1039,7 +1034,8 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll_), ScrollTreeForLayer(pending_scroll_layer) - ->GetScrollOffsetBaseForTesting(pending_scroll_layer->id())); + ->GetScrollOffsetBaseForTesting( + pending_scroll_layer->element_id())); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(pending_scroll_layer)); break; } @@ -1055,7 +1051,7 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { case 0: EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta()); EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); @@ -1064,7 +1060,7 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { case 1: EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(scroll_layer)); EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta()); EXPECT_EQ(impl_scale_, @@ -1097,10 +1093,8 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {} void BeginTest() override { - outer_viewport_container_layer_id_ = layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() - ->id(); + outer_viewport_container_layer_id_ = + layer_tree_host()->outer_viewport_container_layer()->id(); PostSetNeedsCommitToMainThread(); } @@ -1109,7 +1103,7 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); switch (layer_tree_host()->SourceFrameNumber()) { case 0: - scroll_layer->SetScrollClipLayerId(outer_viewport_container_layer_id_); + scroll_layer->SetScrollable(root->bounds()); // Set max_scroll_offset = (100, 100). scroll_layer->SetBounds(gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); @@ -1437,10 +1431,9 @@ class LayerTreeHostScrollTestLayerStructureChange Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) { scoped_refptr<PictureLayer> scroll_layer = PictureLayer::Create(&fake_content_layer_client_); - scroll_layer->SetBounds(gfx::Size(110, 110)); scroll_layer->SetPosition(gfx::PointF()); scroll_layer->SetIsDrawable(true); - scroll_layer->SetScrollClipLayerId(parent->id()); + scroll_layer->SetScrollable(parent->bounds()); scroll_layer->SetElementId( LayerIdToElementIdForTesting(scroll_layer->id())); scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100, @@ -1457,9 +1450,10 @@ class LayerTreeHostScrollTestLayerStructureChange const gfx::Vector2dF& delta) { if (layer_impl->layer_tree_impl() ->property_trees() - ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(), - delta)) - layer_impl->layer_tree_impl()->DidUpdateScrollOffset(layer_impl->id()); + ->scroll_tree.SetScrollOffsetDeltaForTesting( + layer_impl->element_id(), delta)) + layer_impl->layer_tree_impl()->DidUpdateScrollOffset( + layer_impl->element_id()); } FakeLayerScrollClient root_scroll_layer_client_; @@ -1498,10 +1492,8 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { } void BeginTest() override { - outer_viewport_container_layer_id_ = layer_tree_host() - ->outer_viewport_scroll_layer() - ->scroll_clip_layer() - ->id(); + outer_viewport_container_layer_id_ = + layer_tree_host()->outer_viewport_container_layer()->id(); layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( initial_scroll_); layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( @@ -1556,7 +1548,7 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); Scroll(impl); EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); // Ask for commit after we've scrolled. @@ -1566,7 +1558,7 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); Scroll(impl); EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); break; @@ -1575,7 +1567,7 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer)); EXPECT_VECTOR_EQ(third_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); EndTest(); break; } @@ -1593,7 +1585,6 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { LayerImpl* root = impl->active_tree()->root_layer_for_testing(); LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); - scroll_layer->SetScrollClipLayer(outer_viewport_container_layer_id_); scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); scroll_layer->ScrollBy(scroll_amount_); @@ -1738,10 +1729,10 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer)); root_scroll_layer->ScrollBy(impl_scroll_); EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer)); - EXPECT_VECTOR_EQ( - initial_scroll_, - ScrollTreeForLayer(root_scroll_layer) - ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + EXPECT_VECTOR_EQ(initial_scroll_, + ScrollTreeForLayer(root_scroll_layer) + ->GetScrollOffsetBaseForTesting( + root_scroll_layer->element_id())); impl->SetNeedsCommit(); break; } @@ -1751,10 +1742,10 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA root_scroll_layer->ScrollBy(impl_scroll_); EXPECT_VECTOR_EQ(impl_scroll_ + impl_scroll_, ScrollDelta(root_scroll_layer)); - EXPECT_VECTOR_EQ( - initial_scroll_, - ScrollTreeForLayer(root_scroll_layer) - ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + EXPECT_VECTOR_EQ(initial_scroll_, + ScrollTreeForLayer(root_scroll_layer) + ->GetScrollOffsetBaseForTesting( + root_scroll_layer->element_id())); // Ask for another commit (which will abort). impl->SetNeedsCommit(); break; @@ -1777,7 +1768,8 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, prev_delta), ScrollTreeForLayer(root_scroll_layer) - ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + ->GetScrollOffsetBaseForTesting( + root_scroll_layer->element_id())); // Ask for another commit (which will abort). impl->SetNeedsCommit(); break; @@ -1785,10 +1777,10 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA case 2: { gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; - EXPECT_VECTOR_EQ( - gfx::ScrollOffsetWithDelta(initial_scroll_, delta), - ScrollTreeForLayer(root_scroll_layer) - ->GetScrollOffsetBaseForTesting(root_scroll_layer->id())); + EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta), + ScrollTreeForLayer(root_scroll_layer) + ->GetScrollOffsetBaseForTesting( + root_scroll_layer->element_id())); // End test after second aborted commit (fourth commit request). EndTest(); break; @@ -2046,7 +2038,7 @@ class LayerTreeHostScrollTestPropertyTreeUpdate case 0: EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); EXPECT_VECTOR_EQ( initial_scroll_, scroll_layer->layer_tree_impl() @@ -2058,7 +2050,7 @@ class LayerTreeHostScrollTestPropertyTreeUpdate case 1: EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( - scroll_layer->id())); + scroll_layer->element_id())); EXPECT_VECTOR_EQ( second_scroll_, scroll_layer->layer_tree_impl() diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index 2c57e5a1f0e..277ee1a6faf 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -30,7 +30,7 @@ #include "cc/layers/layer_list_iterator.h" #include "cc/layers/render_surface_impl.h" #include "cc/layers/scrollbar_layer_impl_base.h" -#include "cc/output/compositor_frame_sink.h" +#include "cc/output/layer_tree_frame_sink.h" #include "cc/resources/ui_resource_request.h" #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" @@ -89,7 +89,9 @@ LayerTreeImpl::LayerTreeImpl( layers_(new OwnedLayerImplList), viewport_size_invalid_(false), needs_update_draw_properties_(true), + scrollbar_geometries_need_update_(false), needs_full_tree_sync_(true), + needs_surface_ids_sync_(false), next_activation_forces_redraw_(false), has_ever_been_drawn_(false), handle_visibility_changed_(false), @@ -149,138 +151,109 @@ void LayerTreeImpl::RecreateTileResources() { } } -bool LayerTreeImpl::IsViewportLayerId(int id) const { -#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(ElementId id) { + // Scrollbar positions depend on the current scroll offset. + SetScrollbarGeometriesNeedUpdate(); -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; - - // If pending tree topology changed and we still want to notify the pending - // tree about scroll offset in the active tree, we may not find the - // corresponding pending layer. - if (LayerById(layer_id)) { - // TODO(sunxd): when we have a layer_id to property_tree index map in - // property trees, use the transform_id parameter instead of looking for - // indices from LayerImpls. - transform_id = LayerById(layer_id)->transform_tree_index(); - } else { + const auto* scroll_node = scroll_tree.FindNodeFromElementId(id); + + if (!scroll_node) { + // A scroll node should always exist on the active tree but may not exist + // if we're updating the other trees from the active tree. This can occur + // when the pending tree represents a different page, for example. DCHECK(!IsActiveTree()); return; } - if (transform_id != TransformTree::kInvalidNodeId) { - TransformNode* node = transform_tree.Node(transform_id); - if (node->scroll_offset != scroll_tree.current_scroll_offset(layer_id)) { - node->scroll_offset = scroll_tree.current_scroll_offset(layer_id); - node->needs_local_transform_update = true; - transform_tree.set_needs_update(true); - } - node->transform_changed = true; - property_trees()->changed = true; - set_needs_update_draw_properties(); + DCHECK(scroll_node->transform_id != TransformTree::kInvalidNodeId); + TransformTree& transform_tree = property_trees()->transform_tree; + auto* transform_node = transform_tree.Node(scroll_node->transform_id); + if (transform_node->scroll_offset != scroll_tree.current_scroll_offset(id)) { + transform_node->scroll_offset = scroll_tree.current_scroll_offset(id); + transform_node->needs_local_transform_update = true; + transform_tree.set_needs_update(true); } + transform_node->transform_changed = true; + property_trees()->changed = true; + set_needs_update_draw_properties(); - if (IsActiveTree() && layer_tree_host_impl_->pending_tree()) - layer_tree_host_impl_->pending_tree()->DidUpdateScrollOffset(layer_id); + if (IsActiveTree()) { + // Ensure the other trees are kept in sync. + if (layer_tree_host_impl_->pending_tree()) + layer_tree_host_impl_->pending_tree()->DidUpdateScrollOffset(id); + if (layer_tree_host_impl_->recycle_tree()) + layer_tree_host_impl_->recycle_tree()->DidUpdateScrollOffset(id); + } } -void LayerTreeImpl::DidUpdateScrollState(int layer_id) { +void LayerTreeImpl::UpdateScrollbarGeometries() { 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()); + // Layer properties such as bounds should be up-to-date. + DCHECK(lifecycle().AllowsLayerPropertyAccess()); - if (layer_id == Layer::INVALID_ID) + if (!scrollbar_geometries_need_update_) return; - int scroll_layer_id, clip_layer_id; - if (IsViewportLayerId(layer_id)) { - if (!InnerViewportContainerLayer()) - return; + for (auto& pair : element_id_to_scrollbar_layer_ids_) { + ElementId scrolling_element_id = pair.first; - // 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 = 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. - auto i = clip_scroll_map_.find(layer_id); - if (i != clip_scroll_map_.end()) { - scroll_layer_id = i->second; - clip_layer_id = layer_id; - } else { - scroll_layer_id = layer_id; - clip_layer_id = LayerById(scroll_layer_id)->scroll_clip_layer_id(); + auto& scroll_tree = property_trees()->scroll_tree; + auto* scroll_node = scroll_tree.FindNodeFromElementId(scrolling_element_id); + if (!scroll_node) + continue; + gfx::ScrollOffset current_offset = + scroll_tree.current_scroll_offset(scrolling_element_id); + gfx::SizeF scrolling_size(scroll_node->bounds); + gfx::SizeF bounds_size(scroll_tree.container_bounds(scroll_node->id)); + + bool is_viewport_scrollbar = scroll_node->scrolls_inner_viewport || + scroll_node->scrolls_outer_viewport; + if (is_viewport_scrollbar) { + if (scroll_node->scrolls_inner_viewport) { + // Add offset and bounds contribution of outer viewport. + current_offset += OuterViewportScrollLayer()->CurrentScrollOffset(); + gfx::SizeF outer_viewport_bounds(scroll_tree.container_bounds( + OuterViewportScrollLayer()->scroll_tree_index())); + bounds_size.SetToMin(outer_viewport_bounds); + + // The scrolling size is only determined by the outer viewport. + scroll_node = scroll_tree.FindNodeFromElementId( + OuterViewportScrollLayer()->element_id()); + scrolling_size = gfx::SizeF(scroll_node->bounds); + } else { + // Add offset and bounds contribution of inner viewport. + current_offset += InnerViewportScrollLayer()->CurrentScrollOffset(); + gfx::SizeF inner_viewport_bounds(scroll_tree.container_bounds( + InnerViewportScrollLayer()->scroll_tree_index())); + bounds_size.SetToMin(inner_viewport_bounds); + } + bounds_size.Scale(1 / current_page_scale_factor()); } - } - UpdateScrollbars(scroll_layer_id, clip_layer_id); -} -void LayerTreeImpl::UpdateScrollbars(int scroll_layer_id, int clip_layer_id) { - DCHECK(IsActiveTree()); - - LayerImpl* clip_layer = LayerById(clip_layer_id); - LayerImpl* scroll_layer = LayerById(scroll_layer_id); - - if (!clip_layer || !scroll_layer) - return; - - gfx::SizeF clip_size(clip_layer->BoundsForScrolling()); - gfx::SizeF scroll_size(scroll_layer->BoundsForScrolling()); - - if (scroll_size.IsEmpty()) - return; - - gfx::ScrollOffset current_offset = scroll_layer->CurrentScrollOffset(); - if (IsViewportLayerId(scroll_layer_id)) { - current_offset += InnerViewportScrollLayer()->CurrentScrollOffset(); - if (OuterViewportContainerLayer()) - clip_size.SetToMin(OuterViewportContainerLayer()->BoundsForScrolling()); - clip_size.Scale(1 / current_page_scale_factor()); - } - - bool y_offset_did_change = false; - for (auto* scrollbar : ScrollbarsFor(scroll_layer->element_id())) { - if (scrollbar->orientation() == HORIZONTAL) { - scrollbar->SetCurrentPos(current_offset.x()); - scrollbar->SetClipLayerLength(clip_size.width()); - scrollbar->SetScrollLayerLength(scroll_size.width()); - } else { - y_offset_did_change = scrollbar->SetCurrentPos(current_offset.y()); - scrollbar->SetClipLayerLength(clip_size.height()); - scrollbar->SetScrollLayerLength(scroll_size.height()); + for (auto* scrollbar : ScrollbarsFor(scrolling_element_id)) { + if (scrollbar->orientation() == HORIZONTAL) { + scrollbar->SetCurrentPos(current_offset.x()); + scrollbar->SetClipLayerLength(bounds_size.width()); + scrollbar->SetScrollLayerLength(scrolling_size.width()); + } else { + scrollbar->SetCurrentPos(current_offset.y()); + scrollbar->SetClipLayerLength(bounds_size.height()); + scrollbar->SetScrollLayerLength(scrolling_size.height()); + } + if (is_viewport_scrollbar) { + scrollbar->SetVerticalAdjust( + InnerViewportContainerLayer()->ViewportBoundsDelta().y()); + } } - scrollbar->SetVerticalAdjust(clip_layer->ViewportBoundsDelta().y()); } - if (y_offset_did_change && IsViewportLayerId(scroll_layer_id)) - TRACE_COUNTER_ID1("cc", "scroll_offset_y", scroll_layer->id(), - current_offset.y()); + scrollbar_geometries_need_update_ = false; } const RenderSurfaceImpl* LayerTreeImpl::RootRenderSurface() const { @@ -421,10 +394,20 @@ void LayerTreeImpl::PushPropertyTreesTo(LayerTreeImpl* target_tree) { target_tree->SetCurrentlyScrollingNode(scrolling_node); } +void LayerTreeImpl::PushSurfaceIdsTo(LayerTreeImpl* target_tree) { + if (needs_surface_ids_sync()) { + target_tree->ClearSurfaceLayerIds(); + target_tree->SetSurfaceLayerIds(SurfaceLayerIds()); + // Reset for next update + set_needs_surface_ids_sync(false); + } +} + 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); + PushSurfaceIdsTo(target_tree); target_tree->property_trees()->scroll_tree.PushScrollUpdatesFromPendingTree( &property_trees_, target_tree); @@ -655,14 +638,6 @@ void LayerTreeImpl::SetCurrentlyScrollingNode(ScrollNode* node) { ElementId old_element_id = old_node ? old_node->element_id : ElementId(); ElementId new_element_id = node ? node->element_id : ElementId(); - -#if DCHECK_IS_ON() - int old_layer_id = old_node ? old_node->owning_layer_id : Layer::INVALID_ID; - int new_layer_id = node ? node->owning_layer_id : Layer::INVALID_ID; - DCHECK(old_layer_id == LayerIdByElementId(old_element_id)); - DCHECK(new_layer_id == LayerIdByElementId(new_element_id)); -#endif - if (old_element_id == new_element_id) return; @@ -694,29 +669,21 @@ float LayerTreeImpl::ClampPageScaleFactorToLimits( return page_scale_factor; } -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 - // updates from scrolling deltas on the compositor thread that have occurred - // after begin frame and updates from animations that have ticked since begin - // frame to a newly-committed property tree. +void LayerTreeImpl::UpdatePropertyTreeAnimationFromMainThread() { + // TODO(enne): This should get replaced by pulling out animations into their + // own trees. Then animations would have their own ways of synchronizing + // across commits. This occurs to push updates from animations that have + // ticked since begin 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) && - can_delete_animations) { + if (!node->is_currently_animating_opacity || + node->opacity == element_id_to_opacity->second) { element_id_to_opacity_animations_.erase(element_id_to_opacity++); continue; } @@ -731,9 +698,8 @@ 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) && - can_delete_animations) { + if (!node->is_currently_animating_filter || + node->filters == element_id_to_filter->second) { element_id_to_filter_animations_.erase(element_id_to_filter++); continue; } @@ -748,9 +714,8 @@ 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) && - can_delete_animations) { + if (!node->is_currently_animating || + node->local == element_id_to_transform->second) { element_id_to_transform_animations_.erase(element_id_to_transform++); continue; } @@ -762,7 +727,7 @@ void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread( } LayerTreeHostCommon::CallFunctionForEveryLayer(this, [](LayerImpl* layer) { - layer->UpdatePropertyTreeForScrollingAndAnimationIfNeeded(); + layer->UpdatePropertyTreeForAnimationIfNeeded(); }); } @@ -909,7 +874,9 @@ void LayerTreeImpl::DidUpdatePageScale() { ClampPageScaleFactorToLimits(current_page_scale_factor())); set_needs_update_draw_properties(); - DidUpdateScrollState(viewport_layer_ids_.inner_viewport_scroll); + + // Viewport scrollbar sizes depend on the page scale factor. + SetScrollbarGeometriesNeedUpdate(); if (IsActiveTree() && layer_tree_host_impl_->ViewportMainScrollLayer()) { if (ScrollbarAnimationController* controller = @@ -978,6 +945,9 @@ void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { } void LayerTreeImpl::SetViewportLayersFromIds(const ViewportLayerIds& ids) { + if (viewport_layer_ids_ == ids) + return; + viewport_layer_ids_ = ids; // Set the viewport layer types. @@ -1008,17 +978,22 @@ void LayerTreeImpl::SetElementIdsForTesting() { } } -bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { +bool LayerTreeImpl::UpdateDrawProperties() { if (!needs_update_draw_properties_) return true; + // Ensure the scrollbar geometries are up-to-date for hit testing and quads + // generation. This may cause damage on the scrollbar layers which is why + // it occurs before we reset |needs_update_draw_properties_|. + UpdateScrollbarGeometries(); + // Calling UpdateDrawProperties must clear this flag, so there can be no // early outs before this. needs_update_draw_properties_ = false; // For max_texture_size. When a new output surface is received the needs // update draw properties flag is set again. - if (!layer_tree_host_impl_->compositor_frame_sink()) + if (!layer_tree_host_impl_->layer_tree_frame_sink()) return false; // Clear this after the renderer early out, as it should still be @@ -1117,24 +1092,6 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { occlusion_tracker.ComputeVisibleRegionInScreen(this); } - // It'd be ideal if this could be done earlier, but when the raster source - // is updated from the main thread during push properties, update draw - // properties has not occurred yet and so it's not clear whether or not the - // layer can or cannot use lcd text. So, this is the cleanup pass to - // determine if the raster source needs to be replaced with a non-lcd - // raster source due to draw properties. - if (update_lcd_text) { - // TODO(enne): Make LTHI::sync_tree return this value. - LayerTreeImpl* sync_tree = layer_tree_host_impl_->CommitToActiveTree() - ? layer_tree_host_impl_->active_tree() - : layer_tree_host_impl_->pending_tree(); - // If this is not the sync tree, then it is not safe to update lcd text - // as it causes invalidations and the tiles may be in use. - DCHECK_EQ(this, sync_tree); - for (auto* layer : picture_layers_) - layer->UpdateCanUseLCDTextAfterCommit(); - } - // Resourceless draw do not need tiles and should not affect existing tile // priorities. if (!is_in_resourceless_software_draw_mode()) { @@ -1144,7 +1101,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->contributes_to_drawn_render_surface()) + if (!layer->HasValidTilePriorities()) continue; ++layers_updated_count; tile_priorities_updated |= layer->UpdateTiles(); @@ -1162,6 +1119,17 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) { return true; } +void LayerTreeImpl::UpdateCanUseLCDText() { + // If this is not the sync tree, then it is not safe to update lcd text + // as it causes invalidations and the tiles may be in use. + DCHECK(IsSyncTree()); + bool tile_priorities_updated = false; + for (auto* layer : picture_layers_) + tile_priorities_updated |= layer->UpdateCanUseLCDTextAfterCommit(); + if (tile_priorities_updated) + DidModifyTilePriorities(); +} + void LayerTreeImpl::BuildLayerListAndPropertyTreesForTesting() { BuildLayerListForTesting(); BuildPropertyTreesForTesting(); @@ -1218,7 +1186,24 @@ LayerImpl* LayerTreeImpl::LayerById(int id) const { return iter != layer_id_map_.end() ? iter->second : nullptr; } +void LayerTreeImpl::SetSurfaceLayerIds( + const base::flat_set<viz::SurfaceId>& surface_layer_ids) { + DCHECK(surface_layer_ids_.empty()); + surface_layer_ids_ = surface_layer_ids; + needs_surface_ids_sync_ = true; +} + +const base::flat_set<viz::SurfaceId>& LayerTreeImpl::SurfaceLayerIds() const { + return surface_layer_ids_; +} + +void LayerTreeImpl::ClearSurfaceLayerIds() { + surface_layer_ids_.clear(); + needs_surface_ids_sync_ = true; +} + void LayerTreeImpl::AddLayerShouldPushProperties(LayerImpl* layer) { + DCHECK(!IsActiveTree()) << "The active tree does not push layer properties"; layers_that_should_push_properties_.insert(layer); } @@ -1325,8 +1310,8 @@ const LayerTreeDebugState& LayerTreeImpl::debug_state() const { return layer_tree_host_impl_->debug_state(); } -ContextProvider* LayerTreeImpl::context_provider() const { - return layer_tree_host_impl_->compositor_frame_sink()->context_provider(); +viz::ContextProvider* LayerTreeImpl::context_provider() const { + return layer_tree_host_impl_->layer_tree_frame_sink()->context_provider(); } ResourceProvider* LayerTreeImpl::resource_provider() const { @@ -1661,17 +1646,29 @@ void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) { if (!scroll_element_id) return; - 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(); + auto* scrollbar_ids = &element_id_to_scrollbar_layer_ids_[scroll_element_id]; + int* scrollbar_layer_id = scrollbar_layer->orientation() == HORIZONTAL + ? &scrollbar_ids->horizontal + : &scrollbar_ids->vertical; + + // We used to DCHECK this was not the case but this can occur on Android: as + // the visual viewport supplies scrollbars for the outer viewport, if the + // outer viewport is changed, we race between updating the visual viewport + // scrollbars and registering new scrollbars on the old outer viewport. It'd + // be nice if we could fix this to be cleaner but its harmless to just + // unregister here. + if (*scrollbar_layer_id != Layer::INVALID_ID) { + UnregisterScrollbar(scrollbar_layer); + + // The scrollbar_ids could have been erased above so get it again. + scrollbar_ids = &element_id_to_scrollbar_layer_ids_[scroll_element_id]; + scrollbar_layer_id = scrollbar_layer->orientation() == HORIZONTAL + ? &scrollbar_ids->horizontal + : &scrollbar_ids->vertical; } + *scrollbar_layer_id = scrollbar_layer->id(); + if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar() && scrollbar_layer->GetScrollbarAnimator() != LayerTreeSettings::NO_ANIMATOR) { @@ -1679,9 +1676,8 @@ void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) { scroll_element_id, scrollbar_layer->Opacity()); } - // TODO(pdr): Refactor DidUpdateScrollState to use ElementIds instead of - // layer ids and remove this use of LayerIdByElementId. - DidUpdateScrollState(LayerIdByElementId(scroll_element_id)); + // The new scrollbar's geometries need to be initialized. + SetScrollbarGeometriesNeedUpdate(); } void LayerTreeImpl::UnregisterScrollbar( @@ -1719,39 +1715,6 @@ ScrollbarSet LayerTreeImpl::ScrollbarsFor(ElementId scroll_element_id) const { return scrollbars; } -void LayerTreeImpl::RegisterScrollLayer(LayerImpl* layer) { - if (layer->scroll_clip_layer_id() == Layer::INVALID_ID) - return; - - clip_scroll_map_.insert( - 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) { - if (layer->scroll_clip_layer_id() == Layer::INVALID_ID) - return; - - clip_scroll_map_.erase(layer->scroll_clip_layer_id()); -} - -void LayerTreeImpl::AddSurfaceLayer(LayerImpl* layer) { - DCHECK(std::find(surface_layers_.begin(), surface_layers_.end(), layer) == - surface_layers_.end()); - surface_layers_.push_back(layer); -} - -void LayerTreeImpl::RemoveSurfaceLayer(LayerImpl* layer) { - LayerImplList::iterator it = - std::find(surface_layers_.begin(), surface_layers_.end(), layer); - DCHECK(it != surface_layers_.end()); - surface_layers_.erase(it); -} - static bool PointHitsRect( const gfx::PointF& screen_space_point, const gfx::Transform& local_space_to_screen_space_transform, @@ -1902,37 +1865,32 @@ static void FindClosestMatchingLayer(const gfx::PointF& screen_space_point, const Functor& func, FindClosestMatchingLayerState* state) { // We want to iterate from front to back when hit testing. - { - base::ElapsedTimer timer; - for (auto* layer : base::Reversed(*root_layer->layer_tree_impl())) { - if (!func(layer)) - continue; + for (auto* layer : base::Reversed(*root_layer->layer_tree_impl())) { + if (!func(layer)) + continue; - float distance_to_intersection = 0.f; - bool hit = false; - if (layer->Is3dSorted()) - hit = PointHitsLayer(layer, screen_space_point, - &distance_to_intersection); - else - hit = PointHitsLayer(layer, screen_space_point, nullptr); + float distance_to_intersection = 0.f; + bool hit = false; + if (layer->Is3dSorted()) + hit = + PointHitsLayer(layer, screen_space_point, &distance_to_intersection); + else + hit = PointHitsLayer(layer, screen_space_point, nullptr); - if (!hit) - continue; + if (!hit) + continue; - bool in_front_of_previous_candidate = - state->closest_match && - layer->GetSortingContextId() == - state->closest_match->GetSortingContextId() && - distance_to_intersection > - state->closest_distance + std::numeric_limits<float>::epsilon(); + bool in_front_of_previous_candidate = + state->closest_match && + layer->GetSortingContextId() == + state->closest_match->GetSortingContextId() && + distance_to_intersection > + state->closest_distance + std::numeric_limits<float>::epsilon(); - if (!state->closest_match || in_front_of_previous_candidate) { - state->closest_distance = distance_to_intersection; - state->closest_match = layer; - } + if (!state->closest_match || in_front_of_previous_candidate) { + state->closest_distance = distance_to_intersection; + state->closest_match = layer; } - UMA_HISTOGRAM_COUNTS("Compositing.LayerTreeImpl.FindClosestMatchingLayerUs", - timer.Elapsed().InMicroseconds()); } } @@ -1954,9 +1912,8 @@ LayerTreeImpl::FindFirstScrollingLayerOrDrawnScrollbarThatIsHitByPoint( struct HitTestVisibleScrollableOrTouchableFunctor { bool operator()(LayerImpl* layer) const { - return layer->scrollable() || - layer->contributes_to_drawn_render_surface() || - !layer->touch_event_handler_region().IsEmpty(); + return layer->scrollable() || layer->should_hit_test() || + !layer->touch_action_region().region().IsEmpty(); } }; @@ -1964,8 +1921,7 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint( const gfx::PointF& screen_space_point) { if (layer_list_.empty()) return NULL; - bool update_lcd_text = false; - if (!UpdateDrawProperties(update_lcd_text)) + if (!UpdateDrawProperties()) return NULL; FindClosestMatchingLayerState state; FindClosestMatchingLayer(screen_space_point, layer_list_[0], @@ -1976,11 +1932,11 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint( static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point, LayerImpl* layer_impl) { - if (layer_impl->touch_event_handler_region().IsEmpty()) + if (layer_impl->touch_action_region().region().IsEmpty()) return false; if (!PointHitsRegion(screen_space_point, layer_impl->ScreenSpaceTransform(), - layer_impl->touch_event_handler_region())) + layer_impl->touch_action_region().region())) return false; // At this point, we think the point does hit the touch event handler region @@ -2004,8 +1960,7 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion( const gfx::PointF& screen_space_point) { if (layer_list_.empty()) return NULL; - bool update_lcd_text = false; - if (!UpdateDrawProperties(update_lcd_text)) + if (!UpdateDrawProperties()) return NULL; FindTouchEventLayerFunctor func = {screen_space_point}; FindClosestMatchingLayerState state; diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index ccff3c2447b..5c05caf9acc 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -31,9 +31,12 @@ class TracedValue; } } +namespace viz { +class ContextProvider; +} + namespace cc { -class ContextProvider; class DebugRectHistory; class FrameRateCounter; class HeadsUpDisplayLayerImpl; @@ -103,7 +106,7 @@ class CC_EXPORT LayerTreeImpl { // --------------------------------------------------------------------------- const LayerTreeSettings& settings() const; const LayerTreeDebugState& debug_state() const; - ContextProvider* context_provider() const; + viz::ContextProvider* context_provider() const; ResourceProvider* resource_provider() const; TileManager* tile_manager() const; ImageDecodeCache* image_decode_cache() const; @@ -168,6 +171,7 @@ class CC_EXPORT LayerTreeImpl { void PushPropertyTreesTo(LayerTreeImpl* tree_impl); void PushPropertiesTo(LayerTreeImpl* tree_impl); + void PushSurfaceIdsTo(LayerTreeImpl* tree_impl); void MoveChangeTrackingToLayers(); @@ -218,6 +222,15 @@ class CC_EXPORT LayerTreeImpl { int outer_viewport_container = Layer::INVALID_ID; int inner_viewport_scroll = Layer::INVALID_ID; int outer_viewport_scroll = Layer::INVALID_ID; + + bool operator==(const ViewportLayerIds& other) { + return overscroll_elasticity == other.overscroll_elasticity && + page_scale == other.page_scale && + inner_viewport_container == other.inner_viewport_container && + outer_viewport_container == other.outer_viewport_container && + inner_viewport_scroll == other.inner_viewport_scroll && + outer_viewport_scroll == other.outer_viewport_scroll; + } }; void SetViewportLayersFromIds(const ViewportLayerIds& viewport_layer_ids); void ClearViewportLayers(); @@ -252,8 +265,7 @@ class CC_EXPORT LayerTreeImpl { has_transparent_background_ = transparent; } - void UpdatePropertyTreeScrollingAndAnimationFromMainThread( - bool is_impl_side_update); + void UpdatePropertyTreeAnimationFromMainThread(); void SetPageScaleOnActiveTree(float active_page_scale); void PushPageScaleFromMainThread(float page_scale_factor, float min_page_scale_factor, @@ -282,10 +294,12 @@ class CC_EXPORT LayerTreeImpl { void set_content_source_id(uint32_t id) { content_source_id_ = id; } uint32_t content_source_id() { return content_source_id_; } - void set_local_surface_id(const LocalSurfaceId& id) { + void set_local_surface_id(const viz::LocalSurfaceId& id) { local_surface_id_ = id; } - const LocalSurfaceId& local_surface_id() const { return local_surface_id_; } + const viz::LocalSurfaceId& local_surface_id() const { + return local_surface_id_; + } void SetRasterColorSpace(const gfx::ColorSpace& raster_color_space); const gfx::ColorSpace& raster_color_space() const { @@ -311,7 +325,8 @@ class CC_EXPORT LayerTreeImpl { // Updates draw properties and render surface layer list, as well as tile // priorities. Returns false if it was unable to update. Updating lcd // text may cause invalidations, so should only be done after a commit. - bool UpdateDrawProperties(bool update_lcd_text); + bool UpdateDrawProperties(); + void UpdateCanUseLCDText(); void BuildPropertyTreesForTesting(); void BuildLayerListAndPropertyTreesForTesting(); @@ -330,6 +345,11 @@ class CC_EXPORT LayerTreeImpl { void set_needs_full_tree_sync(bool needs) { needs_full_tree_sync_ = needs; } bool needs_full_tree_sync() const { return needs_full_tree_sync_; } + bool needs_surface_ids_sync() const { return needs_surface_ids_sync_; } + void set_needs_surface_ids_sync(bool needs_surface_ids_sync) { + needs_surface_ids_sync_ = needs_surface_ids_sync; + } + void ForceRedrawNextActivation() { next_activation_forces_redraw_ = true; } void set_has_ever_been_drawn(bool has_drawn) { @@ -359,6 +379,11 @@ class CC_EXPORT LayerTreeImpl { void AddToElementMap(LayerImpl* layer); void RemoveFromElementMap(LayerImpl* layer); + void SetSurfaceLayerIds( + const base::flat_set<viz::SurfaceId>& surface_layer_ids); + const base::flat_set<viz::SurfaceId>& SurfaceLayerIds() const; + void ClearSurfaceLayerIds(); + void AddLayerShouldPushProperties(LayerImpl* layer); void RemoveLayerShouldPushProperties(LayerImpl* layer); std::unordered_set<LayerImpl*>& LayersThatShouldPushProperties(); @@ -442,13 +467,6 @@ class CC_EXPORT LayerTreeImpl { void UnregisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer); ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const; - void RegisterScrollLayer(LayerImpl* layer); - void UnregisterScrollLayer(LayerImpl* layer); - - void AddSurfaceLayer(LayerImpl* layer); - void RemoveSurfaceLayer(LayerImpl* layer); - const LayerImplList& SurfaceLayers() const { return surface_layers_; } - LayerImpl* FindFirstScrollingLayerOrDrawnScrollbarThatIsHitByPoint( const gfx::PointF& screen_space_point); @@ -483,8 +501,24 @@ class CC_EXPORT LayerTreeImpl { std::unique_ptr<PendingPageScaleAnimation> pending_animation); std::unique_ptr<PendingPageScaleAnimation> TakePendingPageScaleAnimation(); - void DidUpdateScrollOffset(int layer_id); - void DidUpdateScrollState(int layer_id); + void DidUpdateScrollOffset(ElementId id); + + // Mark the scrollbar geometries (e.g., thumb size and position) as needing an + // update. + void SetScrollbarGeometriesNeedUpdate() { + if (IsActiveTree()) { + scrollbar_geometries_need_update_ = true; + // Scrollbar geometries are updated in |UpdateDrawProperties|. + set_needs_update_draw_properties(); + } + } + bool ScrollbarGeometriesNeedUpdate() const { + return scrollbar_geometries_need_update_; + } + // Update the geometries of all scrollbars (e.g., thumb size and position). An + // update only occurs if a scroll-related layer has changed (see: + // SetScrollbarGeometriesNeedUpdate). + void UpdateScrollbarGeometries(); bool have_scroll_event_handlers() const { return have_scroll_event_handlers_; @@ -524,8 +558,6 @@ class CC_EXPORT LayerTreeImpl { float max_page_scale_factor); bool SetPageScaleFactorLimits(float min_page_scale_factor, float max_page_scale_factor); - bool IsViewportLayerId(int id) const; - void UpdateScrollbars(int scroll_layer_id, int clip_layer_id); void DidUpdatePageScale(); void PushBrowserControls(const float* top_controls_shown_ratio); bool ClampBrowserControlsShownRatio(); @@ -554,7 +586,7 @@ class CC_EXPORT LayerTreeImpl { gfx::ColorSpace raster_color_space_; uint32_t content_source_id_; - LocalSurfaceId local_surface_id_; + viz::LocalSurfaceId local_surface_id_; scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_; @@ -573,11 +605,6 @@ class CC_EXPORT LayerTreeImpl { std::unordered_map<ElementId, FilterOperations, ElementIdHash> element_id_to_filter_animations_; - // Maps from clip layer ids to scroll layer ids. Note that this only includes - // the subset of clip layers that act as scrolling containers. (This is - // derived from LayerImpl::scroll_clip_layer_ and exists to avoid O(n) walks.) - std::unordered_map<int, int> clip_scroll_map_; - struct ScrollbarLayerIds { int horizontal = Layer::INVALID_ID; int vertical = Layer::INVALID_ID; @@ -588,7 +615,8 @@ class CC_EXPORT LayerTreeImpl { element_id_to_scrollbar_layer_ids_; std::vector<PictureLayerImpl*> picture_layers_; - LayerImplList surface_layers_; + + base::flat_set<viz::SurfaceId> surface_layer_ids_; // List of render surfaces for the most recently prepared frame. RenderSurfaceList render_surface_list_; @@ -599,10 +627,16 @@ class CC_EXPORT LayerTreeImpl { bool viewport_size_invalid_; bool needs_update_draw_properties_; + // True if a scrollbar geometry value has changed. For example, if the scroll + // offset changes, scrollbar thumb positions need to be updated. + bool scrollbar_geometries_need_update_; + // In impl-side painting mode, this is true when the tree may contain // structural differences relative to the active tree. bool needs_full_tree_sync_; + bool needs_surface_ids_sync_; + bool next_activation_forces_redraw_; bool has_ever_been_drawn_; diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc index 836ba530118..eb8c2524ae0 100644 --- a/chromium/cc/trees/layer_tree_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_impl_unittest.cc @@ -1212,7 +1212,8 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { } TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { - Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50)); LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); @@ -1233,7 +1234,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { test_point); EXPECT_FALSE(result_layer); - root->SetTouchEventHandlerRegion(touch_handler_region); + root->SetTouchActionRegion(touch_action_region); // Hit checking for a point outside the layer should return a null pointer. test_point = gfx::PointF(101.f, 101.f); result_layer = @@ -1287,13 +1288,14 @@ TEST_F(LayerTreeImplTest, uninvertible_transform.matrix().set(3, 3, 0.0); ASSERT_FALSE(uninvertible_transform.IsInvertible()); - Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50)); LayerImpl* root = root_layer(); root->test_properties()->transform = uninvertible_transform; root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); - root->SetTouchEventHandlerRegion(touch_handler_region); + root->SetTouchActionRegion(touch_action_region); host_impl().SetViewportSize(root->bounds()); host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); @@ -1352,7 +1354,8 @@ TEST_F(LayerTreeImplTest, TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSinglePositionedLayer) { - Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50)); // This layer is positioned, and hit testing should correctly know where the // layer is located. @@ -1360,7 +1363,7 @@ TEST_F(LayerTreeImplTest, root->SetPosition(gfx::PointF(50.f, 50.f)); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); - root->SetTouchEventHandlerRegion(touch_handler_region); + root->SetTouchActionRegion(touch_action_region); host_impl().SetViewportSize(root->bounds()); host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); @@ -1419,7 +1422,8 @@ TEST_F(LayerTreeImplTest, LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); { - Region touch_handler_region(gfx::Rect(10, 10, 30, 30)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30)); gfx::PointF position(25.f, 25.f); gfx::Size bounds(50, 50); std::unique_ptr<LayerImpl> test_layer = @@ -1427,7 +1431,7 @@ TEST_F(LayerTreeImplTest, test_layer->SetPosition(gfx::PointF(25.f, 25.f)); test_layer->SetBounds(gfx::Size(50, 50)); test_layer->SetDrawsContent(true); - test_layer->SetTouchEventHandlerRegion(touch_handler_region); + test_layer->SetTouchActionRegion(touch_action_region); root->test_properties()->AddChild(std::move(test_layer)); } @@ -1564,14 +1568,15 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { clipping_layer->SetBounds(gfx::Size(50, 50)); clipping_layer->SetMasksToBounds(true); - Region touch_handler_region(gfx::Rect(10, 10, 50, 50)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 50, 50)); std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), 456); child->SetPosition(gfx::PointF(-50.f, -50.f)); child->SetBounds(gfx::Size(300, 300)); child->SetDrawsContent(true); - child->SetTouchEventHandlerRegion(touch_handler_region); + child->SetTouchActionRegion(touch_action_region); clipping_layer->test_properties()->AddChild(std::move(child)); root->test_properties()->AddChild(std::move(clipping_layer)); } @@ -1647,14 +1652,15 @@ TEST_F(LayerTreeImplTest, clipping_layer->SetBounds(gfx::Size(50, 50)); clipping_layer->SetMasksToBounds(true); - Region touch_handler_region(gfx::Rect(0, 0, 300, 300)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 300, 300)); std::unique_ptr<LayerImpl> child = LayerImpl::Create(host_impl().active_tree(), 456); child->SetPosition(gfx::PointF(-50.f, -50.f)); child->SetBounds(gfx::Size(300, 300)); child->SetDrawsContent(true); - child->SetTouchEventHandlerRegion(touch_handler_region); + child->SetTouchActionRegion(touch_action_region); clipping_layer->test_properties()->AddChild(std::move(child)); surface->test_properties()->AddChild(std::move(clipping_layer)); root->test_properties()->AddChild(std::move(surface)); @@ -1717,7 +1723,9 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { // layer is located. touch_layer->SetBounds(gfx::Size(50, 50)); touch_layer->SetDrawsContent(true); - touch_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 50, 50)); + touch_layer->SetTouchActionRegion(touch_action_region); root->test_properties()->AddChild(std::move(touch_layer)); } @@ -1782,12 +1790,13 @@ TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) { root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); { - Region touch_handler_region(gfx::Rect(10, 10, 30, 30)); + TouchActionRegion touch_action_region; + touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10, 30, 30)); std::unique_ptr<LayerImpl> test_layer = LayerImpl::Create(host_impl().active_tree(), 12345); test_layer->SetBounds(gfx::Size(50, 50)); test_layer->SetDrawsContent(false); - test_layer->SetTouchEventHandlerRegion(touch_handler_region); + test_layer->SetTouchActionRegion(touch_action_region); root->test_properties()->AddChild(std::move(test_layer)); } host_impl().SetViewportSize(root->bounds()); @@ -2190,7 +2199,7 @@ TEST_F(LayerTreeImplTest, NumLayersSmallTree) { TEST_F(LayerTreeImplTest, DeviceScaleFactorNeedsDrawPropertiesUpdate) { host_impl().active_tree()->BuildPropertyTreesForTesting(); host_impl().active_tree()->SetDeviceScaleFactor(1.f); - host_impl().active_tree()->UpdateDrawProperties(false); + host_impl().active_tree()->UpdateDrawProperties(); EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties()); host_impl().active_tree()->SetDeviceScaleFactor(2.f); EXPECT_TRUE(host_impl().active_tree()->needs_update_draw_properties()); @@ -2200,7 +2209,7 @@ TEST_F(LayerTreeImplTest, RasterColorSpaceDoesNotNeedDrawPropertiesUpdate) { host_impl().active_tree()->BuildPropertyTreesForTesting(); host_impl().active_tree()->SetRasterColorSpace( gfx::ColorSpace::CreateXYZD50()); - host_impl().active_tree()->UpdateDrawProperties(false); + host_impl().active_tree()->UpdateDrawProperties(); EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties()); host_impl().active_tree()->SetRasterColorSpace(gfx::ColorSpace::CreateSRGB()); EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties()); diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc index 2b8531c9e01..5586f353de7 100644 --- a/chromium/cc/trees/layer_tree_settings.cc +++ b/chromium/cc/trees/layer_tree_settings.cc @@ -4,6 +4,7 @@ #include "cc/trees/layer_tree_settings.h" +#include "components/viz/common/resources/platform_color.h" #include "third_party/khronos/GLES2/gl2.h" namespace cc { @@ -17,7 +18,8 @@ LayerTreeSettings::LayerTreeSettings() ManagedMemoryPolicy::kDefaultNumResourcesLimit), software_memory_policy(128 * 1024 * 1024, gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, - ManagedMemoryPolicy::kDefaultNumResourcesLimit) {} + ManagedMemoryPolicy::kDefaultNumResourcesLimit), + preferred_tile_format(viz::PlatformColor::BestTextureFormat()) {} LayerTreeSettings::LayerTreeSettings(const LayerTreeSettings& other) = default; LayerTreeSettings::~LayerTreeSettings() = default; diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index 5191cdc20e3..b727c397c0f 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -13,9 +13,11 @@ #include "cc/cc_export.h" #include "cc/debug/layer_tree_debug_state.h" #include "cc/output/managed_memory_policy.h" -#include "cc/output/renderer_settings.h" #include "cc/scheduler/scheduler_settings.h" #include "cc/tiles/tile_manager_settings.h" +#include "components/viz/common/display/renderer_settings.h" +#include "components/viz/common/quads/resource_format.h" +#include "components/viz/common/resources/resource_settings.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/size.h" @@ -30,7 +32,7 @@ class CC_EXPORT LayerTreeSettings { SchedulerSettings ToSchedulerSettings() const; TileManagerSettings ToTileManagerSettings() const; - RendererSettings renderer_settings; + viz::ResourceSettings resource_settings; bool single_thread_proxy_scheduler = true; bool main_frame_before_activation_enabled = false; bool using_synchronous_renderer_compositor = false; @@ -42,6 +44,7 @@ class CC_EXPORT LayerTreeSettings { int gpu_rasterization_msaa_sample_count = 0; float gpu_rasterization_skewport_target_time_in_seconds = 0.2f; bool create_low_res_tiling = false; + bool use_stream_video_draw_quad = false; enum ScrollbarAnimator { NO_ANIMATOR, @@ -85,11 +88,10 @@ class CC_EXPORT LayerTreeSettings { size_t decoded_image_cache_budget_bytes = 128 * 1024 * 1024; size_t decoded_image_working_set_budget_bytes = 128 * 1024 * 1024; int max_preraster_distance_in_screen_pixels = 1000; + viz::ResourceFormat preferred_tile_format; bool enable_color_correct_rasterization = false; - // TODO(sunxd): remove this flag when filter demoting and aa of mask layers - // are implemented. bool enable_mask_tiling = false; // If set to true, the compositor may selectively defer image decodes to the @@ -100,7 +102,7 @@ class CC_EXPORT LayerTreeSettings { LayerTreeDebugState initial_debug_state; // Indicates that the LayerTreeHost should defer commits unless it has a valid - // LocalSurfaceId set. + // viz::LocalSurfaceId set. bool enable_surface_synchronization = false; // Indicates the case when a sub-frame gets its own LayerTree because it's diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc index 8aa513bfe17..2d20af4e03e 100644 --- a/chromium/cc/trees/occlusion_tracker.cc +++ b/chromium/cc/trees/occlusion_tracker.cc @@ -190,15 +190,17 @@ void OcclusionTracker::FinishedRenderTarget( // Readbacks always happen on render targets so we only need to check // for readbacks here. - bool target_is_only_for_copy_request = - finished_target_surface->HasCopyRequest() && is_hidden; + bool target_is_only_for_copy_request_or_force_render_surface = + (finished_target_surface->HasCopyRequest() || + finished_target_surface->ShouldCacheRenderSurface()) && + is_hidden; // If the occlusion within the surface can not be applied to things outside of // the surface's subtree, then clear the occlusion here so it won't be used. if (finished_target_surface->HasMask() || finished_target_surface->draw_opacity() < 1 || !finished_target_surface->UsesDefaultBlendMode() || - target_is_only_for_copy_request || + target_is_only_for_copy_request_or_force_render_surface || finished_target_surface->Filters().HasFilterThatAffectsOpacity()) { stack_.back().occlusion_from_outside_target.Clear(); stack_.back().occlusion_from_inside_target.Clear(); diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc index a0218f64497..715029576d2 100644 --- a/chromium/cc/trees/occlusion_tracker_unittest.cc +++ b/chromium/cc/trees/occlusion_tracker_unittest.cc @@ -199,15 +199,15 @@ class OcclusionTrackerTest : public testing::Test { void AddCopyRequest(Layer* layer) { layer->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( - base::Bind(&OcclusionTrackerTest::CopyOutputCallback, - base::Unretained(this)))); + base::BindOnce(&OcclusionTrackerTest::CopyOutputCallback, + base::Unretained(this)))); } void AddCopyRequest(LayerImpl* layer) { layer->test_properties()->copy_requests.push_back( CopyOutputRequest::CreateBitmapRequest( - base::Bind(&OcclusionTrackerTest::CopyOutputCallback, - base::Unretained(this)))); + base::BindOnce(&OcclusionTrackerTest::CopyOutputCallback, + base::Unretained(this)))); } void CalcDrawEtc(TestContentLayerImpl* root) { diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc index ff214e50038..7a1b335536b 100644 --- a/chromium/cc/trees/property_tree.cc +++ b/chromium/cc/trees/property_tree.cc @@ -42,6 +42,12 @@ PropertyTree<T>::~PropertyTree() {} template <typename T> PropertyTree<T>& PropertyTree<T>::operator=(const PropertyTree<T>&) = default; +#define DCHECK_NODE_EXISTENCE(check_node_existence, state, property, \ + needs_rebuild) \ + DCHECK(!check_node_existence || ((!state.currently_running[property] && \ + !state.potentially_animating[property]) || \ + needs_rebuild)) + TransformTree::TransformTree() : source_to_parent_updates_allowed_(true), page_scale_factor_(1.f), @@ -70,7 +76,6 @@ void PropertyTree<T>::clear() { nodes_.push_back(T()); back()->id = kRootNodeId; back()->parent_id = kInvalidNodeId; - owning_layer_id_to_node_index_.clear(); #if DCHECK_IS_ON() PropertyTree<T> tree; @@ -80,8 +85,7 @@ void PropertyTree<T>::clear() { template <typename T> bool PropertyTree<T>::operator==(const PropertyTree<T>& other) const { - return nodes_ == other.nodes() && needs_update_ == other.needs_update() && - owning_layer_id_to_node_index_ == other.owning_layer_id_to_node_index_; + return nodes_ == other.nodes() && needs_update_ == other.needs_update(); } template <typename T> @@ -347,6 +351,8 @@ bool TransformTree::CombineInversesBetween(int source_id, return all_are_invertible; } +// This function should match the offset we set for sticky position layer in +// CompositedLayerMapping::UpdateMainGraphicsLayerGeometry. gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { if (node->sticky_position_constraint_id == -1) return gfx::Vector2dF(); @@ -359,7 +365,7 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* 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); + scroll_node->element_id) == scroll_offset); gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); if (transform_node->scrolls) { // The scroll position does not include snapping which shifts the scroll @@ -370,9 +376,7 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { gfx::RectF clip( scroll_position, - gfx::SizeF(property_trees.scroll_tree.scroll_clip_layer_bounds( - scroll_node->id))); - gfx::Vector2dF layer_offset(sticky_data->main_thread_offset); + gfx::SizeF(property_trees.scroll_tree.container_bounds(scroll_node->id))); gfx::Vector2dF ancestor_sticky_box_offset; if (sticky_data->nearest_node_shifting_sticky_box != @@ -400,7 +404,7 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { gfx::RectF(constraint.scroll_container_relative_containing_block_rect) + ancestor_containing_block_offset; - gfx::Vector2dF sticky_offset(sticky_box_rect.OffsetFromOrigin()); + gfx::Vector2dF sticky_offset; // In each of the following cases, we measure the limit which is the point // that the element should stick to, clamping on one side to 0 (because sticky @@ -451,14 +455,12 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { } sticky_data->total_sticky_box_sticky_offset = - ancestor_sticky_box_offset + sticky_offset - - sticky_box_rect.OffsetFromOrigin(); + ancestor_sticky_box_offset + sticky_offset; sticky_data->total_containing_block_sticky_offset = ancestor_sticky_box_offset + ancestor_containing_block_offset + - sticky_offset - sticky_box_rect.OffsetFromOrigin(); + sticky_offset; - return sticky_offset - layer_offset - node->source_to_parent - - sticky_box_rect.OffsetFromOrigin(); + return sticky_offset; } void TransformTree::UpdateLocalTransform(TransformNode* node) { @@ -800,7 +802,7 @@ void EffectTree::UpdateIsDrawn(EffectNode* node, EffectNode* parent_node) { // 2) Nodes that have a background filter. // 3) Nodes with animating screen space opacity on main thread or pending tree // are drawn if their parent is drawn irrespective of their opacity. - if (node->has_copy_request) + if (node->has_copy_request || node->cache_render_surface) node->is_drawn = true; else if (EffectiveOpacity(node) == 0.f && (!node->has_potential_opacity_animation || @@ -1025,7 +1027,7 @@ void EffectTree::UpdateRenderSurfaces(LayerTreeImpl* layer_tree_impl) { if (needs_render_surface) { render_surfaces_[id] = base::MakeUnique<RenderSurfaceImpl>( - layer_tree_impl, effect_node->owning_layer_id); + layer_tree_impl, effect_node->stable_id); render_surfaces_[id]->set_effect_tree_index(id); } else { render_surfaces_[id].reset(); @@ -1065,12 +1067,12 @@ bool EffectTree::CreateOrReuseRenderSurfaces( LayerTreeImpl* layer_tree_impl) { // Make a list of {stable id, node id} pairs for nodes that are supposed to // have surfaces. - std::vector<std::pair<int, int>> stable_id_node_id_list; + std::vector<std::pair<uint64_t, int>> stable_id_node_id_list; for (int id = kContentsRootNodeId; id < static_cast<int>(size()); ++id) { EffectNode* node = Node(id); if (node->has_render_surface) { stable_id_node_id_list.push_back( - std::make_pair(node->owning_layer_id, node->id)); + std::make_pair(node->stable_id, node->id)); } } @@ -1171,7 +1173,7 @@ bool EffectTree::operator==(const EffectTree& other) const { ScrollTree::ScrollTree() : currently_scrolling_node_id_(kInvalidNodeId), - layer_id_to_scroll_offset_map_(ScrollTree::ScrollOffsetMap()) {} + scroll_offset_map_(ScrollTree::ScrollOffsetMap()) {} ScrollTree::~ScrollTree() {} @@ -1187,10 +1189,9 @@ ScrollTree& ScrollTree::operator=(const ScrollTree& from) { } bool ScrollTree::operator==(const ScrollTree& other) const { - if (layer_id_to_scroll_offset_map_ != other.layer_id_to_scroll_offset_map_) + if (scroll_offset_map_ != other.scroll_offset_map_) return false; - if (layer_id_to_synced_scroll_offset_map_ != - other.layer_id_to_synced_scroll_offset_map_) + if (synced_scroll_offset_map_ != other.synced_scroll_offset_map_) return false; bool is_currently_scrolling_node_equal = @@ -1202,9 +1203,8 @@ bool ScrollTree::operator==(const ScrollTree& other) const { #if DCHECK_IS_ON() void ScrollTree::CopyCompleteTreeState(const ScrollTree& other) { currently_scrolling_node_id_ = other.currently_scrolling_node_id_; - layer_id_to_scroll_offset_map_ = other.layer_id_to_scroll_offset_map_; - layer_id_to_synced_scroll_offset_map_ = - other.layer_id_to_synced_scroll_offset_map_; + scroll_offset_map_ = other.scroll_offset_map_; + synced_scroll_offset_map_ = other.synced_scroll_offset_map_; } #endif @@ -1221,16 +1221,15 @@ void ScrollTree::clear() { if (property_trees()->is_main_thread) { currently_scrolling_node_id_ = kInvalidNodeId; - layer_id_to_scroll_offset_map_.clear(); + scroll_offset_map_.clear(); } #if DCHECK_IS_ON() ScrollTree tree; if (!property_trees()->is_main_thread) { - DCHECK(layer_id_to_scroll_offset_map_.empty()); + DCHECK(scroll_offset_map_.empty()); tree.currently_scrolling_node_id_ = currently_scrolling_node_id_; - tree.layer_id_to_synced_scroll_offset_map_ = - layer_id_to_synced_scroll_offset_map_; + tree.synced_scroll_offset_map_ = synced_scroll_offset_map_; } DCHECK(tree == *this); #endif @@ -1259,7 +1258,7 @@ gfx::ScrollOffset ScrollTree::MaxScrollOffset(int scroll_node_id) const { scaled_scroll_bounds.SetSize(std::floor(scaled_scroll_bounds.width()), std::floor(scaled_scroll_bounds.height())); - gfx::Size clip_layer_bounds = scroll_clip_layer_bounds(scroll_node->id); + gfx::Size clip_layer_bounds = container_bounds(scroll_node->id); gfx::ScrollOffset max_offset( scaled_scroll_bounds.width() - clip_layer_bounds.width(), @@ -1270,7 +1269,7 @@ gfx::ScrollOffset ScrollTree::MaxScrollOffset(int scroll_node_id) const { return max_offset; } -void ScrollTree::OnScrollOffsetAnimated(int layer_id, +void ScrollTree::OnScrollOffsetAnimated(ElementId id, int scroll_tree_index, const gfx::ScrollOffset& scroll_offset, LayerTreeImpl* layer_tree_impl) { @@ -1280,31 +1279,29 @@ void ScrollTree::OnScrollOffsetAnimated(int layer_id, return; ScrollNode* scroll_node = Node(scroll_tree_index); - if (SetScrollOffset(layer_id, + if (SetScrollOffset(id, ClampScrollOffsetToLimits(scroll_offset, scroll_node))) - layer_tree_impl->DidUpdateScrollOffset(layer_id); + layer_tree_impl->DidUpdateScrollOffset(id); layer_tree_impl->DidAnimateScrollOffset(); } -gfx::Size ScrollTree::scroll_clip_layer_bounds(int scroll_node_id) const { +gfx::Size ScrollTree::container_bounds(int scroll_node_id) const { const ScrollNode* scroll_node = Node(scroll_node_id); - gfx::Size scroll_clip_layer_bounds = scroll_node->scroll_clip_layer_bounds; + gfx::Size container_bounds = scroll_node->container_bounds; - gfx::Vector2dF scroll_clip_layer_bounds_delta; + gfx::Vector2dF container_bounds_delta; if (scroll_node->scrolls_inner_viewport) { - scroll_clip_layer_bounds_delta.Add( + container_bounds_delta.Add( property_trees()->inner_viewport_container_bounds_delta()); } else if (scroll_node->scrolls_outer_viewport) { - scroll_clip_layer_bounds_delta.Add( + container_bounds_delta.Add( property_trees()->outer_viewport_container_bounds_delta()); } - gfx::Vector2d delta = gfx::ToCeiledVector2d(scroll_clip_layer_bounds_delta); - scroll_clip_layer_bounds.SetSize( - scroll_clip_layer_bounds.width() + delta.x(), - scroll_clip_layer_bounds.height() + delta.y()); + gfx::Vector2d delta = gfx::ToCeiledVector2d(container_bounds_delta); + container_bounds.Enlarge(delta.x(), delta.y()); - return scroll_clip_layer_bounds; + return container_bounds; } ScrollNode* ScrollTree::CurrentlyScrollingNode() { @@ -1342,33 +1339,28 @@ gfx::Transform ScrollTree::ScreenSpaceTransform(int scroll_node_id) const { return screen_space_transform; } -SyncedScrollOffset* ScrollTree::GetOrCreateSyncedScrollOffset(int layer_id) { +SyncedScrollOffset* ScrollTree::GetOrCreateSyncedScrollOffset(ElementId id) { 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()) { - layer_id_to_synced_scroll_offset_map_[layer_id] = new SyncedScrollOffset; + if (synced_scroll_offset_map_.find(id) == synced_scroll_offset_map_.end()) { + synced_scroll_offset_map_[id] = new SyncedScrollOffset; } - return layer_id_to_synced_scroll_offset_map_[layer_id].get(); + return synced_scroll_offset_map_[id].get(); } const SyncedScrollOffset* ScrollTree::GetSyncedScrollOffset( - int layer_id) const { + ElementId id) const { DCHECK(!property_trees()->is_main_thread); - 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; + auto it = synced_scroll_offset_map_.find(id); + return it != synced_scroll_offset_map_.end() ? it->second.get() : nullptr; } -const gfx::ScrollOffset ScrollTree::current_scroll_offset(int layer_id) const { +const gfx::ScrollOffset ScrollTree::current_scroll_offset(ElementId id) const { if (property_trees()->is_main_thread) { - ScrollOffsetMap::const_iterator it = - layer_id_to_scroll_offset_map_.find(layer_id); - return it != layer_id_to_scroll_offset_map_.end() ? it->second - : gfx::ScrollOffset(); - } - return GetSyncedScrollOffset(layer_id) - ? GetSyncedScrollOffset(layer_id)->Current( - property_trees()->is_active) + ScrollOffsetMap::const_iterator it = scroll_offset_map_.find(id); + return it != scroll_offset_map_.end() ? it->second : gfx::ScrollOffset(); + } + return GetSyncedScrollOffset(id) + ? GetSyncedScrollOffset(id)->Current(property_trees()->is_active) : gfx::ScrollOffset(); } @@ -1391,24 +1383,25 @@ gfx::ScrollOffset ScrollTree::PullDeltaForMainThread( return delta; } -void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info, - int inner_viewport_layer_id) { +void ScrollTree::CollectScrollDeltas( + ScrollAndScaleSet* scroll_info, + ElementId inner_viewport_scroll_element_id) { DCHECK(!property_trees()->is_main_thread); - for (auto map_entry : layer_id_to_synced_scroll_offset_map_) { + for (auto map_entry : synced_scroll_offset_map_) { gfx::ScrollOffset scroll_delta = PullDeltaForMainThread(map_entry.second.get()); gfx::Vector2d scroll_delta_vector(scroll_delta.x(), scroll_delta.y()); - int layer_id = map_entry.first; + ElementId id = map_entry.first; if (!scroll_delta.IsZero()) { - if (layer_id == inner_viewport_layer_id) { + if (id == inner_viewport_scroll_element_id) { // Inner (visual) viewport is stored separately. - scroll_info->inner_viewport_scroll.layer_id = layer_id; + scroll_info->inner_viewport_scroll.element_id = id; scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta_vector; } else { LayerTreeHostCommon::ScrollUpdateInfo scroll; - scroll.layer_id = layer_id; + scroll.element_id = id; scroll.scroll_delta = scroll_delta_vector; scroll_info->scrolls.push_back(scroll); } @@ -1417,7 +1410,7 @@ void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info, } void ScrollTree::CollectScrollDeltasForTesting() { - for (auto map_entry : layer_id_to_synced_scroll_offset_map_) { + for (auto map_entry : synced_scroll_offset_map_) { PullDeltaForMainThread(map_entry.second.get()); } } @@ -1427,23 +1420,23 @@ void ScrollTree::PushScrollUpdatesFromMainThread( LayerTreeImpl* sync_tree) { DCHECK(!property_trees()->is_main_thread); const ScrollOffsetMap& main_scroll_offset_map = - main_property_trees->scroll_tree.layer_id_to_scroll_offset_map_; + main_property_trees->scroll_tree.scroll_offset_map_; // We first want to clear SyncedProperty instances for layers which were // destroyed or became non-scrollable on the main thread. - for (auto map_entry = layer_id_to_synced_scroll_offset_map_.begin(); - map_entry != layer_id_to_synced_scroll_offset_map_.end();) { - int layer_id = map_entry->first; - if (main_scroll_offset_map.find(layer_id) == main_scroll_offset_map.end()) - map_entry = layer_id_to_synced_scroll_offset_map_.erase(map_entry); + for (auto map_entry = synced_scroll_offset_map_.begin(); + map_entry != synced_scroll_offset_map_.end();) { + ElementId id = map_entry->first; + if (main_scroll_offset_map.find(id) == main_scroll_offset_map.end()) + map_entry = synced_scroll_offset_map_.erase(map_entry); else map_entry++; } for (auto map_entry : main_scroll_offset_map) { - int layer_id = map_entry.first; + ElementId id = map_entry.first; SyncedScrollOffset* synced_scroll_offset = - GetOrCreateSyncedScrollOffset(layer_id); + GetOrCreateSyncedScrollOffset(id); bool changed = synced_scroll_offset->PushFromMainThread(map_entry.second); // If we are committing directly to the active tree, push pending to active @@ -1452,7 +1445,7 @@ void ScrollTree::PushScrollUpdatesFromMainThread( changed |= synced_scroll_offset->PushPendingToActive(); if (changed) - sync_tree->DidUpdateScrollOffset(layer_id); + sync_tree->DidUpdateScrollOffset(id); } } @@ -1466,10 +1459,10 @@ void ScrollTree::PushScrollUpdatesFromPendingTree( // When pushing to the active tree, we can simply copy over the map from the // pending tree. The pending and active tree hold a reference to the same // SyncedProperty instances. - layer_id_to_synced_scroll_offset_map_.clear(); - for (auto map_entry : pending_property_trees->scroll_tree - .layer_id_to_synced_scroll_offset_map_) { - layer_id_to_synced_scroll_offset_map_[map_entry.first] = map_entry.second; + synced_scroll_offset_map_.clear(); + for (auto map_entry : + pending_property_trees->scroll_tree.synced_scroll_offset_map_) { + synced_scroll_offset_map_[map_entry.first] = map_entry.second; if (map_entry.second->PushPendingToActive()) active_tree->DidUpdateScrollOffset(map_entry.first); } @@ -1477,77 +1470,75 @@ void ScrollTree::PushScrollUpdatesFromPendingTree( void ScrollTree::ApplySentScrollDeltasFromAbortedCommit() { DCHECK(property_trees()->is_active); - for (auto& map_entry : layer_id_to_synced_scroll_offset_map_) + for (auto& map_entry : synced_scroll_offset_map_) map_entry.second->AbortCommit(); } -bool ScrollTree::SetBaseScrollOffset(int layer_id, +bool ScrollTree::SetBaseScrollOffset(ElementId id, const gfx::ScrollOffset& scroll_offset) { if (property_trees()->is_main_thread) { - layer_id_to_scroll_offset_map_[layer_id] = scroll_offset; + scroll_offset_map_[id] = scroll_offset; return true; } // Scroll offset updates on the impl thread should only be for layers which // were created on the main thread. But this method is called when we build // PropertyTrees on the impl thread from LayerTreeImpl. - return GetOrCreateSyncedScrollOffset(layer_id)->PushFromMainThread( - scroll_offset); + return GetOrCreateSyncedScrollOffset(id)->PushFromMainThread(scroll_offset); } -bool ScrollTree::SetScrollOffset(int layer_id, +bool ScrollTree::SetScrollOffset(ElementId id, const gfx::ScrollOffset& scroll_offset) { if (property_trees()->is_main_thread) { - if (layer_id_to_scroll_offset_map_[layer_id] == scroll_offset) + if (scroll_offset_map_[id] == scroll_offset) return false; - layer_id_to_scroll_offset_map_[layer_id] = scroll_offset; + scroll_offset_map_[id] = scroll_offset; return true; } if (property_trees()->is_active) { - return GetOrCreateSyncedScrollOffset(layer_id)->SetCurrent(scroll_offset); + return GetOrCreateSyncedScrollOffset(id)->SetCurrent(scroll_offset); } return false; } bool ScrollTree::UpdateScrollOffsetBaseForTesting( - int layer_id, + ElementId id, const gfx::ScrollOffset& offset) { DCHECK(!property_trees()->is_main_thread); - SyncedScrollOffset* synced_scroll_offset = - GetOrCreateSyncedScrollOffset(layer_id); + SyncedScrollOffset* synced_scroll_offset = GetOrCreateSyncedScrollOffset(id); bool changed = synced_scroll_offset->PushFromMainThread(offset); if (property_trees()->is_active) changed |= synced_scroll_offset->PushPendingToActive(); return changed; } -bool ScrollTree::SetScrollOffsetDeltaForTesting(int layer_id, +bool ScrollTree::SetScrollOffsetDeltaForTesting(ElementId id, const gfx::Vector2dF& delta) { - return GetOrCreateSyncedScrollOffset(layer_id)->SetCurrent( - GetOrCreateSyncedScrollOffset(layer_id)->ActiveBase() + + return GetOrCreateSyncedScrollOffset(id)->SetCurrent( + GetOrCreateSyncedScrollOffset(id)->ActiveBase() + gfx::ScrollOffset(delta)); } const gfx::ScrollOffset ScrollTree::GetScrollOffsetBaseForTesting( - int layer_id) const { + ElementId id) const { DCHECK(!property_trees()->is_main_thread); - if (GetSyncedScrollOffset(layer_id)) + if (GetSyncedScrollOffset(id)) return property_trees()->is_active - ? GetSyncedScrollOffset(layer_id)->ActiveBase() - : GetSyncedScrollOffset(layer_id)->PendingBase(); + ? GetSyncedScrollOffset(id)->ActiveBase() + : GetSyncedScrollOffset(id)->PendingBase(); else return gfx::ScrollOffset(); } const gfx::ScrollOffset ScrollTree::GetScrollOffsetDeltaForTesting( - int layer_id) const { + ElementId id) const { DCHECK(!property_trees()->is_main_thread); - if (GetSyncedScrollOffset(layer_id)) + if (GetSyncedScrollOffset(id)) return property_trees()->is_active - ? GetSyncedScrollOffset(layer_id)->Delta() - : GetSyncedScrollOffset(layer_id)->PendingDelta().get(); + ? GetSyncedScrollOffset(id)->Delta() + : GetSyncedScrollOffset(id)->PendingDelta().get(); else return gfx::ScrollOffset(); } @@ -1580,12 +1571,11 @@ gfx::Vector2dF ScrollTree::ScrollBy(ScrollNode* scroll_node, if (!scroll_node->user_scrollable_vertical) adjusted_scroll.set_y(0); DCHECK(scroll_node->scrollable); - gfx::ScrollOffset old_offset = - current_scroll_offset(scroll_node->owning_layer_id); + gfx::ScrollOffset old_offset = current_scroll_offset(scroll_node->element_id); gfx::ScrollOffset new_offset = ClampScrollOffsetToLimits(old_offset + adjusted_scroll, scroll_node); - if (SetScrollOffset(scroll_node->owning_layer_id, new_offset)) - layer_tree_impl->DidUpdateScrollOffset(scroll_node->owning_layer_id); + if (SetScrollOffset(scroll_node->element_id, new_offset)) + layer_tree_impl->DidUpdateScrollOffset(scroll_node->element_id); gfx::ScrollOffset unscrolled = old_offset + gfx::ScrollOffset(scroll) - new_offset; @@ -1718,18 +1708,93 @@ void PropertyTrees::SetOuterViewportContainerBoundsDelta( transform_tree.UpdateOuterViewportContainerBoundsDelta(); } +bool PropertyTrees::ElementIsAnimatingChanged( + const MutatorHost* mutator_host, + ElementId element_id, + ElementListType list_type, + const PropertyAnimationState& mask, + const PropertyAnimationState& state, + bool check_node_existence) { + bool updated_transform = false; + for (int property = TargetProperty::FIRST_TARGET_PROPERTY; + property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) { + if (!mask.currently_running[property] && + !mask.potentially_animating[property]) + continue; + + switch (property) { + case TargetProperty::TRANSFORM: + if (TransformNode* transform_node = + transform_tree.FindNodeFromElementId(element_id)) { + if (mask.currently_running[property]) + transform_node->is_currently_animating = + state.currently_running[property]; + if (mask.potentially_animating[property]) { + transform_node->has_potential_animation = + state.potentially_animating[property]; + transform_node->has_only_translation_animations = + mutator_host->HasOnlyTranslationTransforms(element_id, + list_type); + transform_tree.set_needs_update(true); + // We track transform updates specifically, whereas we + // don't do so for opacity/filter, because whether a + // transform is animating can change what layer(s) we + // draw. + updated_transform = true; + } + } else { + DCHECK_NODE_EXISTENCE(check_node_existence, state, property, + needs_rebuild) + << "Attempting to animate non existent transform node"; + } + break; + case TargetProperty::OPACITY: + if (EffectNode* effect_node = + effect_tree.FindNodeFromElementId(element_id)) { + if (mask.currently_running[property]) + effect_node->is_currently_animating_opacity = + state.currently_running[property]; + if (mask.potentially_animating[property]) { + effect_node->has_potential_opacity_animation = + state.potentially_animating[property]; + // We may need to propagate things like screen space opacity. + effect_tree.set_needs_update(true); + } + } else { + DCHECK_NODE_EXISTENCE(check_node_existence, state, property, + needs_rebuild) + << "Attempting to animate opacity on non existent effect node"; + } + break; + case TargetProperty::FILTER: + if (EffectNode* effect_node = + effect_tree.FindNodeFromElementId(element_id)) { + if (mask.currently_running[property]) + effect_node->is_currently_animating_filter = + state.currently_running[property]; + if (mask.potentially_animating[property]) + effect_node->has_potential_filter_animation = + state.potentially_animating[property]; + // Filter animation changes only the node, and the subtree does not + // care, thus there is no need to request property tree update. + } else { + DCHECK_NODE_EXISTENCE(check_node_existence, state, property, + needs_rebuild) + << "Attempting to animate filter on non existent effect node"; + } + break; + default: + break; + } + } + return updated_transform; +} + void PropertyTrees::SetInnerViewportScrollBoundsDelta( gfx::Vector2dF bounds_delta) { inner_viewport_scroll_bounds_delta_ = bounds_delta; } -void PropertyTrees::RemoveIdFromIdToIndexMaps(int id) { - transform_tree.SetOwningLayerIdForNode(nullptr, id); - clip_tree.SetOwningLayerIdForNode(nullptr, id); - scroll_tree.SetOwningLayerIdForNode(nullptr, id); - effect_tree.SetOwningLayerIdForNode(nullptr, id); -} - void PropertyTrees::UpdateChangeTracking() { for (int id = EffectTree::kContentsRootNodeId; id < static_cast<int>(effect_tree.size()); ++id) { @@ -1889,15 +1954,16 @@ CombinedAnimationScale PropertyTrees::GetAnimationScales( .combined_starting_animation_scale = max_local_scale * ancestor_starting_animation_scale; } else { - // TODO(sunxd): make LayerTreeImpl::MaximumTargetScale take layer id as - // parameter. - LayerImpl* layer_impl = layer_tree_impl->LayerById(node->owning_layer_id); - layer_impl->GetMutatorHost()->MaximumTargetScale( - layer_impl->element_id(), layer_impl->GetElementTypeForAnimation(), + ElementListType list_type = layer_tree_impl->IsActiveTree() + ? ElementListType::ACTIVE + : ElementListType::PENDING; + + layer_tree_impl->mutator_host()->MaximumTargetScale( + node->element_id, list_type, &cached_data_.animation_scales[transform_node_id] .local_maximum_animation_target_scale); - layer_impl->GetMutatorHost()->AnimationStartScale( - layer_impl->element_id(), layer_impl->GetElementTypeForAnimation(), + layer_tree_impl->mutator_host()->AnimationStartScale( + node->element_id, list_type, &cached_data_.animation_scales[transform_node_id] .local_starting_animation_scale); gfx::Vector2dF local_scales = @@ -2024,12 +2090,13 @@ DrawTransformData& PropertyTrees::FetchDrawTransformsDataFromCache( ClipRectData* PropertyTrees::FetchClipRectFromCache(int clip_id, int target_id) { ClipNode* clip_node = clip_tree.Node(clip_id); - for (auto& data : clip_node->cached_clip_rects) { + for (size_t i = 0; i < clip_node->cached_clip_rects->size(); ++i) { + auto& data = clip_node->cached_clip_rects[i]; if (data.target_id == target_id || data.target_id == -1) return &data; } - clip_node->cached_clip_rects.push_back(ClipRectData()); - return &clip_node->cached_clip_rects.back(); + clip_node->cached_clip_rects->emplace_back(); + return &clip_node->cached_clip_rects->back(); } DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id, diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h index 3ea602ad1c0..a9610cbb888 100644 --- a/chromium/cc/trees/property_tree.h +++ b/chromium/cc/trees/property_tree.h @@ -17,6 +17,7 @@ #include "cc/cc_export.h" #include "cc/layers/layer_sticky_position_constraint.h" #include "cc/trees/element_id.h" +#include "cc/trees/mutator_host_client.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/transform.h" @@ -31,6 +32,7 @@ namespace cc { class CopyOutputRequest; class LayerTreeImpl; +class MutatorHost; class RenderSurfaceImpl; class ScrollState; struct ClipNode; @@ -100,45 +102,8 @@ class CC_EXPORT PropertyTree { void AsValueInto(base::trace_event::TracedValue* value) const; - const T* FindNodeFromOwningLayerId(int id) const { - return Node(FindNodeIndexFromOwningLayerId(id)); - } - T* UpdateNodeFromOwningLayerId(int id) { - int index = FindNodeIndexFromOwningLayerId(id); - if (index == kInvalidNodeId) { - DCHECK(property_trees()->is_main_thread); - property_trees()->needs_rebuild = true; - } - - return Node(index); - } - - int FindNodeIndexFromOwningLayerId(int id) const { - auto iter = owning_layer_id_to_node_index_.find(id); - if (iter == owning_layer_id_to_node_index_.end()) - return kInvalidNodeId; - else - return iter->second; - } - - void SetOwningLayerIdForNode(const T* node, int id) { - if (!node) { - owning_layer_id_to_node_index_[id] = kInvalidNodeId; - return; - } - - DCHECK(node == Node(node->id)); - owning_layer_id_to_node_index_[id] = node->id; - } - - private: + protected: std::vector<T> nodes_; - - // Maps from layer id to the property tree node index. This container is - // typically very small and the memory overhead of unordered_map will - // dominate so use a flat_map. See http://crbug.com/709243 - base::flat_map<int, int> owning_layer_id_to_node_index_; - bool needs_update_; PropertyTrees* property_trees_; }; @@ -309,11 +274,6 @@ struct StickyPositionNodeData { int scroll_ancestor; LayerStickyPositionConstraint constraints; - // This is the offset that blink has already applied to counteract the main - // thread scroll offset of the scroll ancestor. We need to account for this - // by computing the additional offset necessary to keep the element stuck. - gfx::Vector2dF main_thread_offset; - // In order to properly compute the sticky offset, we need to know if we have // any sticky ancestors both between ourselves and our containing block and // between our containing block and the viewport. These ancestors are then @@ -436,11 +396,11 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { void clear(); gfx::ScrollOffset MaxScrollOffset(int scroll_node_id) const; - void OnScrollOffsetAnimated(int layer_id, + void OnScrollOffsetAnimated(ElementId id, int scroll_tree_index, const gfx::ScrollOffset& scroll_offset, LayerTreeImpl* layer_tree_impl); - gfx::Size scroll_clip_layer_bounds(int scroll_node_id) const; + gfx::Size container_bounds(int scroll_node_id) const; ScrollNode* CurrentlyScrollingNode(); const ScrollNode* CurrentlyScrollingNode() const; #if DCHECK_IS_ON() @@ -452,13 +412,13 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { // Returns the current scroll offset. On the main thread this would return the // value for the LayerTree while on the impl thread this is the current value // on the active tree. - const gfx::ScrollOffset current_scroll_offset(int layer_id) const; + const gfx::ScrollOffset current_scroll_offset(ElementId id) const; // Collects deltas for scroll changes on the impl thread that need to be // reported to the main thread during the main frame. As such, should only be // called on the impl thread side PropertyTrees. void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, - int inner_viewport_layer_id); + ElementId inner_viewport_scroll_element_id); // Applies deltas sent in the previous main frame onto the impl thread state. // Should only be called on the impl thread side PropertyTrees. @@ -474,18 +434,18 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { void PushScrollUpdatesFromPendingTree(PropertyTrees* pending_property_trees, LayerTreeImpl* active_tree); - bool SetBaseScrollOffset(int layer_id, + bool SetBaseScrollOffset(ElementId id, const gfx::ScrollOffset& scroll_offset); - bool SetScrollOffset(int layer_id, const gfx::ScrollOffset& scroll_offset); - void SetScrollOffsetClobberActiveValue(int layer_id) { - GetOrCreateSyncedScrollOffset(layer_id)->set_clobber_active_value(); + bool SetScrollOffset(ElementId id, const gfx::ScrollOffset& scroll_offset); + void SetScrollOffsetClobberActiveValue(ElementId id) { + GetOrCreateSyncedScrollOffset(id)->set_clobber_active_value(); } - bool UpdateScrollOffsetBaseForTesting(int layer_id, + bool UpdateScrollOffsetBaseForTesting(ElementId id, const gfx::ScrollOffset& offset); - bool SetScrollOffsetDeltaForTesting(int layer_id, + bool SetScrollOffsetDeltaForTesting(ElementId id, const gfx::Vector2dF& delta); - const gfx::ScrollOffset GetScrollOffsetBaseForTesting(int layer_id) const; - const gfx::ScrollOffset GetScrollOffsetDeltaForTesting(int layer_id) const; + const gfx::ScrollOffset GetScrollOffsetBaseForTesting(ElementId id) const; + const gfx::ScrollOffset GetScrollOffsetDeltaForTesting(ElementId id) const; void CollectScrollDeltasForTesting(); void DistributeScroll(ScrollNode* scroll_node, ScrollState* scroll_state); @@ -495,7 +455,7 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { gfx::ScrollOffset ClampScrollOffsetToLimits(gfx::ScrollOffset offset, ScrollNode* scroll_node) const; - const SyncedScrollOffset* GetSyncedScrollOffset(int layer_id) const; + const SyncedScrollOffset* GetSyncedScrollOffset(ElementId id) const; #if DCHECK_IS_ON() void CopyCompleteTreeState(const ScrollTree& other); @@ -504,9 +464,9 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { ScrollNode* FindNodeFromElementId(ElementId id); private: - using ScrollOffsetMap = base::flat_map<int, gfx::ScrollOffset>; + using ScrollOffsetMap = base::flat_map<ElementId, gfx::ScrollOffset>; using SyncedScrollOffsetMap = - base::flat_map<int, scoped_refptr<SyncedScrollOffset>>; + base::flat_map<ElementId, scoped_refptr<SyncedScrollOffset>>; int currently_scrolling_node_id_; @@ -515,10 +475,10 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { // thread stores a map of SyncedProperty instances in order to track // additional state necessary to synchronize scroll changes between the main // and impl threads. - ScrollOffsetMap layer_id_to_scroll_offset_map_; - SyncedScrollOffsetMap layer_id_to_synced_scroll_offset_map_; + ScrollOffsetMap scroll_offset_map_; + SyncedScrollOffsetMap synced_scroll_offset_map_; - SyncedScrollOffset* GetOrCreateSyncedScrollOffset(int layer_id); + SyncedScrollOffset* GetOrCreateSyncedScrollOffset(ElementId id); gfx::ScrollOffset PullDeltaForMainThread(SyncedScrollOffset* scroll_offset); }; @@ -670,10 +630,18 @@ class CC_EXPORT PropertyTrees final { void clear(); + // Applies an animation state change for a particular element in + // this property tree. Returns whether a draw property update is + // needed. + bool ElementIsAnimatingChanged(const MutatorHost* mutator_host, + ElementId element_id, + ElementListType list_type, + const PropertyAnimationState& mask, + const PropertyAnimationState& state, + bool check_node_existence); void SetInnerViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); void SetOuterViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); void SetInnerViewportScrollBoundsDelta(gfx::Vector2dF bounds_delta); - void RemoveIdFromIdToIndexMaps(int id); void UpdateChangeTracking(); void PushChangeTrackingTo(PropertyTrees* tree); void ResetAllChangeTracking(); diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc index a7efa0a7155..4b5292df6ba 100644 --- a/chromium/cc/trees/property_tree_builder.cc +++ b/chromium/cc/trees/property_tree_builder.cc @@ -35,28 +35,29 @@ struct DataForRecursion { PropertyTrees* property_trees; LayerType* transform_tree_parent; LayerType* transform_fixed_parent; - 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; const LayerType* overscroll_elasticity_layer; - gfx::Vector2dF elastic_overscroll; + const gfx::Transform* device_transform; float page_scale_factor; + int clip_tree_parent; + int effect_tree_parent; + int scroll_tree_parent; + int closest_ancestor_with_cached_render_surface; + int closest_ancestor_with_copy_request; + uint32_t main_thread_scrolling_reasons; + SkColor safe_opaque_background_color; bool in_subtree_of_page_scale_layer; bool affected_by_inner_viewport_bounds_delta; bool affected_by_outer_viewport_bounds_delta; bool should_flatten; bool is_hidden; - uint32_t main_thread_scrolling_reasons; bool scroll_tree_parent_created_by_uninheritable_criteria; - const gfx::Transform* device_transform; - gfx::Transform compound_transform_since_render_target; bool animation_axis_aligned_since_render_target; bool not_axis_aligned_since_last_clip; - SkColor safe_opaque_background_color; + gfx::Transform compound_transform_since_render_target; + gfx::Vector2dF elastic_overscroll; }; static LayerPositionConstraint PositionConstraint(Layer* layer) { @@ -140,12 +141,6 @@ static const gfx::Transform& Transform(LayerImpl* layer) { return layer->test_properties()->transform; } -static void SetIsScrollClipLayer(Layer* layer) { - layer->set_is_scroll_clip_layer(); -} - -static void SetIsScrollClipLayer(LayerImpl* layer) {} - // Methods to query state from the AnimationHost ---------------------- template <typename LayerType> bool OpacityIsAnimating(LayerType* layer) { @@ -274,7 +269,6 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, node.clip = gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(), gfx::SizeF(layer->bounds())); node.transform_id = transform_parent->transform_tree_index(); - node.owning_layer_id = layer->id(); if (layer_clips_subtree) { node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; } else { @@ -285,13 +279,19 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, } data_for_children->clip_tree_parent = data_for_children->property_trees->clip_tree.Insert(node, parent_id); - data_for_children->property_trees->clip_tree.SetOwningLayerIdForNode( - data_for_children->property_trees->clip_tree.back(), layer->id()); } layer->SetClipTreeIndex(data_for_children->clip_tree_parent); } +static Layer* LayerById(Layer* layer, int id) { + return layer->layer_tree_host()->LayerById(id); +} + +static LayerImpl* LayerById(LayerImpl* layer, int id) { + return layer->layer_tree_impl()->LayerById(id); +} + template <typename LayerType> static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { return Parent(layer) @@ -389,7 +389,6 @@ bool AddTransformNodeIfNeeded( data_for_children->affected_by_outer_viewport_bounds_delta = layer == data_from_ancestor.outer_viewport_scroll_layer; if (is_scrollable) { - DCHECK(!is_root); DCHECK(Transform(layer).IsIdentity()); data_for_children->transform_fixed_parent = Parent(layer); } else { @@ -423,14 +422,13 @@ bool AddTransformNodeIfNeeded( TransformNode* node = data_for_children->property_trees->transform_tree.back(); layer->SetTransformTreeIndex(node->id); - data_for_children->property_trees->transform_tree.SetOwningLayerIdForNode( - node, layer->id()); // For animation subsystem purposes, if this layer has a compositor element // id, we build a map from that id to this transform node. if (layer->element_id()) { data_for_children->property_trees ->element_id_to_transform_node_index[layer->element_id()] = node->id; + node->element_id = layer->element_id(); } node->scrolls = is_scrollable; @@ -540,14 +538,6 @@ bool AddTransformNodeIfNeeded( .AddNodeAffectedByOuterViewportBoundsDelta(node->id); } } - // TODO(smcgruer): Pass main thread sticky-shifting offsets of - // non-promoted ancestors, or promote all ancestor sticky elements. - // See http://crbug.com/702229 - sticky_data->main_thread_offset = - layer->position().OffsetFromOrigin() - - sticky_data->constraints.parent_relative_sticky_box_offset - .OffsetFromOrigin(); - // Copy the ancestor nodes for later use. These layers are guaranteed to // have transform nodes at this point because they are our ancestors (so // have already been processed) and are sticky (so have transform nodes). @@ -555,8 +545,8 @@ bool AddTransformNodeIfNeeded( sticky_data->constraints.nearest_layer_shifting_sticky_box; if (shifting_sticky_box_layer_id != Layer::INVALID_ID) { sticky_data->nearest_node_shifting_sticky_box = - data_for_children->property_trees->transform_tree - .FindNodeIndexFromOwningLayerId(shifting_sticky_box_layer_id); + LayerById(layer, shifting_sticky_box_layer_id) + ->transform_tree_index(); DCHECK(sticky_data->nearest_node_shifting_sticky_box != TransformTree::kInvalidNodeId); } @@ -564,9 +554,8 @@ bool AddTransformNodeIfNeeded( sticky_data->constraints.nearest_layer_shifting_containing_block; if (shifting_containing_block_layer_id != Layer::INVALID_ID) { sticky_data->nearest_node_shifting_containing_block = - data_for_children->property_trees->transform_tree - .FindNodeIndexFromOwningLayerId( - shifting_containing_block_layer_id); + LayerById(layer, shifting_containing_block_layer_id) + ->transform_tree_index(); DCHECK(sticky_data->nearest_node_shifting_containing_block != TransformTree::kInvalidNodeId); } @@ -580,8 +569,6 @@ bool AddTransformNodeIfNeeded( // Flattening (if needed) will be handled by |node|. layer->set_should_flatten_transform_from_property_tree(false); - node->owning_layer_id = layer->id(); - return true; } @@ -603,6 +590,14 @@ static inline bool DoubleSided(LayerImpl* layer) { return layer->test_properties()->double_sided; } +static inline bool CacheRenderSurface(Layer* layer) { + return layer->cache_render_surface(); +} + +static inline bool CacheRenderSurface(LayerImpl* layer) { + return layer->test_properties()->cache_render_surface; +} + static inline bool ForceRenderSurface(Layer* layer) { return layer->force_render_surface_for_testing(); } @@ -809,6 +804,10 @@ bool ShouldCreateRenderSurface(LayerType* layer, if (ForceRenderSurface(layer)) return true; + // If we cache it. + if (CacheRenderSurface(layer)) + return true; + // If we'll make a copy of the layer's contents. if (HasCopyRequest(layer)) return true; @@ -910,11 +909,12 @@ bool AddEffectNodeIfNeeded( int node_id = effect_tree.Insert(EffectNode(), parent_id); EffectNode* node = effect_tree.back(); - node->owning_layer_id = layer->id(); + node->stable_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->cache_render_surface = CacheRenderSurface(layer); node->has_copy_request = HasCopyRequest(layer); node->filters = Filters(layer); node->background_filters = BackgroundFilters(layer); @@ -927,6 +927,10 @@ bool AddEffectNodeIfNeeded( node->is_currently_animating_filter = FilterIsAnimating(layer); node->effect_changed = PropertyChanged(layer); node->subtree_has_copy_request = SubtreeHasCopyRequest(layer); + node->closest_ancestor_with_cached_render_surface_id = + CacheRenderSurface(layer) + ? node_id + : data_from_ancestor.closest_ancestor_with_cached_render_surface; node->closest_ancestor_with_copy_request_id = HasCopyRequest(layer) ? node_id @@ -960,12 +964,12 @@ bool AddEffectNodeIfNeeded( node->clip_id = ClipTree::kViewportNodeId; } + data_for_children->closest_ancestor_with_cached_render_surface = + node->closest_ancestor_with_cached_render_surface_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( - effect_tree.back(), layer->id()); // For animation subsystem purposes, if this layer has a compositor element // id, we build a map from that id to this effect node. @@ -989,6 +993,36 @@ bool AddEffectNodeIfNeeded( return should_create_render_surface; } +static inline bool UserScrollableHorizontal(Layer* layer) { + return layer->user_scrollable_horizontal(); +} + +static inline bool UserScrollableHorizontal(LayerImpl* layer) { + return layer->test_properties()->user_scrollable_horizontal; +} + +static inline bool UserScrollableVertical(Layer* layer) { + return layer->user_scrollable_vertical(); +} + +static inline bool UserScrollableVertical(LayerImpl* layer) { + return layer->test_properties()->user_scrollable_vertical; +} + +static inline ScrollBoundaryBehavior GetScrollBoundaryBehavior(Layer* layer) { + return layer->scroll_boundary_behavior(); +} + +static inline ScrollBoundaryBehavior GetScrollBoundaryBehavior( + LayerImpl* layer) { + return layer->test_properties()->scroll_boundary_behavior; +} + +template <typename LayerType> +void SetHasTransformNode(LayerType* layer, bool val) { + layer->SetHasTransformNode(val); +} + template <typename LayerType> void AddScrollNodeIfNeeded( const DataForRecursion<LayerType>& data_from_ancestor, @@ -1022,37 +1056,29 @@ void AddScrollNodeIfNeeded( data_for_children->scroll_tree_parent = node_id; } else { ScrollNode node; - node.owning_layer_id = layer->id(); node.scrollable = scrollable; node.main_thread_scrolling_reasons = main_thread_scrolling_reasons; node.non_fast_scrollable_region = layer->non_fast_scrollable_region(); - gfx::Size clip_bounds; - if (LayerType* scroll_clip_layer = layer->scroll_clip_layer()) { - SetIsScrollClipLayer(scroll_clip_layer); - clip_bounds = scroll_clip_layer->bounds(); - DCHECK(scroll_clip_layer->transform_tree_index() != - TransformTree::kInvalidNodeId); - node.max_scroll_offset_affected_by_page_scale = - !data_from_ancestor.property_trees->transform_tree - .Node(scroll_clip_layer->transform_tree_index()) - ->in_subtree_of_page_scale_layer && - data_from_ancestor.in_subtree_of_page_scale_layer; - } - - node.scroll_clip_layer_bounds = clip_bounds; node.scrolls_inner_viewport = layer == data_from_ancestor.inner_viewport_scroll_layer; node.scrolls_outer_viewport = layer == data_from_ancestor.outer_viewport_scroll_layer; + if (node.scrolls_inner_viewport && + data_from_ancestor.in_subtree_of_page_scale_layer) { + node.max_scroll_offset_affected_by_page_scale = true; + } + node.bounds = layer->bounds(); + node.container_bounds = layer->scroll_container_bounds(); node.offset_to_transform_parent = layer->offset_to_transform_parent(); node.should_flatten = layer->should_flatten_transform_from_property_tree(); - node.user_scrollable_horizontal = layer->user_scrollable_horizontal(); - node.user_scrollable_vertical = layer->user_scrollable_vertical(); + node.user_scrollable_horizontal = UserScrollableHorizontal(layer); + node.user_scrollable_vertical = UserScrollableVertical(layer); node.element_id = layer->element_id(); node.transform_id = data_for_children->transform_tree_parent->transform_tree_index(); + node.scroll_boundary_behavior = GetScrollBoundaryBehavior(layer); node_id = data_for_children->property_trees->scroll_tree.Insert(node, parent_id); @@ -1061,8 +1087,6 @@ void AddScrollNodeIfNeeded( node.main_thread_scrolling_reasons; data_for_children->scroll_tree_parent_created_by_uninheritable_criteria = scroll_node_uninheritable_criteria; - data_for_children->property_trees->scroll_tree.SetOwningLayerIdForNode( - data_for_children->property_trees->scroll_tree.back(), layer->id()); // For animation subsystem purposes, if this layer has a compositor element // id, we build a map from that id to this scroll node. if (layer->element_id()) { @@ -1072,7 +1096,7 @@ void AddScrollNodeIfNeeded( if (node.scrollable) { data_for_children->property_trees->scroll_tree.SetBaseScrollOffset( - layer->id(), layer->CurrentScrollOffset()); + layer->element_id(), layer->CurrentScrollOffset()); } } @@ -1082,37 +1106,19 @@ void AddScrollNodeIfNeeded( template <typename LayerType> void SetBackfaceVisibilityTransform(LayerType* layer, bool created_transform_node) { - const bool is_at_boundary_of_3d_rendering_context = - IsAtBoundaryOf3dRenderingContext(layer); if (layer->use_parent_backface_visibility()) { - DCHECK(!is_at_boundary_of_3d_rendering_context); DCHECK(Parent(layer)); DCHECK(!Parent(layer)->use_parent_backface_visibility()); - layer->SetUseLocalTransformForBackfaceVisibility( - Parent(layer)->use_local_transform_for_backface_visibility()); layer->SetShouldCheckBackfaceVisibility( Parent(layer)->should_check_backface_visibility()); } else { - // The current W3C spec on CSS transforms says that backface visibility - // should be determined differently depending on whether the layer is in a - // "3d rendering context" or not. For Chromium code, we can determine - // whether we are in a 3d rendering context by checking if the parent - // preserves 3d. - const bool use_local_transform = - !Is3dSorted(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 visible. - if (DoubleSided(layer)) - layer->SetShouldCheckBackfaceVisibility(false); - // The backface of a layer that uses local transform for backface visibility - // is not visible when it does not create a transform node as its local - // transform is identity or 2d translation and is not animating. - else if (use_local_transform && !created_transform_node) - layer->SetShouldCheckBackfaceVisibility(false); - else - layer->SetShouldCheckBackfaceVisibility(true); + // In addition, we need to check if (1) there might be a local 3D transform + // on the layer that might turn it to the backface, or (2) it is not drawn + // into a flattened space. + layer->SetShouldCheckBackfaceVisibility( + !DoubleSided(layer) && + (created_transform_node || !ShouldFlattenTransform(Parent(layer)))); } } @@ -1153,6 +1159,7 @@ void BuildPropertyTreesInternal( bool created_transform_node = AddTransformNodeIfNeeded( data_from_parent, layer, created_render_surface, &data_for_children); + SetHasTransformNode(layer, created_transform_node); AddClipNodeIfNeeded(data_from_parent, layer, created_transform_node, &data_for_children); @@ -1259,6 +1266,8 @@ void BuildPropertyTreesTopLevelInternal( 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_cached_render_surface = + EffectTree::kInvalidNodeId; data_for_recursion.closest_ancestor_with_copy_request = EffectTree::kInvalidNodeId; data_for_recursion.page_scale_layer = page_scale_layer; diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h index 7bb9145a894..5e06000b2f1 100644 --- a/chromium/cc/trees/proxy.h +++ b/chromium/cc/trees/proxy.h @@ -23,8 +23,8 @@ class Rect; } namespace cc { +class LayerTreeFrameSink; class LayerTreeMutator; -class CompositorFrameSink; // Abstract interface responsible for proxying commands from the main-thread // side of the compositor over to the compositor implementation. @@ -35,12 +35,9 @@ class CC_EXPORT Proxy { virtual bool IsStarted() const = 0; virtual bool CommitToActiveTree() const = 0; - // Will call LayerTreeHost::OnCreateAndInitializeCompositorFrameSinkAttempted - // with the result of this function. - virtual void SetCompositorFrameSink( - CompositorFrameSink* compositor_frame_sink) = 0; - - virtual void ReleaseCompositorFrameSink() = 0; + virtual void SetLayerTreeFrameSink( + LayerTreeFrameSink* layer_tree_frame_sink) = 0; + virtual void ReleaseLayerTreeFrameSink() = 0; virtual void SetVisible(bool visible) = 0; @@ -73,6 +70,8 @@ class CC_EXPORT Proxy { BrowserControlsState current, bool animate) = 0; + virtual void RequestBeginMainFrameNotExpected(bool new_state) = 0; + // Testing hooks virtual bool MainFrameWillHappenForTesting() = 0; }; diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc index 01a96109c89..6fe0a166539 100644 --- a/chromium/cc/trees/proxy_impl.cc +++ b/chromium/cc/trees/proxy_impl.cc @@ -15,12 +15,10 @@ #include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" -#include "base/trace_event/trace_event_synthetic_delay.h" #include "cc/base/devtools_instrumentation.h" #include "cc/benchmarks/benchmark_instrumentation.h" #include "cc/input/browser_controls_offset_manager.h" -#include "cc/output/compositor_frame_sink.h" -#include "cc/output/context_provider.h" +#include "cc/output/layer_tree_frame_sink.h" #include "cc/scheduler/compositor_timing_history.h" #include "cc/scheduler/delay_based_time_source.h" #include "cc/trees/layer_tree_host.h" @@ -28,6 +26,7 @@ #include "cc/trees/mutator_host.h" #include "cc/trees/proxy_main.h" #include "cc/trees/task_runner_provider.h" +#include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" namespace cc { @@ -98,9 +97,9 @@ ProxyImpl::~ProxyImpl() { // Prevent the scheduler from performing actions while we're in an // inconsistent state. scheduler_->Stop(); - // Take away the CompositorFrameSink before destroying things so it doesn't + // Take away the LayerTreeFrameSink before destroying things so it doesn't // try to call into its client mid-shutdown. - layer_tree_host_impl_->ReleaseCompositorFrameSink(); + layer_tree_host_impl_->ReleaseLayerTreeFrameSink(); scheduler_ = nullptr; layer_tree_host_impl_ = nullptr; // We need to explicitly shutdown the notifier to destroy any weakptrs it is @@ -125,21 +124,21 @@ void ProxyImpl::UpdateBrowserControlsStateOnImpl( constraints, current, animate); } -void ProxyImpl::InitializeCompositorFrameSinkOnImpl( - CompositorFrameSink* compositor_frame_sink, +void ProxyImpl::InitializeLayerTreeFrameSinkOnImpl( + LayerTreeFrameSink* layer_tree_frame_sink, base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr) { - TRACE_EVENT0("cc", "ProxyImpl::InitializeCompositorFrameSinkOnImplThread"); + TRACE_EVENT0("cc", "ProxyImpl::InitializeLayerTreeFrameSinkOnImplThread"); 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); + bool success = host_impl->InitializeRenderer(layer_tree_frame_sink); MainThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyMain::DidInitializeCompositorFrameSink, + FROM_HERE, base::BindOnce(&ProxyMain::DidInitializeLayerTreeFrameSink, proxy_main_weak_ptr_, success)); if (success) - scheduler_->DidCreateAndInitializeCompositorFrameSink(); + scheduler_->DidCreateAndInitializeLayerTreeFrameSink(); } void ProxyImpl::MainThreadHasStoppedFlingingOnImpl() { @@ -196,22 +195,22 @@ void ProxyImpl::SetVisibleOnImpl(bool visible) { scheduler_->SetVisible(visible); } -void ProxyImpl::ReleaseCompositorFrameSinkOnImpl(CompletionEvent* completion) { +void ProxyImpl::ReleaseLayerTreeFrameSinkOnImpl(CompletionEvent* completion) { DCHECK(IsImplThread()); - // Unlike DidLoseCompositorFrameSinkOnImplThread, we don't need to call - // LayerTreeHost::DidLoseCompositorFrameSink since it already knows. - scheduler_->DidLoseCompositorFrameSink(); - layer_tree_host_impl_->ReleaseCompositorFrameSink(); + // Unlike DidLoseLayerTreeFrameSinkOnImplThread, we don't need to call + // LayerTreeHost::DidLoseLayerTreeFrameSink since it already knows. + scheduler_->DidLoseLayerTreeFrameSink(); + layer_tree_host_impl_->ReleaseLayerTreeFrameSink(); completion->Signal(); } void ProxyImpl::FinishGLOnImpl(CompletionEvent* completion) { TRACE_EVENT0("cc", "ProxyImpl::FinishGLOnImplThread"); DCHECK(IsImplThread()); - if (layer_tree_host_impl_->compositor_frame_sink()) { - ContextProvider* context_provider = - layer_tree_host_impl_->compositor_frame_sink()->context_provider(); + if (layer_tree_host_impl_->layer_tree_frame_sink()) { + viz::ContextProvider* context_provider = + layer_tree_host_impl_->layer_tree_frame_sink()->context_provider(); if (context_provider) context_provider->ContextGL()->Finish(); } @@ -222,7 +221,7 @@ void ProxyImpl::MainFrameWillHappenOnImplForTesting( CompletionEvent* completion, bool* main_frame_will_happen) { DCHECK(IsImplThread()); - if (layer_tree_host_impl_->compositor_frame_sink()) { + if (layer_tree_host_impl_->layer_tree_frame_sink()) { *main_frame_will_happen = scheduler_->MainFrameForTestingWillHappen(); } else { *main_frame_will_happen = false; @@ -230,6 +229,14 @@ void ProxyImpl::MainFrameWillHappenOnImplForTesting( completion->Signal(); } +void ProxyImpl::RequestBeginMainFrameNotExpected(bool new_state) { + DCHECK(IsImplThread()); + DCHECK(scheduler_); + TRACE_EVENT1("cc", "ProxyImpl::RequestBeginMainFrameNotExpected", "new_state", + new_state); + scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(new_state); +} + // TODO(sunnyps): Remove this code once crbug.com/668892 is fixed. NOINLINE void ProxyImpl::DumpForBeginMainFrameHang() { DCHECK(IsImplThread()); @@ -291,17 +298,17 @@ void ProxyImpl::NotifyReadyToCommitOnImpl( scheduler_->NotifyReadyToCommit(); } -void ProxyImpl::DidLoseCompositorFrameSinkOnImplThread() { - TRACE_EVENT0("cc", "ProxyImpl::DidLoseCompositorFrameSinkOnImplThread"); +void ProxyImpl::DidLoseLayerTreeFrameSinkOnImplThread() { + TRACE_EVENT0("cc", "ProxyImpl::DidLoseLayerTreeFrameSinkOnImplThread"); DCHECK(IsImplThread()); MainThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyMain::DidLoseCompositorFrameSink, + FROM_HERE, base::BindOnce(&ProxyMain::DidLoseLayerTreeFrameSink, proxy_main_weak_ptr_)); - scheduler_->DidLoseCompositorFrameSink(); + scheduler_->DidLoseLayerTreeFrameSink(); } void ProxyImpl::SetBeginFrameSource(BeginFrameSource* source) { - // During shutdown, destroying the CompositorFrameSink may unset the + // During shutdown, destroying the LayerTreeFrameSink may unset the // BeginFrameSource. if (scheduler_) { // TODO(enne): this overrides any preexisting begin frame source. Those @@ -463,9 +470,9 @@ void ProxyImpl::DidCompletePageScaleAnimationOnImplThread() { proxy_main_weak_ptr_)); } -void ProxyImpl::OnDrawForCompositorFrameSink(bool resourceless_software_draw) { +void ProxyImpl::OnDrawForLayerTreeFrameSink(bool resourceless_software_draw) { DCHECK(IsImplThread()); - scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); + scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw); } void ProxyImpl::NeedsImplSideInvalidation() { @@ -473,6 +480,11 @@ void ProxyImpl::NeedsImplSideInvalidation() { scheduler_->SetNeedsImplSideInvalidation(); } +void ProxyImpl::NotifyImageDecodeRequestFinished() { + DCHECK(IsImplThread()); + SetNeedsCommitOnImplThread(); +} + void ProxyImpl::WillBeginImplFrame(const BeginFrameArgs& args) { DCHECK(IsImplThread()); layer_tree_host_impl_->WillBeginImplFrame(args); @@ -582,12 +594,12 @@ void ProxyImpl::ScheduledActionActivateSyncTree() { layer_tree_host_impl_->ActivateSyncTree(); } -void ProxyImpl::ScheduledActionBeginCompositorFrameSinkCreation() { +void ProxyImpl::ScheduledActionBeginLayerTreeFrameSinkCreation() { TRACE_EVENT0("cc", - "ProxyImpl::ScheduledActionBeginCompositorFrameSinkCreation"); + "ProxyImpl::ScheduledActionBeginLayerTreeFrameSinkCreation"); DCHECK(IsImplThread()); MainThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyMain::RequestNewCompositorFrameSink, + FROM_HERE, base::BindOnce(&ProxyMain::RequestNewLayerTreeFrameSink, proxy_main_weak_ptr_)); } @@ -597,11 +609,11 @@ void ProxyImpl::ScheduledActionPrepareTiles() { layer_tree_host_impl_->PrepareTiles(); } -void ProxyImpl::ScheduledActionInvalidateCompositorFrameSink() { - TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionInvalidateCompositorFrameSink"); +void ProxyImpl::ScheduledActionInvalidateLayerTreeFrameSink() { + TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionInvalidateLayerTreeFrameSink"); DCHECK(IsImplThread()); - DCHECK(layer_tree_host_impl_->compositor_frame_sink()); - layer_tree_host_impl_->compositor_frame_sink()->Invalidate(); + DCHECK(layer_tree_host_impl_->layer_tree_frame_sink()); + layer_tree_host_impl_->layer_tree_frame_sink()->Invalidate(); } void ProxyImpl::ScheduledActionPerformImplSideInvalidation() { @@ -626,18 +638,13 @@ void ProxyImpl::ScheduledActionBeginMainFrameNotExpectedUntil( } DrawResult ProxyImpl::DrawInternal(bool forced_draw) { - TRACE_EVENT_SYNTHETIC_DELAY("cc.Draw"); - DCHECK(IsImplThread()); DCHECK(layer_tree_host_impl_.get()); base::AutoReset<bool> mark_inside(&inside_draw_, true); - if (layer_tree_host_impl_->pending_tree()) { - bool update_lcd_text = false; - layer_tree_host_impl_->pending_tree()->UpdateDrawProperties( - update_lcd_text); - } + if (layer_tree_host_impl_->pending_tree()) + layer_tree_host_impl_->pending_tree()->UpdateDrawProperties(); // This method is called on a forced draw, regardless of whether we are able // to produce a frame, as the calling site on main thread is blocked until its @@ -664,7 +671,7 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) { if (draw_frame) { if (layer_tree_host_impl_->DrawLayers(&frame)) - // Drawing implies we submitted a frame to the CompositorFrameSink. + // Drawing implies we submitted a frame to the LayerTreeFrameSink. scheduler_->DidSubmitCompositorFrame(); result = DRAW_SUCCESS; } else { diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h index 0953ae7a0e1..c98285be1e6 100644 --- a/chromium/cc/trees/proxy_impl.h +++ b/chromium/cc/trees/proxy_impl.h @@ -33,8 +33,8 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void UpdateBrowserControlsStateOnImpl(BrowserControlsState constraints, BrowserControlsState current, bool animate); - void InitializeCompositorFrameSinkOnImpl( - CompositorFrameSink* compositor_frame_sink, + void InitializeLayerTreeFrameSinkOnImpl( + LayerTreeFrameSink* layer_tree_frame_sink, base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr); void InitializeMutatorOnImpl(std::unique_ptr<LayerTreeMutator> mutator); void MainThreadHasStoppedFlingingOnImpl(); @@ -47,7 +47,7 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), base::TimeTicks main_thread_start_time, std::vector<std::unique_ptr<SwapPromise>> swap_promises); void SetVisibleOnImpl(bool visible); - void ReleaseCompositorFrameSinkOnImpl(CompletionEvent* completion); + void ReleaseLayerTreeFrameSinkOnImpl(CompletionEvent* completion); void FinishGLOnImpl(CompletionEvent* completion); void NotifyReadyToCommitOnImpl(CompletionEvent* completion, LayerTreeHost* layer_tree_host, @@ -57,6 +57,8 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void MainFrameWillHappenOnImplForTesting(CompletionEvent* completion, bool* main_frame_will_happen); + void RequestBeginMainFrameNotExpected(bool new_state) override; + NOINLINE void DumpForBeginMainFrameHang(); private: @@ -69,7 +71,7 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), }; // LayerTreeHostImplClient implementation - void DidLoseCompositorFrameSinkOnImplThread() override; + void DidLoseLayerTreeFrameSinkOnImplThread() override; void SetBeginFrameSource(BeginFrameSource* source) override; void DidReceiveCompositorFrameAckOnImplThread() override; void OnCanDrawStateChanged(bool can_draw) override; @@ -92,8 +94,9 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void WillPrepareTiles() override; void DidPrepareTiles() override; void DidCompletePageScaleAnimationOnImplThread() override; - void OnDrawForCompositorFrameSink(bool resourceless_software_draw) override; + void OnDrawForLayerTreeFrameSink(bool resourceless_software_draw) override; void NeedsImplSideInvalidation() override; + void NotifyImageDecodeRequestFinished() override; // SchedulerClient implementation void WillBeginImplFrame(const BeginFrameArgs& args) override; @@ -104,9 +107,9 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), DrawResult ScheduledActionDrawForced() override; void ScheduledActionCommit() override; void ScheduledActionActivateSyncTree() override; - void ScheduledActionBeginCompositorFrameSinkCreation() override; + void ScheduledActionBeginLayerTreeFrameSinkCreation() override; void ScheduledActionPrepareTiles() override; - void ScheduledActionInvalidateCompositorFrameSink() override; + void ScheduledActionInvalidateLayerTreeFrameSink() override; void ScheduledActionPerformImplSideInvalidation() override; void SendBeginMainFrameNotExpectedSoon() override; void ScheduledActionBeginMainFrameNotExpectedUntil( @@ -153,7 +156,7 @@ 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 + // A weak pointer to ProxyMain that is invalidated when LayerTreeFrameSink is // released. base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr_; diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc index 8632105c293..9ca0ce87d36 100644 --- a/chromium/cc/trees/proxy_main.cc +++ b/chromium/cc/trees/proxy_main.cc @@ -10,11 +10,10 @@ #include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" -#include "base/trace_event/trace_event_synthetic_delay.h" #include "cc/base/completion_event.h" #include "cc/base/devtools_instrumentation.h" #include "cc/benchmarks/benchmark_instrumentation.h" -#include "cc/output/compositor_frame_sink.h" +#include "cc/output/layer_tree_frame_sink.h" #include "cc/output/swap_promise.h" #include "cc/resources/ui_resource_manager.h" #include "cc/trees/blocking_task_runner.h" @@ -92,26 +91,26 @@ void ProxyMain::SetAnimationEvents(std::unique_ptr<MutatorEvents> events) { layer_tree_host_->SetAnimationEvents(std::move(events)); } -void ProxyMain::DidLoseCompositorFrameSink() { - TRACE_EVENT0("cc", "ProxyMain::DidLoseCompositorFrameSink"); +void ProxyMain::DidLoseLayerTreeFrameSink() { + TRACE_EVENT0("cc", "ProxyMain::DidLoseLayerTreeFrameSink"); DCHECK(IsMainThread()); - layer_tree_host_->DidLoseCompositorFrameSink(); + layer_tree_host_->DidLoseLayerTreeFrameSink(); } -void ProxyMain::RequestNewCompositorFrameSink() { - TRACE_EVENT0("cc", "ProxyMain::RequestNewCompositorFrameSink"); +void ProxyMain::RequestNewLayerTreeFrameSink() { + TRACE_EVENT0("cc", "ProxyMain::RequestNewLayerTreeFrameSink"); DCHECK(IsMainThread()); - layer_tree_host_->RequestNewCompositorFrameSink(); + layer_tree_host_->RequestNewLayerTreeFrameSink(); } -void ProxyMain::DidInitializeCompositorFrameSink(bool success) { - TRACE_EVENT0("cc", "ProxyMain::DidInitializeCompositorFrameSink"); +void ProxyMain::DidInitializeLayerTreeFrameSink(bool success) { + TRACE_EVENT0("cc", "ProxyMain::DidInitializeLayerTreeFrameSink"); DCHECK(IsMainThread()); if (!success) - layer_tree_host_->DidFailToInitializeCompositorFrameSink(); + layer_tree_host_->DidFailToInitializeLayerTreeFrameSink(); else - layer_tree_host_->DidInitializeCompositorFrameSink(); + layer_tree_host_->DidInitializeLayerTreeFrameSink(); } void ProxyMain::DidCompletePageScaleAnimation() { @@ -127,7 +126,6 @@ void ProxyMain::BeginMainFrame( base::TimeTicks begin_main_frame_start_time = base::TimeTicks::Now(); - TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("cc.BeginMainFrame"); DCHECK(IsMainThread()); DCHECK_EQ(NO_PIPELINE_STAGE, current_pipeline_stage_); @@ -214,22 +212,25 @@ void ProxyMain::BeginMainFrame( return; } - TRACE_EVENT_SYNTHETIC_DELAY_END("cc.BeginMainFrame"); - - bool can_cancel_this_commit = final_pipeline_stage_ < COMMIT_PIPELINE_STAGE && - !begin_main_frame_state->evicted_ui_resources; + // If UI resources were evicted on the impl thread, we need a commit. + if (begin_main_frame_state->evicted_ui_resources) + final_pipeline_stage_ = COMMIT_PIPELINE_STAGE; current_pipeline_stage_ = UPDATE_LAYERS_PIPELINE_STAGE; bool should_update_layers = final_pipeline_stage_ >= UPDATE_LAYERS_PIPELINE_STAGE; bool updated = should_update_layers && layer_tree_host_->UpdateLayers(); + // If updating the layers resulted in a content update, we need a commit. + if (updated) + final_pipeline_stage_ = COMMIT_PIPELINE_STAGE; + layer_tree_host_->WillCommit(); devtools_instrumentation::ScopedCommitTrace commit_task( layer_tree_host_->GetId()); current_pipeline_stage_ = COMMIT_PIPELINE_STAGE; - if (!updated && can_cancel_this_commit) { + if (final_pipeline_stage_ < COMMIT_PIPELINE_STAGE) { TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD); std::vector<std::unique_ptr<SwapPromise>> swap_promises = layer_tree_host_->GetSwapPromiseManager()->TakeSwapPromises(); @@ -292,12 +293,12 @@ bool ProxyMain::CommitToActiveTree() const { return false; } -void ProxyMain::SetCompositorFrameSink( - CompositorFrameSink* compositor_frame_sink) { +void ProxyMain::SetLayerTreeFrameSink( + LayerTreeFrameSink* layer_tree_frame_sink) { ImplThreadTaskRunner()->PostTask( FROM_HERE, - base::BindOnce(&ProxyImpl::InitializeCompositorFrameSinkOnImpl, - base::Unretained(proxy_impl_.get()), compositor_frame_sink, + base::BindOnce(&ProxyImpl::InitializeLayerTreeFrameSinkOnImpl, + base::Unretained(proxy_impl_.get()), layer_tree_frame_sink, frame_sink_bound_weak_factory_.GetWeakPtr())); } @@ -475,14 +476,14 @@ bool ProxyMain::MainFrameWillHappenForTesting() { return main_frame_will_happen; } -void ProxyMain::ReleaseCompositorFrameSink() { +void ProxyMain::ReleaseLayerTreeFrameSink() { DCHECK(IsMainThread()); frame_sink_bound_weak_factory_.InvalidateWeakPtrs(); DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); CompletionEvent completion; ImplThreadTaskRunner()->PostTask( FROM_HERE, - base::BindOnce(&ProxyImpl::ReleaseCompositorFrameSinkOnImpl, + base::BindOnce(&ProxyImpl::ReleaseLayerTreeFrameSinkOnImpl, base::Unretained(proxy_impl_.get()), &completion)); completion.Wait(); } @@ -497,6 +498,14 @@ void ProxyMain::UpdateBrowserControlsState(BrowserControlsState constraints, constraints, current, animate)); } +void ProxyMain::RequestBeginMainFrameNotExpected(bool new_state) { + DCHECK(IsMainThread()); + ImplThreadTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce(&ProxyImpl::RequestBeginMainFrameNotExpected, + base::Unretained(proxy_impl_.get()), new_state)); +} + bool ProxyMain::SendCommitRequestToImplThreadIfNeeded( CommitPipelineStage required_stage) { DCHECK(IsMainThread()); diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h index e4ab354345e..5007bb296a9 100644 --- a/chromium/cc/trees/proxy_main.h +++ b/chromium/cc/trees/proxy_main.h @@ -15,7 +15,7 @@ namespace cc { class MutatorEvents; class CompletionEvent; -class CompositorFrameSink; +class LayerTreeFrameSink; class LayerTreeHost; class LayerTreeMutator; class ProxyImpl; @@ -45,9 +45,9 @@ class CC_EXPORT ProxyMain : public Proxy { void BeginMainFrameNotExpectedUntil(base::TimeTicks time); void DidCommitAndDrawFrame(); void SetAnimationEvents(std::unique_ptr<MutatorEvents> events); - void DidLoseCompositorFrameSink(); - void RequestNewCompositorFrameSink(); - void DidInitializeCompositorFrameSink(bool success); + void DidLoseLayerTreeFrameSink(); + void RequestNewLayerTreeFrameSink(); + void DidInitializeLayerTreeFrameSink(bool success); void DidCompletePageScaleAnimation(); void BeginMainFrame( std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state); @@ -66,8 +66,8 @@ class CC_EXPORT ProxyMain : public Proxy { // Proxy implementation. bool IsStarted() const override; bool CommitToActiveTree() const override; - void SetCompositorFrameSink( - CompositorFrameSink* compositor_frame_sink) override; + void SetLayerTreeFrameSink( + LayerTreeFrameSink* layer_tree_frame_sink) override; void SetVisible(bool visible) override; void SetNeedsAnimate() override; void SetNeedsUpdateLayers() override; @@ -83,10 +83,11 @@ class CC_EXPORT ProxyMain : public Proxy { bool SupportsImplScrolling() const override; void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) override; bool MainFrameWillHappenForTesting() override; - void ReleaseCompositorFrameSink() override; + void ReleaseLayerTreeFrameSink() override; void UpdateBrowserControlsState(BrowserControlsState constraints, BrowserControlsState current, bool animate) override; + void RequestBeginMainFrameNotExpected(bool new_state) override; // Returns |true| if the request was actually sent, |false| if one was // already outstanding. @@ -131,7 +132,7 @@ class CC_EXPORT ProxyMain : public Proxy { std::unique_ptr<ProxyImpl> proxy_impl_; // WeakPtrs generated by this factory will be invalidated when - // CompositorFrameSink is released. + // LayerTreeFrameSink is released. base::WeakPtrFactory<ProxyMain> frame_sink_bound_weak_factory_; base::WeakPtrFactory<ProxyMain> weak_factory_; diff --git a/chromium/cc/trees/scroll_node.cc b/chromium/cc/trees/scroll_node.cc index 3c8bcf78d02..db5e6c2e5d0 100644 --- a/chromium/cc/trees/scroll_node.cc +++ b/chromium/cc/trees/scroll_node.cc @@ -15,7 +15,6 @@ namespace cc { ScrollNode::ScrollNode() : id(ScrollTree::kInvalidNodeId), parent_id(ScrollTree::kInvalidNodeId), - owning_layer_id(Layer::INVALID_ID), main_thread_scrolling_reasons( MainThreadScrollingReason::kNotScrollingOnMain), scrollable(false), @@ -25,18 +24,18 @@ ScrollNode::ScrollNode() should_flatten(false), user_scrollable_horizontal(false), user_scrollable_vertical(false), - transform_id(0) {} + transform_id(0), + scroll_boundary_behavior( + ScrollBoundaryBehavior::kScrollBoundaryBehaviorTypeAuto) {} ScrollNode::ScrollNode(const ScrollNode& other) = default; bool ScrollNode::operator==(const ScrollNode& other) const { return id == other.id && parent_id == other.parent_id && - owning_layer_id == other.owning_layer_id && scrollable == other.scrollable && main_thread_scrolling_reasons == other.main_thread_scrolling_reasons && non_fast_scrollable_region == other.non_fast_scrollable_region && - scroll_clip_layer_bounds == other.scroll_clip_layer_bounds && - bounds == other.bounds && + container_bounds == other.container_bounds && bounds == other.bounds && max_scroll_offset_affected_by_page_scale == other.max_scroll_offset_affected_by_page_scale && scrolls_inner_viewport == other.scrolls_inner_viewport && @@ -45,16 +44,15 @@ bool ScrollNode::operator==(const ScrollNode& other) const { should_flatten == other.should_flatten && user_scrollable_horizontal == other.user_scrollable_horizontal && user_scrollable_vertical == other.user_scrollable_vertical && - element_id == other.element_id && transform_id == other.transform_id; + element_id == other.element_id && transform_id == other.transform_id && + scroll_boundary_behavior == other.scroll_boundary_behavior; } void ScrollNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); - value->SetInteger("owning_layer_id", owning_layer_id); value->SetBoolean("scrollable", scrollable); - MathUtil::AddToTracedValue("scroll_clip_layer_bounds", - scroll_clip_layer_bounds, value); + MathUtil::AddToTracedValue("container_bounds", container_bounds, value); MathUtil::AddToTracedValue("bounds", bounds, value); MathUtil::AddToTracedValue("offset_to_transform_parent", offset_to_transform_parent, value); @@ -64,6 +62,8 @@ void ScrollNode::AsValueInto(base::trace_event::TracedValue* value) const { element_id.AddToTracedValue(value); value->SetInteger("transform_id", transform_id); + value->SetInteger("scroll_boundary_behavior_x", scroll_boundary_behavior.x); + value->SetInteger("scroll_boundary_behavior_y", scroll_boundary_behavior.y); } } // namespace cc diff --git a/chromium/cc/trees/scroll_node.h b/chromium/cc/trees/scroll_node.h index 43841bf2f15..d257aed7b87 100644 --- a/chromium/cc/trees/scroll_node.h +++ b/chromium/cc/trees/scroll_node.h @@ -8,6 +8,7 @@ #include "cc/base/filter_operations.h" #include "cc/base/region.h" #include "cc/cc_export.h" +#include "cc/input/scroll_boundary_behavior.h" #include "ui/gfx/geometry/size.h" namespace base { @@ -27,20 +28,15 @@ struct CC_EXPORT ScrollNode { // The node index of the parent node in the scroll tree node vector. int parent_id; - // The layer id that corresponds to the layer contents that are scrolled. - // Unlike |id|, this id is stable across frames that don't change the - // composited layer list. - int owning_layer_id; - uint32_t main_thread_scrolling_reasons; Region non_fast_scrollable_region; - // Size of the clipped area, not including non-overlay scrollbars. Overlay - // scrollbars do not affect the clipped area. - gfx::Size scroll_clip_layer_bounds; + // Size of the container area that the contents scrolls in, not including + // non-overlay scrollbars. Overlay scrollbars do not affect these bounds. + gfx::Size container_bounds; - // Bounds of the overflow scrolling area. + // Size of the content that is scrolled within the container bounds. gfx::Size bounds; // This is used for subtrees that should not be scrolled independently. For @@ -61,6 +57,8 @@ struct CC_EXPORT ScrollNode { ElementId element_id; int transform_id; + ScrollBoundaryBehavior scroll_boundary_behavior; + bool operator==(const ScrollNode& other) const; void AsValueInto(base::trace_event::TracedValue* value) const; }; diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index 1769c19fe60..39b09aaae4a 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -10,8 +10,7 @@ #include "base/trace_event/trace_event.h" #include "cc/base/devtools_instrumentation.h" #include "cc/benchmarks/benchmark_instrumentation.h" -#include "cc/output/compositor_frame_sink.h" -#include "cc/output/context_provider.h" +#include "cc/output/layer_tree_frame_sink.h" #include "cc/quads/draw_quad.h" #include "cc/resources/ui_resource_manager.h" #include "cc/scheduler/commit_earlyout_reason.h" @@ -24,6 +23,7 @@ #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/scoped_abort_remaining_swap_promises.h" +#include "components/viz/common/gpu/context_provider.h" namespace cc { @@ -50,8 +50,8 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, animate_requested_(false), commit_requested_(false), inside_synchronous_composite_(false), - compositor_frame_sink_creation_requested_(false), - compositor_frame_sink_lost_(true), + layer_tree_frame_sink_creation_requested_(false), + layer_tree_frame_sink_lost_(true), frame_sink_bound_weak_factory_(this), weak_factory_(this) { TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); @@ -113,49 +113,49 @@ void SingleThreadProxy::SetVisible(bool visible) { scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); } -void SingleThreadProxy::RequestNewCompositorFrameSink() { +void SingleThreadProxy::RequestNewLayerTreeFrameSink() { DCHECK(task_runner_provider_->IsMainThread()); - compositor_frame_sink_creation_callback_.Cancel(); - if (compositor_frame_sink_creation_requested_) + layer_tree_frame_sink_creation_callback_.Cancel(); + if (layer_tree_frame_sink_creation_requested_) return; - compositor_frame_sink_creation_requested_ = true; - layer_tree_host_->RequestNewCompositorFrameSink(); + layer_tree_frame_sink_creation_requested_ = true; + layer_tree_host_->RequestNewLayerTreeFrameSink(); } -void SingleThreadProxy::ReleaseCompositorFrameSink() { - compositor_frame_sink_lost_ = true; +void SingleThreadProxy::ReleaseLayerTreeFrameSink() { + layer_tree_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(); + scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink(); + return layer_tree_host_impl_->ReleaseLayerTreeFrameSink(); } -void SingleThreadProxy::SetCompositorFrameSink( - CompositorFrameSink* compositor_frame_sink) { +void SingleThreadProxy::SetLayerTreeFrameSink( + LayerTreeFrameSink* layer_tree_frame_sink) { DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(compositor_frame_sink_creation_requested_); + DCHECK(layer_tree_frame_sink_creation_requested_); bool success; { DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); DebugScopedSetImplThread impl(task_runner_provider_); - success = layer_tree_host_impl_->InitializeRenderer(compositor_frame_sink); + success = layer_tree_host_impl_->InitializeRenderer(layer_tree_frame_sink); } if (success) { frame_sink_bound_weak_ptr_ = frame_sink_bound_weak_factory_.GetWeakPtr(); - layer_tree_host_->DidInitializeCompositorFrameSink(); + layer_tree_host_->DidInitializeLayerTreeFrameSink(); if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidCreateAndInitializeCompositorFrameSink(); + scheduler_on_impl_thread_->DidCreateAndInitializeLayerTreeFrameSink(); else if (!inside_synchronous_composite_) SetNeedsCommit(); - compositor_frame_sink_creation_requested_ = false; - compositor_frame_sink_lost_ = false; + layer_tree_frame_sink_creation_requested_ = false; + layer_tree_frame_sink_lost_ = false; } else { - // DidFailToInitializeCompositorFrameSink is treated as a - // RequestNewCompositorFrameSink, and so - // compositor_frame_sink_creation_requested remains true. - layer_tree_host_->DidFailToInitializeCompositorFrameSink(); + // DidFailToInitializeLayerTreeFrameSink is treated as a + // RequestNewLayerTreeFrameSink, and so + // layer_tree_frame_sink_creation_requested remains true. + layer_tree_host_->DidFailToInitializeLayerTreeFrameSink(); } } @@ -207,12 +207,7 @@ void SingleThreadProxy::DoCommit() { if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidCommit(); - // Issue decode callbacks. - auto completed_decode_callbacks = - layer_tree_host_impl_->TakeCompletedImageDecodeCallbacks(); - for (auto& callback : completed_decode_callbacks) - callback.Run(); - + IssueImageDecodeFinishedCallbacks(); layer_tree_host_impl_->CommitComplete(); // Commit goes directly to the active tree, but we need to synchronously @@ -224,6 +219,15 @@ void SingleThreadProxy::DoCommit() { } } +void SingleThreadProxy::IssueImageDecodeFinishedCallbacks() { + DCHECK(task_runner_provider_->IsImplThread()); + + auto completed_decode_callbacks = + layer_tree_host_impl_->TakeCompletedImageDecodeCallbacks(); + for (auto& callback : completed_decode_callbacks) + callback.Run(); +} + void SingleThreadProxy::CommitComplete() { // Commit complete happens on the main side after activate to satisfy any // SetNextCommitWaitsForActivation calls. @@ -296,9 +300,9 @@ void SingleThreadProxy::Stop() { // inconsistent state. if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->Stop(); - // Take away the CompositorFrameSink before destroying things so it doesn't + // Take away the LayerTreeFrameSink before destroying things so it doesn't // try to call into its client mid-shutdown. - layer_tree_host_impl_->ReleaseCompositorFrameSink(); + layer_tree_host_impl_->ReleaseLayerTreeFrameSink(); scheduler_on_impl_thread_ = nullptr; layer_tree_host_impl_ = nullptr; } @@ -403,19 +407,19 @@ void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() { layer_tree_host_->DidCompletePageScaleAnimation(); } -void SingleThreadProxy::DidLoseCompositorFrameSinkOnImplThread() { +void SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread() { TRACE_EVENT0("cc", - "SingleThreadProxy::DidLoseCompositorFrameSinkOnImplThread"); + "SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread"); { DebugScopedSetMainThread main(task_runner_provider_); // This must happen before we notify the scheduler as it may try to recreate // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE. - layer_tree_host_->DidLoseCompositorFrameSink(); + layer_tree_host_->DidLoseLayerTreeFrameSink(); } - single_thread_client_->DidLoseCompositorFrameSink(); + single_thread_client_->DidLoseLayerTreeFrameSink(); if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidLoseCompositorFrameSink(); - compositor_frame_sink_lost_ = true; + scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink(); + layer_tree_frame_sink_lost_ = true; } void SingleThreadProxy::SetBeginFrameSource(BeginFrameSource* source) { @@ -436,7 +440,7 @@ void SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread() { frame_sink_bound_weak_ptr_)); } -void SingleThreadProxy::OnDrawForCompositorFrameSink( +void SingleThreadProxy::OnDrawForLayerTreeFrameSink( bool resourceless_software_draw) { NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor."; } @@ -446,6 +450,26 @@ void SingleThreadProxy::NeedsImplSideInvalidation() { scheduler_on_impl_thread_->SetNeedsImplSideInvalidation(); } +void SingleThreadProxy::NotifyImageDecodeRequestFinished() { + // If we don't have a scheduler, then just issue the callbacks here. + // Otherwise, schedule a commit. + if (!scheduler_on_impl_thread_) { + DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); + DebugScopedSetImplThread impl(task_runner_provider_); + + IssueImageDecodeFinishedCallbacks(); + return; + } + SetNeedsCommitOnImplThread(); +} + +void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) { + if (scheduler_on_impl_thread_) { + scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected( + new_state); + } +} + void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately"); DCHECK(task_runner_provider_->IsMainThread()); @@ -454,11 +478,11 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { #endif base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true); - if (compositor_frame_sink_lost_) { - RequestNewCompositorFrameSink(); - // RequestNewCompositorFrameSink could have synchronously created an output + if (layer_tree_frame_sink_lost_) { + RequestNewLayerTreeFrameSink(); + // RequestNewLayerTreeFrameSink could have synchronously created an output // surface, so check again before returning. - if (compositor_frame_sink_lost_) + if (layer_tree_frame_sink_lost_) return; } @@ -502,8 +526,7 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { LayerTreeHostImpl::FrameData frame; frame.begin_frame_ack = BeginFrameAck( - begin_frame_args.source_id, begin_frame_args.sequence_number, - begin_frame_args.sequence_number, true); + begin_frame_args.source_id, begin_frame_args.sequence_number, true); DoComposite(&frame); // DoComposite could abort, but because this is a synchronous composite @@ -524,14 +547,14 @@ bool SingleThreadProxy::ShouldComposite() const { return layer_tree_host_impl_->visible() && layer_tree_host_impl_->CanDraw(); } -void SingleThreadProxy::ScheduleRequestNewCompositorFrameSink() { - if (compositor_frame_sink_creation_callback_.IsCancelled() && - !compositor_frame_sink_creation_requested_) { - compositor_frame_sink_creation_callback_.Reset( - base::Bind(&SingleThreadProxy::RequestNewCompositorFrameSink, +void SingleThreadProxy::ScheduleRequestNewLayerTreeFrameSink() { + if (layer_tree_frame_sink_creation_callback_.IsCancelled() && + !layer_tree_frame_sink_creation_requested_) { + layer_tree_frame_sink_creation_callback_.Reset( + base::Bind(&SingleThreadProxy::RequestNewLayerTreeFrameSink, weak_factory_.GetWeakPtr())); task_runner_provider_->MainThreadTaskRunner()->PostTask( - FROM_HERE, compositor_frame_sink_creation_callback_.callback()); + FROM_HERE, layer_tree_frame_sink_creation_callback_.callback()); } } @@ -568,7 +591,7 @@ DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) { if (draw_frame) { if (layer_tree_host_impl_->DrawLayers(frame)) { if (scheduler_on_impl_thread_) - // Drawing implies we submitted a frame to the CompositorFrameSink. + // Drawing implies we submitted a frame to the LayerTreeFrameSink. scheduler_on_impl_thread_->DidSubmitCompositorFrame(); single_thread_client_->DidSubmitCompositorFrame(); } @@ -751,7 +774,7 @@ void SingleThreadProxy::ScheduledActionActivateSyncTree() { layer_tree_host_impl_->ActivateSyncTree(); } -void SingleThreadProxy::ScheduledActionBeginCompositorFrameSinkCreation() { +void SingleThreadProxy::ScheduledActionBeginLayerTreeFrameSinkCreation() { DebugScopedSetMainThread main(task_runner_provider_); DCHECK(scheduler_on_impl_thread_); // If possible, create the output surface in a post task. Synchronously @@ -759,9 +782,9 @@ void SingleThreadProxy::ScheduledActionBeginCompositorFrameSinkCreation() { // from the ThreadProxy behavior. However, sometimes there is no // task runner. if (task_runner_provider_->MainThreadTaskRunner()) { - ScheduleRequestNewCompositorFrameSink(); + ScheduleRequestNewLayerTreeFrameSink(); } else { - RequestNewCompositorFrameSink(); + RequestNewLayerTreeFrameSink(); } } @@ -771,7 +794,7 @@ void SingleThreadProxy::ScheduledActionPrepareTiles() { layer_tree_host_impl_->PrepareTiles(); } -void SingleThreadProxy::ScheduledActionInvalidateCompositorFrameSink() { +void SingleThreadProxy::ScheduledActionInvalidateLayerTreeFrameSink() { NOTREACHED(); } diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h index 54842c41bf2..6bbe3cf0be0 100644 --- a/chromium/cc/trees/single_thread_proxy.h +++ b/chromium/cc/trees/single_thread_proxy.h @@ -37,9 +37,9 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // Proxy implementation bool IsStarted() const override; bool CommitToActiveTree() const override; - void SetCompositorFrameSink( - CompositorFrameSink* compositor_frame_sink) override; - void ReleaseCompositorFrameSink() override; + void SetLayerTreeFrameSink( + LayerTreeFrameSink* layer_tree_frame_sink) override; + void ReleaseLayerTreeFrameSink() override; void SetVisible(bool visible) override; void SetNeedsAnimate() override; void SetNeedsUpdateLayers() override; @@ -68,16 +68,16 @@ class CC_EXPORT SingleThreadProxy : public Proxy, DrawResult ScheduledActionDrawForced() override; void ScheduledActionCommit() override; void ScheduledActionActivateSyncTree() override; - void ScheduledActionBeginCompositorFrameSinkCreation() override; + void ScheduledActionBeginLayerTreeFrameSinkCreation() override; void ScheduledActionPrepareTiles() override; - void ScheduledActionInvalidateCompositorFrameSink() override; + void ScheduledActionInvalidateLayerTreeFrameSink() override; void ScheduledActionPerformImplSideInvalidation() override; void SendBeginMainFrameNotExpectedSoon() override; void ScheduledActionBeginMainFrameNotExpectedUntil( base::TimeTicks time) override; // LayerTreeHostImplClient implementation - void DidLoseCompositorFrameSinkOnImplThread() override; + void DidLoseLayerTreeFrameSinkOnImplThread() override; void SetBeginFrameSource(BeginFrameSource* source) override; void DidReceiveCompositorFrameAckOnImplThread() override; void OnCanDrawStateChanged(bool can_draw) override; @@ -98,10 +98,12 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void WillPrepareTiles() override; void DidPrepareTiles() override; void DidCompletePageScaleAnimationOnImplThread() override; - void OnDrawForCompositorFrameSink(bool resourceless_software_draw) override; + void OnDrawForLayerTreeFrameSink(bool resourceless_software_draw) override; void NeedsImplSideInvalidation() override; + void RequestBeginMainFrameNotExpected(bool new_state) override; + void NotifyImageDecodeRequestFinished() override; - void RequestNewCompositorFrameSink(); + void RequestNewLayerTreeFrameSink(); // Called by the legacy path where RenderWidget does the scheduling. void CompositeImmediately(base::TimeTicks frame_begin_time); @@ -123,7 +125,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void CommitComplete(); bool ShouldComposite() const; - void ScheduleRequestNewCompositorFrameSink(); + void ScheduleRequestNewLayerTreeFrameSink(); + void IssueImageDecodeFinishedCallbacks(); void DidReceiveCompositorFrameAck(); @@ -155,18 +158,18 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // True if a request to the LayerTreeHostClient to create an output surface // is still outstanding. - bool compositor_frame_sink_creation_requested_; + bool layer_tree_frame_sink_creation_requested_; // When output surface is lost, is set to true until a new output surface is // initialized. - bool compositor_frame_sink_lost_; + bool layer_tree_frame_sink_lost_; - // This is the callback for the scheduled RequestNewCompositorFrameSink. - base::CancelableClosure compositor_frame_sink_creation_callback_; + // This is the callback for the scheduled RequestNewLayerTreeFrameSink. + base::CancelableClosure layer_tree_frame_sink_creation_callback_; base::WeakPtr<SingleThreadProxy> frame_sink_bound_weak_ptr_; // WeakPtrs generated by this factory will be invalidated when - // CompositorFrameSink is released. + // LayerTreeFrameSink is released. base::WeakPtrFactory<SingleThreadProxy> frame_sink_bound_weak_factory_; base::WeakPtrFactory<SingleThreadProxy> weak_factory_; diff --git a/chromium/cc/trees/target_property.cc b/chromium/cc/trees/target_property.cc index cabff92b5a5..ee81147088e 100644 --- a/chromium/cc/trees/target_property.cc +++ b/chromium/cc/trees/target_property.cc @@ -15,7 +15,8 @@ static_assert(TargetProperty::FIRST_TARGET_PROPERTY == 0, // This should match the TargetProperty enum. static const char* const s_targetPropertyNames[] = { - "TRANSFORM", "OPACITY", "FILTER", "SCROLL_OFFSET", "BACKGROUND_COLOR"}; + "TRANSFORM", "OPACITY", "FILTER", "SCROLL_OFFSET", + "BACKGROUND_COLOR", "BOUNDS", "VISIBILITY"}; static_assert(static_cast<int>(TargetProperty::LAST_TARGET_PROPERTY) + 1 == arraysize(s_targetPropertyNames), diff --git a/chromium/cc/trees/target_property.h b/chromium/cc/trees/target_property.h index 177ef965afa..535459865d2 100644 --- a/chromium/cc/trees/target_property.h +++ b/chromium/cc/trees/target_property.h @@ -19,9 +19,11 @@ enum Type { FILTER, SCROLL_OFFSET, BACKGROUND_COLOR, + BOUNDS, + VISIBILITY, // These sentinels must be last FIRST_TARGET_PROPERTY = TRANSFORM, - LAST_TARGET_PROPERTY = BACKGROUND_COLOR + LAST_TARGET_PROPERTY = VISIBILITY, }; CC_EXPORT const char* GetName(TargetProperty::Type property); diff --git a/chromium/cc/trees/transform_node.cc b/chromium/cc/trees/transform_node.cc index 6f89261dd29..044975f2e36 100644 --- a/chromium/cc/trees/transform_node.cc +++ b/chromium/cc/trees/transform_node.cc @@ -14,7 +14,6 @@ namespace cc { TransformNode::TransformNode() : id(TransformTree::kInvalidNodeId), parent_id(TransformTree::kInvalidNodeId), - owning_layer_id(Layer::INVALID_ID), sticky_position_constraint_id(-1), source_node_id(TransformTree::kInvalidNodeId), sorting_context_id(0), @@ -43,9 +42,9 @@ TransformNode::TransformNode(const TransformNode&) = default; bool TransformNode::operator==(const TransformNode& other) const { return id == other.id && parent_id == other.parent_id && - owning_layer_id == other.owning_layer_id && - pre_local == other.pre_local && local == other.local && - post_local == other.post_local && to_parent == other.to_parent && + element_id == other.element_id && pre_local == other.pre_local && + local == other.local && post_local == other.post_local && + to_parent == other.to_parent && source_node_id == other.source_node_id && sorting_context_id == other.sorting_context_id && needs_local_transform_update == other.needs_local_transform_update && @@ -104,7 +103,7 @@ void TransformNode::update_post_local_transform( void TransformNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); - value->SetInteger("owning_layer_id", owning_layer_id); + value->SetInteger("element_id", element_id.id_); MathUtil::AddToTracedValue("pre_local", pre_local, value); MathUtil::AddToTracedValue("local", local, value); MathUtil::AddToTracedValue("post_local", post_local, value); diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h index 2abfb1cc004..931867550f8 100644 --- a/chromium/cc/trees/transform_node.h +++ b/chromium/cc/trees/transform_node.h @@ -26,8 +26,8 @@ struct CC_EXPORT TransformNode { int id; // The node index of the parent node in the transform tree node vector. int parent_id; - // The layer id of the layer that owns this node. - int owning_layer_id; + + ElementId element_id; // The local transform information is combined to form to_parent (ignoring // snapping) as follows: diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc index 1def71a2b67..daf588806b2 100644 --- a/chromium/cc/trees/tree_synchronizer_unittest.cc +++ b/chromium/cc/trees/tree_synchronizer_unittest.cc @@ -494,22 +494,17 @@ TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) { host_impl->CreatePendingTree(); scoped_refptr<Layer> layer_tree_root = Layer::Create(); - scoped_refptr<Layer> scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> scroll_layer = Layer::Create(); - scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> transient_scroll_layer = Layer::Create(); - layer_tree_root->AddChild(transient_scroll_clip_layer); - transient_scroll_clip_layer->AddChild(transient_scroll_layer); - transient_scroll_layer->AddChild(scroll_clip_layer); - scroll_clip_layer->AddChild(scroll_layer); + layer_tree_root->AddChild(transient_scroll_layer); + transient_scroll_layer->AddChild(scroll_layer); ElementId scroll_element_id = ElementId(5); scroll_layer->SetElementId(scroll_element_id); - transient_scroll_layer->SetScrollClipLayerId( - transient_scroll_clip_layer->id()); - scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id()); + transient_scroll_layer->SetScrollable(gfx::Size(1, 1)); + scroll_layer->SetScrollable(gfx::Size(1, 1)); host_->SetRootLayer(layer_tree_root); host_->BuildPropertyTreesForTesting(); host_->CommitAndCreatePendingTree(); @@ -523,7 +518,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) { host_impl->active_tree()->property_trees()->scroll_tree.Node( scroll_layer->scroll_tree_index()); host_impl->active_tree()->SetCurrentlyScrollingNode(scroll_node); - transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID); + transient_scroll_layer->SetScrollable(gfx::Size(0, 0)); host_->BuildPropertyTreesForTesting(); host_impl->CreatePendingTree(); @@ -546,22 +541,20 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) { host_impl->CreatePendingTree(); scoped_refptr<Layer> layer_tree_root = Layer::Create(); - scoped_refptr<Layer> scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> scroll_layer = Layer::Create(); - scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> transient_scroll_layer = Layer::Create(); ElementId scroll_element_id = ElementId(5); scroll_layer->SetElementId(scroll_element_id); - layer_tree_root->AddChild(transient_scroll_clip_layer); - transient_scroll_clip_layer->AddChild(transient_scroll_layer); - transient_scroll_layer->AddChild(scroll_clip_layer); - scroll_clip_layer->AddChild(scroll_layer); + layer_tree_root->AddChild(transient_scroll_layer); + transient_scroll_layer->AddChild(scroll_layer); - transient_scroll_layer->SetScrollClipLayerId( - transient_scroll_clip_layer->id()); - scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id()); + ElementId transient_scroll_element_id = ElementId(7); + transient_scroll_layer->SetElementId(transient_scroll_element_id); + + transient_scroll_layer->SetScrollable(gfx::Size(1, 1)); + scroll_layer->SetScrollable(gfx::Size(1, 1)); transient_scroll_layer->SetScrollOffset(gfx::ScrollOffset(1, 2)); scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20)); @@ -585,43 +578,45 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) { scroll_layer_offset.get(), host_impl->active_tree() ->property_trees() - ->scroll_tree.GetSyncedScrollOffset(scroll_layer->id()))); + ->scroll_tree.GetSyncedScrollOffset(scroll_layer->element_id()))); scoped_refptr<SyncedScrollOffset> transient_scroll_layer_offset = new SyncedScrollOffset; transient_scroll_layer_offset->PushFromMainThread( transient_scroll_layer->scroll_offset()); transient_scroll_layer_offset->PushPendingToActive(); - EXPECT_TRUE(AreScrollOffsetsEqual( - transient_scroll_layer_offset.get(), - host_impl->active_tree() - ->property_trees() - ->scroll_tree.GetSyncedScrollOffset(transient_scroll_layer->id()))); + EXPECT_TRUE( + AreScrollOffsetsEqual(transient_scroll_layer_offset.get(), + host_impl->active_tree() + ->property_trees() + ->scroll_tree.GetSyncedScrollOffset( + transient_scroll_layer->element_id()))); // Set ScrollOffset active delta: gfx::ScrollOffset(10, 10) LayerImpl* scroll_layer_impl = host_impl->active_tree()->LayerById(scroll_layer->id()); ScrollTree& scroll_tree = host_impl->active_tree()->property_trees()->scroll_tree; - scroll_tree.SetScrollOffset(scroll_layer_impl->id(), + scroll_tree.SetScrollOffset(scroll_layer_impl->element_id(), gfx::ScrollOffset(20, 30)); // Pull ScrollOffset delta for main thread, and change offset on main thread std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); - scroll_tree.CollectScrollDeltas(scroll_info.get(), Layer::INVALID_ID); + scroll_tree.CollectScrollDeltas(scroll_info.get(), ElementId()); host_->proxy()->SetNeedsCommit(); host_->ApplyScrollAndScale(scroll_info.get()); EXPECT_EQ(gfx::ScrollOffset(20, 30), scroll_layer->scroll_offset()); scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 100)); // More update to ScrollOffset active delta: gfx::ScrollOffset(20, 20) - scroll_tree.SetScrollOffset(scroll_layer_impl->id(), + scroll_tree.SetScrollOffset(scroll_layer_impl->element_id(), gfx::ScrollOffset(40, 50)); host_impl->active_tree()->SetCurrentlyScrollingNode( scroll_tree.Node(scroll_layer_impl->scroll_tree_index())); - // Make one layer unscrollable so that scroll tree topology changes - transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID); + // Change the scroll tree topology by removing transient_scroll_layer. + transient_scroll_layer->RemoveFromParent(); + layer_tree_root->AddChild(scroll_layer); host_->BuildPropertyTreesForTesting(); host_impl->CreatePendingTree(); @@ -639,11 +634,11 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) { scroll_layer_offset.get(), host_impl->active_tree() ->property_trees() - ->scroll_tree.GetSyncedScrollOffset(scroll_layer->id()))); + ->scroll_tree.GetSyncedScrollOffset(scroll_layer->element_id()))); EXPECT_EQ(nullptr, host_impl->active_tree() ->property_trees() ->scroll_tree.GetSyncedScrollOffset( - transient_scroll_layer->id())); + transient_scroll_layer->element_id())); } TEST_F(TreeSynchronizerTest, RefreshPropertyTreesCachedData) { |