Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3978)

Unified Diff: cc/trees/property_tree.cc

Issue 2266223002: cc: Compute draw transforms dynamically. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix layout tests Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
}

Powered by Google App Engine
This is Rietveld 408576698