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

Side by Side Diff: cc/trees/draw_property_utils.cc

Issue 1252313004: Add ClipNode when Render Surface Inherits Clip (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 4 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 "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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | cc/trees/layer_tree_host_common_unittest.cc » ('j') | cc/trees/layer_tree_host_common_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698