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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 | 10 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 const ClipData& clip_rect, | 181 const ClipData& clip_rect, |
182 RenderPass* dest_pass) { | 182 RenderPass* dest_pass) { |
183 SurfaceId surface_id = surface_quad->surface_id; | 183 SurfaceId surface_id = surface_quad->surface_id; |
184 // If this surface's id is already in our referenced set then it creates | 184 // If this surface's id is already in our referenced set then it creates |
185 // a cycle in the graph and should be dropped. | 185 // a cycle in the graph and should be dropped. |
186 if (referenced_surfaces_.count(surface_id)) | 186 if (referenced_surfaces_.count(surface_id)) |
187 return; | 187 return; |
188 Surface* surface = manager_->GetSurfaceForId(surface_id); | 188 Surface* surface = manager_->GetSurfaceForId(surface_id); |
189 if (!surface) | 189 if (!surface) |
190 return; | 190 return; |
191 const CompositorFrame& frame = surface->GetEligibleFrame(); | 191 const CompositorFrame* frame = surface->GetEligibleFrame(); |
192 const DelegatedFrameData* frame_data = frame.delegated_frame_data.get(); | 192 if (!frame) |
| 193 return; |
| 194 const DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); |
193 if (!frame_data) | 195 if (!frame_data) |
194 return; | 196 return; |
195 | 197 |
196 std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>> copy_requests; | 198 std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>> copy_requests; |
197 surface->TakeCopyOutputRequests(©_requests); | 199 surface->TakeCopyOutputRequests(©_requests); |
198 | 200 |
199 const RenderPassList& render_pass_list = frame_data->render_pass_list; | 201 const RenderPassList& render_pass_list = frame_data->render_pass_list; |
200 if (!valid_surfaces_.count(surface->surface_id())) { | 202 if (!valid_surfaces_.count(surface->surface_id())) { |
201 for (auto& request : copy_requests) | 203 for (auto& request : copy_requests) |
202 request.second->SendEmptyResult(); | 204 request.second->SendEmptyResult(); |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 base::WeakPtr<SurfaceAggregator> debug_weak_this = weak_factory_.GetWeakPtr(); | 556 base::WeakPtr<SurfaceAggregator> debug_weak_this = weak_factory_.GetWeakPtr(); |
555 | 557 |
556 if (referenced_surfaces_.count(surface_id)) | 558 if (referenced_surfaces_.count(surface_id)) |
557 return gfx::Rect(); | 559 return gfx::Rect(); |
558 Surface* surface = manager_->GetSurfaceForId(surface_id); | 560 Surface* surface = manager_->GetSurfaceForId(surface_id); |
559 if (!surface) { | 561 if (!surface) { |
560 contained_surfaces_[surface_id] = 0; | 562 contained_surfaces_[surface_id] = 0; |
561 return gfx::Rect(); | 563 return gfx::Rect(); |
562 } | 564 } |
563 contained_surfaces_[surface_id] = surface->frame_index(); | 565 contained_surfaces_[surface_id] = surface->frame_index(); |
564 const CompositorFrame& surface_frame = surface->GetEligibleFrame(); | 566 const CompositorFrame* surface_frame = surface->GetEligibleFrame(); |
| 567 if (!surface_frame) |
| 568 return gfx::Rect(); |
565 const DelegatedFrameData* frame_data = | 569 const DelegatedFrameData* frame_data = |
566 surface_frame.delegated_frame_data.get(); | 570 surface_frame->delegated_frame_data.get(); |
567 if (!frame_data) | 571 if (!frame_data) |
568 return gfx::Rect(); | 572 return gfx::Rect(); |
569 int child_id = 0; | 573 int child_id = 0; |
570 // TODO(jbauman): hack for unit tests that don't set up rp | 574 // TODO(jbauman): hack for unit tests that don't set up rp |
571 if (provider_) { | 575 if (provider_) { |
572 child_id = ChildIdForSurface(surface); | 576 child_id = ChildIdForSurface(surface); |
573 if (surface->factory()) | 577 if (surface->factory()) |
574 surface->factory()->RefResources(frame_data->resource_list); | 578 surface->factory()->RefResources(frame_data->resource_list); |
575 provider_->ReceiveFromChild(child_id, frame_data->resource_list); | 579 provider_->ReceiveFromChild(child_id, frame_data->resource_list); |
576 } | 580 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 // modified if there is a filter that moves pixels. | 680 // modified if there is a filter that moves pixels. |
677 damage_rect = full_damage; | 681 damage_rect = full_damage; |
678 continue; | 682 continue; |
679 } | 683 } |
680 | 684 |
681 damage_rect.Union(MathUtil::MapEnclosingClippedRect( | 685 damage_rect.Union(MathUtil::MapEnclosingClippedRect( |
682 surface_info.target_to_surface_transform, surface_damage)); | 686 surface_info.target_to_surface_transform, surface_damage)); |
683 } | 687 } |
684 | 688 |
685 CHECK(debug_weak_this.get()); | 689 CHECK(debug_weak_this.get()); |
686 for (const auto& surface_id : surface_frame.metadata.referenced_surfaces) { | 690 for (const auto& surface_id : surface_frame->metadata.referenced_surfaces) { |
687 if (!contained_surfaces_.count(surface_id)) { | 691 if (!contained_surfaces_.count(surface_id)) { |
688 result->undrawn_surfaces.insert(surface_id); | 692 result->undrawn_surfaces.insert(surface_id); |
689 PrewalkTree(surface_id, false, RenderPassId(), result); | 693 PrewalkTree(surface_id, false, RenderPassId(), result); |
690 } | 694 } |
691 } | 695 } |
692 | 696 |
693 CHECK(debug_weak_this.get()); | 697 CHECK(debug_weak_this.get()); |
694 if (surface->factory()) | 698 if (surface->factory()) |
695 surface->factory()->WillDrawSurface(surface->surface_id(), damage_rect); | 699 surface->factory()->WillDrawSurface(surface->surface_id(), damage_rect); |
696 | 700 |
(...skipping 16 matching lines...) Expand all Loading... |
713 // (or on Surfaces they reference) are executed. | 717 // (or on Surfaces they reference) are executed. |
714 std::vector<SurfaceId> surfaces_to_copy( | 718 std::vector<SurfaceId> surfaces_to_copy( |
715 prewalk_result->undrawn_surfaces.begin(), | 719 prewalk_result->undrawn_surfaces.begin(), |
716 prewalk_result->undrawn_surfaces.end()); | 720 prewalk_result->undrawn_surfaces.end()); |
717 | 721 |
718 for (size_t i = 0; i < surfaces_to_copy.size(); i++) { | 722 for (size_t i = 0; i < surfaces_to_copy.size(); i++) { |
719 SurfaceId surface_id = surfaces_to_copy[i]; | 723 SurfaceId surface_id = surfaces_to_copy[i]; |
720 Surface* surface = manager_->GetSurfaceForId(surface_id); | 724 Surface* surface = manager_->GetSurfaceForId(surface_id); |
721 if (!surface) | 725 if (!surface) |
722 continue; | 726 continue; |
723 const CompositorFrame& surface_frame = surface->GetEligibleFrame(); | 727 const CompositorFrame* surface_frame = surface->GetEligibleFrame(); |
724 if (!surface_frame.delegated_frame_data) | 728 if (!surface_frame) |
725 continue; | 729 continue; |
726 bool surface_has_copy_requests = false; | 730 bool surface_has_copy_requests = false; |
727 for (const auto& render_pass : | 731 for (const auto& render_pass : |
728 surface_frame.delegated_frame_data->render_pass_list) { | 732 surface_frame->delegated_frame_data->render_pass_list) { |
729 surface_has_copy_requests |= !render_pass->copy_requests.empty(); | 733 surface_has_copy_requests |= !render_pass->copy_requests.empty(); |
730 } | 734 } |
731 if (!surface_has_copy_requests) { | 735 if (!surface_has_copy_requests) { |
732 // Children are not necessarily included in undrawn_surfaces (because | 736 // Children are not necessarily included in undrawn_surfaces (because |
733 // they weren't referenced directly from a drawn surface), but may have | 737 // they weren't referenced directly from a drawn surface), but may have |
734 // copy requests, so make sure to check them as well. | 738 // copy requests, so make sure to check them as well. |
735 for (const auto& child_id : surface_frame.metadata.referenced_surfaces) { | 739 for (const auto& child_id : surface_frame->metadata.referenced_surfaces) { |
736 // Don't iterate over the child Surface if it was already listed as a | 740 // Don't iterate over the child Surface if it was already listed as a |
737 // child of a different Surface, or in the case where there's infinite | 741 // child of a different Surface, or in the case where there's infinite |
738 // recursion. | 742 // recursion. |
739 if (!prewalk_result->undrawn_surfaces.count(child_id)) { | 743 if (!prewalk_result->undrawn_surfaces.count(child_id)) { |
740 surfaces_to_copy.push_back(child_id); | 744 surfaces_to_copy.push_back(child_id); |
741 prewalk_result->undrawn_surfaces.insert(child_id); | 745 prewalk_result->undrawn_surfaces.insert(child_id); |
742 } | 746 } |
743 } | 747 } |
744 } else { | 748 } else { |
745 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 749 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
746 CopyPasses(surface_frame.delegated_frame_data.get(), surface); | 750 CopyPasses(surface_frame->delegated_frame_data.get(), surface); |
747 referenced_surfaces_.erase(it); | 751 referenced_surfaces_.erase(it); |
748 } | 752 } |
749 } | 753 } |
750 } | 754 } |
751 | 755 |
752 void SurfaceAggregator::PropagateCopyRequestPasses() { | 756 void SurfaceAggregator::PropagateCopyRequestPasses() { |
753 std::vector<RenderPassId> copy_requests_to_iterate( | 757 std::vector<RenderPassId> copy_requests_to_iterate( |
754 copy_request_passes_.begin(), copy_request_passes_.end()); | 758 copy_request_passes_.begin(), copy_request_passes_.end()); |
755 while (!copy_requests_to_iterate.empty()) { | 759 while (!copy_requests_to_iterate.empty()) { |
756 RenderPassId first = copy_requests_to_iterate.back(); | 760 RenderPassId first = copy_requests_to_iterate.back(); |
757 copy_requests_to_iterate.pop_back(); | 761 copy_requests_to_iterate.pop_back(); |
758 auto it = render_pass_dependencies_.find(first); | 762 auto it = render_pass_dependencies_.find(first); |
759 if (it == render_pass_dependencies_.end()) | 763 if (it == render_pass_dependencies_.end()) |
760 continue; | 764 continue; |
761 for (auto pass : it->second) { | 765 for (auto pass : it->second) { |
762 if (copy_request_passes_.insert(pass).second) { | 766 if (copy_request_passes_.insert(pass).second) { |
763 copy_requests_to_iterate.push_back(pass); | 767 copy_requests_to_iterate.push_back(pass); |
764 } | 768 } |
765 } | 769 } |
766 } | 770 } |
767 } | 771 } |
768 | 772 |
769 CompositorFrame SurfaceAggregator::Aggregate(SurfaceId surface_id) { | 773 std::unique_ptr<CompositorFrame> SurfaceAggregator::Aggregate( |
| 774 SurfaceId surface_id) { |
770 Surface* surface = manager_->GetSurfaceForId(surface_id); | 775 Surface* surface = manager_->GetSurfaceForId(surface_id); |
771 DCHECK(surface); | 776 DCHECK(surface); |
772 contained_surfaces_[surface_id] = surface->frame_index(); | 777 contained_surfaces_[surface_id] = surface->frame_index(); |
773 const CompositorFrame& root_surface_frame = surface->GetEligibleFrame(); | 778 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); |
774 if (!root_surface_frame.delegated_frame_data) | 779 if (!root_surface_frame) |
775 return CompositorFrame(); | 780 return nullptr; |
776 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); | 781 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); |
777 | 782 |
778 CompositorFrame frame; | 783 std::unique_ptr<CompositorFrame> frame(new CompositorFrame); |
779 frame.delegated_frame_data = base::WrapUnique(new DelegatedFrameData); | 784 frame->delegated_frame_data = base::WrapUnique(new DelegatedFrameData); |
780 | 785 |
781 dest_resource_list_ = &frame.delegated_frame_data->resource_list; | 786 DCHECK(root_surface_frame->delegated_frame_data); |
782 dest_pass_list_ = &frame.delegated_frame_data->render_pass_list; | 787 |
| 788 dest_resource_list_ = &frame->delegated_frame_data->resource_list; |
| 789 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; |
783 | 790 |
784 valid_surfaces_.clear(); | 791 valid_surfaces_.clear(); |
785 PrewalkResult prewalk_result; | 792 PrewalkResult prewalk_result; |
786 root_damage_rect_ = | 793 root_damage_rect_ = |
787 PrewalkTree(surface_id, false, RenderPassId(), &prewalk_result); | 794 PrewalkTree(surface_id, false, RenderPassId(), &prewalk_result); |
788 PropagateCopyRequestPasses(); | 795 PropagateCopyRequestPasses(); |
789 has_copy_requests_ = !copy_request_passes_.empty(); | 796 has_copy_requests_ = !copy_request_passes_.empty(); |
790 | 797 |
791 CopyUndrawnSurfaces(&prewalk_result); | 798 CopyUndrawnSurfaces(&prewalk_result); |
792 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 799 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
793 CopyPasses(root_surface_frame.delegated_frame_data.get(), surface); | 800 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); |
794 referenced_surfaces_.erase(it); | 801 referenced_surfaces_.erase(it); |
795 | 802 |
796 moved_pixel_passes_.clear(); | 803 moved_pixel_passes_.clear(); |
797 copy_request_passes_.clear(); | 804 copy_request_passes_.clear(); |
798 render_pass_dependencies_.clear(); | 805 render_pass_dependencies_.clear(); |
799 | 806 |
800 DCHECK(referenced_surfaces_.empty()); | 807 DCHECK(referenced_surfaces_.empty()); |
801 | 808 |
802 if (dest_pass_list_->empty()) | 809 if (dest_pass_list_->empty()) |
803 return CompositorFrame(); | 810 return nullptr; |
804 | 811 |
805 dest_pass_list_ = NULL; | 812 dest_pass_list_ = NULL; |
806 ProcessAddedAndRemovedSurfaces(); | 813 ProcessAddedAndRemovedSurfaces(); |
807 contained_surfaces_.swap(previous_contained_surfaces_); | 814 contained_surfaces_.swap(previous_contained_surfaces_); |
808 contained_surfaces_.clear(); | 815 contained_surfaces_.clear(); |
809 | 816 |
810 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); | 817 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); |
811 it != previous_contained_surfaces_.end(); | 818 it != previous_contained_surfaces_.end(); |
812 ++it) { | 819 ++it) { |
813 Surface* surface = manager_->GetSurfaceForId(it->first); | 820 Surface* surface = manager_->GetSurfaceForId(it->first); |
814 if (surface) | 821 if (surface) |
815 surface->TakeLatencyInfo(&frame.metadata.latency_info); | 822 surface->TakeLatencyInfo(&frame->metadata.latency_info); |
816 } | 823 } |
817 | 824 |
818 // TODO(jamesr): Aggregate all resource references into the returned frame's | 825 // TODO(jamesr): Aggregate all resource references into the returned frame's |
819 // resource list. | 826 // resource list. |
820 | 827 |
821 return frame; | 828 return frame; |
822 } | 829 } |
823 | 830 |
824 void SurfaceAggregator::ReleaseResources(SurfaceId surface_id) { | 831 void SurfaceAggregator::ReleaseResources(SurfaceId surface_id) { |
825 SurfaceToResourceChildIdMap::iterator it = | 832 SurfaceToResourceChildIdMap::iterator it = |
826 surface_id_to_resource_child_id_.find(surface_id); | 833 surface_id_to_resource_child_id_.find(surface_id); |
827 if (it != surface_id_to_resource_child_id_.end()) { | 834 if (it != surface_id_to_resource_child_id_.end()) { |
828 provider_->DestroyChild(it->second); | 835 provider_->DestroyChild(it->second); |
829 surface_id_to_resource_child_id_.erase(it); | 836 surface_id_to_resource_child_id_.erase(it); |
830 } | 837 } |
831 } | 838 } |
832 | 839 |
833 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { | 840 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { |
834 auto it = previous_contained_surfaces_.find(surface_id); | 841 auto it = previous_contained_surfaces_.find(surface_id); |
835 if (it == previous_contained_surfaces_.end()) | 842 if (it == previous_contained_surfaces_.end()) |
836 return; | 843 return; |
837 // Set the last drawn index as 0 to ensure full damage next time it's drawn. | 844 // Set the last drawn index as 0 to ensure full damage next time it's drawn. |
838 it->second = 0; | 845 it->second = 0; |
839 } | 846 } |
840 | 847 |
841 } // namespace cc | 848 } // namespace cc |
OLD | NEW |