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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) { | 381 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) { |
382 if (!clip_tree->needs_update()) | 382 if (!clip_tree->needs_update()) |
383 return; | 383 return; |
384 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) { | 384 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) { |
385 ClipNode* clip_node = clip_tree->Node(i); | 385 ClipNode* clip_node = clip_tree->Node(i); |
386 | 386 |
387 // Only descendants of a real clipping layer (i.e., not 0) may have their | 387 // Only descendants of a real clipping layer (i.e., not 0) may have their |
388 // clip adjusted due to intersecting with an ancestor clip. | 388 // clip adjusted due to intersecting with an ancestor clip. |
389 const bool is_clipped = clip_node->parent_id > 0; | 389 const bool is_clipped = clip_node->parent_id > 0; |
390 if (!is_clipped) { | 390 if (!is_clipped) { |
391 DCHECK(!clip_node->data.inherit_parent_target_space_clip); | |
391 clip_node->data.combined_clip = clip_node->data.clip; | 392 clip_node->data.combined_clip = clip_node->data.clip; |
392 continue; | 393 continue; |
393 } | 394 } |
394 | 395 |
395 ClipNode* parent_clip_node = clip_tree->parent(clip_node); | 396 ClipNode* parent_clip_node = clip_tree->parent(clip_node); |
396 const TransformNode* parent_transform_node = | 397 const TransformNode* parent_transform_node = |
397 transform_tree.Node(parent_clip_node->data.transform_id); | 398 transform_tree.Node(parent_clip_node->data.transform_id); |
398 const TransformNode* transform_node = | 399 const TransformNode* transform_node = |
399 transform_tree.Node(clip_node->data.transform_id); | 400 transform_tree.Node(clip_node->data.transform_id); |
400 | 401 |
401 // Clips must be combined in target space. We cannot, for example, combine | 402 // 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 | 403 // 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 | 404 // 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 | 405 // 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 | 406 // 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. | 407 // 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 | 408 // Since it's the relationship in target space that matters, that's where we |
408 // must combine clips. | 409 // must combine clips. |
409 gfx::Transform parent_to_target; | 410 gfx::Transform parent_to_target; |
410 gfx::Transform clip_to_target; | 411 gfx::Transform clip_to_target; |
411 gfx::Transform target_to_clip; | 412 gfx::Transform target_to_clip; |
413 gfx::Transform parent_to_transform_target; | |
414 gfx::Transform transform_target_to_target; | |
412 | 415 |
413 const bool target_is_root_surface = clip_node->data.target_id == 1; | 416 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 | 417 // 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. | 418 // transform by walking up to the root of the transform tree. |
416 const int target_id = | 419 const int target_id = |
417 target_is_root_surface ? 0 : clip_node->data.target_id; | 420 target_is_root_surface ? 0 : clip_node->data.target_id; |
418 | 421 |
419 bool success = true; | 422 bool success = true; |
420 if (parent_transform_node->data.content_target_id == | 423 // When render surface applies clip, we need the clip from the target's |
421 clip_node->data.target_id) { | 424 // target space. But, as the combined clip is in parent clip's target |
425 // space, we need to first transform it from parent's target space to | |
426 // target's target space. | |
427 if (clip_node->data.inherit_parent_target_space_clip) { | |
428 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | |
429 parent_transform_node->id, transform_node->data.target_id, | |
430 &parent_to_transform_target); | |
431 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | |
432 transform_node->data.target_id, target_id, | |
433 &transform_target_to_target); | |
434 } else if (parent_transform_node->data.content_target_id == | |
435 clip_node->data.target_id) { | |
422 parent_to_target = parent_transform_node->data.to_target; | 436 parent_to_target = parent_transform_node->data.to_target; |
423 } else { | 437 } else { |
424 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | 438 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( |
425 parent_transform_node->id, target_id, &parent_to_target); | 439 parent_transform_node->id, target_id, &parent_to_target); |
426 } | 440 } |
427 | 441 |
428 if (transform_node->data.content_target_id == clip_node->data.target_id) { | 442 if (transform_node->data.content_target_id == clip_node->data.target_id) { |
429 clip_to_target = transform_node->data.to_target; | 443 clip_to_target = transform_node->data.to_target; |
430 } else { | 444 } else { |
431 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | 445 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( |
432 transform_node->id, target_id, &clip_to_target); | 446 transform_node->id, target_id, &clip_to_target); |
433 } | 447 } |
434 | 448 |
435 if (transform_node->data.content_target_id == clip_node->data.target_id && | 449 if (transform_node->data.content_target_id == clip_node->data.target_id && |
436 transform_node->data.ancestors_are_invertible) { | 450 transform_node->data.ancestors_are_invertible) { |
437 target_to_clip = transform_node->data.from_target; | 451 target_to_clip = transform_node->data.from_target; |
438 } else { | 452 } else { |
439 success &= clip_to_target.GetInverse(&target_to_clip); | 453 success &= clip_to_target.GetInverse(&target_to_clip); |
440 } | 454 } |
441 | 455 |
442 // If we can't compute a transform, it's because we had to use the inverse | 456 // 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 | 457 // of a singular transform. We won't draw in this case, so there's no need |
444 // to compute clips. | 458 // to compute clips. |
445 if (!success) | 459 if (!success) |
446 continue; | 460 continue; |
447 | 461 |
448 // In order to intersect with as small a rect as possible, we do a | 462 // 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 | 463 // preliminary clip in target space so that when we project back, there's |
450 // less likelihood of intersecting the view plane. | 464 // less likelihood of intersecting the view plane. |
451 gfx::RectF inherited_clip_in_target_space = MathUtil::MapClippedRect( | 465 gfx::RectF inherited_clip_in_target_space; |
452 parent_to_target, parent_clip_node->data.combined_clip); | 466 if (clip_node->data.inherit_parent_target_space_clip && |
467 parent_transform_node->id > transform_node->data.target_id) { | |
468 gfx::RectF combined_clip_in_transform_target_space = | |
469 MathUtil::MapClippedRect(parent_to_transform_target, | |
470 parent_clip_node->data.combined_clip); | |
471 inherited_clip_in_target_space = MathUtil::ProjectClippedRect( | |
472 transform_target_to_target, combined_clip_in_transform_target_space); | |
473 } else if (parent_transform_node->id > target_id) { | |
474 inherited_clip_in_target_space = MathUtil::MapClippedRect( | |
475 parent_to_target, parent_clip_node->data.combined_clip); | |
476 } else { | |
477 inherited_clip_in_target_space = MathUtil::ProjectClippedRect( | |
jaydasika
2015/07/31 17:34:14
I am not sure if this is ever reached as it did no
ajuma
2015/07/31 22:41:01
I think you meant "parent is an ancestor of target
| |
478 parent_to_target, parent_clip_node->data.combined_clip); | |
479 } | |
453 | 480 |
454 gfx::RectF clip_in_target_space = | 481 // When render surface applies clip, the layer that created the clip node |
455 MathUtil::MapClippedRect(clip_to_target, clip_node->data.clip); | 482 // doesn't apply any clip. So, we should clip using the clip value |
483 // stored in the clip node. | |
484 gfx::RectF intersected_in_target_space; | |
485 if (!clip_node->data.inherit_parent_target_space_clip) { | |
486 gfx::RectF clip_in_target_space = | |
487 MathUtil::MapClippedRect(clip_to_target, clip_node->data.clip); | |
456 | 488 |
457 gfx::RectF intersected_in_target_space = gfx::IntersectRects( | 489 intersected_in_target_space = gfx::IntersectRects( |
458 inherited_clip_in_target_space, clip_in_target_space); | 490 inherited_clip_in_target_space, clip_in_target_space); |
491 } else { | |
492 intersected_in_target_space = inherited_clip_in_target_space; | |
493 } | |
459 | 494 |
460 clip_node->data.combined_clip = MathUtil::ProjectClippedRect( | 495 clip_node->data.combined_clip = MathUtil::ProjectClippedRect( |
461 target_to_clip, intersected_in_target_space); | 496 target_to_clip, intersected_in_target_space); |
462 | 497 |
463 clip_node->data.combined_clip.Intersect(clip_node->data.clip); | 498 if (!clip_node->data.inherit_parent_target_space_clip) |
499 clip_node->data.combined_clip.Intersect(clip_node->data.clip); | |
464 } | 500 } |
465 clip_tree->set_needs_update(false); | 501 clip_tree->set_needs_update(false); |
466 } | 502 } |
467 | 503 |
468 void ComputeTransforms(TransformTree* transform_tree) { | 504 void ComputeTransforms(TransformTree* transform_tree) { |
469 if (!transform_tree->needs_update()) | 505 if (!transform_tree->needs_update()) |
470 return; | 506 return; |
471 for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i) | 507 for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i) |
472 transform_tree->UpdateTransforms(i); | 508 transform_tree->UpdateTransforms(i); |
473 transform_tree->set_needs_update(false); | 509 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()) != | 723 if (static_cast<int>(layer->offset_to_transform_parent().x()) != |
688 layer->offset_to_transform_parent().x()) | 724 layer->offset_to_transform_parent().x()) |
689 return false; | 725 return false; |
690 if (static_cast<int>(layer->offset_to_transform_parent().y()) != | 726 if (static_cast<int>(layer->offset_to_transform_parent().y()) != |
691 layer->offset_to_transform_parent().y()) | 727 layer->offset_to_transform_parent().y()) |
692 return false; | 728 return false; |
693 return true; | 729 return true; |
694 } | 730 } |
695 | 731 |
696 } // namespace cc | 732 } // namespace cc |
OLD | NEW |