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

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

Issue 2285363002: [NOT FOR REVIEW] calc visible rect dynamically
Patch Set: Created 4 years, 3 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 | no next file » | 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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 343
344 if (!clip_rect_in_target_space.IsEmpty()) { 344 if (!clip_rect_in_target_space.IsEmpty()) {
345 layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space)); 345 layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space));
346 } else { 346 } else {
347 layer->set_clip_rect(gfx::Rect()); 347 layer->set_clip_rect(gfx::Rect());
348 } 348 }
349 } 349 }
350 } 350 }
351 } 351 }
352 352
353 bool GetLayerClipRect(const LayerImpl* layer,
354 const ClipNode* clip_node,
355 const PropertyTrees* property_trees,
356 int target_node_id,
357 gfx::RectF* clip_rect_in_target_space) {
358 // This is equivalent of calling ComputeClipRectInTargetSpace.
359 *clip_rect_in_target_space = gfx::RectF(layer->clip_rect());
360 return property_trees->transform_tree.Node(target_node_id)
361 ->ancestors_are_invertible;
362 }
363
364 void CalculateVisibleRects(const LayerImplList& visible_layer_list, 353 void CalculateVisibleRects(const LayerImplList& visible_layer_list,
365 const PropertyTrees* property_trees, 354 const PropertyTrees* property_trees,
366 bool non_root_surfaces_enabled) { 355 bool non_root_surfaces_enabled) {
367 const EffectTree& effect_tree = property_trees->effect_tree; 356 const EffectTree& effect_tree = property_trees->effect_tree;
368 const TransformTree& transform_tree = property_trees->transform_tree;
369 const ClipTree& clip_tree = property_trees->clip_tree;
370 for (auto& layer : visible_layer_list) { 357 for (auto& layer : visible_layer_list) {
371 gfx::Size layer_bounds = layer->bounds(); 358 gfx::Size layer_bounds = layer->bounds();
372 359
360 int root_effect_space = EffectTree::kContentsRootNodeId;
361
373 int effect_ancestor_with_copy_request = 362 int effect_ancestor_with_copy_request =
374 effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index()); 363 effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index());
375 if (effect_ancestor_with_copy_request > 1) { 364 // If there is copy request, regard copy request as the "root space".
376 // Non root copy request. 365 if (effect_ancestor_with_copy_request > 0)
377 ConditionalClip accumulated_clip_rect = 366 root_effect_space = effect_ancestor_with_copy_request;
378 ComputeAccumulatedClip(property_trees, layer->clip_tree_index(),
379 effect_ancestor_with_copy_request);
380 if (!accumulated_clip_rect.is_clipped) {
381 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
382 continue;
383 }
384 367
385 gfx::RectF accumulated_clip_in_copy_request_space = 368 // Accumulates all clips appied to layer in "root space".
386 accumulated_clip_rect.clip_rect; 369 ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip(
387 370 property_trees, layer->clip_tree_index(), root_effect_space);
388 const EffectNode* copy_request_effect_node = 371 if (!accumulated_clip_rect.is_clipped) {
389 effect_tree.Node(effect_ancestor_with_copy_request);
390 ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace(
391 accumulated_clip_in_copy_request_space, property_trees,
392 copy_request_effect_node->transform_id, layer->transform_tree_index(),
393 copy_request_effect_node->id);
394
395 if (clip_in_layer_space.is_clipped) {
396 gfx::RectF clip_rect = clip_in_layer_space.clip_rect;
397 clip_rect.Offset(-layer->offset_to_transform_parent());
398 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect);
399 visible_rect.Intersect(gfx::Rect(layer_bounds));
400 layer->set_visible_layer_rect(visible_rect);
401 } else {
402 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
403 }
404 continue;
405 }
406
407 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
408 const TransformNode* transform_node =
409 transform_tree.Node(layer->transform_tree_index());
410 if (!non_root_surfaces_enabled) {
411 // When we only have a root surface, the clip node and the layer must
412 // necessarily have the same target (the root).
413 if (transform_node->ancestors_are_invertible) {
414 gfx::RectF combined_clip_rect_in_target_space =
415 clip_node->combined_clip_in_target_space;
416 gfx::Transform target_to_content;
417 target_to_content.Translate(-layer->offset_to_transform_parent().x(),
418 -layer->offset_to_transform_parent().y());
419 target_to_content.PreconcatTransform(
420 transform_tree.FromScreen(transform_node->id));
421
422 gfx::Rect visible_rect =
423 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
424 target_to_content, combined_clip_rect_in_target_space));
425 visible_rect.Intersect(gfx::Rect(layer_bounds));
426 layer->set_visible_layer_rect(visible_rect);
427 } else {
428 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
429 }
430 continue;
431 }
432
433 // When both the layer and the target are unclipped, the entire layer
434 // content rect is visible.
435 const bool fully_visible =
436 !clip_node->layers_are_clipped && !clip_node->target_is_clipped;
437
438 if (fully_visible) {
439 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 372 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
440 continue; 373 continue;
441 } 374 }
442 375
443 int target_node_id = transform_tree.ContentTargetId(transform_node->id); 376 gfx::RectF accumulated_clip_in_root_space = accumulated_clip_rect.clip_rect;
444 377
445 // The clip node stores clip rect in its target space. If required, 378 // Convert accumulated clip into layer space.
446 // this clip rect should be mapped to the current layer's target space. 379 const EffectNode* root_effect_node = effect_tree.Node(root_effect_space);
447 gfx::RectF combined_clip_rect_in_target_space; 380 ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace(
381 accumulated_clip_in_root_space, property_trees,
382 root_effect_node->transform_id, layer->transform_tree_index(),
383 root_effect_node->id);
448 384
449 if (clip_node->target_transform_id != target_node_id) { 385 if (clip_in_layer_space.is_clipped) {
450 // In this case, layer has a clip parent or scroll parent (or shares the 386 gfx::RectF clip_rect = clip_in_layer_space.clip_rect;
451 // target with an ancestor layer that has clip parent) and the clip 387 clip_rect.Offset(-layer->offset_to_transform_parent());
452 // parent's target is different from the layer's target. As the layer's 388 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect);
453 // target has unclippped descendants, it is unclippped. 389 visible_rect.Intersect(gfx::Rect(layer_bounds));
454 if (!clip_node->layers_are_clipped) { 390 layer->set_visible_layer_rect(visible_rect);
455 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
456 continue;
457 }
458
459 // We use the clip node's clip_in_target_space (and not
460 // combined_clip_in_target_space) here because we want to clip
461 // with respect to clip parent's local clip and not its combined clip as
462 // the combined clip has even the clip parent's target's clip baked into
463 // it and as our target is different, we don't want to use it in our
464 // visible rect computation.
465 if (!GetLayerClipRect(layer, clip_node, property_trees, target_node_id,
466 &combined_clip_rect_in_target_space)) {
467 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
468 continue;
469 }
470 } else { 391 } else {
471 if (clip_node->target_is_clipped) { 392 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
472 combined_clip_rect_in_target_space =
473 clip_node->combined_clip_in_target_space;
474 } else {
475 combined_clip_rect_in_target_space = clip_node->clip_in_target_space;
476 }
477 } 393 }
478
479 // The clip rect should be intersected with layer rect in target space.
480 gfx::Transform content_to_target = transform_tree.ToTarget(
481 transform_node->id, layer->render_target_effect_tree_index());
482 content_to_target.Translate(layer->offset_to_transform_parent().x(),
483 layer->offset_to_transform_parent().y());
484 gfx::Rect layer_content_rect = gfx::Rect(layer_bounds);
485 gfx::RectF layer_content_bounds_in_target_space = MathUtil::MapClippedRect(
486 content_to_target, gfx::RectF(layer_content_rect));
487 // If the layer is fully contained within the clip, treat it as fully
488 // visible.
489 if (!layer_content_bounds_in_target_space.IsEmpty() &&
490 combined_clip_rect_in_target_space.Contains(
491 layer_content_bounds_in_target_space)) {
492 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
493 continue;
494 }
495
496 combined_clip_rect_in_target_space.Intersect(
497 layer_content_bounds_in_target_space);
498 if (combined_clip_rect_in_target_space.IsEmpty()) {
499 layer->set_visible_layer_rect(gfx::Rect());
500 continue;
501 }
502
503 gfx::Transform target_to_layer;
504 if (transform_node->ancestors_are_invertible) {
505 target_to_layer = transform_tree.FromTarget(
506 transform_node->id, layer->render_target_effect_tree_index());
507 } else {
508 const EffectNode* target_effect_node =
509 ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree);
510 bool success = property_trees->ComputeTransformFromTarget(
511 transform_node->id, target_effect_node->id, &target_to_layer);
512 if (!success) {
513 // An animated singular transform may become non-singular during the
514 // animation, so we still need to compute a visible rect. In this
515 // situation, we treat the entire layer as visible.
516 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
517 continue;
518 }
519 if (target_effect_node->id > EffectTree::kContentsRootNodeId) {
520 ConcatInverseSurfaceContentsScale(target_effect_node, &target_to_layer);
521 #if DCHECK_IS_ON()
522 VerifySurfaceContentsScalesMatch(target_effect_node->id, target_node_id,
523 effect_tree, transform_tree);
524 #endif
525 }
526 }
527 gfx::Transform target_to_content;
528 target_to_content.Translate(-layer->offset_to_transform_parent().x(),
529 -layer->offset_to_transform_parent().y());
530 target_to_content.PreconcatTransform(target_to_layer);
531
532 gfx::Rect visible_rect = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
533 target_to_content, combined_clip_rect_in_target_space));
534 visible_rect.Intersect(gfx::Rect(layer_bounds));
535 layer->set_visible_layer_rect(visible_rect);
536 } 394 }
537 } 395 }
538 396
539 static bool HasSingularTransform(int transform_tree_index, 397 static bool HasSingularTransform(int transform_tree_index,
540 const TransformTree& tree) { 398 const TransformTree& tree) {
541 const TransformNode* node = tree.Node(transform_tree_index); 399 const TransformNode* node = tree.Node(transform_tree_index);
542 return !node->is_invertible || !node->ancestors_are_invertible; 400 return !node->is_invertible || !node->ancestors_are_invertible;
543 } 401 }
544 402
545 template <typename LayerType> 403 template <typename LayerType>
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1453 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1596 const Layer* overscroll_elasticity_layer, 1454 const Layer* overscroll_elasticity_layer,
1597 const gfx::Vector2dF& elastic_overscroll) { 1455 const gfx::Vector2dF& elastic_overscroll) {
1598 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1456 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1599 elastic_overscroll); 1457 elastic_overscroll);
1600 } 1458 }
1601 1459
1602 } // namespace draw_property_utils 1460 } // namespace draw_property_utils
1603 1461
1604 } // namespace cc 1462 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698