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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 152
153 #if DCHECK_IS_ON() 153 #if DCHECK_IS_ON()
154 TransformTree tree; 154 TransformTree tree;
155 // TODO(jaydasika) : Move tests that expect source_to_parent_updates_allowed 155 // TODO(jaydasika) : Move tests that expect source_to_parent_updates_allowed
156 // to be true on impl thread to main thread and set it to is_main_thread here. 156 // to be true on impl thread to main thread and set it to is_main_thread here.
157 tree.source_to_parent_updates_allowed_ = source_to_parent_updates_allowed_; 157 tree.source_to_parent_updates_allowed_ = source_to_parent_updates_allowed_;
158 DCHECK(tree == *this); 158 DCHECK(tree == *this);
159 #endif 159 #endif
160 } 160 }
161 161
162 bool TransformTree::ComputeTransform(int source_id,
163 int dest_id,
164 gfx::Transform* transform) const {
165 transform->MakeIdentity();
166
167 if (source_id == dest_id)
168 return true;
169
170 if (source_id > dest_id) {
171 CombineTransformsBetween(source_id, dest_id, transform);
172 return true;
173 }
174
175 return CombineInversesBetween(source_id, dest_id, transform);
176 }
177
178 bool TransformTree::ComputeTranslation(int source_id, 162 bool TransformTree::ComputeTranslation(int source_id,
179 int dest_id, 163 int dest_id,
180 gfx::Transform* transform) const { 164 gfx::Transform* transform) const {
181 transform->MakeIdentity(); 165 transform->MakeIdentity();
182 if (source_id == dest_id) 166 if (source_id == dest_id)
183 return true; 167 return true;
184 168
185 const TransformNode* dest = Node(dest_id); 169 const TransformNode* dest = Node(dest_id);
186 if (!dest->ancestors_are_invertible) 170 if (!dest->ancestors_are_invertible)
187 return false; 171 return false;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 TransformNode* source_node = Node(node->source_node_id); 235 TransformNode* source_node = Node(node->source_node_id);
252 property_trees()->UpdateCachedNumber(); 236 property_trees()->UpdateCachedNumber();
253 if (node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) 237 if (node->needs_local_transform_update || NeedsSourceToParentUpdate(node))
254 UpdateLocalTransform(node); 238 UpdateLocalTransform(node);
255 else 239 else
256 UndoSnapping(node); 240 UndoSnapping(node);
257 UpdateScreenSpaceTransform(node, parent_node, target_node); 241 UpdateScreenSpaceTransform(node, parent_node, target_node);
258 UpdateSurfaceContentsScale(node); 242 UpdateSurfaceContentsScale(node);
259 UpdateAnimationProperties(node, parent_node); 243 UpdateAnimationProperties(node, parent_node);
260 UpdateSnapping(node); 244 UpdateSnapping(node);
261 UpdateTargetSpaceTransform(node, target_node);
262 UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); 245 UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node);
263 UpdateTransformChanged(node, parent_node, source_node); 246 UpdateTransformChanged(node, parent_node, source_node);
264 UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); 247 UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node);
265 } 248 }
266 249
267 bool TransformTree::IsDescendant(int desc_id, int source_id) const { 250 bool TransformTree::IsDescendant(int desc_id, int source_id) const {
268 while (desc_id != source_id) { 251 while (desc_id != source_id) {
269 if (desc_id == kInvalidNodeId) 252 if (desc_id == kInvalidNodeId)
270 return false; 253 return false;
271 desc_id = Node(desc_id)->parent_id; 254 desc_id = Node(desc_id)->parent_id;
272 } 255 }
273 return true; 256 return true;
274 } 257 }
275 258
276 void TransformTree::CombineTransformsBetween(int source_id,
277 int dest_id,
278 gfx::Transform* transform) const {
279 DCHECK(source_id > dest_id);
280 const TransformNode* current = Node(source_id);
281 const TransformNode* dest = Node(dest_id);
282 // Combine transforms to and from the screen when possible. Since flattening
283 // is a non-linear operation, we cannot use this approach when there is
284 // non-trivial flattening between the source and destination nodes. For
285 // example, consider the tree R->A->B->C, where B flattens its inherited
286 // transform, and A has a non-flat transform. Suppose C is the source and A is
287 // the destination. The expected result is C * B. But C's to_screen
288 // transform is C * B * flattened(A * R), and A's from_screen transform is
289 // R^{-1} * A^{-1}. If at least one of A and R isn't flat, the inverse of
290 // flattened(A * R) won't be R^{-1} * A{-1}, so multiplying C's to_screen and
291 // A's from_screen will not produce the correct result.
292 if (!dest ||
293 (dest->ancestors_are_invertible && dest->node_and_ancestors_are_flat)) {
294 transform->ConcatTransform(ToScreen(current->id));
295 if (dest)
296 transform->ConcatTransform(FromScreen(dest->id));
297 return;
298 }
299
300 // Flattening is defined in a way that requires it to be applied while
301 // traversing downward in the tree. We first identify nodes that are on the
302 // path from the source to the destination (this is traversing upward), and
303 // then we visit these nodes in reverse order, flattening as needed. We
304 // early-out if we get to a node whose target node is the destination, since
305 // we can then re-use the target space transform stored at that node. However,
306 // we cannot re-use a stored target space transform if the destination has a
307 // zero surface contents scale, since stored target space transforms have
308 // surface contents scale baked in, but we need to compute an unscaled
309 // transform.
310 std::vector<int> source_to_destination;
311 source_to_destination.push_back(current->id);
312 current = parent(current);
313 bool destination_has_non_zero_surface_contents_scale =
314 dest->surface_contents_scale.x() != 0.f &&
315 dest->surface_contents_scale.y() != 0.f;
316 DCHECK(destination_has_non_zero_surface_contents_scale ||
317 !dest->ancestors_are_invertible);
318 for (; current && current->id > dest_id; current = parent(current)) {
319 if (destination_has_non_zero_surface_contents_scale &&
320 TargetId(current->id) == dest_id &&
321 ContentTargetId(current->id) == dest_id)
322 break;
323 source_to_destination.push_back(current->id);
324 }
325
326 gfx::Transform combined_transform;
327 if (current->id > dest_id) {
328 // TODO(sunxd): Instead of using target space transform, only use to_parent
329 // here when we fully implement computing draw transforms on demand.
330 combined_transform = ToTarget(current->id, kInvalidNodeId);
331 // The stored target space transform has surface contents scale baked in,
332 // but we need the unscaled transform.
333 combined_transform.matrix().postScale(
334 1.0f / dest->surface_contents_scale.x(),
335 1.0f / dest->surface_contents_scale.y(), 1.0f);
336 } else if (current->id < dest_id) {
337 // We have reached the lowest common ancestor of the source and destination
338 // nodes. This case can occur when we are transforming between a node
339 // corresponding to a fixed-position layer (or its descendant) and the node
340 // corresponding to the layer's render target. For example, consider the
341 // layer tree R->T->S->F where F is fixed-position, S owns a render surface,
342 // and T has a significant transform. This will yield the following
343 // transform tree:
344 // R
345 // |
346 // T
347 // /|
348 // S F
349 // In this example, T will have id 2, S will have id 3, and F will have id
350 // 4. When walking up the ancestor chain from F, the first node with a
351 // smaller id than S will be T, the lowest common ancestor of these nodes.
352 // We compute the transform from T to S here, and then from F to T in the
353 // loop below.
354 DCHECK(IsDescendant(dest_id, current->id));
355 CombineInversesBetween(current->id, dest_id, &combined_transform);
356 DCHECK(combined_transform.IsApproximatelyIdentityOrTranslation(
357 SkDoubleToMScalar(1e-4)));
358 }
359
360 size_t source_to_destination_size = source_to_destination.size();
361 for (size_t i = 0; i < source_to_destination_size; ++i) {
362 size_t index = source_to_destination_size - 1 - i;
363 const TransformNode* node = Node(source_to_destination[index]);
364 if (node->flattens_inherited_transform)
365 combined_transform.FlattenTo2d();
366 combined_transform.PreconcatTransform(node->to_parent);
367 }
368
369 transform->ConcatTransform(combined_transform);
370 }
371
372 bool TransformTree::CombineInversesBetween(int source_id,
373 int dest_id,
374 gfx::Transform* transform) const {
375 DCHECK(source_id < dest_id);
376 const TransformNode* current = Node(dest_id);
377 const TransformNode* dest = Node(source_id);
378 // Just as in CombineTransformsBetween, we can use screen space transforms in
379 // this computation only when there isn't any non-trivial flattening
380 // involved.
381 if (current->ancestors_are_invertible &&
382 current->node_and_ancestors_are_flat) {
383 transform->PreconcatTransform(FromScreen(current->id));
384 if (dest)
385 transform->PreconcatTransform(ToScreen(dest->id));
386 return true;
387 }
388
389 // Inverting a flattening is not equivalent to flattening an inverse. This
390 // means we cannot, for example, use the inverse of each node's to_parent
391 // transform, flattening where needed. Instead, we must compute the transform
392 // from the destination to the source, with flattening, and then invert the
393 // result.
394 gfx::Transform dest_to_source;
395 CombineTransformsBetween(dest_id, source_id, &dest_to_source);
396 gfx::Transform source_to_dest;
397 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest);
398 transform->PreconcatTransform(source_to_dest);
399 return all_are_invertible;
400 }
401
402 void TransformTree::UpdateLocalTransform(TransformNode* node) { 259 void TransformTree::UpdateLocalTransform(TransformNode* node) {
403 gfx::Transform transform = node->post_local; 260 gfx::Transform transform = node->post_local;
404 if (NeedsSourceToParentUpdate(node)) { 261 if (NeedsSourceToParentUpdate(node)) {
405 gfx::Transform to_parent; 262 gfx::Transform to_parent;
406 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent); 263 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent);
407 gfx::Vector2dF unsnapping; 264 gfx::Vector2dF unsnapping;
408 TransformNode* current; 265 TransformNode* current;
409 TransformNode* parent_node; 266 TransformNode* parent_node;
410 for (current = Node(node->source_node_id); current->id > node->parent_id; 267 for (current = Node(node->source_node_id); current->id > node->parent_id;
411 current = parent(current)) { 268 current = parent(current)) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } 345 }
489 346
490 float layer_scale_factor = 347 float layer_scale_factor =
491 device_scale_factor_ * device_transform_scale_factor_; 348 device_scale_factor_ * device_transform_scale_factor_;
492 if (node->in_subtree_of_page_scale_layer) 349 if (node->in_subtree_of_page_scale_layer)
493 layer_scale_factor *= page_scale_factor_; 350 layer_scale_factor *= page_scale_factor_;
494 node->surface_contents_scale = MathUtil::ComputeTransform2dScaleComponents( 351 node->surface_contents_scale = MathUtil::ComputeTransform2dScaleComponents(
495 ToScreen(node->id), layer_scale_factor); 352 ToScreen(node->id), layer_scale_factor);
496 } 353 }
497 354
498 void TransformTree::UpdateTargetSpaceTransform(TransformNode* node,
499 TransformNode* target_node) {
500 gfx::Transform target_space_transform;
501 if (node->needs_surface_contents_scale) {
502 target_space_transform.MakeIdentity();
503 target_space_transform.Scale(node->surface_contents_scale.x(),
504 node->surface_contents_scale.y());
505 } else {
506 // In order to include the root transform for the root surface, we walk up
507 // to the root of the transform tree in ComputeTransform.
508 int target_id = target_node->id;
509 ComputeTransform(node->id, target_id, &target_space_transform);
510 if (target_id != kRootNodeId) {
511 target_space_transform.matrix().postScale(
512 target_node->surface_contents_scale.x(),
513 target_node->surface_contents_scale.y(), 1.f);
514 }
515 }
516
517 gfx::Transform from_target;
518 if (!target_space_transform.GetInverse(&from_target))
519 node->ancestors_are_invertible = false;
520 SetToTarget(node->id, target_space_transform);
521 SetFromTarget(node->id, from_target);
522 }
523
524 void TransformTree::UpdateAnimationProperties(TransformNode* node, 355 void TransformTree::UpdateAnimationProperties(TransformNode* node,
525 TransformNode* parent_node) { 356 TransformNode* parent_node) {
526 bool ancestor_is_animating = false; 357 bool ancestor_is_animating = false;
527 if (parent_node) 358 if (parent_node)
528 ancestor_is_animating = parent_node->to_screen_is_potentially_animated; 359 ancestor_is_animating = parent_node->to_screen_is_potentially_animated;
529 node->to_screen_is_potentially_animated = 360 node->to_screen_is_potentially_animated =
530 node->has_potential_animation || ancestor_is_animating; 361 node->has_potential_animation || ancestor_is_animating;
531 } 362 }
532 363
533 void TransformTree::UndoSnapping(TransformNode* node) { 364 void TransformTree::UndoSnapping(TransformNode* node) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 bool TransformTree::HasNodesAffectedByInnerViewportBoundsDelta() const { 491 bool TransformTree::HasNodesAffectedByInnerViewportBoundsDelta() const {
661 return !nodes_affected_by_inner_viewport_bounds_delta_.empty(); 492 return !nodes_affected_by_inner_viewport_bounds_delta_.empty();
662 } 493 }
663 494
664 bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { 495 bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const {
665 return !nodes_affected_by_outer_viewport_bounds_delta_.empty(); 496 return !nodes_affected_by_outer_viewport_bounds_delta_.empty();
666 } 497 }
667 498
668 const gfx::Transform& TransformTree::FromTarget(int node_id, 499 const gfx::Transform& TransformTree::FromTarget(int node_id,
669 int effect_id) const { 500 int effect_id) const {
670 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 501 DCHECK(effect_id != EffectTree::kInvalidNodeId);
671 if (effect_id != kInvalidNodeId && 502 return property_trees()->GetDrawTransforms(node_id, effect_id).from_target;
672 property_trees()->verify_transform_tree_calculations) {
673 const gfx::Transform& transform =
674 property_trees()->GetDrawTransforms(node_id, effect_id).from_target;
675 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].from_target));
676 }
677 return cached_data_[node_id].from_target;
678 }
679
680 void TransformTree::SetFromTarget(int node_id,
681 const gfx::Transform& transform) {
682 DCHECK(static_cast<int>(cached_data_.size()) > node_id);
683 cached_data_[node_id].from_target = transform;
684 } 503 }
685 504
686 const gfx::Transform& TransformTree::ToTarget(int node_id, 505 const gfx::Transform& TransformTree::ToTarget(int node_id,
687 int effect_id) const { 506 int effect_id) const {
688 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 507 DCHECK(effect_id != EffectTree::kInvalidNodeId);
689 if (effect_id != kInvalidNodeId && 508 return property_trees()->GetDrawTransforms(node_id, effect_id).to_target;
690 property_trees()->verify_transform_tree_calculations) {
691 const gfx::Transform& transform =
692 property_trees()->GetDrawTransforms(node_id, effect_id).to_target;
693 if (property_trees()->non_root_surfaces_enabled)
694 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_target));
695 else
696 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_screen));
697 }
698 return cached_data_[node_id].to_target;
699 }
700
701 void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) {
702 DCHECK(static_cast<int>(cached_data_.size()) > node_id);
703 cached_data_[node_id].to_target = transform;
704 } 509 }
705 510
706 const gfx::Transform& TransformTree::FromScreen(int node_id) const { 511 const gfx::Transform& TransformTree::FromScreen(int node_id) const {
707 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 512 DCHECK(static_cast<int>(cached_data_.size()) > node_id);
708 return cached_data_[node_id].from_screen; 513 return cached_data_[node_id].from_screen;
709 } 514 }
710 515
711 void TransformTree::SetFromScreen(int node_id, 516 void TransformTree::SetFromScreen(int node_id,
712 const gfx::Transform& transform) { 517 const gfx::Transform& transform) {
713 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 518 DCHECK(static_cast<int>(cached_data_.size()) > node_id);
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 if (effect_node->parent_id != -1) { 825 if (effect_node->parent_id != -1) {
1021 // For non-root surfaces, transform only by sub-layer scale. 826 // For non-root surfaces, transform only by sub-layer scale.
1022 source_id = destination_id; 827 source_id = destination_id;
1023 } else { 828 } else {
1024 // The root surface doesn't have the notion of sub-layer scale, but 829 // The root surface doesn't have the notion of sub-layer scale, but
1025 // instead has a similar notion of transforming from the space of the root 830 // instead has a similar notion of transforming from the space of the root
1026 // layer to the space of the screen. 831 // layer to the space of the screen.
1027 DCHECK_EQ(kRootNodeId, destination_id); 832 DCHECK_EQ(kRootNodeId, destination_id);
1028 source_id = TransformTree::kContentsRootNodeId; 833 source_id = TransformTree::kContentsRootNodeId;
1029 } 834 }
1030 gfx::Transform transform; 835 gfx::Transform transform =
1031 property_trees()->transform_tree.ComputeTransform(source_id, destination_id, 836 property_trees()->GetDrawTransforms(source_id, node_id).to_target;
1032 &transform);
1033 if (effect_node->id != kContentsRootNodeId) {
1034 transform.matrix().postScale(effect_node->surface_contents_scale.x(),
1035 effect_node->surface_contents_scale.y(),
1036 1.f);
1037 }
1038 it->set_area(MathUtil::MapEnclosingClippedRect(transform, it->area())); 837 it->set_area(MathUtil::MapEnclosingClippedRect(transform, it->area()));
1039 } 838 }
1040 } 839 }
1041 840
1042 bool EffectTree::HasCopyRequests() const { 841 bool EffectTree::HasCopyRequests() const {
1043 return !copy_requests_.empty(); 842 return !copy_requests_.empty();
1044 } 843 }
1045 844
1046 void EffectTree::ClearCopyRequests() { 845 void EffectTree::ClearCopyRequests() {
1047 for (auto& node : nodes()) { 846 for (auto& node : nodes()) {
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 1409
1611 PropertyTreesCachedData::~PropertyTreesCachedData() {} 1410 PropertyTreesCachedData::~PropertyTreesCachedData() {}
1612 1411
1613 PropertyTrees::PropertyTrees() 1412 PropertyTrees::PropertyTrees()
1614 : needs_rebuild(true), 1413 : needs_rebuild(true),
1615 non_root_surfaces_enabled(true), 1414 non_root_surfaces_enabled(true),
1616 changed(false), 1415 changed(false),
1617 full_tree_damaged(false), 1416 full_tree_damaged(false),
1618 sequence_number(0), 1417 sequence_number(0),
1619 is_main_thread(true), 1418 is_main_thread(true),
1620 is_active(false), 1419 is_active(false) {
1621 verify_transform_tree_calculations(false) {
1622 transform_tree.SetPropertyTrees(this); 1420 transform_tree.SetPropertyTrees(this);
1623 effect_tree.SetPropertyTrees(this); 1421 effect_tree.SetPropertyTrees(this);
1624 clip_tree.SetPropertyTrees(this); 1422 clip_tree.SetPropertyTrees(this);
1625 scroll_tree.SetPropertyTrees(this); 1423 scroll_tree.SetPropertyTrees(this);
1626 } 1424 }
1627 1425
1628 PropertyTrees::~PropertyTrees() {} 1426 PropertyTrees::~PropertyTrees() {}
1629 1427
1630 bool PropertyTrees::operator==(const PropertyTrees& other) const { 1428 bool PropertyTrees::operator==(const PropertyTrees& other) const {
1631 return transform_tree == other.transform_tree && 1429 return transform_tree == other.transform_tree &&
(...skipping 24 matching lines...) Expand all
1656 from.always_use_active_tree_opacity_effect_ids; 1454 from.always_use_active_tree_opacity_effect_ids;
1657 clip_id_to_index_map = from.clip_id_to_index_map; 1455 clip_id_to_index_map = from.clip_id_to_index_map;
1658 scroll_id_to_index_map = from.scroll_id_to_index_map; 1456 scroll_id_to_index_map = from.scroll_id_to_index_map;
1659 needs_rebuild = from.needs_rebuild; 1457 needs_rebuild = from.needs_rebuild;
1660 changed = from.changed; 1458 changed = from.changed;
1661 full_tree_damaged = from.full_tree_damaged; 1459 full_tree_damaged = from.full_tree_damaged;
1662 non_root_surfaces_enabled = from.non_root_surfaces_enabled; 1460 non_root_surfaces_enabled = from.non_root_surfaces_enabled;
1663 sequence_number = from.sequence_number; 1461 sequence_number = from.sequence_number;
1664 is_main_thread = from.is_main_thread; 1462 is_main_thread = from.is_main_thread;
1665 is_active = from.is_active; 1463 is_active = from.is_active;
1666 verify_transform_tree_calculations = from.verify_transform_tree_calculations;
1667 inner_viewport_container_bounds_delta_ = 1464 inner_viewport_container_bounds_delta_ =
1668 from.inner_viewport_container_bounds_delta(); 1465 from.inner_viewport_container_bounds_delta();
1669 outer_viewport_container_bounds_delta_ = 1466 outer_viewport_container_bounds_delta_ =
1670 from.outer_viewport_container_bounds_delta(); 1467 from.outer_viewport_container_bounds_delta();
1671 inner_viewport_scroll_bounds_delta_ = 1468 inner_viewport_scroll_bounds_delta_ =
1672 from.inner_viewport_scroll_bounds_delta(); 1469 from.inner_viewport_scroll_bounds_delta();
1673 transform_tree.SetPropertyTrees(this); 1470 transform_tree.SetPropertyTrees(this);
1674 effect_tree.SetPropertyTrees(this); 1471 effect_tree.SetPropertyTrees(this);
1675 clip_tree.SetPropertyTrees(this); 1472 clip_tree.SetPropertyTrees(this);
1676 scroll_tree.SetPropertyTrees(this); 1473 scroll_tree.SetPropertyTrees(this);
1677 ResetCachedData(); 1474 ResetCachedData();
1678 return *this; 1475 return *this;
1679 } 1476 }
1680 1477
1681 void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const { 1478 void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const {
1682 // TODO(khushalsagar): Add support for sending diffs when serializaing 1479 // TODO(khushalsagar): Add support for sending diffs when serializaing
1683 // property trees. See crbug/555370. 1480 // property trees. See crbug/555370.
1684 transform_tree.ToProtobuf(proto->mutable_transform_tree()); 1481 transform_tree.ToProtobuf(proto->mutable_transform_tree());
1685 effect_tree.ToProtobuf(proto->mutable_effect_tree()); 1482 effect_tree.ToProtobuf(proto->mutable_effect_tree());
1686 clip_tree.ToProtobuf(proto->mutable_clip_tree()); 1483 clip_tree.ToProtobuf(proto->mutable_clip_tree());
1687 scroll_tree.ToProtobuf(proto->mutable_scroll_tree()); 1484 scroll_tree.ToProtobuf(proto->mutable_scroll_tree());
1688 proto->set_needs_rebuild(needs_rebuild); 1485 proto->set_needs_rebuild(needs_rebuild);
1689 proto->set_changed(changed); 1486 proto->set_changed(changed);
1690 proto->set_full_tree_damaged(full_tree_damaged); 1487 proto->set_full_tree_damaged(full_tree_damaged);
1691 proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled); 1488 proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled);
1692 proto->set_is_main_thread(is_main_thread); 1489 proto->set_is_main_thread(is_main_thread);
1693 proto->set_is_active(is_active); 1490 proto->set_is_active(is_active);
1694 proto->set_verify_transform_tree_calculations(
1695 verify_transform_tree_calculations);
1696 1491
1697 // TODO(khushalsagar): Consider using the sequence number to decide if 1492 // TODO(khushalsagar): Consider using the sequence number to decide if
1698 // property trees need to be serialized again for a commit. See crbug/555370. 1493 // property trees need to be serialized again for a commit. See crbug/555370.
1699 proto->set_sequence_number(sequence_number); 1494 proto->set_sequence_number(sequence_number);
1700 1495
1701 for (auto i : always_use_active_tree_opacity_effect_ids) 1496 for (auto i : always_use_active_tree_opacity_effect_ids)
1702 proto->add_always_use_active_tree_opacity_effect_ids(i); 1497 proto->add_always_use_active_tree_opacity_effect_ids(i);
1703 } 1498 }
1704 1499
1705 // static 1500 // static
1706 void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) { 1501 void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) {
1707 transform_tree.FromProtobuf(proto.transform_tree(), 1502 transform_tree.FromProtobuf(proto.transform_tree(),
1708 &transform_id_to_index_map); 1503 &transform_id_to_index_map);
1709 effect_tree.FromProtobuf(proto.effect_tree(), &effect_id_to_index_map); 1504 effect_tree.FromProtobuf(proto.effect_tree(), &effect_id_to_index_map);
1710 clip_tree.FromProtobuf(proto.clip_tree(), &clip_id_to_index_map); 1505 clip_tree.FromProtobuf(proto.clip_tree(), &clip_id_to_index_map);
1711 scroll_tree.FromProtobuf(proto.scroll_tree(), &scroll_id_to_index_map); 1506 scroll_tree.FromProtobuf(proto.scroll_tree(), &scroll_id_to_index_map);
1712 1507
1713 needs_rebuild = proto.needs_rebuild(); 1508 needs_rebuild = proto.needs_rebuild();
1714 changed = proto.changed(); 1509 changed = proto.changed();
1715 full_tree_damaged = proto.full_tree_damaged(); 1510 full_tree_damaged = proto.full_tree_damaged();
1716 non_root_surfaces_enabled = proto.non_root_surfaces_enabled(); 1511 non_root_surfaces_enabled = proto.non_root_surfaces_enabled();
1717 sequence_number = proto.sequence_number(); 1512 sequence_number = proto.sequence_number();
1718 is_main_thread = proto.is_main_thread(); 1513 is_main_thread = proto.is_main_thread();
1719 is_active = proto.is_active(); 1514 is_active = proto.is_active();
1720 verify_transform_tree_calculations =
1721 proto.verify_transform_tree_calculations();
1722 1515
1723 transform_tree.SetPropertyTrees(this); 1516 transform_tree.SetPropertyTrees(this);
1724 effect_tree.SetPropertyTrees(this); 1517 effect_tree.SetPropertyTrees(this);
1725 clip_tree.SetPropertyTrees(this); 1518 clip_tree.SetPropertyTrees(this);
1726 scroll_tree.SetPropertyTrees(this); 1519 scroll_tree.SetPropertyTrees(this);
1727 for (auto i : proto.always_use_active_tree_opacity_effect_ids()) 1520 for (auto i : proto.always_use_active_tree_opacity_effect_ids())
1728 always_use_active_tree_opacity_effect_ids.push_back(i); 1521 always_use_active_tree_opacity_effect_ids.push_back(i);
1729 } 1522 }
1730 1523
1731 void PropertyTrees::clear() { 1524 void PropertyTrees::clear() {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 !node->has_only_translation_animations || ancestor_is_animating_scale; 1732 !node->has_only_translation_animations || ancestor_is_animating_scale;
1940 1733
1941 // Once we've failed to compute a maximum animated scale at an ancestor, we 1734 // Once we've failed to compute a maximum animated scale at an ancestor, we
1942 // continue to fail. 1735 // continue to fail.
1943 bool failed_at_ancestor = 1736 bool failed_at_ancestor =
1944 ancestor_is_animating_scale && ancestor_maximum_target_scale == 0.f; 1737 ancestor_is_animating_scale && ancestor_maximum_target_scale == 0.f;
1945 1738
1946 // Computing maximum animated scale in the presence of non-scale/translation 1739 // Computing maximum animated scale in the presence of non-scale/translation
1947 // transforms isn't supported. 1740 // transforms isn't supported.
1948 bool failed_for_non_scale_or_translation = 1741 bool failed_for_non_scale_or_translation =
1949 !transform_tree.Node(transform_node_id) 1742 !node->to_parent.IsScaleOrTranslation();
1950 ->to_parent.IsScaleOrTranslation();
1951 1743
1952 // We don't attempt to accumulate animation scale from multiple nodes with 1744 // We don't attempt to accumulate animation scale from multiple nodes with
1953 // scale animations, because of the risk of significant overestimation. For 1745 // scale animations, because of the risk of significant overestimation. For
1954 // example, one node might be increasing scale from 1 to 10 at the same time 1746 // example, one node might be increasing scale from 1 to 10 at the same time
1955 // as another node is decreasing scale from 10 to 1. Naively combining these 1747 // as another node is decreasing scale from 10 to 1. Naively combining these
1956 // scales would produce a scale of 100. 1748 // scales would produce a scale of 100.
1957 bool failed_for_multiple_scale_animations = 1749 bool failed_for_multiple_scale_animations =
1958 ancestor_is_animating_scale && !node->has_only_translation_animations; 1750 ancestor_is_animating_scale && !node->has_only_translation_animations;
1959 1751
1960 if (failed_at_ancestor || failed_for_non_scale_or_translation || 1752 if (failed_at_ancestor || failed_for_non_scale_or_translation ||
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 cached_data_.draw_transforms[effect_id][transform_id].transforms.to_target = 1922 cached_data_.draw_transforms[effect_id][transform_id].transforms.to_target =
2131 target_space_transform; 1923 target_space_transform;
2132 } 1924 }
2133 return cached_data_.draw_transforms[effect_id][transform_id].transforms; 1925 return cached_data_.draw_transforms[effect_id][transform_id].transforms;
2134 } 1926 }
2135 1927
2136 void PropertyTrees::ResetCachedData() { 1928 void PropertyTrees::ResetCachedData() {
2137 cached_data_.property_tree_update_number = 0; 1929 cached_data_.property_tree_update_number = 0;
2138 cached_data_.animation_scales = std::vector<AnimationScaleData>( 1930 cached_data_.animation_scales = std::vector<AnimationScaleData>(
2139 transform_tree.nodes().size(), AnimationScaleData()); 1931 transform_tree.nodes().size(), AnimationScaleData());
2140 cached_data_.draw_transforms = 1932 cached_data_.draw_transforms = std::vector<std::map<int, DrawTransformData>>(
2141 std::vector<std::unordered_map<int, DrawTransformData>>( 1933 effect_tree.nodes().size(), std::map<int, DrawTransformData>());
2142 effect_tree.nodes().size(),
2143 std::unordered_map<int, DrawTransformData>());
2144 } 1934 }
2145 1935
2146 void PropertyTrees::UpdateCachedNumber() { 1936 void PropertyTrees::UpdateCachedNumber() {
2147 cached_data_.property_tree_update_number++; 1937 cached_data_.property_tree_update_number++;
2148 } 1938 }
2149 1939
2150 gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale( 1940 gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale(
2151 int transform_id, 1941 int transform_id,
2152 int effect_id) const { 1942 int effect_id) const {
2153 DCHECK_GT(transform_id, 0); 1943 DCHECK_GT(transform_id, 0);
(...skipping 11 matching lines...) Expand all
2165 } 1955 }
2166 1956
2167 bool PropertyTrees::ComputeTransformToTarget(int transform_id, 1957 bool PropertyTrees::ComputeTransformToTarget(int transform_id,
2168 int effect_id, 1958 int effect_id,
2169 gfx::Transform* transform) const { 1959 gfx::Transform* transform) const {
2170 transform->MakeIdentity(); 1960 transform->MakeIdentity();
2171 1961
2172 if (transform_id == TransformTree::kInvalidNodeId) 1962 if (transform_id == TransformTree::kInvalidNodeId)
2173 return true; 1963 return true;
2174 1964
2175 int target_transform_id;
2176 const EffectNode* effect_node = effect_tree.Node(effect_id); 1965 const EffectNode* effect_node = effect_tree.Node(effect_id);
2177 if (effect_id == EffectTree::kInvalidNodeId) { 1966 bool success = true;
2178 // This can happen when PaintArtifactCompositor builds property trees as 1967 auto draw_transforms = GetDrawTransforms(transform_id, effect_id);
2179 // it doesn't set effect ids on clip nodes. We want to compute transform 1968 success = draw_transforms.invertible;
2180 // to the root in this case. 1969 transform->ConcatTransform(draw_transforms.to_target);
2181 target_transform_id = TransformTree::kRootNodeId; 1970 if (effect_node->surface_contents_scale.x() != 0.f &&
2182 } else { 1971 effect_node->surface_contents_scale.y() != 0.f)
2183 DCHECK(effect_node->has_render_surface || 1972 transform->matrix().postScale(
2184 effect_node->id == EffectTree::kRootNodeId); 1973 1.0f / effect_node->surface_contents_scale.x(),
2185 target_transform_id = effect_node->transform_id; 1974 1.0f / effect_node->surface_contents_scale.y(), 1.0f);
2186 }
2187
2188 bool success = transform_tree.ComputeTransform(
2189 transform_id, target_transform_id, transform);
2190 if (verify_transform_tree_calculations) {
2191 gfx::Transform to_target;
2192 to_target.ConcatTransform(
2193 GetDrawTransforms(transform_id, effect_id).to_target);
2194 if (effect_node->surface_contents_scale.x() != 0.f &&
2195 effect_node->surface_contents_scale.y() != 0.f)
2196 to_target.matrix().postScale(
2197 1.0f / effect_node->surface_contents_scale.x(),
2198 1.0f / effect_node->surface_contents_scale.y(), 1.0f);
2199 DCHECK(to_target.ApproximatelyEqual(*transform));
2200 }
2201 return success; 1975 return success;
2202 } 1976 }
2203 1977
2204 bool PropertyTrees::ComputeTransformFromTarget( 1978 bool PropertyTrees::ComputeTransformFromTarget(
2205 int transform_id, 1979 int transform_id,
2206 int effect_id, 1980 int effect_id,
2207 gfx::Transform* transform) const { 1981 gfx::Transform* transform) const {
2208 transform->MakeIdentity(); 1982 transform->MakeIdentity();
2209 1983
2210 if (transform_id == TransformTree::kInvalidNodeId) 1984 if (transform_id == TransformTree::kInvalidNodeId)
2211 return true; 1985 return true;
2212 1986
2213 int target_transform_id;
2214 const EffectNode* effect_node = effect_tree.Node(effect_id); 1987 const EffectNode* effect_node = effect_tree.Node(effect_id);
2215 if (effect_id == EffectTree::kInvalidNodeId) { 1988 bool success = true;
2216 // This can happen when PaintArtifactCompositor builds property trees as 1989 auto draw_transforms = GetDrawTransforms(transform_id, effect_id);
2217 // it doesn't set effect ids on clip nodes. We want to compute transform 1990 success = draw_transforms.invertible;
2218 // to the root in this case. 1991 transform->ConcatTransform(draw_transforms.from_target);
2219 target_transform_id = TransformTree::kRootNodeId; 1992 transform->Scale(effect_node->surface_contents_scale.x(),
2220 } else { 1993 effect_node->surface_contents_scale.y());
2221 DCHECK(effect_node->has_render_surface ||
2222 effect_node->id == EffectTree::kRootNodeId);
2223 target_transform_id = effect_node->transform_id;
2224 }
2225
2226 bool success = transform_tree.ComputeTransform(target_transform_id,
2227 transform_id, transform);
2228 if (verify_transform_tree_calculations) {
2229 auto draw_transforms = GetDrawTransforms(transform_id, effect_id);
2230 gfx::Transform from_target;
2231 from_target.ConcatTransform(draw_transforms.from_target);
2232 from_target.Scale(effect_node->surface_contents_scale.x(),
2233 effect_node->surface_contents_scale.y());
2234 DCHECK(from_target.ApproximatelyEqual(*transform) ||
2235 !draw_transforms.invertible);
2236 }
2237 return success; 1994 return success;
2238 } 1995 }
2239 1996
2240 } // namespace cc 1997 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698