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

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: to run layout tests 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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW
« no previous file with comments | « no previous file | cc/trees/layer_tree_host_common_unittest.cc » ('j') | cc/trees/property_tree_builder.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698