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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) { | 380 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) { |
382 if (!clip_tree->needs_update()) | 381 if (!clip_tree->needs_update()) |
383 return; | 382 return; |
384 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) { | 383 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) { |
385 ClipNode* clip_node = clip_tree->Node(i); | 384 ClipNode* clip_node = clip_tree->Node(i); |
386 | 385 |
387 // Only descendants of a real clipping layer (i.e., not 0) may have their | 386 // Only descendants of a real clipping layer (i.e., not 0) may have their |
388 // clip adjusted due to intersecting with an ancestor clip. | 387 // clip adjusted due to intersecting with an ancestor clip. |
389 const bool is_clipped = clip_node->parent_id > 0; | 388 const bool is_clipped = clip_node->parent_id > 0; |
390 if (!is_clipped) { | 389 if (!is_clipped) { |
390 DCHECK(!clip_node->data.inherit_parent_target_space_clip); | |
391 clip_node->data.combined_clip = clip_node->data.clip; | 391 clip_node->data.combined_clip = clip_node->data.clip; |
392 continue; | 392 continue; |
393 } | 393 } |
394 | 394 |
395 ClipNode* parent_clip_node = clip_tree->parent(clip_node); | 395 ClipNode* parent_clip_node = clip_tree->parent(clip_node); |
396 const TransformNode* parent_transform_node = | 396 const TransformNode* parent_transform_node = |
397 transform_tree.Node(parent_clip_node->data.transform_id); | 397 transform_tree.Node(parent_clip_node->data.transform_id); |
398 const TransformNode* transform_node = | 398 const TransformNode* transform_node = |
399 transform_tree.Node(clip_node->data.transform_id); | 399 transform_tree.Node(clip_node->data.transform_id); |
400 | 400 |
401 // Clips must be combined in target space. We cannot, for example, combine | 401 // Clips must be combined in target space. We cannot, for example, combine |
402 // clips in the space of the child clip. The reason is non-affine | 402 // clips in the space of the child clip. The reason is non-affine |
403 // transforms. Say we have the following tree T->A->B->C, and B clips C, but | 403 // transforms. Say we have the following tree T->A->B->C, and B clips C, but |
404 // draw into target T. It may be the case that A applies a perspective | 404 // draw into target T. It may be the case that A applies a perspective |
405 // transform, and B and C are at different z positions. When projected into | 405 // transform, and B and C are at different z positions. When projected into |
406 // target space, the relative sizes and positions of B and C can shift. | 406 // target space, the relative sizes and positions of B and C can shift. |
407 // Since it's the relationship in target space that matters, that's where we | 407 // Since it's the relationship in target space that matters, that's where we |
408 // must combine clips. | 408 // must combine clips. |
409 gfx::Transform parent_to_target; | 409 gfx::Transform parent_to_target; |
410 gfx::Transform clip_to_target; | 410 gfx::Transform clip_to_target; |
411 gfx::Transform target_to_clip; | 411 gfx::Transform target_to_clip; |
412 gfx::Transform parent_to_transform_target; | |
413 gfx::Transform transform_target_to_target; | |
412 | 414 |
413 const bool target_is_root_surface = clip_node->data.target_id == 1; | 415 const bool target_is_root_surface = clip_node->data.target_id == 1; |
414 // When the target is the root surface, we need to include the root | 416 // When the target is the root surface, we need to include the root |
415 // transform by walking up to the root of the transform tree. | 417 // transform by walking up to the root of the transform tree. |
416 const int target_id = | 418 const int target_id = |
417 target_is_root_surface ? 0 : clip_node->data.target_id; | 419 target_is_root_surface ? 0 : clip_node->data.target_id; |
418 | 420 |
419 bool success = true; | 421 bool success = true; |
420 if (parent_transform_node->data.content_target_id == | 422 // When render surface applies clip, we need the clip from the target's |
421 clip_node->data.target_id) { | 423 // target space. But, as the combined clip is in parent clip's target |
424 // space, we need to first transform it from parent's target space to | |
425 // target's target space. | |
426 if (clip_node->data.inherit_parent_target_space_clip) { | |
427 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | |
428 parent_transform_node->id, transform_node->data.target_id, | |
429 &parent_to_transform_target); | |
430 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | |
431 transform_node->data.target_id, target_id, | |
432 &transform_target_to_target); | |
433 } else if (parent_transform_node->data.content_target_id == | |
434 clip_node->data.target_id) { | |
422 parent_to_target = parent_transform_node->data.to_target; | 435 parent_to_target = parent_transform_node->data.to_target; |
423 } else { | 436 } else { |
424 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | 437 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( |
425 parent_transform_node->id, target_id, &parent_to_target); | 438 parent_transform_node->id, target_id, &parent_to_target); |
426 } | 439 } |
427 | 440 |
428 if (transform_node->data.content_target_id == clip_node->data.target_id) { | 441 if (transform_node->data.content_target_id == clip_node->data.target_id) { |
429 clip_to_target = transform_node->data.to_target; | 442 clip_to_target = transform_node->data.to_target; |
430 } else { | 443 } else { |
431 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | 444 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( |
432 transform_node->id, target_id, &clip_to_target); | 445 transform_node->id, target_id, &clip_to_target); |
433 } | 446 } |
434 | 447 |
435 if (transform_node->data.content_target_id == clip_node->data.target_id && | 448 if (transform_node->data.content_target_id == clip_node->data.target_id && |
436 transform_node->data.ancestors_are_invertible) { | 449 transform_node->data.ancestors_are_invertible) { |
437 target_to_clip = transform_node->data.from_target; | 450 target_to_clip = transform_node->data.from_target; |
438 } else { | 451 } else { |
439 success &= clip_to_target.GetInverse(&target_to_clip); | 452 success &= clip_to_target.GetInverse(&target_to_clip); |
440 } | 453 } |
441 | 454 |
442 // If we can't compute a transform, it's because we had to use the inverse | 455 // If we can't compute a transform, it's because we had to use the inverse |
443 // of a singular transform. We won't draw in this case, so there's no need | 456 // of a singular transform. We won't draw in this case, so there's no need |
444 // to compute clips. | 457 // to compute clips. |
445 if (!success) | 458 if (!success) { |
459 if (clip_node->data.inherit_parent_target_space_clip) { | |
460 clip_node->data.transform_id = parent_clip_node->data.transform_id; | |
ajuma
2015/08/05 13:51:09
I don't think we should be changing the transform
jaydasika
2015/08/05 15:07:20
Ah, I see the problem. But I am still not sure wha
ajuma
2015/08/05 15:21:58
If we reach this point, we have an uninvertible tr
jaydasika
2015/08/05 21:50:11
Done.
| |
461 clip_node->data.combined_clip = parent_clip_node->data.combined_clip; | |
462 } else { | |
463 clip_node->data.combined_clip = clip_node->data.clip; | |
464 } | |
446 continue; | 465 continue; |
466 } | |
447 | 467 |
448 // In order to intersect with as small a rect as possible, we do a | 468 // In order to intersect with as small a rect as possible, we do a |
449 // preliminary clip in target space so that when we project back, there's | 469 // preliminary clip in target space so that when we project back, there's |
450 // less likelihood of intersecting the view plane. | 470 // less likelihood of intersecting the view plane. |
451 gfx::RectF inherited_clip_in_target_space = MathUtil::MapClippedRect( | 471 gfx::RectF inherited_clip_in_target_space; |
452 parent_to_target, parent_clip_node->data.combined_clip); | 472 if (clip_node->data.inherit_parent_target_space_clip) { |
473 gfx::RectF combined_clip_in_transform_target_space; | |
474 if (parent_transform_node->id > transform_node->data.target_id) | |
475 combined_clip_in_transform_target_space = MathUtil::MapClippedRect( | |
476 parent_to_transform_target, parent_clip_node->data.combined_clip); | |
477 else | |
478 combined_clip_in_transform_target_space = MathUtil::ProjectClippedRect( | |
479 parent_to_transform_target, parent_clip_node->data.combined_clip); | |
480 inherited_clip_in_target_space = MathUtil::ProjectClippedRect( | |
481 transform_target_to_target, combined_clip_in_transform_target_space); | |
482 } else if (parent_transform_node->id > target_id) { | |
483 inherited_clip_in_target_space = MathUtil::MapClippedRect( | |
484 parent_to_target, parent_clip_node->data.combined_clip); | |
485 } else { | |
486 inherited_clip_in_target_space = MathUtil::ProjectClippedRect( | |
487 parent_to_target, parent_clip_node->data.combined_clip); | |
488 } | |
453 | 489 |
454 gfx::RectF clip_in_target_space = | 490 // When render surface applies clip, the layer that created the clip node |
455 MathUtil::MapClippedRect(clip_to_target, clip_node->data.clip); | 491 // doesn't apply any clip. So, we should clip using the clip value |
492 // stored in the clip node. | |
493 gfx::RectF intersected_in_target_space; | |
494 if (!clip_node->data.inherit_parent_target_space_clip) { | |
495 gfx::RectF clip_in_target_space = | |
496 MathUtil::MapClippedRect(clip_to_target, clip_node->data.clip); | |
456 | 497 |
457 gfx::RectF intersected_in_target_space = gfx::IntersectRects( | 498 intersected_in_target_space = gfx::IntersectRects( |
458 inherited_clip_in_target_space, clip_in_target_space); | 499 inherited_clip_in_target_space, clip_in_target_space); |
500 } else { | |
501 intersected_in_target_space = inherited_clip_in_target_space; | |
502 } | |
459 | 503 |
460 clip_node->data.combined_clip = MathUtil::ProjectClippedRect( | 504 clip_node->data.combined_clip = MathUtil::ProjectClippedRect( |
461 target_to_clip, intersected_in_target_space); | 505 target_to_clip, intersected_in_target_space); |
462 | 506 |
463 clip_node->data.combined_clip.Intersect(clip_node->data.clip); | 507 if (!clip_node->data.inherit_parent_target_space_clip) |
508 clip_node->data.combined_clip.Intersect(clip_node->data.clip); | |
464 } | 509 } |
465 clip_tree->set_needs_update(false); | 510 clip_tree->set_needs_update(false); |
466 } | 511 } |
467 | 512 |
468 void ComputeTransforms(TransformTree* transform_tree) { | 513 void ComputeTransforms(TransformTree* transform_tree) { |
469 if (!transform_tree->needs_update()) | 514 if (!transform_tree->needs_update()) |
470 return; | 515 return; |
471 for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i) | 516 for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i) |
472 transform_tree->UpdateTransforms(i); | 517 transform_tree->UpdateTransforms(i); |
473 transform_tree->set_needs_update(false); | 518 transform_tree->set_needs_update(false); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
687 if (static_cast<int>(layer->offset_to_transform_parent().x()) != | 732 if (static_cast<int>(layer->offset_to_transform_parent().x()) != |
688 layer->offset_to_transform_parent().x()) | 733 layer->offset_to_transform_parent().x()) |
689 return false; | 734 return false; |
690 if (static_cast<int>(layer->offset_to_transform_parent().y()) != | 735 if (static_cast<int>(layer->offset_to_transform_parent().y()) != |
691 layer->offset_to_transform_parent().y()) | 736 layer->offset_to_transform_parent().y()) |
692 return false; | 737 return false; |
693 return true; | 738 return true; |
694 } | 739 } |
695 | 740 |
696 } // namespace cc | 741 } // namespace cc |
OLD | NEW |