Index: cc/trees/property_tree.cc |
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc |
index 912226b25e525f0e9045e26070783bbe0cb7c5eb..d01ebb4eb822a54ebb34355efe0e1819d76e500b 100644 |
--- a/cc/trees/property_tree.cc |
+++ b/cc/trees/property_tree.cc |
@@ -159,22 +159,6 @@ void TransformTree::clear() { |
#endif |
} |
-bool TransformTree::ComputeTransform(int source_id, |
- int dest_id, |
- gfx::Transform* transform) const { |
- transform->MakeIdentity(); |
- |
- if (source_id == dest_id) |
- return true; |
- |
- if (source_id > dest_id) { |
- CombineTransformsBetween(source_id, dest_id, transform); |
- return true; |
- } |
- |
- return CombineInversesBetween(source_id, dest_id, transform); |
-} |
- |
bool TransformTree::ComputeTranslation(int source_id, |
int dest_id, |
gfx::Transform* transform) const { |
@@ -258,7 +242,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); |
@@ -273,132 +256,6 @@ bool TransformTree::IsDescendant(int desc_id, int source_id) const { |
return true; |
} |
-void TransformTree::CombineTransformsBetween(int source_id, |
- int dest_id, |
- gfx::Transform* transform) const { |
- DCHECK(source_id > dest_id); |
- const TransformNode* current = Node(source_id); |
- const TransformNode* dest = Node(dest_id); |
- // Combine transforms to and from the screen when possible. Since flattening |
- // is a non-linear operation, we cannot use this approach when there is |
- // non-trivial flattening between the source and destination nodes. For |
- // example, consider the tree R->A->B->C, where B flattens its inherited |
- // transform, and A has a non-flat transform. Suppose C is the source and A is |
- // the destination. The expected result is C * B. But C's to_screen |
- // transform is C * B * flattened(A * R), and A's from_screen transform is |
- // R^{-1} * A^{-1}. If at least one of A and R isn't flat, the inverse of |
- // flattened(A * R) won't be R^{-1} * A{-1}, so multiplying C's to_screen and |
- // A's from_screen will not produce the correct result. |
- if (!dest || |
- (dest->ancestors_are_invertible && dest->node_and_ancestors_are_flat)) { |
- transform->ConcatTransform(ToScreen(current->id)); |
- if (dest) |
- transform->ConcatTransform(FromScreen(dest->id)); |
- return; |
- } |
- |
- // Flattening is defined in a way that requires it to be applied while |
- // traversing downward in the tree. We first identify nodes that are on the |
- // path from the source to the destination (this is traversing upward), and |
- // then we visit these nodes in reverse order, flattening as needed. We |
- // early-out if we get to a node whose target node is the destination, since |
- // we can then re-use the target space transform stored at that node. However, |
- // we cannot re-use a stored target space transform if the destination has a |
- // zero surface contents scale, since stored target space transforms have |
- // surface contents scale baked in, but we need to compute an unscaled |
- // transform. |
- std::vector<int> source_to_destination; |
- source_to_destination.push_back(current->id); |
- current = parent(current); |
- bool destination_has_non_zero_surface_contents_scale = |
- dest->surface_contents_scale.x() != 0.f && |
- 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; |
- 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( |
- 1.0f / dest->surface_contents_scale.x(), |
- 1.0f / dest->surface_contents_scale.y(), 1.0f); |
- } else if (current->id < dest_id) { |
- // We have reached the lowest common ancestor of the source and destination |
- // nodes. This case can occur when we are transforming between a node |
- // corresponding to a fixed-position layer (or its descendant) and the node |
- // corresponding to the layer's render target. For example, consider the |
- // layer tree R->T->S->F where F is fixed-position, S owns a render surface, |
- // and T has a significant transform. This will yield the following |
- // transform tree: |
- // R |
- // | |
- // T |
- // /| |
- // S F |
- // In this example, T will have id 2, S will have id 3, and F will have id |
- // 4. When walking up the ancestor chain from F, the first node with a |
- // smaller id than S will be T, the lowest common ancestor of these nodes. |
- // We compute the transform from T to S here, and then from F to T in the |
- // loop below. |
- DCHECK(IsDescendant(dest_id, current->id)); |
- CombineInversesBetween(current->id, dest_id, &combined_transform); |
- DCHECK(combined_transform.IsApproximatelyIdentityOrTranslation( |
- SkDoubleToMScalar(1e-4))); |
- } |
- |
- 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 = Node(source_to_destination[index]); |
- if (node->flattens_inherited_transform) |
- combined_transform.FlattenTo2d(); |
- combined_transform.PreconcatTransform(node->to_parent); |
- } |
- |
- transform->ConcatTransform(combined_transform); |
-} |
- |
-bool TransformTree::CombineInversesBetween(int source_id, |
- int dest_id, |
- gfx::Transform* transform) const { |
- DCHECK(source_id < dest_id); |
- const TransformNode* current = Node(dest_id); |
- const TransformNode* dest = Node(source_id); |
- // Just as in CombineTransformsBetween, we can use screen space transforms in |
- // this computation only when there isn't any non-trivial flattening |
- // involved. |
- if (current->ancestors_are_invertible && |
- current->node_and_ancestors_are_flat) { |
- transform->PreconcatTransform(FromScreen(current->id)); |
- if (dest) |
- transform->PreconcatTransform(ToScreen(dest->id)); |
- return true; |
- } |
- |
- // Inverting a flattening is not equivalent to flattening an inverse. This |
- // means we cannot, for example, use the inverse of each node's to_parent |
- // transform, flattening where needed. Instead, we must compute the transform |
- // from the destination to the source, with flattening, and then invert the |
- // result. |
- gfx::Transform dest_to_source; |
- CombineTransformsBetween(dest_id, source_id, &dest_to_source); |
- gfx::Transform source_to_dest; |
- bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest); |
- transform->PreconcatTransform(source_to_dest); |
- return all_are_invertible; |
-} |
- |
void TransformTree::UpdateLocalTransform(TransformNode* node) { |
gfx::Transform transform = node->post_local; |
if (NeedsSourceToParentUpdate(node)) { |
@@ -495,32 +352,6 @@ void TransformTree::UpdateSurfaceContentsScale(TransformNode* node) { |
ToScreen(node->id), layer_scale_factor); |
} |
-void TransformTree::UpdateTargetSpaceTransform(TransformNode* node, |
- TransformNode* target_node) { |
- gfx::Transform target_space_transform; |
- if (node->needs_surface_contents_scale) { |
- target_space_transform.MakeIdentity(); |
- target_space_transform.Scale(node->surface_contents_scale.x(), |
- node->surface_contents_scale.y()); |
- } else { |
- // In order to include the root transform for the root surface, we walk up |
- // to the root of the transform tree in ComputeTransform. |
- int target_id = target_node->id; |
- ComputeTransform(node->id, target_id, &target_space_transform); |
- if (target_id != kRootNodeId) { |
- target_space_transform.matrix().postScale( |
- target_node->surface_contents_scale.x(), |
- target_node->surface_contents_scale.y(), 1.f); |
- } |
- } |
- |
- gfx::Transform from_target; |
- if (!target_space_transform.GetInverse(&from_target)) |
- node->ancestors_are_invertible = false; |
- SetToTarget(node->id, target_space_transform); |
- SetFromTarget(node->id, from_target); |
-} |
- |
void TransformTree::UpdateAnimationProperties(TransformNode* node, |
TransformNode* parent_node) { |
bool ancestor_is_animating = false; |
@@ -667,40 +498,14 @@ bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { |
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; |
-} |
- |
-void TransformTree::SetFromTarget(int node_id, |
- const gfx::Transform& transform) { |
- DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
- cached_data_[node_id].from_target = transform; |
+ DCHECK(effect_id != EffectTree::kInvalidNodeId); |
+ return property_trees()->GetDrawTransforms(node_id, effect_id).from_target; |
} |
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; |
-} |
- |
-void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) { |
- DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
- cached_data_[node_id].to_target = transform; |
+ DCHECK(effect_id != EffectTree::kInvalidNodeId); |
+ return property_trees()->GetDrawTransforms(node_id, effect_id).to_target; |
} |
const gfx::Transform& TransformTree::FromScreen(int node_id) const { |
@@ -1027,14 +832,8 @@ void EffectTree::TakeCopyRequestsAndTransformToSurface( |
DCHECK_EQ(kRootNodeId, destination_id); |
source_id = TransformTree::kContentsRootNodeId; |
} |
- gfx::Transform transform; |
- property_trees()->transform_tree.ComputeTransform(source_id, destination_id, |
- &transform); |
- if (effect_node->id != kContentsRootNodeId) { |
- transform.matrix().postScale(effect_node->surface_contents_scale.x(), |
- effect_node->surface_contents_scale.y(), |
- 1.f); |
- } |
+ gfx::Transform transform = |
+ property_trees()->GetDrawTransforms(source_id, node_id).to_target; |
it->set_area(MathUtil::MapEnclosingClippedRect(transform, it->area())); |
} |
} |
@@ -1617,8 +1416,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); |
@@ -1663,7 +1461,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_ = |
@@ -1691,8 +1488,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. |
@@ -1717,8 +1512,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); |
@@ -1946,8 +1739,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 |
@@ -2137,10 +1929,8 @@ 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::map<int, DrawTransformData>>( |
+ effect_tree.nodes().size(), std::map<int, DrawTransformData>()); |
} |
void PropertyTrees::UpdateCachedNumber() { |
@@ -2172,32 +1962,16 @@ bool PropertyTrees::ComputeTransformToTarget(int transform_id, |
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 = true; |
+ auto draw_transforms = GetDrawTransforms(transform_id, effect_id); |
+ success = draw_transforms.invertible; |
+ transform->ConcatTransform(draw_transforms.to_target); |
+ 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; |
} |
@@ -2210,30 +1984,13 @@ bool PropertyTrees::ComputeTransformFromTarget( |
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 = true; |
+ auto draw_transforms = GetDrawTransforms(transform_id, effect_id); |
+ success = draw_transforms.invertible; |
+ transform->ConcatTransform(draw_transforms.from_target); |
+ transform->Scale(effect_node->surface_contents_scale.x(), |
+ effect_node->surface_contents_scale.y()); |
return success; |
} |