From 9fc1aefe025a56eec2b2cab4107484b68820833f Mon Sep 17 00:00:00 2001 From: jaydasika Date: Fri, 26 Jun 2015 16:35:57 -0700 Subject: [PATCH] Add screen space opacity to opacity tree Screen space opacity is required to compute if a layer can use lcd text using property trees. CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1209213002 Cr-Commit-Position: refs/heads/master@{#336474} --- cc/layers/layer.cc | 6 ++++-- cc/layers/layer_impl.cc | 3 ++- cc/trees/draw_property_utils.cc | 10 +++++++++- cc/trees/draw_property_utils.h | 3 +++ cc/trees/property_tree.cc | 12 ++++++++++++ cc/trees/property_tree.h | 14 ++++++++++++-- cc/trees/property_tree_builder.cc | 8 +++++++- cc/trees/property_tree_unittest.cc | 20 ++++++++++++++++++++ 8 files changed, 69 insertions(+), 7 deletions(-) diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 45c9839dcd5e..0e87ff758e6d 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -1412,8 +1412,10 @@ void Layer::OnOpacityAnimated(float opacity) { if (OpacityNode* node = layer_tree_host_->property_trees()->opacity_tree.Node( opacity_tree_index())) { - if (node->owner_id == id()) - node->data = opacity; + if (node->owner_id == id()) { + node->data.opacity = opacity; + layer_tree_host_->property_trees()->opacity_tree.set_needs_update(true); + } } } } diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index bc61a2a1447b..cde5339e2b3c 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -791,7 +791,8 @@ void LayerImpl::UpdatePropertyTreeOpacity() { OpacityTree& opacity_tree = layer_tree_impl()->property_trees()->opacity_tree; OpacityNode* node = opacity_tree.Node(opacity_tree_index_); - node->data = opacity_; + node->data.opacity = opacity_; + opacity_tree.set_needs_update(true); } } diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc index d06ec664b16c..ce23bd480538 100644 --- a/cc/trees/draw_property_utils.cc +++ b/cc/trees/draw_property_utils.cc @@ -430,6 +430,14 @@ void ComputeTransforms(TransformTree* transform_tree) { transform_tree->set_needs_update(false); } +void ComputeOpacities(OpacityTree* opacity_tree) { + if (!opacity_tree->needs_update()) + return; + for (int i = 1; i < static_cast(opacity_tree->size()); ++i) + opacity_tree->UpdateOpacities(i); + opacity_tree->set_needs_update(false); +} + template void ComputeVisibleRectsUsingPropertyTreesInternal( LayerType* root_layer, @@ -582,7 +590,7 @@ float DrawOpacityFromPropertyTreesInternal(LayerType layer, float draw_opacity = 1.f; while (node != target_node) { - draw_opacity *= node->data; + draw_opacity *= node->data.opacity; node = tree.parent(node); } return draw_opacity; diff --git a/cc/trees/draw_property_utils.h b/cc/trees/draw_property_utils.h index a26bc05dcbc3..5eb012d9520b 100644 --- a/cc/trees/draw_property_utils.h +++ b/cc/trees/draw_property_utils.h @@ -33,6 +33,9 @@ ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree); // tree. This must be done prior to calling |ComputeClips|. void CC_EXPORT ComputeTransforms(TransformTree* transform_tree); +// Computes screen space opacity for every node in the opacity tree. +void CC_EXPORT ComputeOpacities(OpacityTree* opacity_tree); + // Computes the visible content rect for every layer under |root_layer|. The // visible content rect is the clipped content space rect that will be used for // recording. diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc index b2e084748b7c..6bb49b470e3c 100644 --- a/cc/trees/property_tree.cc +++ b/cc/trees/property_tree.cc @@ -96,6 +96,9 @@ void TransformNodeData::update_post_local_transform( ClipNodeData::ClipNodeData() : transform_id(-1), target_id(-1) { } +OpacityNodeData::OpacityNodeData() : opacity(1.f), screen_space_opacity(1.f) { +} + bool TransformTree::ComputeTransform(int source_id, int dest_id, gfx::Transform* transform) const { @@ -421,6 +424,15 @@ void TransformTree::UpdateSnapping(TransformNode* node) { node->data.scroll_snap = translation; } +void OpacityTree::UpdateOpacities(int id) { + OpacityNode* node = Node(id); + node->data.screen_space_opacity = node->data.opacity; + + OpacityNode* parent_node = parent(node); + if (parent_node) + node->data.screen_space_opacity *= parent_node->data.screen_space_opacity; +} + PropertyTrees::PropertyTrees() : needs_rebuild(true), sequence_number(0) { } diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h index 3629c473d60d..a9bf41480c63 100644 --- a/cc/trees/property_tree.h +++ b/cc/trees/property_tree.h @@ -140,7 +140,14 @@ struct CC_EXPORT ClipNodeData { typedef TreeNode ClipNode; -typedef TreeNode OpacityNode; +struct CC_EXPORT OpacityNodeData { + OpacityNodeData(); + + float opacity; + float screen_space_opacity; +}; + +typedef TreeNode OpacityNode; template class CC_EXPORT PropertyTree { @@ -290,7 +297,10 @@ class CC_EXPORT TransformTree final : public PropertyTree { class CC_EXPORT ClipTree final : public PropertyTree {}; -class CC_EXPORT OpacityTree final : public PropertyTree {}; +class CC_EXPORT OpacityTree final : public PropertyTree { + public: + void UpdateOpacities(int id); +}; class CC_EXPORT PropertyTrees final { public: diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 54d724b6858f..0091975e93aa 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc @@ -364,7 +364,12 @@ void AddOpacityNodeIfNeeded( OpacityNode node; node.owner_id = layer->id(); - node.data = layer->opacity(); + node.data.opacity = layer->opacity(); + node.data.screen_space_opacity = layer->opacity(); + if (!is_root) + node.data.screen_space_opacity *= + data_from_ancestor.opacity_tree->Node(parent_id) + ->data.screen_space_opacity; data_for_children->opacity_tree_parent = data_for_children->opacity_tree->Insert(node, parent_id); layer->SetOpacityTreeIndex(data_for_children->opacity_tree_parent); @@ -462,6 +467,7 @@ void BuildPropertyTreesTopLevelInternal( // building. property_trees->transform_tree.set_needs_update(false); property_trees->clip_tree.set_needs_update(true); + property_trees->opacity_tree.set_needs_update(false); } void PropertyTreeBuilder::BuildPropertyTrees( diff --git a/cc/trees/property_tree_unittest.cc b/cc/trees/property_tree_unittest.cc index 7e179388b5f6..1bcf3bfe0bef 100644 --- a/cc/trees/property_tree_unittest.cc +++ b/cc/trees/property_tree_unittest.cc @@ -464,4 +464,24 @@ TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) { grand_child_to_parent); } +TEST(PropertyTreeTest, ScreenSpaceOpacityUpdateTest) { + // This tests that screen space opacity is updated for the subtree when + // opacity of a node changes. + OpacityTree tree; + + int parent = tree.Insert(OpacityNode(), 0); + int child = tree.Insert(OpacityNode(), parent); + + EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 1.f); + tree.Node(parent)->data.opacity = 0.5f; + tree.set_needs_update(true); + ComputeOpacities(&tree); + EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 0.5f); + + tree.Node(child)->data.opacity = 0.5f; + tree.set_needs_update(true); + ComputeOpacities(&tree); + EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 0.25f); +} + } // namespace cc -- 2.11.4.GIT