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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... |
28 namespace { | 28 namespace { |
29 | 29 |
30 static bool IsRootLayer(const Layer* layer) { | 30 static bool IsRootLayer(const Layer* layer) { |
31 return !layer->parent(); | 31 return !layer->parent(); |
32 } | 32 } |
33 | 33 |
34 static bool IsRootLayer(const LayerImpl* layer) { | 34 static bool IsRootLayer(const LayerImpl* layer) { |
35 return layer->layer_tree_impl()->IsRootLayer(layer); | 35 return layer->layer_tree_impl()->IsRootLayer(layer); |
36 } | 36 } |
37 | 37 |
| 38 static void PostConcatSurfaceContentsScale(const EffectNode* effect_node, |
| 39 gfx::Transform* transform) { |
| 40 if (!effect_node) { |
| 41 // This can happen when PaintArtifactCompositor builds property trees as it |
| 42 // doesn't set effect ids on clip nodes. |
| 43 return; |
| 44 } |
| 45 DCHECK(effect_node->has_render_surface); |
| 46 transform->matrix().postScale(effect_node->surface_contents_scale.x(), |
| 47 effect_node->surface_contents_scale.y(), 1.f); |
| 48 } |
| 49 |
38 static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, | 50 static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, |
39 int source_effect_id, | 51 int source_effect_id, |
40 int dest_effect_id, | 52 int dest_effect_id, |
41 gfx::RectF clip_in_source_space, | 53 gfx::RectF clip_in_source_space, |
42 gfx::RectF* clip_in_dest_space) { | 54 gfx::RectF* clip_in_dest_space) { |
43 const EffectNode* source_effect_node = | 55 const EffectNode* source_effect_node = |
44 property_trees->effect_tree.Node(source_effect_id); | 56 property_trees->effect_tree.Node(source_effect_id); |
45 int source_transform_id = source_effect_node->transform_id; | 57 int source_transform_id = source_effect_node->transform_id; |
46 const EffectNode* dest_effect_node = | 58 const EffectNode* dest_effect_node = |
47 property_trees->effect_tree.Node(dest_effect_id); | 59 property_trees->effect_tree.Node(dest_effect_id); |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 // backface is not visible. | 409 // backface is not visible. |
398 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && | 410 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && |
399 !HasSingularTransform(backface_transform_id, tree) && | 411 !HasSingularTransform(backface_transform_id, tree) && |
400 IsLayerBackFaceVisible(layer, backface_transform_id, property_trees)) | 412 IsLayerBackFaceVisible(layer, backface_transform_id, property_trees)) |
401 return false; | 413 return false; |
402 } | 414 } |
403 | 415 |
404 return true; | 416 return true; |
405 } | 417 } |
406 | 418 |
407 | |
408 | |
409 } // namespace | |
410 | |
411 template <typename LayerType> | 419 template <typename LayerType> |
412 static inline bool LayerShouldBeSkippedInternal( | 420 static inline bool LayerShouldBeSkippedInternal( |
413 LayerType* layer, | 421 LayerType* layer, |
414 const TransformTree& transform_tree, | 422 const TransformTree& transform_tree, |
415 const EffectTree& effect_tree) { | 423 const EffectTree& effect_tree) { |
416 const TransformNode* transform_node = | 424 const TransformNode* transform_node = |
417 transform_tree.Node(layer->transform_tree_index()); | 425 transform_tree.Node(layer->transform_tree_index()); |
418 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); | 426 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); |
419 | 427 |
420 if (effect_node->has_render_surface && | 428 if (effect_node->has_render_surface && |
421 effect_node->num_copy_requests_in_subtree > 0) | 429 effect_node->num_copy_requests_in_subtree > 0) |
422 return false; | 430 return false; |
423 // If the layer transform is not invertible, it should be skipped. | 431 // If the layer transform is not invertible, it should be skipped. |
424 // TODO(ajuma): Correctly process subtrees with singular transform for the | 432 // TODO(ajuma): Correctly process subtrees with singular transform for the |
425 // case where we may animate to a non-singular transform and wish to | 433 // case where we may animate to a non-singular transform and wish to |
426 // pre-raster. | 434 // pre-raster. |
427 return !transform_node->node_and_ancestors_are_animated_or_invertible || | 435 return !transform_node->node_and_ancestors_are_animated_or_invertible || |
428 effect_node->hidden_by_backface_visibility || !effect_node->is_drawn; | 436 effect_node->hidden_by_backface_visibility || !effect_node->is_drawn; |
429 } | 437 } |
430 | 438 |
431 bool LayerShouldBeSkipped(LayerImpl* layer, | 439 template <typename LayerType> |
432 const TransformTree& transform_tree, | 440 static void UpdateElasticOverscrollInternal( |
433 const EffectTree& effect_tree) { | 441 PropertyTrees* property_trees, |
434 return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); | 442 const LayerType* overscroll_elasticity_layer, |
| 443 const gfx::Vector2dF& elastic_overscroll) { |
| 444 if (!overscroll_elasticity_layer) { |
| 445 DCHECK(elastic_overscroll.IsZero()); |
| 446 return; |
| 447 } |
| 448 |
| 449 TransformNode* node = property_trees->transform_tree.Node( |
| 450 overscroll_elasticity_layer->transform_tree_index()); |
| 451 if (node->scroll_offset == gfx::ScrollOffset(elastic_overscroll)) |
| 452 return; |
| 453 |
| 454 node->scroll_offset = gfx::ScrollOffset(elastic_overscroll); |
| 455 node->needs_local_transform_update = true; |
| 456 property_trees->transform_tree.set_needs_update(true); |
435 } | 457 } |
436 | 458 |
437 bool LayerShouldBeSkipped(Layer* layer, | 459 #if DCHECK_IS_ON() |
438 const TransformTree& transform_tree, | 460 static void ValidatePageScaleLayer(const Layer* page_scale_layer) { |
439 const EffectTree& effect_tree) { | 461 DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString()); |
440 return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); | 462 DCHECK_EQ(page_scale_layer->transform_origin().ToString(), |
| 463 gfx::Point3F().ToString()); |
441 } | 464 } |
442 | 465 |
443 void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, | 466 static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {} |
444 const PropertyTrees* property_trees, | 467 #endif |
445 LayerList* update_layer_list) { | 468 |
446 const TransformTree& transform_tree = property_trees->transform_tree; | 469 template <typename LayerType> |
| 470 static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees, |
| 471 const LayerType* page_scale_layer, |
| 472 float page_scale_factor, |
| 473 float device_scale_factor, |
| 474 gfx::Transform device_transform) { |
| 475 if (property_trees->transform_tree.page_scale_factor() == page_scale_factor) |
| 476 return; |
| 477 |
| 478 property_trees->transform_tree.set_page_scale_factor(page_scale_factor); |
| 479 DCHECK(page_scale_layer); |
| 480 DCHECK_GE(page_scale_layer->transform_tree_index(), |
| 481 TransformTree::kRootNodeId); |
| 482 TransformNode* node = property_trees->transform_tree.Node( |
| 483 page_scale_layer->transform_tree_index()); |
| 484 // TODO(enne): property trees can't ask the layer these things, but |
| 485 // the page scale layer should *just* be the page scale. |
| 486 #if DCHECK_IS_ON() |
| 487 ValidatePageScaleLayer(page_scale_layer); |
| 488 #endif |
| 489 |
| 490 if (IsRootLayer(page_scale_layer)) { |
| 491 // When the page scale layer is also the root layer, the node should also |
| 492 // store the combined scale factor and not just the page scale factor. |
| 493 float post_local_scale_factor = page_scale_factor * device_scale_factor; |
| 494 node->post_local_scale_factor = post_local_scale_factor; |
| 495 node->post_local = device_transform; |
| 496 node->post_local.Scale(post_local_scale_factor, post_local_scale_factor); |
| 497 } else { |
| 498 node->post_local_scale_factor = page_scale_factor; |
| 499 node->update_post_local_transform(gfx::PointF(), gfx::Point3F()); |
| 500 } |
| 501 node->needs_local_transform_update = true; |
| 502 property_trees->transform_tree.set_needs_update(true); |
| 503 } |
| 504 |
| 505 static gfx::Rect LayerDrawableContentRect( |
| 506 const LayerImpl* layer, |
| 507 const gfx::Rect& layer_bounds_in_target_space, |
| 508 const gfx::Rect& clip_rect) { |
| 509 if (layer->is_clipped()) |
| 510 return IntersectRects(layer_bounds_in_target_space, clip_rect); |
| 511 |
| 512 return layer_bounds_in_target_space; |
| 513 } |
| 514 |
| 515 static void SetSurfaceDrawOpacity(const EffectTree& tree, |
| 516 RenderSurfaceImpl* render_surface) { |
| 517 // Draw opacity of a surface is the product of opacities between the surface |
| 518 // (included) and its target surface (excluded). |
| 519 const EffectNode* node = tree.Node(render_surface->EffectTreeIndex()); |
| 520 float draw_opacity = tree.EffectiveOpacity(node); |
| 521 for (node = tree.parent(node); node && !node->has_render_surface; |
| 522 node = tree.parent(node)) { |
| 523 draw_opacity *= tree.EffectiveOpacity(node); |
| 524 } |
| 525 render_surface->SetDrawOpacity(draw_opacity); |
| 526 } |
| 527 |
| 528 static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { |
| 529 if (!layer->render_target()) |
| 530 return 0.f; |
| 531 |
| 532 const EffectNode* target_node = |
| 533 tree.Node(layer->render_target()->EffectTreeIndex()); |
| 534 const EffectNode* node = tree.Node(layer->effect_tree_index()); |
| 535 if (node == target_node) |
| 536 return 1.f; |
| 537 |
| 538 float draw_opacity = 1.f; |
| 539 while (node != target_node) { |
| 540 draw_opacity *= tree.EffectiveOpacity(node); |
| 541 node = tree.parent(node); |
| 542 } |
| 543 return draw_opacity; |
| 544 } |
| 545 |
| 546 template <typename LayerType> |
| 547 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, |
| 548 const TransformTree& tree) { |
| 549 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), |
| 550 layer->offset_to_transform_parent().y()); |
| 551 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); |
| 552 xform.ConcatTransform(ssxform); |
| 553 if (layer->should_flatten_transform_from_property_tree()) |
| 554 xform.FlattenTo2d(); |
| 555 return xform; |
| 556 } |
| 557 |
| 558 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
| 559 PropertyTrees* property_trees, |
| 560 RenderSurfaceImpl* render_surface) { |
| 561 if (!render_surface->is_clipped()) { |
| 562 render_surface->SetClipRect(gfx::Rect()); |
| 563 return; |
| 564 } |
| 565 |
447 const EffectTree& effect_tree = property_trees->effect_tree; | 566 const EffectTree& effect_tree = property_trees->effect_tree; |
448 for (auto* layer : *layer_tree_host) { | 567 const ClipTree& clip_tree = property_trees->clip_tree; |
449 if (!IsRootLayer(layer) && | 568 const EffectNode* effect_node = |
450 LayerShouldBeSkipped(layer, transform_tree, effect_tree)) | 569 effect_tree.Node(render_surface->EffectTreeIndex()); |
451 continue; | 570 const EffectNode* target_node = effect_tree.Node(effect_node->target_id); |
452 | 571 bool include_expanding_clips = false; |
453 bool layer_is_drawn = | 572 if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { |
454 effect_tree.Node(layer->effect_tree_index())->is_drawn; | 573 render_surface->SetClipRect( |
455 | 574 gfx::ToEnclosingRect(clip_tree.Node(effect_node->clip_id)->clip)); |
456 if (LayerNeedsUpdate(layer, layer_is_drawn, property_trees)) { | 575 } else { |
457 update_layer_list->push_back(layer); | 576 ConditionalClip accumulated_clip_rect = |
458 } | 577 ComputeAccumulatedClip(property_trees, include_expanding_clips, |
459 | 578 effect_node->clip_id, target_node->id); |
460 // Append mask layers to the update layer list. They don't have valid | 579 render_surface->SetClipRect( |
461 // visible rects, so need to get added after the above calculation. | 580 gfx::ToEnclosingRect(accumulated_clip_rect.clip_rect)); |
462 if (Layer* mask_layer = layer->mask_layer()) | |
463 update_layer_list->push_back(mask_layer); | |
464 } | 581 } |
465 } | 582 } |
466 | 583 |
467 void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, | 584 static void SetSurfaceDrawTransform(const PropertyTrees* property_trees, |
468 const PropertyTrees* property_trees, | 585 RenderSurfaceImpl* render_surface) { |
469 std::vector<LayerImpl*>* visible_layer_list) { | |
470 const TransformTree& transform_tree = property_trees->transform_tree; | 586 const TransformTree& transform_tree = property_trees->transform_tree; |
471 const EffectTree& effect_tree = property_trees->effect_tree; | 587 const EffectTree& effect_tree = property_trees->effect_tree; |
472 | 588 const TransformNode* transform_node = |
473 for (auto* layer_impl : *layer_tree_impl) { | 589 transform_tree.Node(render_surface->TransformTreeIndex()); |
474 if (!IsRootLayer(layer_impl) && | 590 const EffectNode* effect_node = |
475 LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree)) | 591 effect_tree.Node(render_surface->EffectTreeIndex()); |
476 continue; | 592 // The draw transform of root render surface is identity tranform. |
477 | 593 if (transform_node->id == TransformTree::kRootNodeId) { |
478 bool layer_is_drawn = | 594 render_surface->SetDrawTransform(gfx::Transform()); |
479 effect_tree.Node(layer_impl->effect_tree_index())->is_drawn; | |
480 | |
481 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees)) | |
482 visible_layer_list->push_back(layer_impl); | |
483 } | |
484 } | |
485 | |
486 void PostConcatSurfaceContentsScale(const EffectNode* effect_node, | |
487 gfx::Transform* transform) { | |
488 if (!effect_node) { | |
489 // This can happen when PaintArtifactCompositor builds property trees as it | |
490 // doesn't set effect ids on clip nodes. | |
491 return; | 595 return; |
492 } | 596 } |
493 DCHECK(effect_node->has_render_surface); | |
494 transform->matrix().postScale(effect_node->surface_contents_scale.x(), | |
495 effect_node->surface_contents_scale.y(), 1.f); | |
496 } | |
497 | 597 |
498 void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, | 598 gfx::Transform render_surface_transform; |
499 gfx::Transform* transform) { | 599 const EffectNode* target_effect_node = |
500 DCHECK(effect_node->has_render_surface); | 600 effect_tree.Node(effect_node->target_id); |
501 if (effect_node->surface_contents_scale.x() != 0.0 && | 601 property_trees->GetToTarget(transform_node->id, target_effect_node->id, |
502 effect_node->surface_contents_scale.y() != 0.0) | 602 &render_surface_transform); |
503 transform->Scale(1.0 / effect_node->surface_contents_scale.x(), | |
504 1.0 / effect_node->surface_contents_scale.y()); | |
505 } | |
506 | 603 |
507 void UpdateScrollTree(ScrollTree* scroll_tree, | 604 ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform); |
508 const LayerTreeHost* layer_tree_host) { | 605 render_surface->SetDrawTransform(render_surface_transform); |
509 if (!scroll_tree->needs_update()) | |
510 return; | |
511 | |
512 for (int i = ScrollTree::kRootNodeId; | |
513 i < static_cast<int>(scroll_tree->size()); ++i) { | |
514 ScrollNode* scroll_node = scroll_tree->Node(i); | |
515 if (Layer* scroll_layer = | |
516 layer_tree_host->LayerById(scroll_node->owning_layer_id)) { | |
517 if (Layer* scroll_clip_layer = scroll_layer->scroll_clip_layer()) { | |
518 scroll_node->scroll_clip_layer_bounds = scroll_clip_layer->bounds(); | |
519 } | |
520 } | |
521 } | |
522 } | |
523 | |
524 void ComputeTransforms(TransformTree* transform_tree) { | |
525 if (!transform_tree->needs_update()) | |
526 return; | |
527 for (int i = TransformTree::kContentsRootNodeId; | |
528 i < static_cast<int>(transform_tree->size()); ++i) | |
529 transform_tree->UpdateTransforms(i); | |
530 transform_tree->set_needs_update(false); | |
531 } | |
532 | |
533 void UpdateRenderTarget(EffectTree* effect_tree, | |
534 bool can_render_to_separate_surface) { | |
535 for (int i = EffectTree::kContentsRootNodeId; | |
536 i < static_cast<int>(effect_tree->size()); ++i) { | |
537 EffectNode* node = effect_tree->Node(i); | |
538 if (i == EffectTree::kContentsRootNodeId) { | |
539 // Render target of the node corresponding to root is itself. | |
540 node->target_id = EffectTree::kContentsRootNodeId; | |
541 } else if (!can_render_to_separate_surface) { | |
542 node->target_id = EffectTree::kContentsRootNodeId; | |
543 } else if (effect_tree->parent(node)->has_render_surface) { | |
544 node->target_id = node->parent_id; | |
545 } else { | |
546 node->target_id = effect_tree->parent(node)->target_id; | |
547 } | |
548 } | |
549 } | |
550 | |
551 void ComputeEffects(EffectTree* effect_tree) { | |
552 if (!effect_tree->needs_update()) | |
553 return; | |
554 for (int i = EffectTree::kContentsRootNodeId; | |
555 i < static_cast<int>(effect_tree->size()); ++i) | |
556 effect_tree->UpdateEffects(i); | |
557 effect_tree->set_needs_update(false); | |
558 } | |
559 | |
560 void ComputeClips(PropertyTrees* property_trees) { | |
561 DCHECK(!property_trees->transform_tree.needs_update()); | |
562 ClipTree* clip_tree = &property_trees->clip_tree; | |
563 if (!clip_tree->needs_update()) | |
564 return; | |
565 const int target_effect_id = EffectTree::kContentsRootNodeId; | |
566 const int target_transform_id = TransformTree::kRootNodeId; | |
567 const bool include_expanding_clips = true; | |
568 for (int i = ClipTree::kViewportNodeId; | |
569 i < static_cast<int>(clip_tree->size()); ++i) { | |
570 ClipNode* clip_node = clip_tree->Node(i); | |
571 // Clear the clip rect cache | |
572 clip_node->cached_clip_rects = std::vector<ClipRectData>(1); | |
573 if (clip_node->id == ClipTree::kViewportNodeId) { | |
574 clip_node->cached_accumulated_rect_in_screen_space = clip_node->clip; | |
575 continue; | |
576 } | |
577 ClipNode* parent_clip_node = clip_tree->parent(clip_node); | |
578 DCHECK(parent_clip_node); | |
579 gfx::RectF accumulated_clip = | |
580 parent_clip_node->cached_accumulated_rect_in_screen_space; | |
581 bool success = ApplyClipNodeToAccumulatedClip( | |
582 property_trees, include_expanding_clips, target_effect_id, | |
583 target_transform_id, clip_node, &accumulated_clip); | |
584 DCHECK(success); | |
585 clip_node->cached_accumulated_rect_in_screen_space = accumulated_clip; | |
586 } | |
587 clip_tree->set_needs_update(false); | |
588 } | |
589 | |
590 static ConditionalClip LayerClipRect(PropertyTrees* property_trees, | |
591 LayerImpl* layer) { | |
592 const EffectTree* effect_tree = &property_trees->effect_tree; | |
593 const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); | |
594 const EffectNode* target_node = | |
595 effect_node->has_render_surface | |
596 ? effect_node | |
597 : effect_tree->Node(effect_node->target_id); | |
598 // TODO(weiliangc): When effect node has up to date render surface info on | |
599 // compositor thread, no need to check for resourceless draw mode | |
600 if (!property_trees->non_root_surfaces_enabled) { | |
601 target_node = effect_tree->Node(1); | |
602 } | |
603 | |
604 bool include_expanding_clips = false; | |
605 return ComputeAccumulatedClip(property_trees, include_expanding_clips, | |
606 layer->clip_tree_index(), target_node->id); | |
607 } | 606 } |
608 | 607 |
609 static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, | 608 static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, |
610 LayerImpl* layer) { | 609 LayerImpl* layer) { |
611 int effect_ancestor_with_copy_request = | 610 int effect_ancestor_with_copy_request = |
612 property_trees->effect_tree.ClosestAncestorWithCopyRequest( | 611 property_trees->effect_tree.ClosestAncestorWithCopyRequest( |
613 layer->effect_tree_index()); | 612 layer->effect_tree_index()); |
614 bool non_root_copy_request = | 613 bool non_root_copy_request = |
615 effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId; | 614 effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId; |
616 gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); | 615 gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 return layer_content_rect; | 650 return layer_content_rect; |
652 } | 651 } |
653 gfx::RectF clip_in_layer_space = accumulated_clip_in_layer_space.clip_rect; | 652 gfx::RectF clip_in_layer_space = accumulated_clip_in_layer_space.clip_rect; |
654 clip_in_layer_space.Offset(-layer->offset_to_transform_parent()); | 653 clip_in_layer_space.Offset(-layer->offset_to_transform_parent()); |
655 | 654 |
656 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_in_layer_space); | 655 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_in_layer_space); |
657 visible_rect.Intersect(layer_content_rect); | 656 visible_rect.Intersect(layer_content_rect); |
658 return visible_rect; | 657 return visible_rect; |
659 } | 658 } |
660 | 659 |
| 660 static ConditionalClip LayerClipRect(PropertyTrees* property_trees, |
| 661 LayerImpl* layer) { |
| 662 const EffectTree* effect_tree = &property_trees->effect_tree; |
| 663 const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); |
| 664 const EffectNode* target_node = |
| 665 effect_node->has_render_surface |
| 666 ? effect_node |
| 667 : effect_tree->Node(effect_node->target_id); |
| 668 // TODO(weiliangc): When effect node has up to date render surface info on |
| 669 // compositor thread, no need to check for resourceless draw mode |
| 670 if (!property_trees->non_root_surfaces_enabled) { |
| 671 target_node = effect_tree->Node(1); |
| 672 } |
| 673 |
| 674 bool include_expanding_clips = false; |
| 675 return ComputeAccumulatedClip(property_trees, include_expanding_clips, |
| 676 layer->clip_tree_index(), target_node->id); |
| 677 } |
| 678 |
| 679 static void UpdateRenderTarget(EffectTree* effect_tree, |
| 680 bool can_render_to_separate_surface) { |
| 681 for (int i = EffectTree::kContentsRootNodeId; |
| 682 i < static_cast<int>(effect_tree->size()); ++i) { |
| 683 EffectNode* node = effect_tree->Node(i); |
| 684 if (i == EffectTree::kContentsRootNodeId) { |
| 685 // Render target of the node corresponding to root is itself. |
| 686 node->target_id = EffectTree::kContentsRootNodeId; |
| 687 } else if (!can_render_to_separate_surface) { |
| 688 node->target_id = EffectTree::kContentsRootNodeId; |
| 689 } else if (effect_tree->parent(node)->has_render_surface) { |
| 690 node->target_id = node->parent_id; |
| 691 } else { |
| 692 node->target_id = effect_tree->parent(node)->target_id; |
| 693 } |
| 694 } |
| 695 } |
| 696 |
| 697 static void UpdateScrollTree(ScrollTree* scroll_tree, |
| 698 const LayerTreeHost* layer_tree_host) { |
| 699 if (!scroll_tree->needs_update()) |
| 700 return; |
| 701 |
| 702 for (int i = ScrollTree::kRootNodeId; |
| 703 i < static_cast<int>(scroll_tree->size()); ++i) { |
| 704 ScrollNode* scroll_node = scroll_tree->Node(i); |
| 705 if (Layer* scroll_layer = |
| 706 layer_tree_host->LayerById(scroll_node->owning_layer_id)) { |
| 707 if (Layer* scroll_clip_layer = scroll_layer->scroll_clip_layer()) { |
| 708 scroll_node->scroll_clip_layer_bounds = scroll_clip_layer->bounds(); |
| 709 } |
| 710 } |
| 711 } |
| 712 } |
| 713 |
| 714 static void ComputeClips(PropertyTrees* property_trees) { |
| 715 DCHECK(!property_trees->transform_tree.needs_update()); |
| 716 ClipTree* clip_tree = &property_trees->clip_tree; |
| 717 if (!clip_tree->needs_update()) |
| 718 return; |
| 719 const int target_effect_id = EffectTree::kContentsRootNodeId; |
| 720 const int target_transform_id = TransformTree::kRootNodeId; |
| 721 const bool include_expanding_clips = true; |
| 722 for (int i = ClipTree::kViewportNodeId; |
| 723 i < static_cast<int>(clip_tree->size()); ++i) { |
| 724 ClipNode* clip_node = clip_tree->Node(i); |
| 725 // Clear the clip rect cache |
| 726 clip_node->cached_clip_rects = std::vector<ClipRectData>(1); |
| 727 if (clip_node->id == ClipTree::kViewportNodeId) { |
| 728 clip_node->cached_accumulated_rect_in_screen_space = clip_node->clip; |
| 729 continue; |
| 730 } |
| 731 ClipNode* parent_clip_node = clip_tree->parent(clip_node); |
| 732 DCHECK(parent_clip_node); |
| 733 gfx::RectF accumulated_clip = |
| 734 parent_clip_node->cached_accumulated_rect_in_screen_space; |
| 735 bool success = ApplyClipNodeToAccumulatedClip( |
| 736 property_trees, include_expanding_clips, target_effect_id, |
| 737 target_transform_id, clip_node, &accumulated_clip); |
| 738 DCHECK(success); |
| 739 clip_node->cached_accumulated_rect_in_screen_space = accumulated_clip; |
| 740 } |
| 741 clip_tree->set_needs_update(false); |
| 742 } |
| 743 |
| 744 } // namespace |
| 745 |
| 746 void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, |
| 747 gfx::Transform* transform) { |
| 748 DCHECK(effect_node->has_render_surface); |
| 749 if (effect_node->surface_contents_scale.x() != 0.0 && |
| 750 effect_node->surface_contents_scale.y() != 0.0) |
| 751 transform->Scale(1.0 / effect_node->surface_contents_scale.x(), |
| 752 1.0 / effect_node->surface_contents_scale.y()); |
| 753 } |
| 754 |
| 755 bool LayerShouldBeSkipped(LayerImpl* layer, |
| 756 const TransformTree& transform_tree, |
| 757 const EffectTree& effect_tree) { |
| 758 return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); |
| 759 } |
| 760 |
| 761 bool LayerShouldBeSkipped(Layer* layer, |
| 762 const TransformTree& transform_tree, |
| 763 const EffectTree& effect_tree) { |
| 764 return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); |
| 765 } |
| 766 |
| 767 void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, |
| 768 const PropertyTrees* property_trees, |
| 769 LayerList* update_layer_list) { |
| 770 const TransformTree& transform_tree = property_trees->transform_tree; |
| 771 const EffectTree& effect_tree = property_trees->effect_tree; |
| 772 for (auto* layer : *layer_tree_host) { |
| 773 if (!IsRootLayer(layer) && |
| 774 LayerShouldBeSkipped(layer, transform_tree, effect_tree)) |
| 775 continue; |
| 776 |
| 777 bool layer_is_drawn = |
| 778 effect_tree.Node(layer->effect_tree_index())->is_drawn; |
| 779 |
| 780 if (LayerNeedsUpdate(layer, layer_is_drawn, property_trees)) { |
| 781 update_layer_list->push_back(layer); |
| 782 } |
| 783 |
| 784 // Append mask layers to the update layer list. They don't have valid |
| 785 // visible rects, so need to get added after the above calculation. |
| 786 if (Layer* mask_layer = layer->mask_layer()) |
| 787 update_layer_list->push_back(mask_layer); |
| 788 } |
| 789 } |
| 790 |
| 791 void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, |
| 792 const PropertyTrees* property_trees, |
| 793 std::vector<LayerImpl*>* visible_layer_list) { |
| 794 const TransformTree& transform_tree = property_trees->transform_tree; |
| 795 const EffectTree& effect_tree = property_trees->effect_tree; |
| 796 |
| 797 for (auto* layer_impl : *layer_tree_impl) { |
| 798 if (!IsRootLayer(layer_impl) && |
| 799 LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree)) |
| 800 continue; |
| 801 |
| 802 bool layer_is_drawn = |
| 803 effect_tree.Node(layer_impl->effect_tree_index())->is_drawn; |
| 804 |
| 805 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees)) |
| 806 visible_layer_list->push_back(layer_impl); |
| 807 } |
| 808 } |
| 809 |
| 810 void ComputeTransforms(TransformTree* transform_tree) { |
| 811 if (!transform_tree->needs_update()) |
| 812 return; |
| 813 for (int i = TransformTree::kContentsRootNodeId; |
| 814 i < static_cast<int>(transform_tree->size()); ++i) |
| 815 transform_tree->UpdateTransforms(i); |
| 816 transform_tree->set_needs_update(false); |
| 817 } |
| 818 |
| 819 void ComputeEffects(EffectTree* effect_tree) { |
| 820 if (!effect_tree->needs_update()) |
| 821 return; |
| 822 for (int i = EffectTree::kContentsRootNodeId; |
| 823 i < static_cast<int>(effect_tree->size()); ++i) |
| 824 effect_tree->UpdateEffects(i); |
| 825 effect_tree->set_needs_update(false); |
| 826 } |
| 827 |
661 void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, | 828 void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, |
662 PropertyTrees* property_trees, | 829 PropertyTrees* property_trees, |
663 bool can_render_to_separate_surface) { | 830 bool can_render_to_separate_surface) { |
664 DCHECK(layer_tree_host); | 831 DCHECK(layer_tree_host); |
665 DCHECK(property_trees); | 832 DCHECK(property_trees); |
666 DCHECK_EQ(layer_tree_host->property_trees(), property_trees); | 833 DCHECK_EQ(layer_tree_host->property_trees(), property_trees); |
667 if (property_trees->non_root_surfaces_enabled != | 834 if (property_trees->non_root_surfaces_enabled != |
668 can_render_to_separate_surface) { | 835 can_render_to_separate_surface) { |
669 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | 836 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; |
670 property_trees->transform_tree.set_needs_update(true); | 837 property_trees->transform_tree.set_needs_update(true); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 &xform); | 902 &xform); |
736 else | 903 else |
737 xform = transform_tree.ToScreen(layer->transform_tree_index()); | 904 xform = transform_tree.ToScreen(layer->transform_tree_index()); |
738 if (layer->should_flatten_transform_from_property_tree()) | 905 if (layer->should_flatten_transform_from_property_tree()) |
739 xform.FlattenTo2d(); | 906 xform.FlattenTo2d(); |
740 xform.Translate(layer->offset_to_transform_parent().x(), | 907 xform.Translate(layer->offset_to_transform_parent().x(), |
741 layer->offset_to_transform_parent().y()); | 908 layer->offset_to_transform_parent().y()); |
742 return xform; | 909 return xform; |
743 } | 910 } |
744 | 911 |
745 static void SetSurfaceDrawTransform(const PropertyTrees* property_trees, | |
746 RenderSurfaceImpl* render_surface) { | |
747 const TransformTree& transform_tree = property_trees->transform_tree; | |
748 const EffectTree& effect_tree = property_trees->effect_tree; | |
749 const TransformNode* transform_node = | |
750 transform_tree.Node(render_surface->TransformTreeIndex()); | |
751 const EffectNode* effect_node = | |
752 effect_tree.Node(render_surface->EffectTreeIndex()); | |
753 // The draw transform of root render surface is identity tranform. | |
754 if (transform_node->id == TransformTree::kRootNodeId) { | |
755 render_surface->SetDrawTransform(gfx::Transform()); | |
756 return; | |
757 } | |
758 | |
759 gfx::Transform render_surface_transform; | |
760 const EffectNode* target_effect_node = | |
761 effect_tree.Node(effect_node->target_id); | |
762 property_trees->GetToTarget(transform_node->id, target_effect_node->id, | |
763 &render_surface_transform); | |
764 | |
765 ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform); | |
766 render_surface->SetDrawTransform(render_surface_transform); | |
767 } | |
768 | |
769 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, | |
770 PropertyTrees* property_trees, | |
771 RenderSurfaceImpl* render_surface) { | |
772 if (!render_surface->is_clipped()) { | |
773 render_surface->SetClipRect(gfx::Rect()); | |
774 return; | |
775 } | |
776 | |
777 const EffectTree& effect_tree = property_trees->effect_tree; | |
778 const ClipTree& clip_tree = property_trees->clip_tree; | |
779 const EffectNode* effect_node = | |
780 effect_tree.Node(render_surface->EffectTreeIndex()); | |
781 const EffectNode* target_node = effect_tree.Node(effect_node->target_id); | |
782 bool include_expanding_clips = false; | |
783 if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { | |
784 render_surface->SetClipRect( | |
785 gfx::ToEnclosingRect(clip_tree.Node(effect_node->clip_id)->clip)); | |
786 } else { | |
787 ConditionalClip accumulated_clip_rect = | |
788 ComputeAccumulatedClip(property_trees, include_expanding_clips, | |
789 effect_node->clip_id, target_node->id); | |
790 render_surface->SetClipRect( | |
791 gfx::ToEnclosingRect(accumulated_clip_rect.clip_rect)); | |
792 } | |
793 } | |
794 | |
795 template <typename LayerType> | |
796 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, | |
797 const TransformTree& tree) { | |
798 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), | |
799 layer->offset_to_transform_parent().y()); | |
800 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); | |
801 xform.ConcatTransform(ssxform); | |
802 if (layer->should_flatten_transform_from_property_tree()) | |
803 xform.FlattenTo2d(); | |
804 return xform; | |
805 } | |
806 | |
807 gfx::Transform ScreenSpaceTransform(const Layer* layer, | 912 gfx::Transform ScreenSpaceTransform(const Layer* layer, |
808 const TransformTree& tree) { | 913 const TransformTree& tree) { |
809 return ScreenSpaceTransformInternal(layer, tree); | 914 return ScreenSpaceTransformInternal(layer, tree); |
810 } | 915 } |
811 | 916 |
812 gfx::Transform ScreenSpaceTransform(const LayerImpl* layer, | 917 gfx::Transform ScreenSpaceTransform(const LayerImpl* layer, |
813 const TransformTree& tree) { | 918 const TransformTree& tree) { |
814 return ScreenSpaceTransformInternal(layer, tree); | 919 return ScreenSpaceTransformInternal(layer, tree); |
815 } | 920 } |
816 | 921 |
817 static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { | |
818 if (!layer->render_target()) | |
819 return 0.f; | |
820 | |
821 const EffectNode* target_node = | |
822 tree.Node(layer->render_target()->EffectTreeIndex()); | |
823 const EffectNode* node = tree.Node(layer->effect_tree_index()); | |
824 if (node == target_node) | |
825 return 1.f; | |
826 | |
827 float draw_opacity = 1.f; | |
828 while (node != target_node) { | |
829 draw_opacity *= tree.EffectiveOpacity(node); | |
830 node = tree.parent(node); | |
831 } | |
832 return draw_opacity; | |
833 } | |
834 | |
835 static void SetSurfaceDrawOpacity(const EffectTree& tree, | |
836 RenderSurfaceImpl* render_surface) { | |
837 // Draw opacity of a surface is the product of opacities between the surface | |
838 // (included) and its target surface (excluded). | |
839 const EffectNode* node = tree.Node(render_surface->EffectTreeIndex()); | |
840 float draw_opacity = tree.EffectiveOpacity(node); | |
841 for (node = tree.parent(node); node && !node->has_render_surface; | |
842 node = tree.parent(node)) { | |
843 draw_opacity *= tree.EffectiveOpacity(node); | |
844 } | |
845 render_surface->SetDrawOpacity(draw_opacity); | |
846 } | |
847 | |
848 static gfx::Rect LayerDrawableContentRect( | |
849 const LayerImpl* layer, | |
850 const gfx::Rect& layer_bounds_in_target_space, | |
851 const gfx::Rect& clip_rect) { | |
852 if (layer->is_clipped()) | |
853 return IntersectRects(layer_bounds_in_target_space, clip_rect); | |
854 | |
855 return layer_bounds_in_target_space; | |
856 } | |
857 | |
858 void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, | 922 void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, |
859 PropertyTrees* property_trees) { | 923 PropertyTrees* property_trees) { |
860 // Compute transforms | 924 // Compute transforms |
861 for (LayerImpl* layer : *layer_list) { | 925 for (LayerImpl* layer : *layer_list) { |
862 const TransformNode* transform_node = | 926 const TransformNode* transform_node = |
863 property_trees->transform_tree.Node(layer->transform_tree_index()); | 927 property_trees->transform_tree.Node(layer->transform_tree_index()); |
864 | 928 |
865 layer->draw_properties().screen_space_transform = | 929 layer->draw_properties().screen_space_transform = |
866 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); | 930 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); |
867 layer->draw_properties().target_space_transform = DrawTransform( | 931 layer->draw_properties().target_space_transform = DrawTransform( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 render_surface->SetScreenSpaceTransform( | 993 render_surface->SetScreenSpaceTransform( |
930 property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( | 994 property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( |
931 render_surface->TransformTreeIndex(), | 995 render_surface->TransformTreeIndex(), |
932 render_surface->EffectTreeIndex())); | 996 render_surface->EffectTreeIndex())); |
933 | 997 |
934 const ClipNode* clip_node = | 998 const ClipNode* clip_node = |
935 property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); | 999 property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); |
936 SetSurfaceClipRect(clip_node, property_trees, render_surface); | 1000 SetSurfaceClipRect(clip_node, property_trees, render_surface); |
937 } | 1001 } |
938 | 1002 |
939 #if DCHECK_IS_ON() | |
940 static void ValidatePageScaleLayer(const Layer* page_scale_layer) { | |
941 DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString()); | |
942 DCHECK_EQ(page_scale_layer->transform_origin().ToString(), | |
943 gfx::Point3F().ToString()); | |
944 } | |
945 | |
946 static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {} | |
947 #endif | |
948 | |
949 template <typename LayerType> | |
950 static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees, | |
951 const LayerType* page_scale_layer, | |
952 float page_scale_factor, | |
953 float device_scale_factor, | |
954 gfx::Transform device_transform) { | |
955 if (property_trees->transform_tree.page_scale_factor() == page_scale_factor) | |
956 return; | |
957 | |
958 property_trees->transform_tree.set_page_scale_factor(page_scale_factor); | |
959 DCHECK(page_scale_layer); | |
960 DCHECK_GE(page_scale_layer->transform_tree_index(), | |
961 TransformTree::kRootNodeId); | |
962 TransformNode* node = property_trees->transform_tree.Node( | |
963 page_scale_layer->transform_tree_index()); | |
964 // TODO(enne): property trees can't ask the layer these things, but | |
965 // the page scale layer should *just* be the page scale. | |
966 #if DCHECK_IS_ON() | |
967 ValidatePageScaleLayer(page_scale_layer); | |
968 #endif | |
969 | |
970 if (IsRootLayer(page_scale_layer)) { | |
971 // When the page scale layer is also the root layer, the node should also | |
972 // store the combined scale factor and not just the page scale factor. | |
973 float post_local_scale_factor = page_scale_factor * device_scale_factor; | |
974 node->post_local_scale_factor = post_local_scale_factor; | |
975 node->post_local = device_transform; | |
976 node->post_local.Scale(post_local_scale_factor, post_local_scale_factor); | |
977 } else { | |
978 node->post_local_scale_factor = page_scale_factor; | |
979 node->update_post_local_transform(gfx::PointF(), gfx::Point3F()); | |
980 } | |
981 node->needs_local_transform_update = true; | |
982 property_trees->transform_tree.set_needs_update(true); | |
983 } | |
984 | |
985 void UpdatePageScaleFactor(PropertyTrees* property_trees, | 1003 void UpdatePageScaleFactor(PropertyTrees* property_trees, |
986 const LayerImpl* page_scale_layer, | 1004 const LayerImpl* page_scale_layer, |
987 float page_scale_factor, | 1005 float page_scale_factor, |
988 float device_scale_factor, | 1006 float device_scale_factor, |
989 const gfx::Transform device_transform) { | 1007 const gfx::Transform device_transform) { |
990 UpdatePageScaleFactorInternal(property_trees, page_scale_layer, | 1008 UpdatePageScaleFactorInternal(property_trees, page_scale_layer, |
991 page_scale_factor, device_scale_factor, | 1009 page_scale_factor, device_scale_factor, |
992 device_transform); | 1010 device_transform); |
993 } | 1011 } |
994 | 1012 |
995 void UpdatePageScaleFactor(PropertyTrees* property_trees, | 1013 void UpdatePageScaleFactor(PropertyTrees* property_trees, |
996 const Layer* page_scale_layer, | 1014 const Layer* page_scale_layer, |
997 float page_scale_factor, | 1015 float page_scale_factor, |
998 float device_scale_factor, | 1016 float device_scale_factor, |
999 const gfx::Transform device_transform) { | 1017 const gfx::Transform device_transform) { |
1000 UpdatePageScaleFactorInternal(property_trees, page_scale_layer, | 1018 UpdatePageScaleFactorInternal(property_trees, page_scale_layer, |
1001 page_scale_factor, device_scale_factor, | 1019 page_scale_factor, device_scale_factor, |
1002 device_transform); | 1020 device_transform); |
1003 } | 1021 } |
1004 | 1022 |
1005 template <typename LayerType> | |
1006 static void UpdateElasticOverscrollInternal( | |
1007 PropertyTrees* property_trees, | |
1008 const LayerType* overscroll_elasticity_layer, | |
1009 const gfx::Vector2dF& elastic_overscroll) { | |
1010 if (!overscroll_elasticity_layer) { | |
1011 DCHECK(elastic_overscroll.IsZero()); | |
1012 return; | |
1013 } | |
1014 | |
1015 TransformNode* node = property_trees->transform_tree.Node( | |
1016 overscroll_elasticity_layer->transform_tree_index()); | |
1017 if (node->scroll_offset == gfx::ScrollOffset(elastic_overscroll)) | |
1018 return; | |
1019 | |
1020 node->scroll_offset = gfx::ScrollOffset(elastic_overscroll); | |
1021 node->needs_local_transform_update = true; | |
1022 property_trees->transform_tree.set_needs_update(true); | |
1023 } | |
1024 | |
1025 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1023 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
1026 const LayerImpl* overscroll_elasticity_layer, | 1024 const LayerImpl* overscroll_elasticity_layer, |
1027 const gfx::Vector2dF& elastic_overscroll) { | 1025 const gfx::Vector2dF& elastic_overscroll) { |
1028 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1026 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
1029 elastic_overscroll); | 1027 elastic_overscroll); |
1030 } | 1028 } |
1031 | 1029 |
1032 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1030 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
1033 const Layer* overscroll_elasticity_layer, | 1031 const Layer* overscroll_elasticity_layer, |
1034 const gfx::Vector2dF& elastic_overscroll) { | 1032 const gfx::Vector2dF& elastic_overscroll) { |
1035 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1033 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
1036 elastic_overscroll); | 1034 elastic_overscroll); |
1037 } | 1035 } |
1038 | 1036 |
1039 } // namespace draw_property_utils | 1037 } // namespace draw_property_utils |
1040 | 1038 |
1041 } // namespace cc | 1039 } // namespace cc |
OLD | NEW |