Chromium Code Reviews| Index: cc/trees/property_tree.cc |
| diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc |
| index acc34795448ed974e952394e018b5092d051f8e9..838d19397c62edf3030ad2ba94d1706820563c2d 100644 |
| --- a/cc/trees/property_tree.cc |
| +++ b/cc/trees/property_tree.cc |
| @@ -174,6 +174,12 @@ void TransformTree::clear() { |
| #endif |
| } |
| +void TransformTree::set_needs_update(bool needs_update) { |
| + if (needs_update && !needs_update_) |
| + property_trees()->UpdateCachedNumber(); |
| + needs_update_ = needs_update; |
|
ajuma
2016/10/12 20:08:47
Can we make needs_update_ private to make sure it'
sunxd
2016/10/12 21:08:19
I think needs_update_ is already private. Transfor
|
| +} |
| + |
| bool TransformTree::ComputeTransform(int source_id, |
| int dest_id, |
| gfx::Transform* transform) const { |
| @@ -264,7 +270,6 @@ void TransformTree::UpdateTransforms(int id) { |
| TransformNode* parent_node = parent(node); |
| TransformNode* target_node = Node(TargetId(id)); |
| TransformNode* source_node = Node(node->source_node_id); |
| - property_trees()->UpdateCachedNumber(); |
| // TODO(flackr): Only dirty when scroll offset changes. |
| if (node->sticky_position_constraint_id >= 0 || |
| node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) { |
| @@ -276,7 +281,6 @@ void TransformTree::UpdateTransforms(int id) { |
| UpdateSurfaceContentsScale(node); |
| UpdateAnimationProperties(node, parent_node); |
| UpdateSnapping(node); |
| - UpdateTargetSpaceTransform(node, target_node); |
| UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); |
| UpdateTransformChanged(node, parent_node, source_node); |
| UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); |
| @@ -333,19 +337,11 @@ void TransformTree::CombineTransformsBetween(int source_id, |
| dest->surface_contents_scale.y() != 0.f; |
| DCHECK(destination_has_non_zero_surface_contents_scale || |
| !dest->ancestors_are_invertible); |
| - for (; current && current->id > dest_id; current = parent(current)) { |
| - if (destination_has_non_zero_surface_contents_scale && |
| - TargetId(current->id) == dest_id && |
| - ContentTargetId(current->id) == dest_id) |
| - break; |
| + for (; current && current->id > dest_id; current = parent(current)) |
| source_to_destination.push_back(current->id); |
| - } |
| gfx::Transform combined_transform; |
| if (current->id > dest_id) { |
| - // TODO(sunxd): Instead of using target space transform, only use to_parent |
| - // here when we fully implement computing draw transforms on demand. |
| - combined_transform = ToTarget(current->id, kInvalidNodeId); |
| // The stored target space transform has surface contents scale baked in, |
| // but we need the unscaled transform. |
| combined_transform.matrix().postScale( |
| @@ -765,16 +761,10 @@ bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { |
| return !nodes_affected_by_outer_viewport_bounds_delta_.empty(); |
| } |
| -const gfx::Transform& TransformTree::FromTarget(int node_id, |
| - int effect_id) const { |
| - DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
| - if (effect_id != kInvalidNodeId && |
| - property_trees()->verify_transform_tree_calculations) { |
| - const gfx::Transform& transform = |
| - property_trees()->GetDrawTransforms(node_id, effect_id).from_target; |
| - CHECK(transform.ApproximatelyEqual(cached_data_[node_id].from_target)); |
| - } |
| - return cached_data_[node_id].from_target; |
| +gfx::Transform TransformTree::FromTarget(int node_id, int effect_id) const { |
| + gfx::Transform from_target; |
| + property_trees()->GetFromTarget(node_id, effect_id, &from_target); |
| + return from_target; |
| } |
| void TransformTree::SetFromTarget(int node_id, |
| @@ -783,19 +773,10 @@ void TransformTree::SetFromTarget(int node_id, |
| cached_data_[node_id].from_target = transform; |
| } |
| -const gfx::Transform& TransformTree::ToTarget(int node_id, |
| - int effect_id) const { |
| - DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
| - if (effect_id != kInvalidNodeId && |
| - property_trees()->verify_transform_tree_calculations) { |
| - const gfx::Transform& transform = |
| - property_trees()->GetDrawTransforms(node_id, effect_id).to_target; |
| - if (property_trees()->non_root_surfaces_enabled) |
| - CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_target)); |
| - else |
| - CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_screen)); |
| - } |
| - return cached_data_[node_id].to_target; |
| +gfx::Transform TransformTree::ToTarget(int node_id, int effect_id) const { |
| + gfx::Transform to_target; |
| + property_trees()->GetToTarget(node_id, effect_id, &to_target); |
| + return to_target; |
| } |
| void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) { |
| @@ -1751,8 +1732,7 @@ PropertyTrees::PropertyTrees() |
| full_tree_damaged(false), |
| sequence_number(0), |
| is_main_thread(true), |
| - is_active(false), |
| - verify_transform_tree_calculations(false) { |
| + is_active(false) { |
| transform_tree.SetPropertyTrees(this); |
| effect_tree.SetPropertyTrees(this); |
| clip_tree.SetPropertyTrees(this); |
| @@ -1797,7 +1777,6 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) { |
| sequence_number = from.sequence_number; |
| is_main_thread = from.is_main_thread; |
| is_active = from.is_active; |
| - verify_transform_tree_calculations = from.verify_transform_tree_calculations; |
| inner_viewport_container_bounds_delta_ = |
| from.inner_viewport_container_bounds_delta(); |
| outer_viewport_container_bounds_delta_ = |
| @@ -1825,8 +1804,6 @@ void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const { |
| proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled); |
| proto->set_is_main_thread(is_main_thread); |
| proto->set_is_active(is_active); |
| - proto->set_verify_transform_tree_calculations( |
| - verify_transform_tree_calculations); |
| // TODO(khushalsagar): Consider using the sequence number to decide if |
| // property trees need to be serialized again for a commit. See crbug/555370. |
| @@ -1851,8 +1828,6 @@ void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) { |
| sequence_number = proto.sequence_number(); |
| is_main_thread = proto.is_main_thread(); |
| is_active = proto.is_active(); |
| - verify_transform_tree_calculations = |
| - proto.verify_transform_tree_calculations(); |
| transform_tree.SetPropertyTrees(this); |
| effect_tree.SetPropertyTrees(this); |
| @@ -2080,8 +2055,7 @@ CombinedAnimationScale PropertyTrees::GetAnimationScales( |
| // Computing maximum animated scale in the presence of non-scale/translation |
| // transforms isn't supported. |
| bool failed_for_non_scale_or_translation = |
| - !transform_tree.Node(transform_node_id) |
| - ->to_parent.IsScaleOrTranslation(); |
| + !node->to_parent.IsScaleOrTranslation(); |
| // We don't attempt to accumulate animation scale from multiple nodes with |
| // scale animations, because of the risk of significant overestimation. For |
| @@ -2186,95 +2160,122 @@ void PropertyTrees::SetAnimationScalesForTesting( |
| cached_data_.property_tree_update_number; |
| } |
| -const DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id, |
| - int effect_id) const { |
| - if (cached_data_.draw_transforms[effect_id][transform_id].update_number != |
| - cached_data_.property_tree_update_number) { |
| - gfx::Transform target_space_transform; |
| - gfx::Transform from_target; |
| - const TransformNode* transform_node = transform_tree.Node(transform_id); |
| - const EffectNode* effect_node = effect_tree.Node(effect_id); |
| - const TransformNode* dest_node = |
| - transform_tree.Node(effect_node->transform_id); |
| - DCHECK(effect_id == effect_tree.kRootNodeId || |
| - effect_node->has_render_surface); |
| - bool already_computed_inverse = false; |
| - if (transform_id == effect_node->transform_id) { |
| - target_space_transform.Scale(effect_node->surface_contents_scale.x(), |
| - effect_node->surface_contents_scale.y()); |
| - } else if (!dest_node || (dest_node->ancestors_are_invertible && |
| - dest_node->node_and_ancestors_are_flat)) { |
| - // Compute transform from transform_id to effect_node->transform using |
| - // screen space transforms. |
| - target_space_transform.ConcatTransform( |
| - transform_tree.ToScreen(transform_id)); |
| - if (dest_node) |
| - target_space_transform.ConcatTransform( |
| - transform_tree.FromScreen(dest_node->id)); |
| - if (dest_node->needs_surface_contents_scale) |
| - target_space_transform.matrix().postScale( |
| - dest_node->surface_contents_scale.x(), |
| - dest_node->surface_contents_scale.y(), 1.f); |
| - } else if (transform_node->id > dest_node->id) { |
| - target_space_transform = |
| - GetDrawTransforms(transform_node->parent_id, effect_id).to_target; |
| - if (transform_node->flattens_inherited_transform) |
| - target_space_transform.FlattenTo2d(); |
| - target_space_transform.PreconcatTransform(transform_node->to_parent); |
| - } else { |
| - const TransformNode* current = dest_node; |
| - std::vector<int> source_to_destination; |
| - source_to_destination.push_back(current->id); |
| - current = transform_tree.parent(current); |
| - for (; current && current->id > transform_node->id; |
| - current = transform_tree.parent(current)) { |
| - source_to_destination.push_back(current->id); |
| - } |
| - DCHECK_EQ(current, transform_node); |
| - gfx::Transform combined_transform; |
| - size_t source_to_destination_size = source_to_destination.size(); |
| - for (size_t i = 0; i < source_to_destination_size; ++i) { |
| - size_t index = source_to_destination_size - 1 - i; |
| - const TransformNode* node = |
| - transform_tree.Node(source_to_destination[index]); |
| - if (node->flattens_inherited_transform) |
| - combined_transform.FlattenTo2d(); |
| - combined_transform.PreconcatTransform(node->to_parent); |
| - } |
| - if (effect_node->surface_contents_scale.x() != 0.f && |
| - effect_node->surface_contents_scale.y() != 0.f) |
| - combined_transform.Scale( |
| - 1.0f / effect_node->surface_contents_scale.x(), |
| - 1.0f / effect_node->surface_contents_scale.y()); |
| - cached_data_.draw_transforms[effect_id][transform_id] |
| - .transforms.invertible = |
| - combined_transform.GetInverse(&target_space_transform); |
| - from_target = combined_transform; |
| - already_computed_inverse = true; |
| - } |
| - if (!already_computed_inverse) { |
| - cached_data_.draw_transforms[effect_id][transform_id] |
| - .transforms.invertible = |
| - target_space_transform.GetInverse(&from_target); |
| +bool PropertyTrees::GetToTarget(int transform_id, |
| + int effect_id, |
| + gfx::Transform* to_target) const { |
| + DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id); |
| + if (transforms.to_valid) { |
| + *to_target = transforms.to_target; |
| + return true; |
| + } else if (!transforms.invertible) { |
| + return false; |
| + } else { |
| + transforms.invertible = transforms.from_target.GetInverse(to_target); |
| + transforms.to_valid = transforms.invertible; |
| + transforms.to_target = *to_target; |
| + return transforms.to_valid; |
| + } |
| +} |
| + |
| +bool PropertyTrees::GetFromTarget(int transform_id, |
| + int effect_id, |
| + gfx::Transform* from_target) const { |
| + DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id); |
| + if (transforms.from_valid) { |
| + *from_target = transforms.from_target; |
| + return true; |
| + } else if (!transforms.invertible) { |
| + return false; |
| + } else { |
| + transforms.invertible = transforms.to_target.GetInverse(from_target); |
| + transforms.from_valid = transforms.invertible; |
| + transforms.from_target = *from_target; |
| + return transforms.from_valid; |
| + } |
| +} |
| + |
| +DrawTransformData& PropertyTrees::FetchDrawTransformsDataFromCache( |
| + int transform_id, |
| + int dest_id) const { |
| + int cnt = 0; |
| + for (const auto& transform_data : |
| + cached_data_.draw_transforms[transform_id]) { |
| + if (transform_data.target_id == dest_id || transform_data.target_id == -1) { |
|
ajuma
2016/10/12 20:08:47
Which cases is the "-1" check supposed to handle?
sunxd
2016/10/12 21:08:19
In PropertyTrees::ResetCachedData, we initialize d
ajuma
2016/10/12 21:37:41
Ah! Please add a comment about this.
|
| + return cached_data_.draw_transforms[transform_id][cnt]; |
|
ajuma
2016/10/12 20:08:47
Would it work to return |transform_data| here (so
sunxd
2016/10/12 21:08:19
Done.
|
| } |
| - cached_data_.draw_transforms[effect_id][transform_id].update_number = |
| - cached_data_.property_tree_update_number; |
| - cached_data_.draw_transforms[effect_id][transform_id] |
| - .transforms.from_target = from_target; |
| - cached_data_.draw_transforms[effect_id][transform_id].transforms.to_target = |
| - target_space_transform; |
| + cnt++; |
| + } |
| + // Add an entry to the cache. |
| + cached_data_.draw_transforms[transform_id].push_back(DrawTransformData()); |
| + DrawTransformData& data = cached_data_.draw_transforms[transform_id][cnt]; |
| + data.update_number = -1; |
| + data.target_id = dest_id; |
| + return data; |
| +} |
| + |
| +DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id, |
| + int effect_id) const { |
| + const EffectNode* effect_node = effect_tree.Node(effect_id); |
| + int dest_id = effect_node->transform_id; |
| + |
| + DrawTransformData& data = |
| + FetchDrawTransformsDataFromCache(transform_id, dest_id); |
| + |
| + DCHECK(data.update_number != cached_data_.property_tree_update_number || |
| + data.target_id != -1); |
|
ajuma
2016/10/12 20:08:47
In what situations do we have target_id -1 (and wh
sunxd
2016/10/12 21:08:19
As stated in the comments in Fetch function, it is
|
| + if (data.update_number == cached_data_.property_tree_update_number) |
| + return data.transforms; |
| + |
| + // Cache miss. |
| + gfx::Transform target_space_transform; |
| + gfx::Transform from_target; |
| + bool already_computed_inverse = false; |
| + if (transform_id == dest_id) { |
| + target_space_transform.Scale(effect_node->surface_contents_scale.x(), |
| + effect_node->surface_contents_scale.y()); |
| + data.transforms.to_valid = true; |
| + data.transforms.from_valid = false; |
| + } else if (transform_id > dest_id) { |
| + transform_tree.CombineTransformsBetween(transform_id, dest_id, |
| + &target_space_transform); |
| + if (dest_id != TransformTree::kRootNodeId) |
|
ajuma
2016/10/12 20:08:47
https://codereview.chromium.org/2408243002/ might
sunxd
2016/10/12 21:08:19
Is it safe that we do not apply root surface conte
|
| + target_space_transform.matrix().postScale( |
| + effect_node->surface_contents_scale.x(), |
| + effect_node->surface_contents_scale.y(), 1.f); |
| + data.transforms.to_valid = true; |
| + data.transforms.from_valid = false; |
| + data.transforms.invertible = true; |
| + } else { |
| + gfx::Transform combined_transform; |
| + transform_tree.CombineTransformsBetween(dest_id, transform_id, |
| + &combined_transform); |
| + if (effect_node->surface_contents_scale.x() != 0.f && |
| + effect_node->surface_contents_scale.y() != 0.f) |
| + combined_transform.Scale(1.0f / effect_node->surface_contents_scale.x(), |
| + 1.0f / effect_node->surface_contents_scale.y()); |
| + bool invertible = combined_transform.GetInverse(&target_space_transform); |
| + data.transforms.invertible = invertible; |
| + data.transforms.to_valid = invertible; |
| + data.transforms.from_valid = true; |
| + from_target = combined_transform; |
| + already_computed_inverse = true; |
| } |
| - return cached_data_.draw_transforms[effect_id][transform_id].transforms; |
| + |
| + if (!already_computed_inverse) |
| + data.transforms.to_valid = true; |
| + data.update_number = cached_data_.property_tree_update_number; |
| + data.target_id = dest_id; |
| + data.transforms.from_target = from_target; |
| + data.transforms.to_target = target_space_transform; |
| + return data.transforms; |
| } |
| void PropertyTrees::ResetCachedData() { |
| cached_data_.property_tree_update_number = 0; |
| cached_data_.animation_scales = std::vector<AnimationScaleData>( |
| transform_tree.nodes().size(), AnimationScaleData()); |
| - cached_data_.draw_transforms = |
| - std::vector<std::unordered_map<int, DrawTransformData>>( |
| - effect_tree.nodes().size(), |
| - std::unordered_map<int, DrawTransformData>()); |
| + cached_data_.draw_transforms = std::vector<std::vector<DrawTransformData>>( |
| + transform_tree.nodes().size(), std::vector<DrawTransformData>(1)); |
| } |
| void PropertyTrees::UpdateCachedNumber() { |
| @@ -2302,36 +2303,17 @@ bool PropertyTrees::ComputeTransformToTarget(int transform_id, |
| int effect_id, |
| gfx::Transform* transform) const { |
| transform->MakeIdentity(); |
| - |
| if (transform_id == TransformTree::kInvalidNodeId) |
| return true; |
| - int target_transform_id; |
| const EffectNode* effect_node = effect_tree.Node(effect_id); |
| - if (effect_id == EffectTree::kInvalidNodeId) { |
| - // This can happen when PaintArtifactCompositor builds property trees as |
| - // it doesn't set effect ids on clip nodes. We want to compute transform |
| - // to the root in this case. |
| - target_transform_id = TransformTree::kRootNodeId; |
| - } else { |
| - DCHECK(effect_node->has_render_surface || |
| - effect_node->id == EffectTree::kRootNodeId); |
| - target_transform_id = effect_node->transform_id; |
| - } |
| - bool success = transform_tree.ComputeTransform( |
| - transform_id, target_transform_id, transform); |
| - if (verify_transform_tree_calculations) { |
| - gfx::Transform to_target; |
| - to_target.ConcatTransform( |
| - GetDrawTransforms(transform_id, effect_id).to_target); |
| - if (effect_node->surface_contents_scale.x() != 0.f && |
| - effect_node->surface_contents_scale.y() != 0.f) |
| - to_target.matrix().postScale( |
| - 1.0f / effect_node->surface_contents_scale.x(), |
| - 1.0f / effect_node->surface_contents_scale.y(), 1.0f); |
| - DCHECK(to_target.ApproximatelyEqual(*transform)); |
| - } |
| + bool success = GetToTarget(transform_id, effect_id, transform); |
| + if (effect_node->surface_contents_scale.x() != 0.f && |
| + effect_node->surface_contents_scale.y() != 0.f) |
| + transform->matrix().postScale( |
| + 1.0f / effect_node->surface_contents_scale.x(), |
| + 1.0f / effect_node->surface_contents_scale.y(), 1.0f); |
| return success; |
| } |
| @@ -2340,34 +2322,14 @@ bool PropertyTrees::ComputeTransformFromTarget( |
| int effect_id, |
| gfx::Transform* transform) const { |
| transform->MakeIdentity(); |
| - |
| if (transform_id == TransformTree::kInvalidNodeId) |
| return true; |
| - int target_transform_id; |
| const EffectNode* effect_node = effect_tree.Node(effect_id); |
| - if (effect_id == EffectTree::kInvalidNodeId) { |
| - // This can happen when PaintArtifactCompositor builds property trees as |
| - // it doesn't set effect ids on clip nodes. We want to compute transform |
| - // to the root in this case. |
| - target_transform_id = TransformTree::kRootNodeId; |
| - } else { |
| - DCHECK(effect_node->has_render_surface || |
| - effect_node->id == EffectTree::kRootNodeId); |
| - target_transform_id = effect_node->transform_id; |
| - } |
| - |
| - bool success = transform_tree.ComputeTransform(target_transform_id, |
| - transform_id, transform); |
| - if (verify_transform_tree_calculations) { |
| - auto draw_transforms = GetDrawTransforms(transform_id, effect_id); |
| - gfx::Transform from_target; |
| - from_target.ConcatTransform(draw_transforms.from_target); |
| - from_target.Scale(effect_node->surface_contents_scale.x(), |
| - effect_node->surface_contents_scale.y()); |
| - DCHECK(from_target.ApproximatelyEqual(*transform) || |
| - !draw_transforms.invertible); |
| - } |
| + |
| + bool success = GetFromTarget(transform_id, effect_id, transform); |
| + transform->Scale(effect_node->surface_contents_scale.x(), |
| + effect_node->surface_contents_scale.y()); |
| return success; |
| } |