diff options
author | sunxd <sunxd@chromium.org> | 2016-01-11 13:01:02 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-11 21:02:26 +0000 |
commit | ed58688e7629fa3c56470a241bc758fb5fabf081 (patch) | |
tree | f6ff71f020fca9532faa6c66548894fa126cd900 | |
parent | 41a523c0dbdf29bf1353036e35004cb35c345b17 (diff) | |
download | chromium_src-ed58688e7629fa3c56470a241bc758fb5fabf081.zip chromium_src-ed58688e7629fa3c56470a241bc758fb5fabf081.tar.gz chromium_src-ed58688e7629fa3c56470a241bc758fb5fabf081.tar.bz2 |
cc: Use effect tree to track the number of copy requests
Move num_layer_or_descendants_with_copy_requestfrom layer_tree to
effect_tree.
This update introduces false positives to the variable:
if a layer owns no effect node, it returns the value of its nearest
ancestor who owns a effect node.
BUG=574192
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1566913004
Cr-Commit-Position: refs/heads/master@{#368664}
-rw-r--r-- | cc/layers/layer.cc | 39 | ||||
-rw-r--r-- | cc/layers/layer.h | 14 | ||||
-rw-r--r-- | cc/layers/layer_impl.cc | 11 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 10 | ||||
-rw-r--r-- | cc/layers/layer_unittest.cc | 4 | ||||
-rw-r--r-- | cc/proto/property_tree.proto | 5 | ||||
-rw-r--r-- | cc/trees/draw_property_utils.cc | 4 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_common.cc | 6 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_common_unittest.cc | 64 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 5 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 22 | ||||
-rw-r--r-- | cc/trees/layer_tree_impl.cc | 12 | ||||
-rw-r--r-- | cc/trees/property_tree.cc | 9 | ||||
-rw-r--r-- | cc/trees/property_tree.h | 4 | ||||
-rw-r--r-- | cc/trees/property_tree_builder.cc | 45 |
16 files changed, 152 insertions, 103 deletions
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 9d82b58..9fa2731 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -65,7 +65,6 @@ Layer::Layer(const LayerSettings& settings) effect_tree_index_(-1), clip_tree_index_(-1), property_tree_sequence_number_(-1), - num_layer_or_descendants_with_copy_request_(0), element_id_(0), mutable_properties_(kMutablePropertyNone), should_flatten_transform_from_property_tree_(false), @@ -272,15 +271,7 @@ void Layer::SetParent(Layer* layer) { layer->AddDependentNeedsPushProperties(); } - if (parent_) { - parent_->UpdateNumCopyRequestsForSubtree( - -num_layer_or_descendants_with_copy_request_); - } parent_ = layer; - if (parent_) { - parent_->UpdateNumCopyRequestsForSubtree( - num_layer_or_descendants_with_copy_request_); - } SetLayerTreeHost(parent_ ? parent_->layer_tree_host() : nullptr); if (!layer_tree_host_) @@ -422,7 +413,6 @@ bool Layer::HasAncestor(const Layer* ancestor) const { void Layer::RequestCopyOfOutput( scoped_ptr<CopyOutputRequest> request) { DCHECK(IsPropertyChangeAllowed()); - bool had_no_copy_requests = copy_requests_.empty(); if (void* source = request->source()) { auto it = std::find_if(copy_requests_.begin(), copy_requests_.end(), [source](const scoped_ptr<CopyOutputRequest>& x) { @@ -434,22 +424,9 @@ void Layer::RequestCopyOfOutput( if (request->IsEmpty()) return; copy_requests_.push_back(std::move(request)); - if (had_no_copy_requests) { - UpdateNumCopyRequestsForSubtree(1); - } SetNeedsCommit(); } -void Layer::UpdateNumCopyRequestsForSubtree(int delta) { - if (!delta) - return; - for (Layer* layer = this; layer; layer = layer->parent()) { - layer->num_layer_or_descendants_with_copy_request_ += delta; - layer->SetNeedsPushProperties(); - DCHECK_GE(layer->num_layer_or_descendants_with_copy_request_, 0); - } -} - void Layer::SetBackgroundColor(SkColor background_color) { DCHECK(IsPropertyChangeAllowed()); if (background_color_ == background_color) @@ -1238,8 +1215,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetShouldFlattenTransform(should_flatten_transform_); layer->set_should_flatten_transform_from_property_tree( should_flatten_transform_from_property_tree_); - layer->set_num_layer_or_descendant_with_copy_request( - num_layer_or_descendants_with_copy_request_); layer->set_draw_blend_mode(draw_blend_mode_); layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); if (!layer->TransformIsAnimatingOnImplOnly() && !TransformIsAnimating()) @@ -1311,7 +1286,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetScrollCompensationAdjustment(ScrollCompensationAdjustment()); // Wrap the copy_requests_ in a PostTask to the main thread. - bool had_copy_requests = !copy_requests_.empty(); std::vector<scoped_ptr<CopyOutputRequest>> main_thread_copy_requests; for (auto it = copy_requests_.begin(); it != copy_requests_.end(); ++it) { scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner = @@ -1328,8 +1302,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { } if (!copy_requests_.empty() && layer_tree_host_) layer_tree_host_->property_trees()->needs_rebuild = true; - if (had_copy_requests) - UpdateNumCopyRequestsForSubtree(-1); copy_requests_.clear(); layer->PassCopyRequests(&main_thread_copy_requests); @@ -1512,8 +1484,6 @@ void Layer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto) { base->set_should_flatten_transform(should_flatten_transform_); base->set_should_flatten_transform_from_property_tree( should_flatten_transform_from_property_tree_); - base->set_num_layer_or_descendants_with_copy_request( - num_layer_or_descendants_with_copy_request_); base->set_draw_blend_mode(SkXfermodeModeToProto(draw_blend_mode_)); base->set_use_parent_backface_visibility(use_parent_backface_visibility_); TransformToProto(transform_, base->mutable_transform()); @@ -1600,8 +1570,6 @@ void Layer::FromLayerSpecificPropertiesProto( should_flatten_transform_ = base.should_flatten_transform(); should_flatten_transform_from_property_tree_ = base.should_flatten_transform_from_property_tree(); - num_layer_or_descendants_with_copy_request_ = - base.num_layer_or_descendants_with_copy_request(); draw_blend_mode_ = SkXfermodeModeFromProto(base.draw_blend_mode()); use_parent_backface_visibility_ = base.use_parent_backface_visibility(); transform_ = ProtoToTransform(base.transform()); @@ -2001,6 +1969,13 @@ void Layer::DidBeginTracing() { SetNeedsPushProperties(); } +int Layer::num_copy_requests_in_target_subtree() { + return layer_tree_host() + ->property_trees() + ->effect_tree.Node(effect_tree_index()) + ->data.num_copy_requests_in_subtree; +} + void Layer::set_visited(bool visited) { visited_tracker_ = visited ? layer_tree_host()->meta_information_sequence_number() : 0; diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 7dfe6d0..ef5da33 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h @@ -543,15 +543,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, } void DidBeginTracing(); - // TODO(weiliangc): this should move to the effect tree. - void set_num_layer_or_descendant_with_copy_request( - int num_layer_or_descendants_with_copy_request) { - num_layer_or_descendants_with_copy_request_ = - num_layer_or_descendants_with_copy_request; - } - int num_layer_or_descendants_with_copy_request() { - return num_layer_or_descendants_with_copy_request_; - } + + int num_copy_requests_in_target_subtree(); void SetElementId(uint64_t id); uint64_t element_id() const { return element_id_; } @@ -703,8 +696,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, // indices becomes invalid. void InvalidatePropertyTreesIndices(); - void UpdateNumCopyRequestsForSubtree(int delta); - LayerList children_; Layer* parent_; @@ -729,7 +720,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, int effect_tree_index_; int clip_tree_index_; int property_tree_sequence_number_; - int num_layer_or_descendants_with_copy_request_; uint64_t element_id_; uint32_t mutable_properties_; gfx::Vector2dF offset_to_transform_parent_; diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 93d45a9..b845968 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -94,7 +94,6 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, element_id_(0), mutable_properties_(kMutablePropertyNone), force_render_surface_(false), - num_layer_or_descendants_with_copy_request_(0), frame_timing_requests_dirty_(false), visited_(false), layer_or_descendant_is_drawn_(false), @@ -687,9 +686,6 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetStackingOrderChanged(stacking_order_changed_); layer->SetDebugInfo(debug_info_); - layer->set_num_layer_or_descendant_with_copy_request( - num_layer_or_descendants_with_copy_request_); - set_num_layer_or_descendant_with_copy_request(0); if (frame_timing_requests_dirty_) { layer->SetFrameTimingRequests(frame_timing_requests_); @@ -849,6 +845,13 @@ void LayerImpl::ResetAllChangeTrackingForSubtree() { num_dependents_need_push_properties_ = 0; } +int LayerImpl::num_copy_requests_in_target_subtree() { + return layer_tree_impl() + ->property_trees() + ->effect_tree.Node(effect_tree_index()) + ->data.num_copy_requests_in_subtree; +} + void LayerImpl::UpdatePropertyTreeTransform() { if (transform_tree_index_ != -1) { TransformTree& transform_tree = diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index baccc5d..990a384 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -677,14 +677,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, } bool sorted_for_recursion() { return sorted_for_recursion_; } - void set_num_layer_or_descendant_with_copy_request( - int num_layer_or_descendants_with_copy_request) { - num_layer_or_descendants_with_copy_request_ = - num_layer_or_descendants_with_copy_request; - } - int num_layer_or_descendants_with_copy_request() { - return num_layer_or_descendants_with_copy_request_; - } + int num_copy_requests_in_target_subtree(); void UpdatePropertyTreeForScrollingAndAnimationIfNeeded(); @@ -893,7 +886,6 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, bool force_render_surface_; std::vector<FrameTimingRequest> frame_timing_requests_; - int num_layer_or_descendants_with_copy_request_; bool frame_timing_requests_dirty_; bool visited_; bool layer_or_descendant_is_drawn_; diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index bea4393..f73cb25 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc @@ -154,8 +154,6 @@ class LayerSerializationTest : public testing::Test { EXPECT_EQ(src->should_flatten_transform_, dest->should_flatten_transform_); EXPECT_EQ(src->should_flatten_transform_from_property_tree_, dest->should_flatten_transform_from_property_tree_); - EXPECT_EQ(src->num_layer_or_descendants_with_copy_request_, - dest->num_layer_or_descendants_with_copy_request_); EXPECT_EQ(src->draw_blend_mode_, dest->draw_blend_mode_); EXPECT_EQ(src->use_parent_backface_visibility_, dest->use_parent_backface_visibility_); @@ -268,7 +266,6 @@ class LayerSerializationTest : public testing::Test { layer->position_constraint_ = pos_con; layer->should_flatten_transform_ = true; layer->should_flatten_transform_from_property_tree_ = true; - layer->num_layer_or_descendants_with_copy_request_ = 19; layer->draw_blend_mode_ = SkXfermode::kSrcOut_Mode; layer->use_parent_backface_visibility_ = true; gfx::Transform transform; @@ -322,7 +319,6 @@ class LayerSerializationTest : public testing::Test { layer->should_flatten_transform_ = !layer->should_flatten_transform_; layer->should_flatten_transform_from_property_tree_ = !layer->should_flatten_transform_from_property_tree_; - layer->num_layer_or_descendants_with_copy_request_ = 19; layer->draw_blend_mode_ = SkXfermode::kSrcOut_Mode; layer->use_parent_backface_visibility_ = !layer->use_parent_backface_visibility_; diff --git a/cc/proto/property_tree.proto b/cc/proto/property_tree.proto index 972c0c9..7f1b996 100644 --- a/cc/proto/property_tree.proto +++ b/cc/proto/property_tree.proto @@ -81,8 +81,9 @@ message EffectNodeData { optional float opacity = 1; optional float screen_space_opacity = 2; optional bool has_render_surface = 3; - optional int64 transform_id = 4; - optional int64 clip_id = 5; + optional int64 num_copy_requests_in_subtree = 4; + optional int64 transform_id = 5; + optional int64 clip_id = 6; } // This defines the proto used for all types of struct TreeNode. diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index 2d79a5e..07270db 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc @@ -309,7 +309,7 @@ static inline bool SubtreeShouldBeSkipped(LayerImpl* layer, // When we need to do a readback/copy of a layer's output, we can not skip // it or any of its ancestors. - if (layer->num_layer_or_descendants_with_copy_request() > 0) + if (layer->num_copy_requests_in_target_subtree() > 0) return false; // We cannot skip the the subtree if a descendant has a wheel or touch handler @@ -357,7 +357,7 @@ static inline bool SubtreeShouldBeSkipped(Layer* layer, // When we need to do a readback/copy of a layer's output, we can not skip // it or any of its ancestors. - if (layer->num_layer_or_descendants_with_copy_request() > 0) + if (layer->num_copy_requests_in_target_subtree() > 0) return false; // If the layer is not drawn, then skip it and its subtree. diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index c1e3d10..8f66145 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc @@ -595,7 +595,7 @@ static inline bool SubtreeShouldBeSkipped(LayerImpl* layer, // When we need to do a readback/copy of a layer's output, we can not skip // it or any of its ancestors. - if (layer->num_layer_or_descendants_with_copy_request() > 0) + if (layer->num_copy_requests_in_target_subtree() > 0) return false; // We cannot skip the the subtree if a descendant has a wheel or touch handler @@ -1088,8 +1088,6 @@ static void PreCalculateMetaInformationInternal( layer->set_num_unclipped_descendants( recursive_data->num_unclipped_descendants); - layer->set_num_layer_or_descendant_with_copy_request( - recursive_data->num_layer_or_descendants_with_copy_request); if (IsRootLayer(layer)) layer->layer_tree_host()->SetNeedsMetaInfoRecomputation(false); @@ -1142,8 +1140,6 @@ static void PreCalculateMetaInformationInternal( (recursive_data->num_layer_or_descendants_with_input_handler != 0)); // TODO(enne): this should be synced from the main thread, so is only // for tests constructing layers on the compositor thread. - layer->set_num_layer_or_descendant_with_copy_request( - recursive_data->num_layer_or_descendants_with_copy_request); layer->SetNumDescendantsThatDrawContent( recursive_data->num_descendants_that_draw_content); diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index e729ec3..495b4c8 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc @@ -5507,18 +5507,10 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); - EXPECT_GT(root->num_layer_or_descendants_with_copy_request(), 0); - EXPECT_GT( - copy_grand_parent_layer->num_layer_or_descendants_with_copy_request(), 0); - EXPECT_GT(copy_parent_layer->num_layer_or_descendants_with_copy_request(), 0); - EXPECT_GT(copy_layer->num_layer_or_descendants_with_copy_request(), 0); - EXPECT_EQ(copy_child_layer->num_layer_or_descendants_with_copy_request(), 0); - EXPECT_EQ(copy_grand_parent_sibling_before_layer - ->num_layer_or_descendants_with_copy_request(), - 0); - EXPECT_EQ(copy_grand_parent_sibling_after_layer - ->num_layer_or_descendants_with_copy_request(), - 0); + EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0); + EXPECT_GT(copy_grand_parent_layer->num_copy_requests_in_target_subtree(), 0); + EXPECT_GT(copy_parent_layer->num_copy_requests_in_target_subtree(), 0); + EXPECT_GT(copy_layer->num_copy_requests_in_target_subtree(), 0); // We should have three render surfaces, one for the root, one for the parent // since it owns a surface, and one for the copy_layer. @@ -8572,6 +8564,40 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { } +TEST_F(LayerTreeHostCommonTest, NumCopyRequestsInTargetSubtree) { + // If the layer has a node in effect_tree, the return value of + // num_copy_requests_in_target_subtree() must be equal to the actual number + // of copy requests in the sub-layer_tree; Otherwise, the number is expected + // to be the value of its nearest ancestor that owns an effect node and + // greater than or equal to the actual number of copy requests in the + // sub-layer_tree. + + scoped_refptr<Layer> root = Layer::Create(layer_settings()); + scoped_refptr<Layer> child1 = Layer::Create(layer_settings()); + scoped_refptr<Layer> child2 = Layer::Create(layer_settings()); + scoped_refptr<Layer> grandchild = Layer::Create(layer_settings()); + scoped_refptr<Layer> greatgrandchild = Layer::Create(layer_settings()); + + root->AddChild(child1); + root->AddChild(child2); + child1->AddChild(grandchild); + grandchild->AddChild(greatgrandchild); + host()->SetRootLayer(root); + + child1->RequestCopyOfOutput( + CopyOutputRequest::CreateBitmapRequest(base::Bind(&CopyOutputCallback))); + greatgrandchild->RequestCopyOfOutput( + CopyOutputRequest::CreateBitmapRequest(base::Bind(&CopyOutputCallback))); + child2->SetOpacity(0.f); + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + + EXPECT_EQ(root->num_copy_requests_in_target_subtree(), 2); + EXPECT_EQ(child1->num_copy_requests_in_target_subtree(), 2); + EXPECT_EQ(child2->num_copy_requests_in_target_subtree(), 0); + EXPECT_EQ(grandchild->num_copy_requests_in_target_subtree(), 2); + EXPECT_EQ(greatgrandchild->num_copy_requests_in_target_subtree(), 1); +} + TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { gfx::Transform identity; scoped_refptr<Layer> root = Layer::Create(layer_settings()); @@ -8757,6 +8783,7 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeImpl) { requests.push_back(CopyOutputRequest::CreateEmptyRequest()); greatgrandchild_ptr->PassCopyRequests(&requests); + root.get()->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_rect_from_property_trees()); @@ -8828,14 +8855,15 @@ TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) { host()->SetRootLayer(root); - ExecuteCalculateDrawProperties(root.get()); - EXPECT_EQ(parent->num_unclipped_descendants(), 1u); - child->RequestCopyOfOutput( CopyOutputRequest::CreateRequest(base::Bind(&EmptyCopyOutputCallback))); - EXPECT_GT(root->num_layer_or_descendants_with_copy_request(), 0); - ExecuteCalculateDrawProperties(root.get()); - EXPECT_GT(root->num_layer_or_descendants_with_copy_request(), 0); + + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + EXPECT_EQ(parent->num_unclipped_descendants(), 1u); + + EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0); + ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get()); + EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0); } TEST_F(LayerTreeHostCommonTest, InputHandlersRecursiveUpdateTest) { diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index c12e299..2399289 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -860,10 +860,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( // clear all of the copy request flags so that sanity checks for the counts // succeed. if (!active_tree_->LayersWithCopyOutputRequest().empty()) { - LayerTreeHostCommon::CallFunctionForSubtree( - active_tree_->root_layer(), [](LayerImpl* layer) { - layer->set_num_layer_or_descendant_with_copy_request(0); - }); + active_tree()->property_trees()->effect_tree.ClearCopyRequests(); } // Grab this region here before iterating layers. Taking copy requests from diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 4c39390..8fa0ac3 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -7211,7 +7211,6 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { LayerImpl* root = host_impl_->active_tree()->root_layer(); root->PassCopyRequests(&requests); - root->set_num_layer_or_descendant_with_copy_request(1); LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame)); diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 5bc8f18..62c6206 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -5902,15 +5902,33 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest { void BeginTest() override { PostSetNeedsCommitToMainThread(); } + void WillCommit() override { + switch (layer_tree_host()->source_frame_number()) { + case 1: + EXPECT_GT(root->num_copy_requests_in_target_subtree(), 0); + break; + } + } + void DidCommit() override { + gfx::Transform transform; switch (layer_tree_host()->source_frame_number()) { case 1: child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( base::Bind(CopyOutputCallback))); - EXPECT_GT(root->num_layer_or_descendants_with_copy_request(), 0); + transform.Scale(2.0, 2.0); + child->SetTransform(transform); break; case 2: - EXPECT_EQ(root->num_layer_or_descendants_with_copy_request(), 0); + // By changing the scale of a layer which already owns a transform node, + // a commit will be triggered but a property tree rebuild will not, this + // is used to test sure that clearing copy requestts does trigger a + // rebuild whenever next commit happens. + transform.Scale(1.5, 1.5); + child->SetTransform(transform); + break; + case 3: + EXPECT_EQ(root->num_copy_requests_in_target_subtree(), 0); EndTest(); break; } diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 3834f74..516abb0 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc @@ -670,8 +670,16 @@ int SanityCheckCopyRequestCounts(LayerImpl* layer) { for (size_t i = 0; i < layer->children().size(); ++i) { count += SanityCheckCopyRequestCounts(layer->child_at(i)); } - DCHECK_EQ(count, layer->num_layer_or_descendants_with_copy_request()) - << ", id: " << layer->id(); + if (layer->layer_tree_impl() + ->property_trees() + ->effect_tree.Node(layer->effect_tree_index()) + ->owner_id == layer->id()) { + DCHECK_EQ(count, layer->num_copy_requests_in_target_subtree()) + << ", id: " << layer->id(); + } else { + DCHECK_LE(count, layer->num_copy_requests_in_target_subtree()) + << ", id: " << layer->id(); + } return count; } #endif diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc index 1120d30..1a4b071 100644 --- a/cc/trees/property_tree.cc +++ b/cc/trees/property_tree.cc @@ -413,6 +413,7 @@ EffectNodeData::EffectNodeData() : opacity(1.f), screen_space_opacity(1.f), has_render_surface(false), + num_copy_requests_in_subtree(0), transform_id(0), clip_id(0) {} @@ -420,6 +421,7 @@ bool EffectNodeData::operator==(const EffectNodeData& other) const { return opacity == other.opacity && screen_space_opacity == other.screen_space_opacity && has_render_surface == other.has_render_surface && + num_copy_requests_in_subtree == other.num_copy_requests_in_subtree && transform_id == other.transform_id && clip_id == other.clip_id; } @@ -429,6 +431,7 @@ void EffectNodeData::ToProtobuf(proto::TreeNode* proto) const { data->set_opacity(opacity); data->set_screen_space_opacity(screen_space_opacity); data->set_has_render_surface(has_render_surface); + data->set_num_copy_requests_in_subtree(num_copy_requests_in_subtree); data->set_transform_id(transform_id); data->set_clip_id(clip_id); } @@ -440,6 +443,7 @@ void EffectNodeData::FromProtobuf(const proto::TreeNode& proto) { opacity = data.opacity(); screen_space_opacity = data.screen_space_opacity(); has_render_surface = data.has_render_surface(); + num_copy_requests_in_subtree = data.num_copy_requests_in_subtree(); transform_id = data.transform_id(); clip_id = data.clip_id(); } @@ -1036,6 +1040,11 @@ void EffectTree::UpdateEffects(int id) { UpdateOpacities(node, parent_node); } +void EffectTree::ClearCopyRequests() { + for (auto& node : nodes()) + node.data.num_copy_requests_in_subtree = 0; +} + void TransformTree::UpdateNodeAndAncestorsHaveIntegerTranslations( TransformNode* node, TransformNode* parent_node) { diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h index ff5c8a5..654b5e4 100644 --- a/cc/trees/property_tree.h +++ b/cc/trees/property_tree.h @@ -242,6 +242,7 @@ struct CC_EXPORT EffectNodeData { float screen_space_opacity; bool has_render_surface; + int num_copy_requests_in_subtree; int transform_id; int clip_id; @@ -288,6 +289,7 @@ class CC_EXPORT PropertyTree { void set_needs_update(bool needs_update) { needs_update_ = needs_update; } bool needs_update() const { return needs_update_; } + std::vector<T>& nodes() { return nodes_; } const std::vector<T>& nodes() const { return nodes_; } int next_available_id() const { return static_cast<int>(size()); } @@ -475,6 +477,8 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { void UpdateEffects(int id); + void ClearCopyRequests(); + void ToProtobuf(proto::PropertyTree* proto) const; void FromProtobuf(const proto::PropertyTree& proto); diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 432aa6c..85bdbec 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc @@ -56,6 +56,17 @@ struct DataForRecursion { }; template <typename LayerType> +struct DataForRecursionFromChild { + int num_copy_requests_in_subtree; + + DataForRecursionFromChild() : num_copy_requests_in_subtree(0) {} + + void Merge(const DataForRecursionFromChild& data) { + num_copy_requests_in_subtree += data.num_copy_requests_in_subtree; + } +}; + +template <typename LayerType> static LayerType* GetTransformParent(const DataForRecursion<LayerType>& data, LayerType* layer) { return layer->position_constraint().is_fixed_position() @@ -602,7 +613,8 @@ bool AddEffectNodeIfNeeded( template <typename LayerType> void BuildPropertyTreesInternal( LayerType* layer, - const DataForRecursion<LayerType>& data_from_parent) { + const DataForRecursion<LayerType>& data_from_parent, + DataForRecursionFromChild<LayerType>* data_to_parent) { layer->set_property_tree_sequence_number(data_from_parent.sequence_number); if (layer->mask_layer()) layer->mask_layer()->set_property_tree_sequence_number( @@ -631,7 +643,10 @@ void BuildPropertyTreesInternal( for (size_t i = 0; i < layer->children().size(); ++i) { if (!layer->child_at(i)->scroll_parent()) { - BuildPropertyTreesInternal(layer->child_at(i), data_for_children); + DataForRecursionFromChild<LayerType> data_from_child; + BuildPropertyTreesInternal(layer->child_at(i), data_for_children, + &data_from_child); + data_to_parent->Merge(data_from_child); } else { // The child should be included in its scroll parent's list of scroll // children. @@ -643,12 +658,28 @@ void BuildPropertyTreesInternal( if (layer->scroll_children()) { for (LayerType* scroll_child : *layer->scroll_children()) { DCHECK_EQ(scroll_child->scroll_parent(), layer); - BuildPropertyTreesInternal(scroll_child, data_for_children); + DataForRecursionFromChild<LayerType> data_from_child; + BuildPropertyTreesInternal(scroll_child, data_for_children, + &data_from_child); + data_to_parent->Merge(data_from_child); } } - if (layer->has_replica()) - BuildPropertyTreesInternal(layer->replica_layer(), data_for_children); + if (layer->has_replica()) { + DataForRecursionFromChild<LayerType> data_from_child; + BuildPropertyTreesInternal(layer->replica_layer(), data_for_children, + &data_from_child); + data_to_parent->Merge(data_from_child); + } + + if (layer->HasCopyRequest()) + data_to_parent->num_copy_requests_in_subtree++; + + if (data_for_children.effect_tree->Node(data_for_children.effect_tree_parent) + ->owner_id == layer->id()) + data_for_children.effect_tree->Node(data_for_children.effect_tree_parent) + ->data.num_copy_requests_in_subtree = + data_to_parent->num_copy_requests_in_subtree; } } // namespace @@ -719,7 +750,9 @@ void BuildPropertyTreesTopLevelInternal( root_clip.data.transform_id = kRootPropertyTreeNodeId; data_for_recursion.clip_tree_parent = data_for_recursion.clip_tree->Insert(root_clip, kRootPropertyTreeNodeId); - BuildPropertyTreesInternal(root_layer, data_for_recursion); + + DataForRecursionFromChild<LayerType> data_from_child; + BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child); property_trees->needs_rebuild = false; // The transform tree is kept up-to-date as it is built, but the |