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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 return it->second.id; | 137 return it->second.id; |
138 } | 138 } |
139 | 139 |
140 RenderPassInfo render_pass_info; | 140 RenderPassInfo render_pass_info; |
141 render_pass_info.id = next_render_pass_id_++; | 141 render_pass_info.id = next_render_pass_id_++; |
142 render_pass_allocator_map_[key] = render_pass_info; | 142 render_pass_allocator_map_[key] = render_pass_info; |
143 return render_pass_info.id; | 143 return render_pass_info.id; |
144 } | 144 } |
145 | 145 |
146 int SurfaceAggregator::ChildIdForSurface(Surface* surface) { | 146 int SurfaceAggregator::ChildIdForSurface(Surface* surface) { |
147 auto it = surface_id_to_resource_child_id_.find(surface->surface_id()); | 147 SurfaceToResourceChildIdMap::iterator it = |
| 148 surface_id_to_resource_child_id_.find(surface->surface_id()); |
148 if (it == surface_id_to_resource_child_id_.end()) { | 149 if (it == surface_id_to_resource_child_id_.end()) { |
149 int child_id = | 150 int child_id = |
150 provider_->CreateChild(base::Bind(&UnrefHelper, surface->factory())); | 151 provider_->CreateChild(base::Bind(&UnrefHelper, surface->factory())); |
151 if (surface->factory()) { | 152 if (surface->factory()) { |
152 provider_->SetChildNeedsSyncTokens( | 153 provider_->SetChildNeedsSyncTokens( |
153 child_id, surface->factory()->needs_sync_points()); | 154 child_id, surface->factory()->needs_sync_points()); |
154 } | 155 } |
155 surface_id_to_resource_child_id_[surface->surface_id()] = child_id; | 156 surface_id_to_resource_child_id_[surface->surface_id()] = child_id; |
156 return child_id; | 157 return child_id; |
157 } else { | 158 } else { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 std::multimap<int, std::unique_ptr<CopyOutputRequest>> copy_requests; | 232 std::multimap<int, std::unique_ptr<CopyOutputRequest>> copy_requests; |
232 surface->TakeCopyOutputRequests(©_requests); | 233 surface->TakeCopyOutputRequests(©_requests); |
233 | 234 |
234 const RenderPassList& render_pass_list = frame.render_pass_list; | 235 const RenderPassList& render_pass_list = frame.render_pass_list; |
235 if (!valid_surfaces_.count(surface->surface_id())) { | 236 if (!valid_surfaces_.count(surface->surface_id())) { |
236 for (auto& request : copy_requests) | 237 for (auto& request : copy_requests) |
237 request.second->SendEmptyResult(); | 238 request.second->SendEmptyResult(); |
238 return; | 239 return; |
239 } | 240 } |
240 | 241 |
241 auto it = referenced_surfaces_.insert(surface_id).first; | 242 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
242 // TODO(vmpstr): provider check is a hack for unittests that don't set up a | 243 // TODO(vmpstr): provider check is a hack for unittests that don't set up a |
243 // resource provider. | 244 // resource provider. |
244 ResourceProvider::ResourceIdMap empty_map; | 245 ResourceProvider::ResourceIdMap empty_map; |
245 const ResourceProvider::ResourceIdMap& child_to_parent_map = | 246 const ResourceProvider::ResourceIdMap& child_to_parent_map = |
246 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) | 247 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) |
247 : empty_map; | 248 : empty_map; |
248 bool merge_pass = | 249 bool merge_pass = |
249 surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty(); | 250 surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty(); |
250 | 251 |
251 const RenderPassList& referenced_passes = render_pass_list; | 252 const RenderPassList& referenced_passes = render_pass_list; |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 } | 561 } |
561 | 562 |
562 dest_pass_list_->push_back(std::move(copy_pass)); | 563 dest_pass_list_->push_back(std::move(copy_pass)); |
563 } | 564 } |
564 } | 565 } |
565 | 566 |
566 void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { | 567 void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { |
567 for (const auto& surface : previous_contained_surfaces_) { | 568 for (const auto& surface : previous_contained_surfaces_) { |
568 if (!contained_surfaces_.count(surface.first)) { | 569 if (!contained_surfaces_.count(surface.first)) { |
569 // Release resources of removed surface. | 570 // Release resources of removed surface. |
570 auto it = surface_id_to_resource_child_id_.find(surface.first); | 571 SurfaceToResourceChildIdMap::iterator it = |
| 572 surface_id_to_resource_child_id_.find(surface.first); |
571 if (it != surface_id_to_resource_child_id_.end()) { | 573 if (it != surface_id_to_resource_child_id_.end()) { |
572 provider_->DestroyChild(it->second); | 574 provider_->DestroyChild(it->second); |
573 surface_id_to_resource_child_id_.erase(it); | 575 surface_id_to_resource_child_id_.erase(it); |
574 } | 576 } |
575 | 577 |
576 // Notify client of removed surface. | 578 // Notify client of removed surface. |
577 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); | 579 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); |
578 if (surface_ptr) { | 580 if (surface_ptr) { |
579 surface_ptr->RunDrawCallbacks(); | 581 surface_ptr->RunDrawCallbacks(); |
580 } | 582 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 parent_pass_id(parent_pass_id), | 646 parent_pass_id(parent_pass_id), |
645 target_to_surface_transform(target_to_surface_transform) {} | 647 target_to_surface_transform(target_to_surface_transform) {} |
646 | 648 |
647 SurfaceId id; | 649 SurfaceId id; |
648 bool has_moved_pixels; | 650 bool has_moved_pixels; |
649 int parent_pass_id; | 651 int parent_pass_id; |
650 gfx::Transform target_to_surface_transform; | 652 gfx::Transform target_to_surface_transform; |
651 }; | 653 }; |
652 std::vector<SurfaceInfo> child_surfaces; | 654 std::vector<SurfaceInfo> child_surfaces; |
653 | 655 |
654 // This data is created once and typically small or empty. Collect all items | 656 std::unordered_set<int> pixel_moving_background_filter_passes; |
655 // and pass to a flat_vector to sort once. | |
656 std::vector<int> pixel_moving_background_filter_passes_data; | |
657 for (const auto& render_pass : frame.render_pass_list) { | 657 for (const auto& render_pass : frame.render_pass_list) { |
658 if (render_pass->background_filters.HasFilterThatMovesPixels()) { | 658 if (render_pass->background_filters.HasFilterThatMovesPixels()) { |
659 pixel_moving_background_filter_passes_data.push_back( | 659 pixel_moving_background_filter_passes.insert( |
660 RemapPassId(render_pass->id, surface_id)); | 660 RemapPassId(render_pass->id, surface_id)); |
661 } | 661 } |
662 } | 662 } |
663 base::flat_set<int> pixel_moving_background_filter_passes( | |
664 std::move(pixel_moving_background_filter_passes_data), | |
665 base::KEEP_FIRST_OF_DUPES); | |
666 | 663 |
667 for (const auto& render_pass : base::Reversed(frame.render_pass_list)) { | 664 for (const auto& render_pass : base::Reversed(frame.render_pass_list)) { |
668 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); | 665 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); |
669 bool has_pixel_moving_filter = | 666 bool has_pixel_moving_filter = |
670 render_pass->filters.HasFilterThatMovesPixels(); | 667 render_pass->filters.HasFilterThatMovesPixels(); |
671 if (has_pixel_moving_filter) | 668 if (has_pixel_moving_filter) |
672 moved_pixel_passes_.insert(remapped_pass_id); | 669 moved_pixel_passes_.insert(remapped_pass_id); |
673 bool in_moved_pixel_pass = has_pixel_moving_filter || | 670 bool in_moved_pixel_pass = has_pixel_moving_filter || |
674 !!moved_pixel_passes_.count(remapped_pass_id); | 671 !!moved_pixel_passes_.count(remapped_pass_id); |
675 for (auto* quad : render_pass->quad_list) { | 672 for (auto* quad : render_pass->quad_list) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 gfx::Rect full_damage; | 719 gfx::Rect full_damage; |
723 if (!frame.render_pass_list.empty()) { | 720 if (!frame.render_pass_list.empty()) { |
724 RenderPass* last_pass = frame.render_pass_list.back().get(); | 721 RenderPass* last_pass = frame.render_pass_list.back().get(); |
725 full_damage = last_pass->output_rect; | 722 full_damage = last_pass->output_rect; |
726 damage_rect = | 723 damage_rect = |
727 DamageRectForSurface(surface, *last_pass, last_pass->output_rect); | 724 DamageRectForSurface(surface, *last_pass, last_pass->output_rect); |
728 } | 725 } |
729 | 726 |
730 // Avoid infinite recursion by adding current surface to | 727 // Avoid infinite recursion by adding current surface to |
731 // referenced_surfaces_. | 728 // referenced_surfaces_. |
732 referenced_surfaces_.insert(surface->surface_id()); | 729 SurfaceSet::iterator it = |
| 730 referenced_surfaces_.insert(surface->surface_id()).first; |
733 for (const auto& surface_info : child_surfaces) { | 731 for (const auto& surface_info : child_surfaces) { |
734 gfx::Rect surface_damage = | 732 gfx::Rect surface_damage = |
735 PrewalkTree(surface_info.id, surface_info.has_moved_pixels, | 733 PrewalkTree(surface_info.id, surface_info.has_moved_pixels, |
736 surface_info.parent_pass_id, result); | 734 surface_info.parent_pass_id, result); |
737 if (surface_damage.IsEmpty()) | 735 if (surface_damage.IsEmpty()) |
738 continue; | 736 continue; |
739 if (surface_info.has_moved_pixels) { | 737 if (surface_info.has_moved_pixels) { |
740 // Areas outside the rect hit by target_to_surface_transform may be | 738 // Areas outside the rect hit by target_to_surface_transform may be |
741 // modified if there is a filter that moves pixels. | 739 // modified if there is a filter that moves pixels. |
742 damage_rect = full_damage; | 740 damage_rect = full_damage; |
(...skipping 19 matching lines...) Expand all Loading... |
762 } | 760 } |
763 | 761 |
764 CHECK(debug_weak_this.get()); | 762 CHECK(debug_weak_this.get()); |
765 for (const auto& render_pass : frame.render_pass_list) { | 763 for (const auto& render_pass : frame.render_pass_list) { |
766 if (!render_pass->copy_requests.empty()) { | 764 if (!render_pass->copy_requests.empty()) { |
767 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); | 765 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); |
768 copy_request_passes_.insert(remapped_pass_id); | 766 copy_request_passes_.insert(remapped_pass_id); |
769 } | 767 } |
770 } | 768 } |
771 | 769 |
772 referenced_surfaces_.erase(referenced_surfaces_.find(surface->surface_id())); | 770 referenced_surfaces_.erase(it); |
773 if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video) | 771 if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video) |
774 result->may_contain_video = true; | 772 result->may_contain_video = true; |
775 return damage_rect; | 773 return damage_rect; |
776 } | 774 } |
777 | 775 |
778 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { | 776 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { |
779 // undrawn_surfaces are Surfaces that were identified by prewalk as being | 777 // undrawn_surfaces are Surfaces that were identified by prewalk as being |
780 // referenced by a drawn Surface, but aren't contained in a SurfaceDrawQuad. | 778 // referenced by a drawn Surface, but aren't contained in a SurfaceDrawQuad. |
781 // They need to be iterated over to ensure that any copy requests on them | 779 // They need to be iterated over to ensure that any copy requests on them |
782 // (or on Surfaces they reference) are executed. | 780 // (or on Surfaces they reference) are executed. |
(...skipping 20 matching lines...) Expand all Loading... |
803 for (const auto& child_id : frame.metadata.referenced_surfaces) { | 801 for (const auto& child_id : frame.metadata.referenced_surfaces) { |
804 // Don't iterate over the child Surface if it was already listed as a | 802 // Don't iterate over the child Surface if it was already listed as a |
805 // child of a different Surface, or in the case where there's infinite | 803 // child of a different Surface, or in the case where there's infinite |
806 // recursion. | 804 // recursion. |
807 if (!prewalk_result->undrawn_surfaces.count(child_id)) { | 805 if (!prewalk_result->undrawn_surfaces.count(child_id)) { |
808 surfaces_to_copy.push_back(child_id); | 806 surfaces_to_copy.push_back(child_id); |
809 prewalk_result->undrawn_surfaces.insert(child_id); | 807 prewalk_result->undrawn_surfaces.insert(child_id); |
810 } | 808 } |
811 } | 809 } |
812 } else { | 810 } else { |
813 auto it = referenced_surfaces_.insert(surface_id).first; | 811 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
814 CopyPasses(frame, surface); | 812 CopyPasses(frame, surface); |
815 referenced_surfaces_.erase(it); | 813 referenced_surfaces_.erase(it); |
816 } | 814 } |
817 } | 815 } |
818 } | 816 } |
819 | 817 |
820 void SurfaceAggregator::PropagateCopyRequestPasses() { | 818 void SurfaceAggregator::PropagateCopyRequestPasses() { |
821 std::vector<int> copy_requests_to_iterate(copy_request_passes_.begin(), | 819 std::vector<int> copy_requests_to_iterate(copy_request_passes_.begin(), |
822 copy_request_passes_.end()); | 820 copy_request_passes_.end()); |
823 while (!copy_requests_to_iterate.empty()) { | 821 while (!copy_requests_to_iterate.empty()) { |
(...skipping 29 matching lines...) Expand all Loading... |
853 dest_pass_list_ = &frame.render_pass_list; | 851 dest_pass_list_ = &frame.render_pass_list; |
854 | 852 |
855 valid_surfaces_.clear(); | 853 valid_surfaces_.clear(); |
856 PrewalkResult prewalk_result; | 854 PrewalkResult prewalk_result; |
857 root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result); | 855 root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result); |
858 PropagateCopyRequestPasses(); | 856 PropagateCopyRequestPasses(); |
859 has_copy_requests_ = !copy_request_passes_.empty(); | 857 has_copy_requests_ = !copy_request_passes_.empty(); |
860 frame.metadata.may_contain_video = prewalk_result.may_contain_video; | 858 frame.metadata.may_contain_video = prewalk_result.may_contain_video; |
861 | 859 |
862 CopyUndrawnSurfaces(&prewalk_result); | 860 CopyUndrawnSurfaces(&prewalk_result); |
863 auto it = referenced_surfaces_.insert(surface_id).first; | 861 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
864 CopyPasses(root_surface_frame, surface); | 862 CopyPasses(root_surface_frame, surface); |
865 referenced_surfaces_.erase(it); | 863 referenced_surfaces_.erase(it); |
866 AddColorConversionPass(); | 864 AddColorConversionPass(); |
867 | 865 |
868 moved_pixel_passes_.clear(); | 866 moved_pixel_passes_.clear(); |
869 copy_request_passes_.clear(); | 867 copy_request_passes_.clear(); |
870 render_pass_dependencies_.clear(); | 868 render_pass_dependencies_.clear(); |
871 | 869 |
872 // Remove all render pass mappings that weren't used in the current frame. | 870 // Remove all render pass mappings that weren't used in the current frame. |
873 for (auto it = render_pass_allocator_map_.begin(); | 871 for (auto it = render_pass_allocator_map_.begin(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 kUmaStatMaxSurfaces); | 905 kUmaStatMaxSurfaces); |
908 UMA_HISTOGRAM_EXACT_LINEAR(kUmaMissingSurface, uma_stats_.missing_surface, | 906 UMA_HISTOGRAM_EXACT_LINEAR(kUmaMissingSurface, uma_stats_.missing_surface, |
909 kUmaStatMaxSurfaces); | 907 kUmaStatMaxSurfaces); |
910 UMA_HISTOGRAM_EXACT_LINEAR(kUmaNoActiveFrame, uma_stats_.no_active_frame, | 908 UMA_HISTOGRAM_EXACT_LINEAR(kUmaNoActiveFrame, uma_stats_.no_active_frame, |
911 kUmaStatMaxSurfaces); | 909 kUmaStatMaxSurfaces); |
912 | 910 |
913 return frame; | 911 return frame; |
914 } | 912 } |
915 | 913 |
916 void SurfaceAggregator::ReleaseResources(const SurfaceId& surface_id) { | 914 void SurfaceAggregator::ReleaseResources(const SurfaceId& surface_id) { |
917 auto it = surface_id_to_resource_child_id_.find(surface_id); | 915 SurfaceToResourceChildIdMap::iterator it = |
| 916 surface_id_to_resource_child_id_.find(surface_id); |
918 if (it != surface_id_to_resource_child_id_.end()) { | 917 if (it != surface_id_to_resource_child_id_.end()) { |
919 provider_->DestroyChild(it->second); | 918 provider_->DestroyChild(it->second); |
920 surface_id_to_resource_child_id_.erase(it); | 919 surface_id_to_resource_child_id_.erase(it); |
921 } | 920 } |
922 } | 921 } |
923 | 922 |
924 void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) { | 923 void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) { |
925 auto it = previous_contained_surfaces_.find(surface_id); | 924 auto it = previous_contained_surfaces_.find(surface_id); |
926 if (it == previous_contained_surfaces_.end()) | 925 if (it == previous_contained_surfaces_.end()) |
927 return; | 926 return; |
928 // Set the last drawn index as 0 to ensure full damage next time it's drawn. | 927 // Set the last drawn index as 0 to ensure full damage next time it's drawn. |
929 it->second = 0; | 928 it->second = 0; |
930 } | 929 } |
931 | 930 |
932 void SurfaceAggregator::SetOutputColorSpace( | 931 void SurfaceAggregator::SetOutputColorSpace( |
933 const gfx::ColorSpace& blending_color_space, | 932 const gfx::ColorSpace& blending_color_space, |
934 const gfx::ColorSpace& output_color_space) { | 933 const gfx::ColorSpace& output_color_space) { |
935 blending_color_space_ = blending_color_space; | 934 blending_color_space_ = blending_color_space; |
936 output_color_space_ = output_color_space; | 935 output_color_space_ = output_color_space; |
937 } | 936 } |
938 | 937 |
939 } // namespace cc | 938 } // namespace cc |
OLD | NEW |