summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsunxd <sunxd@chromium.org>2016-01-11 13:01:02 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-11 21:02:26 +0000
commited58688e7629fa3c56470a241bc758fb5fabf081 (patch)
treef6ff71f020fca9532faa6c66548894fa126cd900
parent41a523c0dbdf29bf1353036e35004cb35c345b17 (diff)
downloadchromium_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.cc39
-rw-r--r--cc/layers/layer.h14
-rw-r--r--cc/layers/layer_impl.cc11
-rw-r--r--cc/layers/layer_impl.h10
-rw-r--r--cc/layers/layer_unittest.cc4
-rw-r--r--cc/proto/property_tree.proto5
-rw-r--r--cc/trees/draw_property_utils.cc4
-rw-r--r--cc/trees/layer_tree_host_common.cc6
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc64
-rw-r--r--cc/trees/layer_tree_host_impl.cc5
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc1
-rw-r--r--cc/trees/layer_tree_host_unittest.cc22
-rw-r--r--cc/trees/layer_tree_impl.cc12
-rw-r--r--cc/trees/property_tree.cc9
-rw-r--r--cc/trees/property_tree.h4
-rw-r--r--cc/trees/property_tree_builder.cc45
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