OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |