diff options
-rw-r--r-- | cc/layers/delegated_renderer_layer_impl.cc | 2 | ||||
-rw-r--r-- | cc/layers/layer.cc | 2 | ||||
-rw-r--r-- | cc/layers/layer_impl.cc | 86 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 35 | ||||
-rw-r--r-- | cc/layers/layer_impl_unittest.cc | 78 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 4 | ||||
-rw-r--r-- | cc/layers/texture_layer.cc | 14 | ||||
-rw-r--r-- | cc/layers/texture_layer_impl.cc | 56 | ||||
-rw-r--r-- | cc/layers/texture_layer_impl.h | 29 | ||||
-rw-r--r-- | cc/layers/texture_layer_unittest.cc | 10 | ||||
-rw-r--r-- | cc/layers/video_layer_impl.cc | 2 | ||||
-rw-r--r-- | cc/trees/damage_tracker_unittest.cc | 38 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 48 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 243 | ||||
-rw-r--r-- | cc/trees/tree_synchronizer.cc | 15 | ||||
-rw-r--r-- | cc/trees/tree_synchronizer.h | 3 |
16 files changed, 542 insertions, 123 deletions
diff --git a/cc/layers/delegated_renderer_layer_impl.cc b/cc/layers/delegated_renderer_layer_impl.cc index 2596ec2..e4de653 100644 --- a/cc/layers/delegated_renderer_layer_impl.cc +++ b/cc/layers/delegated_renderer_layer_impl.cc @@ -148,7 +148,7 @@ void DelegatedRendererLayerImpl::SetFrameData( gfx::Size frame_size = new_root_pass->output_rect.size(); gfx::RectF damage_in_layer = MathUtil::MapClippedRect( DelegatedFrameToLayerSpaceTransform(frame_size), damage_in_frame); - set_update_rect(gfx::IntersectRects( + SetUpdateRect(gfx::IntersectRects( gfx::UnionRects(update_rect(), damage_in_layer), gfx::Rect(bounds()))); SetRenderPasses(&render_pass_list); diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index b826fbb..045ea73 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -983,7 +983,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e. // union) any update changes that have occurred on the main thread. update_rect_.Union(layer->update_rect()); - layer->set_update_rect(update_rect_); + layer->SetUpdateRect(update_rect_); layer->SetStackingOrderChanged(stacking_order_changed_); diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index cf017a2..a783a78 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -63,6 +63,8 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) opacity_(1.0), blend_mode_(SkXfermode::kSrcOver_Mode), draw_depth_(0.f), + needs_push_properties_(false), + num_dependents_need_push_properties_(0), current_draw_mode_(DRAW_MODE_NONE), horizontal_scrollbar_layer_(NULL), vertical_scrollbar_layer_(NULL) { @@ -75,6 +77,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) layer_animation_controller_->AddValueObserver(this); if (IsActive()) layer_animation_controller_->set_value_provider(this); + SetNeedsPushProperties(); } LayerImpl::~LayerImpl() { @@ -107,7 +110,7 @@ LayerImpl::~LayerImpl() { } void LayerImpl::AddChild(scoped_ptr<LayerImpl> child) { - child->set_parent(this); + child->SetParent(this); DCHECK_EQ(layer_tree_impl(), child->layer_tree_impl()); children_.push_back(child.Pass()); layer_tree_impl()->set_needs_update_draw_properties(); @@ -127,6 +130,16 @@ scoped_ptr<LayerImpl> LayerImpl::RemoveChild(LayerImpl* child) { return scoped_ptr<LayerImpl>(); } +void LayerImpl::SetParent(LayerImpl* parent) { + if (parent_should_know_need_push_properties()) { + if (parent_) + parent_->RemoveDependentNeedsPushProperties(); + if (parent) + parent->AddDependentNeedsPushProperties(); + } + parent_ = parent; +} + void LayerImpl::ClearChildList() { if (children_.empty()) return; @@ -158,17 +171,20 @@ void LayerImpl::SetScrollParent(LayerImpl* parent) { scroll_parent_->RemoveScrollChild(this); scroll_parent_ = parent; + SetNeedsPushProperties(); } void LayerImpl::SetDebugInfo( scoped_refptr<base::debug::ConvertableToTraceFormat> other) { debug_info_ = other; + SetNeedsPushProperties(); } void LayerImpl::SetScrollChildren(std::set<LayerImpl*>* children) { if (scroll_children_.get() == children) return; scroll_children_.reset(children); + SetNeedsPushProperties(); } void LayerImpl::RemoveScrollChild(LayerImpl* child) { @@ -176,6 +192,7 @@ void LayerImpl::RemoveScrollChild(LayerImpl* child) { scroll_children_->erase(child); if (scroll_children_->empty()) scroll_children_.reset(); + SetNeedsPushProperties(); } void LayerImpl::SetClipParent(LayerImpl* ancestor) { @@ -186,12 +203,14 @@ void LayerImpl::SetClipParent(LayerImpl* ancestor) { clip_parent_->RemoveClipChild(this); clip_parent_ = ancestor; + SetNeedsPushProperties(); } void LayerImpl::SetClipChildren(std::set<LayerImpl*>* children) { if (clip_children_.get() == children) return; clip_children_.reset(children); + SetNeedsPushProperties(); } void LayerImpl::RemoveClipChild(LayerImpl* child) { @@ -199,6 +218,7 @@ void LayerImpl::RemoveClipChild(LayerImpl* child) { clip_children_->erase(child); if (clip_children_->empty()) clip_children_.reset(); + SetNeedsPushProperties(); } void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) { @@ -574,15 +594,16 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e. // union) any update changes that have occurred on the main thread. update_rect_.Union(layer->update_rect()); - layer->set_update_rect(update_rect_); + layer->SetUpdateRect(update_rect_); layer->SetStackingOrderChanged(stacking_order_changed_); + layer->SetDebugInfo(debug_info_); // Reset any state that should be cleared for the next update. stacking_order_changed_ = false; update_rect_ = gfx::RectF(); - - layer->SetDebugInfo(debug_info_); + needs_push_properties_ = false; + num_dependents_need_push_properties_ = 0; } base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { @@ -639,17 +660,28 @@ void LayerImpl::SetStackingOrderChanged(bool stacking_order_changed) { void LayerImpl::NoteLayerPropertyChanged() { layer_property_changed_ = true; layer_tree_impl()->set_needs_update_draw_properties(); + SetNeedsPushProperties(); } void LayerImpl::NoteLayerPropertyChangedForSubtree() { - NoteLayerPropertyChanged(); - NoteLayerPropertyChangedForDescendants(); + layer_property_changed_ = true; + layer_tree_impl()->set_needs_update_draw_properties(); + for (size_t i = 0; i < children_.size(); ++i) + children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); + SetNeedsPushProperties(); +} + +void LayerImpl::NoteLayerPropertyChangedForDescendantsInternal() { + layer_property_changed_ = true; + for (size_t i = 0; i < children_.size(); ++i) + children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); } void LayerImpl::NoteLayerPropertyChangedForDescendants() { layer_tree_impl()->set_needs_update_draw_properties(); for (size_t i = 0; i < children_.size(); ++i) - children_[i]->NoteLayerPropertyChangedForSubtree(); + children_[i]->NoteLayerPropertyChangedForDescendantsInternal(); + SetNeedsPushProperties(); } const char* LayerImpl::LayerTypeAsString() const { @@ -674,6 +706,9 @@ void LayerImpl::ResetAllChangeTrackingForSubtree() { for (size_t i = 0; i < children_.size(); ++i) children_[i]->ResetAllChangeTrackingForSubtree(); + + needs_push_properties_ = false; + num_dependents_need_push_properties_ = 0; } bool LayerImpl::LayerIsAlwaysDamaged() const { @@ -739,7 +774,7 @@ void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) { mask_layer_ = mask_layer.Pass(); mask_layer_id_ = new_layer_id; if (mask_layer_) - mask_layer_->set_parent(this); + mask_layer_->SetParent(this); NoteLayerPropertyChangedForSubtree(); } @@ -761,7 +796,7 @@ void LayerImpl::SetReplicaLayer(scoped_ptr<LayerImpl> replica_layer) { replica_layer_ = replica_layer.Pass(); replica_layer_id_ = new_layer_id; if (replica_layer_) - replica_layer_->set_parent(this); + replica_layer_->SetParent(this); NoteLayerPropertyChangedForSubtree(); } @@ -907,6 +942,7 @@ void LayerImpl::SetIsRootForIsolatedGroup(bool root) { return; is_root_for_isolated_group_ = root; + SetNeedsPushProperties(); } void LayerImpl::SetPosition(const gfx::PointF& position) { @@ -953,6 +989,11 @@ bool LayerImpl::TransformIsAnimatingOnImplOnly() const { return transform_animation && transform_animation->is_impl_only(); } +void LayerImpl::SetUpdateRect(const gfx::RectF& update_rect) { + update_rect_ = update_rect; + SetNeedsPushProperties(); +} + void LayerImpl::SetContentBounds(gfx::Size content_bounds) { if (this->content_bounds() == content_bounds) return; @@ -1134,6 +1175,7 @@ void LayerImpl::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) { layer_tree_impl()->set_needs_update_draw_properties(); UpdateScrollbarPositions(); + SetNeedsPushProperties(); } void LayerImpl::DidBecomeActive() { @@ -1176,6 +1218,7 @@ void LayerImpl::DidBecomeActive() { break; } } + void LayerImpl::SetHorizontalScrollbarLayer( ScrollbarLayerImplBase* scrollbar_layer) { horizontal_scrollbar_layer_ = scrollbar_layer; @@ -1190,6 +1233,31 @@ void LayerImpl::SetVerticalScrollbarLayer( vertical_scrollbar_layer_->set_scroll_layer_id(id()); } +void LayerImpl::SetNeedsPushProperties() { + if (needs_push_properties_) + return; + if (!parent_should_know_need_push_properties() && parent_) + parent_->AddDependentNeedsPushProperties(); + needs_push_properties_ = true; +} + +void LayerImpl::AddDependentNeedsPushProperties() { + DCHECK_GE(num_dependents_need_push_properties_, 0); + + if (!parent_should_know_need_push_properties() && parent_) + parent_->AddDependentNeedsPushProperties(); + + num_dependents_need_push_properties_++; +} + +void LayerImpl::RemoveDependentNeedsPushProperties() { + num_dependents_need_push_properties_--; + DCHECK_GE(num_dependents_need_push_properties_, 0); + + if (!parent_should_know_need_push_properties() && parent_) + parent_->RemoveDependentNeedsPushProperties(); +} + void LayerImpl::AsValueInto(base::DictionaryValue* state) const { TracedValue::MakeDictIntoImplicitSnapshot(state, LayerTypeAsString(), this); state->SetInteger("layer_id", id()); diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index ce05891..039c674e 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -95,7 +95,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, LayerImpl* child_at(size_t index) const { return children_[index]; } void AddChild(scoped_ptr<LayerImpl> child); scoped_ptr<LayerImpl> RemoveChild(LayerImpl* child); - void set_parent(LayerImpl* parent) { parent_ = parent; } + void SetParent(LayerImpl* parent); + // Warning: This does not preserve tree structure invariants. void ClearChildList(); @@ -443,9 +444,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, bool TransformIsAnimatingOnImplOnly() const; // Note this rect is in layer space (not content space). - void set_update_rect(const gfx::RectF& update_rect) { - update_rect_ = update_rect; - } + void SetUpdateRect(const gfx::RectF& update_rect); + const gfx::RectF& update_rect() const { return update_rect_; } virtual base::DictionaryValue* LayerTreeAsJson() const; @@ -500,9 +500,17 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, scoped_ptr<base::Value> AsValue() const; virtual size_t GPUMemoryUsageInBytes() const; - // TODO(danakj): Be true only if needed. crbug.com/259511 - bool needs_push_properties() const { return true; } - bool descendant_needs_push_properties() const { return true; } + void SetNeedsPushProperties(); + void AddDependentNeedsPushProperties(); + void RemoveDependentNeedsPushProperties(); + bool parent_should_know_need_push_properties() const { + return needs_push_properties() || descendant_needs_push_properties(); + } + + bool needs_push_properties() const { return needs_push_properties_; } + bool descendant_needs_push_properties() const { + return num_dependents_need_push_properties_ > 0; + } virtual void RunMicroBenchmark(MicroBenchmarkImpl* benchmark); @@ -533,6 +541,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, void NoteLayerPropertyChangedForDescendants(); private: + void NoteLayerPropertyChangedForDescendantsInternal(); + void UpdateScrollbarPositions(); virtual const char* LayerTypeAsString() const; @@ -620,6 +630,17 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, FilterOperations background_filters_; protected: + friend class TreeSynchronizer; + + // This flag is set when the layer needs to push properties to the active + // side. + bool needs_push_properties_; + + // The number of direct children or dependent layers that need to be recursed + // to in order for them or a descendent of them to push properties to the + // active side. + int num_dependents_need_push_properties_; + DrawMode current_draw_mode_; private: diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index ecedaec..43691ca 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc @@ -22,6 +22,9 @@ namespace { #define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test) \ root->ResetAllChangeTrackingForSubtree(); \ code_to_test; \ + EXPECT_TRUE(root->needs_push_properties()); \ + EXPECT_FALSE(child->needs_push_properties()); \ + EXPECT_FALSE(grand_child->needs_push_properties()); \ EXPECT_TRUE(root->LayerPropertyChanged()); \ EXPECT_TRUE(child->LayerPropertyChanged()); \ EXPECT_TRUE(grand_child->LayerPropertyChanged()); @@ -29,6 +32,20 @@ namespace { #define EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(code_to_test) \ root->ResetAllChangeTrackingForSubtree(); \ code_to_test; \ + EXPECT_FALSE(root->needs_push_properties()); \ + EXPECT_FALSE(child->needs_push_properties()); \ + EXPECT_FALSE(grand_child->needs_push_properties()); \ + EXPECT_FALSE(root->LayerPropertyChanged()); \ + EXPECT_FALSE(child->LayerPropertyChanged()); \ + EXPECT_FALSE(grand_child->LayerPropertyChanged()); + +#define EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( \ + code_to_test) \ + root->ResetAllChangeTrackingForSubtree(); \ + code_to_test; \ + EXPECT_TRUE(root->needs_push_properties()); \ + EXPECT_FALSE(child->needs_push_properties()); \ + EXPECT_FALSE(grand_child->needs_push_properties()); \ EXPECT_FALSE(root->LayerPropertyChanged()); \ EXPECT_FALSE(child->LayerPropertyChanged()); \ EXPECT_FALSE(grand_child->LayerPropertyChanged()); @@ -36,6 +53,9 @@ namespace { #define EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(code_to_test) \ root->ResetAllChangeTrackingForSubtree(); \ code_to_test; \ + EXPECT_TRUE(root->needs_push_properties()); \ + EXPECT_FALSE(child->needs_push_properties()); \ + EXPECT_FALSE(grand_child->needs_push_properties()); \ EXPECT_TRUE(root->LayerPropertyChanged()); \ EXPECT_FALSE(child->LayerPropertyChanged()); \ EXPECT_FALSE(grand_child->LayerPropertyChanged()); @@ -43,6 +63,9 @@ namespace { #define EXECUTE_AND_VERIFY_ONLY_DESCENDANTS_CHANGED(code_to_test) \ root->ResetAllChangeTrackingForSubtree(); \ code_to_test; \ + EXPECT_TRUE(root->needs_push_properties()); \ + EXPECT_FALSE(child->needs_push_properties()); \ + EXPECT_FALSE(grand_child->needs_push_properties()); \ EXPECT_FALSE(root->LayerPropertyChanged()); \ EXPECT_TRUE(child->LayerPropertyChanged()); \ EXPECT_TRUE(grand_child->LayerPropertyChanged()); @@ -72,9 +95,24 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { FakeLayerTreeHostImpl host_impl(&proxy); EXPECT_TRUE(host_impl.InitializeRenderer(CreateFakeOutputSurface())); scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); - root->AddChild(LayerImpl::Create(host_impl.active_tree(), 2)); + + scoped_ptr<LayerImpl> scroll_parent = + LayerImpl::Create(host_impl.active_tree(), 2); + LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 3).get(); + std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>(); + scroll_children->insert(scroll_child); + scroll_children->insert(root.get()); + + scoped_ptr<LayerImpl> clip_parent = + LayerImpl::Create(host_impl.active_tree(), 4); + LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 5).get(); + std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>(); + clip_children->insert(clip_child); + clip_children->insert(root.get()); + + root->AddChild(LayerImpl::Create(host_impl.active_tree(), 6)); LayerImpl* child = root->children()[0]; - child->AddChild(LayerImpl::Create(host_impl.active_tree(), 3)); + child->AddChild(LayerImpl::Create(host_impl.active_tree(), 7)); LayerImpl* grand_child = child->children()[0]; root->SetScrollable(true); @@ -102,9 +140,9 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { // These properties are internal, and should not be considered "change" when // they are used. - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( - root->set_update_rect(arbitrary_rect_f)); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( + root->SetUpdateRect(arbitrary_rect_f)); + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( root->SetMaxScrollOffset(arbitrary_vector2d)); // Changing these properties affects the entire subtree of layers. @@ -113,11 +151,11 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(arbitrary_filters)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(FilterOperations())); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( - root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 4))); + root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 8))); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMasksToBounds(true)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetContentsOpaque(true)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( - root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 5))); + root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 9))); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPosition(arbitrary_point_f)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPreserves3d(true)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( @@ -154,9 +192,25 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { // changed. EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBounds(arbitrary_size)); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( + // Changing this property does not cause the layer to be marked as changed + // but does cause the layer to need to push properties. + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( root->SetIsRootForIsolatedGroup(true)); + // Changing these properties should cause the layer to need to push properties + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( + root->SetScrollParent(scroll_parent.get())); + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( + root->SetScrollChildren(scroll_children)); + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( + root->RemoveScrollChild(scroll_child)); + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( + root->SetClipParent(clip_parent.get())); + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( + root->SetClipChildren(clip_children)); + EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( + root->RemoveClipChild(clip_child)); + // After setting all these properties already, setting to the exact same // values again should not cause any change. EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( @@ -189,6 +243,14 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( root->SetSublayerTransform(arbitrary_transform)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetBounds(arbitrary_size)); + EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( + root->SetScrollParent(scroll_parent.get())); + EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( + root->SetScrollChildren(scroll_children)); + EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( + root->SetClipParent(clip_parent.get())); + EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( + root->SetClipChildren(clip_children)); } TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index df5ca68..cc9a828 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -115,6 +115,10 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { layer_impl->invalidation_.Swap(&invalidation_); invalidation_.Clear(); needs_post_commit_initialization_ = true; + + // We always need to push properties. + // See http://crbug.com/303943 + needs_push_properties_ = true; } void PictureLayerImpl::AppendQuads(QuadSink* quad_sink, diff --git a/cc/layers/texture_layer.cc b/cc/layers/texture_layer.cc index 565a5fe..bc6b58a 100644 --- a/cc/layers/texture_layer.cc +++ b/cc/layers/texture_layer.cc @@ -254,12 +254,12 @@ void TextureLayer::PushPropertiesTo(LayerImpl* layer) { Layer::PushPropertiesTo(layer); TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); - texture_layer->set_flipped(flipped_); - texture_layer->set_uv_top_left(uv_top_left_); - texture_layer->set_uv_bottom_right(uv_bottom_right_); - texture_layer->set_vertex_opacity(vertex_opacity_); - texture_layer->set_premultiplied_alpha(premultiplied_alpha_); - texture_layer->set_blend_background_color(blend_background_color_); + texture_layer->SetFlipped(flipped_); + texture_layer->SetUVTopLeft(uv_top_left_); + texture_layer->SetUVBottomRight(uv_bottom_right_); + texture_layer->SetVertexOpacity(vertex_opacity_); + texture_layer->SetPremultipliedAlpha(premultiplied_alpha_); + texture_layer->SetBlendBackgroundColor(blend_background_color_); if (uses_mailbox_ && needs_set_mailbox_) { TextureMailbox texture_mailbox; scoped_ptr<SingleReleaseCallback> release_callback; @@ -271,7 +271,7 @@ void TextureLayer::PushPropertiesTo(LayerImpl* layer) { texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass()); needs_set_mailbox_ = false; } else { - texture_layer->set_texture_id(texture_id_); + texture_layer->SetTextureId(texture_id_); content_committed_ = DrawsContent(); } } diff --git a/cc/layers/texture_layer_impl.cc b/cc/layers/texture_layer_impl.cc index 6aa02a6..3dfdcb6 100644 --- a/cc/layers/texture_layer_impl.cc +++ b/cc/layers/texture_layer_impl.cc @@ -49,6 +49,7 @@ void TextureLayerImpl::SetTextureMailbox( release_callback_ = release_callback.Pass(); own_mailbox_ = true; valid_texture_copy_ = false; + SetNeedsPushProperties(); } scoped_ptr<LayerImpl> TextureLayerImpl::CreateLayerImpl( @@ -61,18 +62,18 @@ void TextureLayerImpl::PushPropertiesTo(LayerImpl* layer) { LayerImpl::PushPropertiesTo(layer); TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); - texture_layer->set_flipped(flipped_); - texture_layer->set_uv_top_left(uv_top_left_); - texture_layer->set_uv_bottom_right(uv_bottom_right_); - texture_layer->set_vertex_opacity(vertex_opacity_); - texture_layer->set_premultiplied_alpha(premultiplied_alpha_); - texture_layer->set_blend_background_color(blend_background_color_); + texture_layer->SetFlipped(flipped_); + texture_layer->SetUVTopLeft(uv_top_left_); + texture_layer->SetUVBottomRight(uv_bottom_right_); + texture_layer->SetVertexOpacity(vertex_opacity_); + texture_layer->SetPremultipliedAlpha(premultiplied_alpha_); + texture_layer->SetBlendBackgroundColor(blend_background_color_); if (uses_mailbox_ && own_mailbox_) { texture_layer->SetTextureMailbox(texture_mailbox_, release_callback_.Pass()); own_mailbox_ = false; } else { - texture_layer->set_texture_id(texture_id_); + texture_layer->SetTextureId(texture_id_); } } @@ -221,6 +222,47 @@ void TextureLayerImpl::ReleaseResources() { valid_texture_copy_ = false; } +void TextureLayerImpl::SetTextureId(unsigned id) { + texture_id_ = id; + SetNeedsPushProperties(); +} + +void TextureLayerImpl::SetPremultipliedAlpha(bool premultiplied_alpha) { + premultiplied_alpha_ = premultiplied_alpha; + SetNeedsPushProperties(); +} + +void TextureLayerImpl::SetBlendBackgroundColor(bool blend) { + blend_background_color_ = blend; + SetNeedsPushProperties(); +} + +void TextureLayerImpl::SetFlipped(bool flipped) { + flipped_ = flipped; + SetNeedsPushProperties(); +} + +void TextureLayerImpl::SetUVTopLeft(const gfx::PointF top_left) { + uv_top_left_ = top_left; + SetNeedsPushProperties(); +} + +void TextureLayerImpl::SetUVBottomRight(const gfx::PointF bottom_right) { + uv_bottom_right_ = bottom_right; + SetNeedsPushProperties(); +} + +// 1--2 +// | | +// 0--3 +void TextureLayerImpl::SetVertexOpacity(const float vertex_opacity[4]) { + vertex_opacity_[0] = vertex_opacity[0]; + vertex_opacity_[1] = vertex_opacity[1]; + vertex_opacity_[2] = vertex_opacity[2]; + vertex_opacity_[3] = vertex_opacity[3]; + SetNeedsPushProperties(); +} + const char* TextureLayerImpl::LayerTypeAsString() const { return "cc::TextureLayerImpl"; } diff --git a/cc/layers/texture_layer_impl.h b/cc/layers/texture_layer_impl.h index 8f5cab1..50511fe 100644 --- a/cc/layers/texture_layer_impl.h +++ b/cc/layers/texture_layer_impl.h @@ -37,28 +37,21 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl { virtual void ReleaseResources() OVERRIDE; unsigned texture_id() const { return texture_id_; } - void set_texture_id(unsigned id) { texture_id_ = id; } - void set_premultiplied_alpha(bool premultiplied_alpha) { - premultiplied_alpha_ = premultiplied_alpha; - } - void set_blend_background_color(bool blend) { - blend_background_color_ = blend; - } - void set_flipped(bool flipped) { flipped_ = flipped; } - void set_uv_top_left(const gfx::PointF& top_left) { uv_top_left_ = top_left; } - void set_uv_bottom_right(const gfx::PointF& bottom_right) { - uv_bottom_right_ = bottom_right; - } + + // These setter methods don't cause any implicit damage, so the texture client + // must explicitly invalidate if they intend to cause a visible change in the + // layer's output. + void SetTextureId(unsigned id); + void SetPremultipliedAlpha(bool premultiplied_alpha); + void SetBlendBackgroundColor(bool blend); + void SetFlipped(bool flipped); + void SetUVTopLeft(const gfx::PointF top_left); + void SetUVBottomRight(const gfx::PointF bottom_right); // 1--2 // | | // 0--3 - void set_vertex_opacity(const float vertex_opacity[4]) { - vertex_opacity_[0] = vertex_opacity[0]; - vertex_opacity_[1] = vertex_opacity[1]; - vertex_opacity_[2] = vertex_opacity[2]; - vertex_opacity_[3] = vertex_opacity[3]; - } + void SetVertexOpacity(const float vertex_opacity[4]); void SetTextureMailbox(const TextureMailbox& mailbox, scoped_ptr<SingleReleaseCallback> release_callback); diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index eb274b5..6b78a71 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc @@ -1211,7 +1211,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { host_impl_.output_surface()->context_provider(); GLuint texture = 0; context_provider->ContextGL()->GenTextures(1, &texture); - impl_layer->set_texture_id(texture); + impl_layer->SetTextureId(texture); EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); } @@ -1219,7 +1219,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); impl_layer->SetDrawsContent(true); - impl_layer->set_texture_id(0); + impl_layer->SetTextureId(0); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); } @@ -1262,7 +1262,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { host_impl_.output_surface()->context_provider(); GLuint texture = 0; context_provider->ContextGL()->GenTextures(1, &texture); - impl_layer->set_texture_id(texture); + impl_layer->SetTextureId(texture); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); } @@ -1270,7 +1270,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); impl_layer->SetDrawsContent(true); - impl_layer->set_texture_id(0); + impl_layer->SetTextureId(0); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); } @@ -1293,7 +1293,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { host_impl_.output_surface()->context_provider(); GLuint texture = 0; context_provider->ContextGL()->GenTextures(1, &texture); - impl_layer->set_texture_id(texture); + impl_layer->SetTextureId(texture); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE)); } } diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index dc67fc5..9a772c5 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc @@ -302,7 +302,7 @@ void VideoLayerImpl::ReleaseResources() { } void VideoLayerImpl::SetNeedsRedraw() { - set_update_rect(gfx::UnionRects(update_rect(), gfx::RectF(bounds()))); + SetUpdateRect(gfx::UnionRects(update_rect(), gfx::RectF(bounds()))); layer_tree_impl()->SetNeedsRedraw(); } diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc index 7fb8720..31d2b46 100644 --- a/cc/trees/damage_tracker_unittest.cc +++ b/cc/trees/damage_tracker_unittest.cc @@ -231,7 +231,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // CASE 1: Setting the update rect should cause the corresponding damage to // the surface. ClearDamageForAllSurfaces(root.get()); - child->set_update_rect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); + child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); EmulateDrawingOneFrame(root.get()); // Damage position on the surface should be: position of update_rect (10, 11) @@ -243,7 +243,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // CASE 2: The same update rect twice in a row still produces the same // damage. ClearDamageForAllSurfaces(root.get()); - child->set_update_rect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); + child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); @@ -252,7 +252,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // CASE 3: Setting a different update rect should cause damage on the new // update region, but no additional exposed old region. ClearDamageForAllSurfaces(root.get()); - child->set_update_rect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); + child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); EmulateDrawingOneFrame(root.get()); // Damage position on the surface should be: position of update_rect (20, 25) @@ -269,7 +269,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { // CASE 1: The layer's property changed flag takes priority over update rect. // ClearDamageForAllSurfaces(root.get()); - child->set_update_rect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); + child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); child->SetOpacity(0.5f); EmulateDrawingOneFrame(root.get()); @@ -417,7 +417,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { // Setting the update rect should cause the corresponding damage to the // surface, blurred based on the size of the blur filter. ClearDamageForAllSurfaces(root.get()); - child->set_update_rect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); + child->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); EmulateDrawingOneFrame(root.get()); // Damage position on the surface should be: position of update_rect (1, 2) @@ -461,7 +461,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { // CASE 1: Setting the update rect should damage the whole surface (for now) ClearDamageForAllSurfaces(root.get()); - child->set_update_rect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); + child->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -494,7 +494,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // the surface, blurred based on the size of the child's background // blur filter. ClearDamageForAllSurfaces(root.get()); - root->set_update_rect(gfx::RectF(297.f, 297.f, 2.f, 2.f)); + root->SetUpdateRect(gfx::RectF(297.f, 297.f, 2.f, 2.f)); EmulateDrawingOneFrame(root.get()); gfx::RectF root_damage_rect = @@ -516,7 +516,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // blur filter. Since the damage extends to the right/bottom outside // of the blurred layer, only the left/top should end up expanded. ClearDamageForAllSurfaces(root.get()); - root->set_update_rect(gfx::RectF(297.f, 297.f, 30.f, 30.f)); + root->SetUpdateRect(gfx::RectF(297.f, 297.f, 30.f, 30.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -536,7 +536,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // CASE 3: Setting this update rect outside the blurred content_bounds of the // blurred child1 will not cause it to be expanded. ClearDamageForAllSurfaces(root.get()); - root->set_update_rect(gfx::RectF(30.f, 30.f, 2.f, 2.f)); + root->SetUpdateRect(gfx::RectF(30.f, 30.f, 2.f, 2.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -552,7 +552,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // outside the original content_bounds of the blurred child1 will // cause it to be expanded. ClearDamageForAllSurfaces(root.get()); - root->set_update_rect(gfx::RectF(99.f, 99.f, 1.f, 1.f)); + root->SetUpdateRect(gfx::RectF(99.f, 99.f, 1.f, 1.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -572,7 +572,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // CASE 5: Setting the update rect on child2, which is above child1, will // not get blurred by child1, so it does not need to get expanded. ClearDamageForAllSurfaces(root.get()); - child2->set_update_rect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); + child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -588,7 +588,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // that any pixels needed for the blur are redrawn in the current // frame. ClearDamageForAllSurfaces(root.get()); - child1->set_update_rect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); + child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -712,8 +712,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { // - child1 update rect in surface space: gfx::RectF(100.f, 100.f, 1.f, 2.f); // - child2 update rect in surface space: gfx::RectF(400.f, 380.f, 3.f, 4.f); ClearDamageForAllSurfaces(root.get()); - child1->set_update_rect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); - child2->set_update_rect(gfx::RectF(0.f, 0.f, 3.f, 4.f)); + child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); + child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 3.f, 4.f)); EmulateDrawingOneFrame(root.get()); gfx::RectF root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); @@ -916,7 +916,7 @@ TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { // In our specific tree, the update rect of child1 should not cause any // damage to any surface because it does not actually draw content. ClearDamageForAllSurfaces(root.get()); - child1->set_update_rect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); + child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); EmulateDrawingOneFrame(root.get()); child_damage_rect = child1->render_surface()->damage_tracker()->current_damage_rect(); @@ -1070,7 +1070,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // CASE 1: the update_rect on a mask layer should damage the entire target // surface. ClearDamageForAllSurfaces(root.get()); - mask_layer->set_update_rect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); + mask_layer->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); EmulateDrawingOneFrame(root.get()); gfx::RectF child_damage_rect = child->render_surface()->damage_tracker()->current_damage_rect(); @@ -1258,7 +1258,7 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { // it is included with any other partial damage. // ClearDamageForAllSurfaces(root.get()); - child->set_update_rect(gfx::RectF(10, 11, 12, 13)); + child->SetUpdateRect(gfx::RectF(10, 11, 12, 13)); root->render_surface()->damage_tracker()->AddDamageNextUpdate( gfx::RectF(15, 16, 32, 33)); EmulateDrawingOneFrame(root.get()); @@ -1312,7 +1312,7 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { LayerImpl* child = root->children()[0]; ClearDamageForAllSurfaces(root.get()); - child->set_update_rect(gfx::RectF(10.f, 11.f, 1.f, 2.f)); + child->SetUpdateRect(gfx::RectF(10.f, 11.f, 1.f, 2.f)); EmulateDrawingOneFrame(root.get()); // Sanity check damage after the first frame; this isnt the actual test yet. @@ -1322,7 +1322,7 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // New damage, without having cleared the previous damage, should be unioned // to the previous one. - child->set_update_rect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); + child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 1d30479..05fc56c 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -2849,7 +2849,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Opaque layer, drawn without blending. layer1->SetContentsOpaque(true); layer1->SetExpectation(false, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2858,7 +2858,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Layer with translucent content and painting, so drawn with blending. layer1->SetContentsOpaque(false); layer1->SetExpectation(true, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2868,7 +2868,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(0.5f); layer1->SetExpectation(true, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2878,7 +2878,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(0.5f); layer1->SetExpectation(true, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2896,11 +2896,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(1.f); layer1->SetExpectation(false, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); layer2->SetContentsOpaque(true); layer2->SetOpacity(1.f); layer2->SetExpectation(false, false); - layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2911,9 +2911,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Child layer with opaque content, drawn without blending. layer1->SetContentsOpaque(false); layer1->SetExpectation(true, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); layer2->SetExpectation(false, false); - layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2925,9 +2925,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Child layer with opaque content, drawn without blending. layer1->SetContentsOpaque(true); layer1->SetExpectation(false, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); layer2->SetExpectation(false, false); - layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2942,9 +2942,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(0.5f); layer1->SetExpectation(false, true); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); layer2->SetExpectation(false, false); - layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2956,11 +2956,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(1.f); layer1->SetExpectation(false, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); layer2->SetContentsOpaque(true); layer2->SetOpacity(0.5f); layer2->SetExpectation(true, false); - layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2971,11 +2971,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(1.f); layer1->SetExpectation(false, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); layer2->SetContentsOpaque(false); layer2->SetOpacity(1.f); layer2->SetExpectation(true, false); - layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -2987,11 +2987,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(1.f); layer1->SetExpectation(false, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); layer2->SetContentsOpaque(true); layer2->SetOpacity(1.f); layer2->SetExpectation(false, false); - layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3004,7 +3004,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3016,7 +3016,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3028,7 +3028,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3041,7 +3041,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(false, false); - layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3680,7 +3680,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwap) { Mock::VerifyAndClearExpectations(&mock_context); // Damage a portion of the frame. - host_impl_->active_tree()->root_layer()->set_update_rect( + host_impl_->active_tree()->root_layer()->SetUpdateRect( gfx::Rect(0, 0, 2, 3)); // The second frame will be partially-swapped (the y coordinates are flipped). @@ -4027,7 +4027,7 @@ TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) { // The second frame has damage that doesn't touch the child layer. Its quads // should still be generated. gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1); - host_impl_->active_tree()->root_layer()->set_update_rect(small_damage); + host_impl_->active_tree()->root_layer()->SetUpdateRect(small_damage); DrawFrameAndTestDamage(small_damage); // The third frame should have no damage, so no quads should be generated. diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 66b0f92..650f7ca 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -3180,6 +3180,43 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource); +class PushPropertiesCountingLayerImpl : public LayerImpl { + public: + static scoped_ptr<PushPropertiesCountingLayerImpl> Create( + LayerTreeImpl* tree_impl, int id) { + return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id)); + } + + virtual ~PushPropertiesCountingLayerImpl() {} + + virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE { + LayerImpl::PushPropertiesTo(layer); + push_properties_count_++; + // Push state to the active tree because we can only access it from there. + static_cast<PushPropertiesCountingLayerImpl*>( + layer)->push_properties_count_ = push_properties_count_; + } + + virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) + OVERRIDE { + return PushPropertiesCountingLayerImpl::Create(tree_impl, id()). + PassAs<LayerImpl>(); + } + + size_t push_properties_count() const { return push_properties_count_; } + void reset_push_properties_count() { push_properties_count_ = 0; } + + private: + size_t push_properties_count_; + + PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id) + : LayerImpl(tree_impl, id), + push_properties_count_(0) { + SetAnchorPoint(gfx::PointF()); + SetBounds(gfx::Size(1, 1)); + } +}; + class PushPropertiesCountingLayer : public Layer { public: static scoped_refptr<PushPropertiesCountingLayer> Create() { @@ -3193,6 +3230,12 @@ class PushPropertiesCountingLayer : public Layer { needs_push_properties_ = true; } + virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) + OVERRIDE { + return PushPropertiesCountingLayerImpl::Create(tree_impl, id()). + PassAs<LayerImpl>(); + } + size_t push_properties_count() const { return push_properties_count_; } void reset_push_properties_count() { push_properties_count_ = 0; } @@ -3405,6 +3448,206 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties); +class LayerTreeHostTestImplLayersPushProperties + : public LayerTreeHostTestLayersPushProperties { + protected: + virtual void BeginTest() OVERRIDE { + expected_push_properties_root_impl_ = 0; + expected_push_properties_child_impl_ = 0; + expected_push_properties_grandchild_impl_ = 0; + expected_push_properties_child2_impl_ = 0; + expected_push_properties_grandchild2_impl_ = 0; + LayerTreeHostTestLayersPushProperties::BeginTest(); + } + + virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + // These commits are in response to the changes made in + // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame() + switch (num_commits_) { + case 0: + // Tree hasn't been setup yet don't bother to check anything. + return; + case 1: + // Root gets set up, Everyone is initialized. + ++expected_push_properties_root_impl_; + ++expected_push_properties_child_impl_; + ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_child2_impl_; + ++expected_push_properties_grandchild2_impl_; + break; + case 2: + // Tree doesn't change but the one leaf that always pushes is pushed. + ++expected_push_properties_grandchild2_impl_; + break; + case 3: + // Root is swapped here. + // Clear the expected push properties the tree will be rebuilt. + expected_push_properties_root_impl_ = 0; + expected_push_properties_child_impl_ = 0; + expected_push_properties_grandchild_impl_ = 0; + expected_push_properties_child2_impl_ = 0; + expected_push_properties_grandchild2_impl_ = 0; + + // Make sure the new root is pushed. + EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>( + host_impl->RootLayer())->push_properties_count()); + return; + case 4: + // Root is swapped back all of the layers in the tree get pushed. + ++expected_push_properties_root_impl_; + ++expected_push_properties_child_impl_; + ++expected_push_properties_grandchild_impl_; + ++expected_push_properties_child2_impl_; + ++expected_push_properties_grandchild2_impl_; + break; + case 5: + // Tree doesn't change but the one leaf that always pushes is pushed. + ++expected_push_properties_grandchild2_impl_; + break; + case 6: + // First child is removed. Structure of the tree changes here so swap + // some of the values. child_impl becomes child2_impl. + expected_push_properties_child_impl_ = + expected_push_properties_child2_impl_; + expected_push_properties_child2_impl_ = 0; + // grandchild_impl becomes grandchild2_impl. + expected_push_properties_grandchild_impl_ = + expected_push_properties_grandchild2_impl_; + expected_push_properties_grandchild2_impl_ = 0; + + // grandchild_impl is now the leaf that always pushes. It is pushed. + ++expected_push_properties_grandchild_impl_; + break; + case 7: + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild_impl_; + + // Child is added back. New layers are initialized. + ++expected_push_properties_grandchild2_impl_; + ++expected_push_properties_child2_impl_; + break; + case 8: + // Leaf is removed. + expected_push_properties_grandchild2_impl_ = 0; + + // Always pushing. + ++expected_push_properties_grandchild_impl_; + break; + case 9: + // Leaf is added back + ++expected_push_properties_grandchild2_impl_; + + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild_impl_; + break; + case 10: + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild_impl_; + break; + case 11: + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild_impl_; + break; + case 12: + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild_impl_; + + // This child position was changed. + ++expected_push_properties_child2_impl_; + break; + case 13: + // The position of this child was changed. + ++expected_push_properties_child_impl_; + + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild_impl_; + break; + case 14: + // Second child is removed from tree. Don't discard counts because + // they are added back before commit. + + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild_impl_; + + // Second child added back. + ++expected_push_properties_child2_impl_; + ++expected_push_properties_grandchild2_impl_; + + break; + case 15: + // The position of this child was changed. + ++expected_push_properties_grandchild2_impl_; + + // The leaf that always pushes is pushed. + ++expected_push_properties_grandchild_impl_; + break; + case 16: + // Second child is invalidated with SetNeedsDisplay + ++expected_push_properties_child2_impl_; + + // The leaf that always pushed is pushed. + ++expected_push_properties_grandchild_impl_; + break; + } + + PushPropertiesCountingLayerImpl* root_impl_ = NULL; + PushPropertiesCountingLayerImpl* child_impl_ = NULL; + PushPropertiesCountingLayerImpl* child2_impl_ = NULL; + PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL; + PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL; + + // Pull the layers that we need from the tree assuming the same structure + // as LayerTreeHostTestLayersPushProperties + root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( + host_impl->RootLayer()); + + if (root_impl_ && root_impl_->children().size() > 0) { + child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( + root_impl_->children()[0]); + + if (child_impl_ && child_impl_->children().size() > 0) + grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( + child_impl_->children()[0]); + } + + if (root_impl_ && root_impl_->children().size() > 1) { + child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( + root_impl_->children()[1]); + + if (child2_impl_ && child2_impl_->children().size() > 0) + leaf_always_pushing_layer_impl_ = + static_cast<PushPropertiesCountingLayerImpl*>( + child2_impl_->children()[0]); + } + + if (root_impl_) + EXPECT_EQ(expected_push_properties_root_impl_, + root_impl_->push_properties_count()); + if (child_impl_) + EXPECT_EQ(expected_push_properties_child_impl_, + child_impl_->push_properties_count()); + if (grandchild_impl_) + EXPECT_EQ(expected_push_properties_grandchild_impl_, + grandchild_impl_->push_properties_count()); + if (child2_impl_) + EXPECT_EQ(expected_push_properties_child2_impl_, + child2_impl_->push_properties_count()); + if (leaf_always_pushing_layer_impl_) + EXPECT_EQ(expected_push_properties_grandchild2_impl_, + leaf_always_pushing_layer_impl_->push_properties_count()); + } + + size_t expected_push_properties_root_impl_; + size_t expected_push_properties_child_impl_; + size_t expected_push_properties_child2_impl_; + size_t expected_push_properties_grandchild_impl_; + size_t expected_push_properties_grandchild2_impl_; +}; + +TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) { + RunTestWithImplSidePainting(); +} + class LayerTreeHostTestPropertyChangesDuringUpdateArePushed : public LayerTreeHostTest { protected: diff --git a/cc/trees/tree_synchronizer.cc b/cc/trees/tree_synchronizer.cc index 48a9d5b..27f9dab 100644 --- a/cc/trees/tree_synchronizer.cc +++ b/cc/trees/tree_synchronizer.cc @@ -187,17 +187,6 @@ void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers, } // static -void TreeSynchronizer::SetNumDependentsNeedPushProperties( - Layer* layer, size_t num) { - layer->num_dependents_need_push_properties_ = num; -} - -// static -void TreeSynchronizer::SetNumDependentsNeedPushProperties( - LayerImpl* layer, size_t num) { -} - -// static template <typename LayerType> void TreeSynchronizer::PushPropertiesInternal( LayerType* layer, @@ -240,8 +229,8 @@ void TreeSynchronizer::PushPropertiesInternal( // every PushProperties tree walk. Here we keep track of those layers, and // ensure that their ancestors know about them for the next PushProperties // tree walk. - SetNumDependentsNeedPushProperties( - layer, num_dependents_need_push_properties); + layer->num_dependents_need_push_properties_ = + num_dependents_need_push_properties; } bool add_self_to_parent = num_dependents_need_push_properties > 0 || diff --git a/cc/trees/tree_synchronizer.h b/cc/trees/tree_synchronizer.h index de48cee..e7b2e2b 100644 --- a/cc/trees/tree_synchronizer.h +++ b/cc/trees/tree_synchronizer.h @@ -38,9 +38,6 @@ class CC_EXPORT TreeSynchronizer { private: TreeSynchronizer(); // Not instantiable. - static void SetNumDependentsNeedPushProperties(Layer* layer, size_t num); - static void SetNumDependentsNeedPushProperties(LayerImpl* layer, size_t num); - template <typename LayerType> static void PushPropertiesInternal( LayerType* layer, |