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 "cc/trees/draw_property_utils.h" | 5 #include "cc/trees/draw_property_utils.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "cc/base/math_util.h" | 9 #include "cc/base/math_util.h" |
10 #include "cc/layers/layer.h" | 10 #include "cc/layers/layer.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
50 | 50 |
51 gfx::Rect clip_rect_in_target_space; | 51 gfx::Rect clip_rect_in_target_space; |
52 gfx::Transform clip_to_target; | 52 gfx::Transform clip_to_target; |
53 bool success = true; | 53 bool success = true; |
54 if (clip_transform_node->data.target_id == target_node->id) { | 54 if (clip_transform_node->data.target_id == target_node->id) { |
55 clip_to_target = clip_transform_node->data.to_target; | 55 clip_to_target = clip_transform_node->data.to_target; |
56 } else { | 56 } else { |
57 success = transform_tree.ComputeTransformWithDestinationSublayerScale( | 57 success = transform_tree.ComputeTransformWithDestinationSublayerScale( |
58 clip_transform_node->id, target_node->id, &clip_to_target); | 58 clip_transform_node->id, target_node->id, &clip_to_target); |
59 } | 59 } |
60 | |
61 if (target_node->id > clip_node->data.transform_id) { | 60 if (target_node->id > clip_node->data.transform_id) { |
62 if (!success) { | 61 if (!success) { |
63 DCHECK(target_node->data.to_screen_is_animated); | 62 DCHECK(target_node->data.to_screen_is_animated); |
64 | 63 |
65 // An animated singular transform may become non-singular during the | 64 // An animated singular transform may become non-singular during the |
66 // animation, so we still need to compute a visible rect. In this | 65 // animation, so we still need to compute a visible rect. In this |
67 // situation, we treat the entire layer as visible. | 66 // situation, we treat the entire layer as visible. |
68 layer->set_visible_rect_from_property_trees(gfx::Rect(layer_bounds)); | 67 layer->set_visible_rect_from_property_trees(gfx::Rect(layer_bounds)); |
69 continue; | 68 continue; |
70 } | 69 } |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) { | 382 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) { |
384 if (!clip_tree->needs_update()) | 383 if (!clip_tree->needs_update()) |
385 return; | 384 return; |
386 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) { | 385 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) { |
387 ClipNode* clip_node = clip_tree->Node(i); | 386 ClipNode* clip_node = clip_tree->Node(i); |
388 | 387 |
389 // Only descendants of a real clipping layer (i.e., not 0) may have their | 388 // Only descendants of a real clipping layer (i.e., not 0) may have their |
390 // clip adjusted due to intersecting with an ancestor clip. | 389 // clip adjusted due to intersecting with an ancestor clip. |
391 const bool is_clipped = clip_node->parent_id > 0; | 390 const bool is_clipped = clip_node->parent_id > 0; |
392 if (!is_clipped) { | 391 if (!is_clipped) { |
392 DCHECK(!clip_node->data.inherit_parent_target_space_clip); | |
393 clip_node->data.combined_clip = clip_node->data.clip; | 393 clip_node->data.combined_clip = clip_node->data.clip; |
394 continue; | 394 continue; |
395 } | 395 } |
396 | 396 |
397 ClipNode* parent_clip_node = clip_tree->parent(clip_node); | 397 ClipNode* parent_clip_node = clip_tree->parent(clip_node); |
398 const TransformNode* parent_transform_node = | 398 const TransformNode* parent_transform_node = |
399 transform_tree.Node(parent_clip_node->data.transform_id); | 399 transform_tree.Node(parent_clip_node->data.transform_id); |
400 const TransformNode* transform_node = | 400 const TransformNode* transform_node = |
401 transform_tree.Node(clip_node->data.transform_id); | 401 transform_tree.Node(clip_node->data.transform_id); |
402 | 402 |
403 // Clips must be combined in target space. We cannot, for example, combine | 403 // Clips must be combined in target space. We cannot, for example, combine |
404 // clips in the space of the child clip. The reason is non-affine | 404 // clips in the space of the child clip. The reason is non-affine |
405 // transforms. Say we have the following tree T->A->B->C, and B clips C, but | 405 // transforms. Say we have the following tree T->A->B->C, and B clips C, but |
406 // draw into target T. It may be the case that A applies a perspective | 406 // draw into target T. It may be the case that A applies a perspective |
407 // transform, and B and C are at different z positions. When projected into | 407 // transform, and B and C are at different z positions. When projected into |
408 // target space, the relative sizes and positions of B and C can shift. | 408 // target space, the relative sizes and positions of B and C can shift. |
409 // Since it's the relationship in target space that matters, that's where we | 409 // Since it's the relationship in target space that matters, that's where we |
410 // must combine clips. | 410 // must combine clips. |
411 gfx::Transform parent_to_target; | 411 gfx::Transform parent_to_target; |
412 gfx::Transform clip_to_target; | 412 gfx::Transform clip_to_target; |
413 gfx::Transform target_to_clip; | 413 gfx::Transform target_to_clip; |
414 gfx::Transform parent_to_transform_target; | |
415 gfx::Transform transform_target_to_target; | |
414 | 416 |
415 const bool target_is_root_surface = clip_node->data.target_id == 1; | 417 const bool target_is_root_surface = clip_node->data.target_id == 1; |
416 // When the target is the root surface, we need to include the root | 418 // When the target is the root surface, we need to include the root |
417 // transform by walking up to the root of the transform tree. | 419 // transform by walking up to the root of the transform tree. |
418 const int target_id = | 420 const int target_id = |
419 target_is_root_surface ? 0 : clip_node->data.target_id; | 421 target_is_root_surface ? 0 : clip_node->data.target_id; |
420 | 422 |
421 bool success = true; | 423 bool success = true; |
422 if (parent_transform_node->data.content_target_id == | 424 // When render surface applies clip, we need the clip from the target's |
423 clip_node->data.target_id) { | 425 // target space. But, as the combined clip is in parent clip's target |
426 // space, we need to first transform it from parent's target space to | |
427 // target's target space. | |
428 if (clip_node->data.inherit_parent_target_space_clip) { | |
429 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | |
430 parent_transform_node->id, transform_node->data.target_id, | |
431 &parent_to_transform_target); | |
432 success &= transform_tree.ComputeTransformWithSourceSublayerScale( | |
ajuma
2015/08/06 14:25:45
ComputeTransformWithSourceSublayerScale can divide
jaydasika
2015/08/06 16:39:34
Done.
| |
433 transform_node->data.target_id, target_id, | |
434 &transform_target_to_target); | |
435 transform_target_to_target.Scale(transform_node->data.sublayer_scale.x(), | |
436 transform_node->data.sublayer_scale.y()); | |
437 } else if (parent_transform_node->data.content_target_id == | |
438 clip_node->data.target_id) { | |
424 parent_to_target = parent_transform_node->data.to_target; | 439 parent_to_target = parent_transform_node->data.to_target; |
425 } else { | 440 } else { |
426 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | 441 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( |
427 parent_transform_node->id, target_id, &parent_to_target); | 442 parent_transform_node->id, target_id, &parent_to_target); |
428 } | 443 } |
429 | 444 |
430 if (transform_node->data.content_target_id == clip_node->data.target_id) { | 445 if (transform_node->data.content_target_id == clip_node->data.target_id) { |
431 clip_to_target = transform_node->data.to_target; | 446 clip_to_target = transform_node->data.to_target; |
432 } else { | 447 } else { |
433 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | 448 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( |
434 transform_node->id, target_id, &clip_to_target); | 449 transform_node->id, target_id, &clip_to_target); |
435 } | 450 } |
436 | 451 |
437 if (transform_node->data.content_target_id == clip_node->data.target_id && | 452 if (transform_node->data.content_target_id == clip_node->data.target_id && |
438 transform_node->data.ancestors_are_invertible) { | 453 transform_node->data.ancestors_are_invertible) { |
439 target_to_clip = transform_node->data.from_target; | 454 target_to_clip = transform_node->data.from_target; |
440 } else { | 455 } else { |
441 success &= clip_to_target.GetInverse(&target_to_clip); | 456 success &= clip_to_target.GetInverse(&target_to_clip); |
442 } | 457 } |
443 | 458 |
444 // If we can't compute a transform, it's because we had to use the inverse | 459 // If we can't compute a transform, it's because we had to use the inverse |
445 // of a singular transform. We won't draw in this case, so there's no need | 460 // of a singular transform. We won't draw in this case, so there's no need |
446 // to compute clips. | 461 // to compute clips. |
447 if (!success) | 462 if (!success) { |
448 continue; | 463 continue; |
464 } | |
449 | 465 |
450 // In order to intersect with as small a rect as possible, we do a | 466 // In order to intersect with as small a rect as possible, we do a |
451 // preliminary clip in target space so that when we project back, there's | 467 // preliminary clip in target space so that when we project back, there's |
452 // less likelihood of intersecting the view plane. | 468 // less likelihood of intersecting the view plane. |
453 gfx::RectF inherited_clip_in_target_space = MathUtil::MapClippedRect( | 469 gfx::RectF inherited_clip_in_target_space; |
454 parent_to_target, parent_clip_node->data.combined_clip); | 470 if (clip_node->data.inherit_parent_target_space_clip) { |
471 gfx::RectF combined_clip_in_transform_target_space; | |
472 if (parent_transform_node->id > transform_node->data.target_id) | |
473 combined_clip_in_transform_target_space = MathUtil::MapClippedRect( | |
474 parent_to_transform_target, parent_clip_node->data.combined_clip); | |
475 else | |
476 combined_clip_in_transform_target_space = MathUtil::ProjectClippedRect( | |
477 parent_to_transform_target, parent_clip_node->data.combined_clip); | |
478 inherited_clip_in_target_space = MathUtil::ProjectClippedRect( | |
479 transform_target_to_target, combined_clip_in_transform_target_space); | |
480 } else if (parent_transform_node->id > target_id) { | |
481 inherited_clip_in_target_space = MathUtil::MapClippedRect( | |
482 parent_to_target, parent_clip_node->data.combined_clip); | |
483 } else { | |
484 inherited_clip_in_target_space = MathUtil::ProjectClippedRect( | |
485 parent_to_target, parent_clip_node->data.combined_clip); | |
486 } | |
455 | 487 |
456 gfx::RectF clip_in_target_space = | 488 // When render surface applies clip, the layer that created the clip node |
ajuma
2015/08/06 14:25:45
s/applies clip/inherits its parent's target space
jaydasika
2015/08/06 16:39:34
Done.
| |
457 MathUtil::MapClippedRect(clip_to_target, clip_node->data.clip); | 489 // doesn't apply any clip. So, we should clip using the clip value |
ajuma
2015/08/06 14:25:45
Do you mean "we shouldn't clip" instead? (Since in
jaydasika
2015/08/06 16:39:34
Done.
| |
490 // stored in the clip node. | |
491 gfx::RectF intersected_in_target_space; | |
492 if (!clip_node->data.inherit_parent_target_space_clip) { | |
493 gfx::RectF clip_in_target_space = | |
494 MathUtil::MapClippedRect(clip_to_target, clip_node->data.clip); | |
458 | 495 |
459 gfx::RectF intersected_in_target_space = gfx::IntersectRects( | 496 intersected_in_target_space = gfx::IntersectRects( |
460 inherited_clip_in_target_space, clip_in_target_space); | 497 inherited_clip_in_target_space, clip_in_target_space); |
498 } else { | |
499 intersected_in_target_space = inherited_clip_in_target_space; | |
500 } | |
461 | 501 |
462 clip_node->data.combined_clip = MathUtil::ProjectClippedRect( | 502 clip_node->data.combined_clip = MathUtil::ProjectClippedRect( |
463 target_to_clip, intersected_in_target_space); | 503 target_to_clip, intersected_in_target_space); |
464 | 504 |
465 clip_node->data.combined_clip.Intersect(clip_node->data.clip); | 505 if (!clip_node->data.inherit_parent_target_space_clip) |
506 clip_node->data.combined_clip.Intersect(clip_node->data.clip); | |
466 } | 507 } |
467 clip_tree->set_needs_update(false); | 508 clip_tree->set_needs_update(false); |
468 } | 509 } |
469 | 510 |
470 void ComputeTransforms(TransformTree* transform_tree) { | 511 void ComputeTransforms(TransformTree* transform_tree) { |
471 if (!transform_tree->needs_update()) | 512 if (!transform_tree->needs_update()) |
472 return; | 513 return; |
473 for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i) | 514 for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i) |
474 transform_tree->UpdateTransforms(i); | 515 transform_tree->UpdateTransforms(i); |
475 transform_tree->set_needs_update(false); | 516 transform_tree->set_needs_update(false); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
708 if (static_cast<int>(layer->offset_to_transform_parent().x()) != | 749 if (static_cast<int>(layer->offset_to_transform_parent().x()) != |
709 layer->offset_to_transform_parent().x()) | 750 layer->offset_to_transform_parent().x()) |
710 return false; | 751 return false; |
711 if (static_cast<int>(layer->offset_to_transform_parent().y()) != | 752 if (static_cast<int>(layer->offset_to_transform_parent().y()) != |
712 layer->offset_to_transform_parent().y()) | 753 layer->offset_to_transform_parent().y()) |
713 return false; | 754 return false; |
714 return true; | 755 return true; |
715 } | 756 } |
716 | 757 |
717 } // namespace cc | 758 } // namespace cc |
OLD | NEW |