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/surfaces/surface_aggregator.h" | 5 #include "cc/surfaces/surface_aggregator.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 aggregate_only_damaged_(aggregate_only_damaged) { | 52 aggregate_only_damaged_(aggregate_only_damaged) { |
53 DCHECK(manager_); | 53 DCHECK(manager_); |
54 } | 54 } |
55 | 55 |
56 SurfaceAggregator::~SurfaceAggregator() { | 56 SurfaceAggregator::~SurfaceAggregator() { |
57 // Notify client of all surfaces being removed. | 57 // Notify client of all surfaces being removed. |
58 contained_surfaces_.clear(); | 58 contained_surfaces_.clear(); |
59 ProcessAddedAndRemovedSurfaces(); | 59 ProcessAddedAndRemovedSurfaces(); |
60 } | 60 } |
61 | 61 |
62 SurfaceAggregator::PrewalkResult::PrewalkResult() : has_copy_requests(false) {} | |
63 | |
64 SurfaceAggregator::PrewalkResult::~PrewalkResult() {} | |
65 | |
62 // Create a clip rect for an aggregated quad from the original clip rect and | 66 // Create a clip rect for an aggregated quad from the original clip rect and |
63 // the clip rect from the surface it's on. | 67 // the clip rect from the surface it's on. |
64 SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect( | 68 SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect( |
65 const ClipData& surface_clip, | 69 const ClipData& surface_clip, |
66 const ClipData& quad_clip, | 70 const ClipData& quad_clip, |
67 const gfx::Transform& target_transform) { | 71 const gfx::Transform& target_transform) { |
68 ClipData out_clip; | 72 ClipData out_clip; |
69 if (surface_clip.is_clipped) | 73 if (surface_clip.is_clipped) |
70 out_clip = surface_clip; | 74 out_clip = surface_clip; |
71 | 75 |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
487 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); | 491 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); |
488 if (surface_ptr) | 492 if (surface_ptr) |
489 client_->AddSurface(surface_ptr); | 493 client_->AddSurface(surface_ptr); |
490 } | 494 } |
491 } | 495 } |
492 } | 496 } |
493 | 497 |
494 // Walk the Surface tree from surface_id. Validate the resources of the current | 498 // Walk the Surface tree from surface_id. Validate the resources of the current |
495 // surface and its descendants, check if there are any copy requests, and | 499 // surface and its descendants, check if there are any copy requests, and |
496 // return the combined damage rect. | 500 // return the combined damage rect. |
497 gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id) { | 501 gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, |
502 PrewalkResult* result) { | |
498 if (referenced_surfaces_.count(surface_id)) | 503 if (referenced_surfaces_.count(surface_id)) |
499 return gfx::Rect(); | 504 return gfx::Rect(); |
500 Surface* surface = manager_->GetSurfaceForId(surface_id); | 505 Surface* surface = manager_->GetSurfaceForId(surface_id); |
501 if (!surface) { | 506 if (!surface) { |
502 contained_surfaces_[surface_id] = 0; | 507 contained_surfaces_[surface_id] = 0; |
503 return gfx::Rect(); | 508 return gfx::Rect(); |
504 } | 509 } |
505 contained_surfaces_[surface_id] = surface->frame_index(); | 510 contained_surfaces_[surface_id] = surface->frame_index(); |
506 const CompositorFrame* surface_frame = surface->GetEligibleFrame(); | 511 const CompositorFrame* surface_frame = surface->GetEligibleFrame(); |
507 if (!surface_frame) | 512 if (!surface_frame) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 } | 570 } |
566 | 571 |
567 if (invalid_frame) | 572 if (invalid_frame) |
568 return gfx::Rect(); | 573 return gfx::Rect(); |
569 valid_surfaces_.insert(surface->surface_id()); | 574 valid_surfaces_.insert(surface->surface_id()); |
570 | 575 |
571 if (provider_) | 576 if (provider_) |
572 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); | 577 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); |
573 | 578 |
574 for (const auto& render_pass : frame_data->render_pass_list) | 579 for (const auto& render_pass : frame_data->render_pass_list) |
575 has_copy_requests_ |= !render_pass->copy_requests.empty(); | 580 result->has_copy_requests |= !render_pass->copy_requests.empty(); |
576 | 581 |
577 gfx::Rect damage_rect; | 582 gfx::Rect damage_rect; |
578 if (!frame_data->render_pass_list.empty()) { | 583 if (!frame_data->render_pass_list.empty()) { |
579 RenderPass* last_pass = frame_data->render_pass_list.back(); | 584 RenderPass* last_pass = frame_data->render_pass_list.back(); |
580 damage_rect = | 585 damage_rect = |
581 DamageRectForSurface(surface, *last_pass, last_pass->output_rect); | 586 DamageRectForSurface(surface, *last_pass, last_pass->output_rect); |
582 } | 587 } |
583 | 588 |
584 // Avoid infinite recursion by adding current surface to | 589 // Avoid infinite recursion by adding current surface to |
585 // referenced_surfaces_. | 590 // referenced_surfaces_. |
586 SurfaceSet::iterator it = | 591 SurfaceSet::iterator it = |
587 referenced_surfaces_.insert(surface->surface_id()).first; | 592 referenced_surfaces_.insert(surface->surface_id()).first; |
588 for (const auto& surface_info : child_surfaces) { | 593 for (const auto& surface_info : child_surfaces) { |
589 gfx::Rect surface_damage = PrewalkTree(surface_info.first); | 594 gfx::Rect surface_damage = PrewalkTree(surface_info.first, result); |
590 damage_rect.Union( | 595 damage_rect.Union( |
591 MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage)); | 596 MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage)); |
592 } | 597 } |
598 | |
599 for (const SurfaceId surface_id : | |
danakj
2015/11/16 21:45:46
did you mean const&?
or maybe just auto&?
| |
600 surface_frame->metadata.referenced_surfaces) { | |
601 if (!contained_surfaces_.count(surface_id)) { | |
602 result->undrawn_surfaces.insert(surface_id); | |
603 PrewalkTree(surface_id, result); | |
604 } | |
605 } | |
606 | |
593 referenced_surfaces_.erase(it); | 607 referenced_surfaces_.erase(it); |
594 return damage_rect; | 608 return damage_rect; |
595 } | 609 } |
596 | 610 |
611 void SurfaceAggregator::CopyUnreferencedSurfaces( | |
danakj
2015/11/16 21:45:45
CopyUndrawnSurfaces?
| |
612 PrewalkResult* prewalk_result) { | |
613 std::vector<SurfaceId> surfaces_to_copy( | |
danakj
2015/11/16 21:45:45
Can you leave a comment here to the effect of how
| |
614 prewalk_result->undrawn_surfaces.begin(), | |
615 prewalk_result->undrawn_surfaces.end()); | |
616 | |
617 for (size_t i = 0; i < surfaces_to_copy.size(); i++) { | |
618 SurfaceId surface_id = surfaces_to_copy[i]; | |
619 Surface* surface = manager_->GetSurfaceForId(surface_id); | |
620 const CompositorFrame* surface_frame = surface->GetEligibleFrame(); | |
621 if (!surface_frame) | |
622 continue; | |
623 bool has_copy_requests = false; | |
danakj
2015/11/16 21:45:45
can you name this somehow differently to not almos
| |
624 for (const auto& render_pass : | |
625 surface_frame->delegated_frame_data->render_pass_list) { | |
626 has_copy_requests |= !render_pass->copy_requests.empty(); | |
627 } | |
628 if (!has_copy_requests) { | |
629 // Children may have copy requests, so make sure to check them as well. | |
630 for (const SurfaceId child_id : | |
danakj
2015/11/16 21:45:45
ditto?
| |
631 surface_frame->metadata.referenced_surfaces) { | |
632 if (!prewalk_result->undrawn_surfaces.count(child_id)) { | |
danakj
2015/11/16 21:45:45
Why this if? How could a child of an undrawn surfa
| |
633 surfaces_to_copy.push_back(child_id); | |
634 prewalk_result->undrawn_surfaces.insert(child_id); | |
635 } | |
636 } | |
637 } else { | |
638 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | |
639 CopyPasses(surface_frame->delegated_frame_data.get(), surface); | |
640 referenced_surfaces_.erase(it); | |
641 } | |
642 } | |
643 } | |
644 | |
597 scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { | 645 scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { |
598 Surface* surface = manager_->GetSurfaceForId(surface_id); | 646 Surface* surface = manager_->GetSurfaceForId(surface_id); |
599 DCHECK(surface); | 647 DCHECK(surface); |
600 contained_surfaces_[surface_id] = surface->frame_index(); | 648 contained_surfaces_[surface_id] = surface->frame_index(); |
601 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); | 649 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); |
602 if (!root_surface_frame) | 650 if (!root_surface_frame) |
603 return nullptr; | 651 return nullptr; |
604 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); | 652 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); |
605 | 653 |
606 scoped_ptr<CompositorFrame> frame(new CompositorFrame); | 654 scoped_ptr<CompositorFrame> frame(new CompositorFrame); |
607 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); | 655 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); |
608 | 656 |
609 DCHECK(root_surface_frame->delegated_frame_data); | 657 DCHECK(root_surface_frame->delegated_frame_data); |
610 | 658 |
611 dest_resource_list_ = &frame->delegated_frame_data->resource_list; | 659 dest_resource_list_ = &frame->delegated_frame_data->resource_list; |
612 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; | 660 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; |
613 | 661 |
614 valid_surfaces_.clear(); | 662 valid_surfaces_.clear(); |
615 has_copy_requests_ = false; | 663 PrewalkResult prewalk_result; |
616 root_damage_rect_ = PrewalkTree(surface_id); | 664 root_damage_rect_ = PrewalkTree(surface_id, &prewalk_result); |
665 has_copy_requests_ = prewalk_result.has_copy_requests; | |
617 | 666 |
667 CopyUnreferencedSurfaces(&prewalk_result); | |
618 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 668 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
619 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); | 669 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); |
620 referenced_surfaces_.erase(it); | 670 referenced_surfaces_.erase(it); |
621 | 671 |
622 DCHECK(referenced_surfaces_.empty()); | 672 DCHECK(referenced_surfaces_.empty()); |
623 | 673 |
624 if (dest_pass_list_->empty()) | 674 if (dest_pass_list_->empty()) |
625 return nullptr; | 675 return nullptr; |
626 dest_pass_list_->back()->damage_rect = root_damage_rect_; | 676 dest_pass_list_->back()->damage_rect = root_damage_rect_; |
627 | 677 |
(...skipping 27 matching lines...) Expand all Loading... | |
655 | 705 |
656 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { | 706 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { |
657 auto it = previous_contained_surfaces_.find(surface_id); | 707 auto it = previous_contained_surfaces_.find(surface_id); |
658 if (it == previous_contained_surfaces_.end()) | 708 if (it == previous_contained_surfaces_.end()) |
659 return; | 709 return; |
660 // Set the last drawn index as 0 to ensure full damage next time it's drawn. | 710 // Set the last drawn index as 0 to ensure full damage next time it's drawn. |
661 it->second = 0; | 711 it->second = 0; |
662 } | 712 } |
663 | 713 |
664 } // namespace cc | 714 } // namespace cc |
OLD | NEW |