| 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;
|
| }
|
|
|
|
|