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

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: Unit test easier to understand 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
« no previous file with comments | « no previous file | cc/trees/layer_tree_host_common_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW
« no previous file with comments | « no previous file | cc/trees/layer_tree_host_common_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698