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

Side by Side Diff: cc/surfaces/surface_aggregator.cc

Issue 2821353002: Use flat_set in SurfaceAggregator. (Closed)
Patch Set: Fix Created 3 years, 8 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 | « cc/surfaces/surface_aggregator.h ('k') | 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/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
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 SurfaceToResourceChildIdMap::iterator it = 147 auto it = surface_id_to_resource_child_id_.find(surface->surface_id());
148 surface_id_to_resource_child_id_.find(surface->surface_id());
149 if (it == surface_id_to_resource_child_id_.end()) { 148 if (it == surface_id_to_resource_child_id_.end()) {
150 int child_id = 149 int child_id =
151 provider_->CreateChild(base::Bind(&UnrefHelper, surface->factory())); 150 provider_->CreateChild(base::Bind(&UnrefHelper, surface->factory()));
152 if (surface->factory()) { 151 if (surface->factory()) {
153 provider_->SetChildNeedsSyncTokens( 152 provider_->SetChildNeedsSyncTokens(
154 child_id, surface->factory()->needs_sync_points()); 153 child_id, surface->factory()->needs_sync_points());
155 } 154 }
156 surface_id_to_resource_child_id_[surface->surface_id()] = child_id; 155 surface_id_to_resource_child_id_[surface->surface_id()] = child_id;
157 return child_id; 156 return child_id;
158 } else { 157 } else {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 std::multimap<int, std::unique_ptr<CopyOutputRequest>> copy_requests; 231 std::multimap<int, std::unique_ptr<CopyOutputRequest>> copy_requests;
233 surface->TakeCopyOutputRequests(&copy_requests); 232 surface->TakeCopyOutputRequests(&copy_requests);
234 233
235 const RenderPassList& render_pass_list = frame.render_pass_list; 234 const RenderPassList& render_pass_list = frame.render_pass_list;
236 if (!valid_surfaces_.count(surface->surface_id())) { 235 if (!valid_surfaces_.count(surface->surface_id())) {
237 for (auto& request : copy_requests) 236 for (auto& request : copy_requests)
238 request.second->SendEmptyResult(); 237 request.second->SendEmptyResult();
239 return; 238 return;
240 } 239 }
241 240
242 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; 241 referenced_surfaces_.insert(surface_id);
243 // TODO(vmpstr): provider check is a hack for unittests that don't set up a 242 // TODO(vmpstr): provider check is a hack for unittests that don't set up a
244 // resource provider. 243 // resource provider.
245 ResourceProvider::ResourceIdMap empty_map; 244 ResourceProvider::ResourceIdMap empty_map;
246 const ResourceProvider::ResourceIdMap& child_to_parent_map = 245 const ResourceProvider::ResourceIdMap& child_to_parent_map =
247 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) 246 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface))
248 : empty_map; 247 : empty_map;
249 bool merge_pass = 248 bool merge_pass =
250 surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty(); 249 surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty();
251 250
252 const RenderPassList& referenced_passes = render_pass_list; 251 const RenderPassList& referenced_passes = render_pass_list;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 clip_rect, dest_pass); 329 clip_rect, dest_pass);
331 330
332 RenderPassDrawQuad* quad = 331 RenderPassDrawQuad* quad =
333 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); 332 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
334 quad->SetNew(shared_quad_state, surface_quad->rect, 333 quad->SetNew(shared_quad_state, surface_quad->rect,
335 surface_quad->visible_rect, remapped_pass_id, 0, gfx::RectF(), 334 surface_quad->visible_rect, remapped_pass_id, 0, gfx::RectF(),
336 gfx::Size(), gfx::Vector2dF(), gfx::PointF(), 335 gfx::Size(), gfx::Vector2dF(), gfx::PointF(),
337 gfx::RectF(surface_quad->rect)); 336 gfx::RectF(surface_quad->rect));
338 } 337 }
339 338
340 referenced_surfaces_.erase(it); 339 // Need to re-query since referenced_surfaces_ iterators are not stable.
340 referenced_surfaces_.erase(referenced_surfaces_.find(surface_id));
danakj 2017/04/18 17:48:15 Shouldn't this be base::Erase?
danakj 2017/04/18 17:49:12 Oh, or nvm I guess we only have EraseIf for flat_t
brettw 2017/04/18 18:26:05 I thought base::Erase is really a better version o
341 } 341 }
342 342
343 void SurfaceAggregator::AddColorConversionPass() { 343 void SurfaceAggregator::AddColorConversionPass() {
344 if (dest_pass_list_->empty()) 344 if (dest_pass_list_->empty())
345 return; 345 return;
346 346
347 RenderPass* root_render_pass = dest_pass_list_->back().get(); 347 RenderPass* root_render_pass = dest_pass_list_->back().get();
348 if (root_render_pass->color_space == output_color_space_) 348 if (root_render_pass->color_space == output_color_space_)
349 return; 349 return;
350 350
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 } 561 }
562 562
563 dest_pass_list_->push_back(std::move(copy_pass)); 563 dest_pass_list_->push_back(std::move(copy_pass));
564 } 564 }
565 } 565 }
566 566
567 void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { 567 void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() {
568 for (const auto& surface : previous_contained_surfaces_) { 568 for (const auto& surface : previous_contained_surfaces_) {
569 if (!contained_surfaces_.count(surface.first)) { 569 if (!contained_surfaces_.count(surface.first)) {
570 // Release resources of removed surface. 570 // Release resources of removed surface.
571 SurfaceToResourceChildIdMap::iterator it = 571 auto it = surface_id_to_resource_child_id_.find(surface.first);
572 surface_id_to_resource_child_id_.find(surface.first);
573 if (it != surface_id_to_resource_child_id_.end()) { 572 if (it != surface_id_to_resource_child_id_.end()) {
574 provider_->DestroyChild(it->second); 573 provider_->DestroyChild(it->second);
575 surface_id_to_resource_child_id_.erase(it); 574 surface_id_to_resource_child_id_.erase(it);
576 } 575 }
577 576
578 // Notify client of removed surface. 577 // Notify client of removed surface.
579 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); 578 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first);
580 if (surface_ptr) { 579 if (surface_ptr) {
581 surface_ptr->RunDrawCallbacks(); 580 surface_ptr->RunDrawCallbacks();
582 } 581 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 parent_pass_id(parent_pass_id), 645 parent_pass_id(parent_pass_id),
647 target_to_surface_transform(target_to_surface_transform) {} 646 target_to_surface_transform(target_to_surface_transform) {}
648 647
649 SurfaceId id; 648 SurfaceId id;
650 bool has_moved_pixels; 649 bool has_moved_pixels;
651 int parent_pass_id; 650 int parent_pass_id;
652 gfx::Transform target_to_surface_transform; 651 gfx::Transform target_to_surface_transform;
653 }; 652 };
654 std::vector<SurfaceInfo> child_surfaces; 653 std::vector<SurfaceInfo> child_surfaces;
655 654
656 std::unordered_set<int> pixel_moving_background_filter_passes; 655 // This data is created once and typically small or empty. Collect all items
656 // and pass to a flat_vector to sort once.
657 std::vector<int> pixel_moving_background_filter_passes_data;
657 for (const auto& render_pass : frame.render_pass_list) { 658 for (const auto& render_pass : frame.render_pass_list) {
658 if (render_pass->background_filters.HasFilterThatMovesPixels()) { 659 if (render_pass->background_filters.HasFilterThatMovesPixels()) {
659 pixel_moving_background_filter_passes.insert( 660 pixel_moving_background_filter_passes_data.push_back(
660 RemapPassId(render_pass->id, surface_id)); 661 RemapPassId(render_pass->id, surface_id));
661 } 662 }
662 } 663 }
664 base::flat_set<int> pixel_moving_background_filter_passes(
665 std::move(pixel_moving_background_filter_passes_data),
666 base::KEEP_FIRST_OF_DUPES);
663 667
664 for (const auto& render_pass : base::Reversed(frame.render_pass_list)) { 668 for (const auto& render_pass : base::Reversed(frame.render_pass_list)) {
665 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); 669 int remapped_pass_id = RemapPassId(render_pass->id, surface_id);
666 bool has_pixel_moving_filter = 670 bool has_pixel_moving_filter =
667 render_pass->filters.HasFilterThatMovesPixels(); 671 render_pass->filters.HasFilterThatMovesPixels();
668 if (has_pixel_moving_filter) 672 if (has_pixel_moving_filter)
669 moved_pixel_passes_.insert(remapped_pass_id); 673 moved_pixel_passes_.insert(remapped_pass_id);
670 bool in_moved_pixel_pass = has_pixel_moving_filter || 674 bool in_moved_pixel_pass = has_pixel_moving_filter ||
671 !!moved_pixel_passes_.count(remapped_pass_id); 675 !!moved_pixel_passes_.count(remapped_pass_id);
672 for (auto* quad : render_pass->quad_list) { 676 for (auto* quad : render_pass->quad_list) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 gfx::Rect full_damage; 725 gfx::Rect full_damage;
722 if (!frame.render_pass_list.empty()) { 726 if (!frame.render_pass_list.empty()) {
723 RenderPass* last_pass = frame.render_pass_list.back().get(); 727 RenderPass* last_pass = frame.render_pass_list.back().get();
724 full_damage = last_pass->output_rect; 728 full_damage = last_pass->output_rect;
725 damage_rect = 729 damage_rect =
726 DamageRectForSurface(surface, *last_pass, last_pass->output_rect); 730 DamageRectForSurface(surface, *last_pass, last_pass->output_rect);
727 } 731 }
728 732
729 // Avoid infinite recursion by adding current surface to 733 // Avoid infinite recursion by adding current surface to
730 // referenced_surfaces_. 734 // referenced_surfaces_.
731 SurfaceSet::iterator it = 735 referenced_surfaces_.insert(surface->surface_id());
732 referenced_surfaces_.insert(surface->surface_id()).first;
733 for (const auto& surface_info : child_surfaces) { 736 for (const auto& surface_info : child_surfaces) {
734 gfx::Rect surface_damage = 737 gfx::Rect surface_damage =
735 PrewalkTree(surface_info.id, surface_info.has_moved_pixels, 738 PrewalkTree(surface_info.id, surface_info.has_moved_pixels,
736 surface_info.parent_pass_id, result); 739 surface_info.parent_pass_id, result);
737 if (surface_damage.IsEmpty()) 740 if (surface_damage.IsEmpty())
738 continue; 741 continue;
739 if (surface_info.has_moved_pixels) { 742 if (surface_info.has_moved_pixels) {
740 // Areas outside the rect hit by target_to_surface_transform may be 743 // Areas outside the rect hit by target_to_surface_transform may be
741 // modified if there is a filter that moves pixels. 744 // modified if there is a filter that moves pixels.
742 damage_rect = full_damage; 745 damage_rect = full_damage;
(...skipping 19 matching lines...) Expand all
762 } 765 }
763 766
764 CHECK(debug_weak_this.get()); 767 CHECK(debug_weak_this.get());
765 for (const auto& render_pass : frame.render_pass_list) { 768 for (const auto& render_pass : frame.render_pass_list) {
766 if (!render_pass->copy_requests.empty()) { 769 if (!render_pass->copy_requests.empty()) {
767 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); 770 int remapped_pass_id = RemapPassId(render_pass->id, surface_id);
768 copy_request_passes_.insert(remapped_pass_id); 771 copy_request_passes_.insert(remapped_pass_id);
769 } 772 }
770 } 773 }
771 774
772 referenced_surfaces_.erase(it); 775 referenced_surfaces_.erase(referenced_surfaces_.find(surface->surface_id()));
773 if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video) 776 if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video)
774 result->may_contain_video = true; 777 result->may_contain_video = true;
775 return damage_rect; 778 return damage_rect;
776 } 779 }
777 780
778 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { 781 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) {
779 // undrawn_surfaces are Surfaces that were identified by prewalk as being 782 // undrawn_surfaces are Surfaces that were identified by prewalk as being
780 // referenced by a drawn Surface, but aren't contained in a SurfaceDrawQuad. 783 // 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 784 // They need to be iterated over to ensure that any copy requests on them
782 // (or on Surfaces they reference) are executed. 785 // (or on Surfaces they reference) are executed.
(...skipping 20 matching lines...) Expand all
803 for (const auto& child_id : frame.metadata.referenced_surfaces) { 806 for (const auto& child_id : frame.metadata.referenced_surfaces) {
804 // Don't iterate over the child Surface if it was already listed as a 807 // 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 808 // child of a different Surface, or in the case where there's infinite
806 // recursion. 809 // recursion.
807 if (!prewalk_result->undrawn_surfaces.count(child_id)) { 810 if (!prewalk_result->undrawn_surfaces.count(child_id)) {
808 surfaces_to_copy.push_back(child_id); 811 surfaces_to_copy.push_back(child_id);
809 prewalk_result->undrawn_surfaces.insert(child_id); 812 prewalk_result->undrawn_surfaces.insert(child_id);
810 } 813 }
811 } 814 }
812 } else { 815 } else {
813 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; 816 auto it = referenced_surfaces_.insert(surface_id).first;
814 CopyPasses(frame, surface); 817 CopyPasses(frame, surface);
815 referenced_surfaces_.erase(it); 818 referenced_surfaces_.erase(it);
816 } 819 }
817 } 820 }
818 } 821 }
819 822
820 void SurfaceAggregator::PropagateCopyRequestPasses() { 823 void SurfaceAggregator::PropagateCopyRequestPasses() {
821 std::vector<int> copy_requests_to_iterate(copy_request_passes_.begin(), 824 std::vector<int> copy_requests_to_iterate(copy_request_passes_.begin(),
822 copy_request_passes_.end()); 825 copy_request_passes_.end());
823 while (!copy_requests_to_iterate.empty()) { 826 while (!copy_requests_to_iterate.empty()) {
(...skipping 29 matching lines...) Expand all
853 dest_pass_list_ = &frame.render_pass_list; 856 dest_pass_list_ = &frame.render_pass_list;
854 857
855 valid_surfaces_.clear(); 858 valid_surfaces_.clear();
856 PrewalkResult prewalk_result; 859 PrewalkResult prewalk_result;
857 root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result); 860 root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result);
858 PropagateCopyRequestPasses(); 861 PropagateCopyRequestPasses();
859 has_copy_requests_ = !copy_request_passes_.empty(); 862 has_copy_requests_ = !copy_request_passes_.empty();
860 frame.metadata.may_contain_video = prewalk_result.may_contain_video; 863 frame.metadata.may_contain_video = prewalk_result.may_contain_video;
861 864
862 CopyUndrawnSurfaces(&prewalk_result); 865 CopyUndrawnSurfaces(&prewalk_result);
863 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; 866 auto it = referenced_surfaces_.insert(surface_id).first;
864 CopyPasses(root_surface_frame, surface); 867 CopyPasses(root_surface_frame, surface);
865 referenced_surfaces_.erase(it); 868 referenced_surfaces_.erase(it);
866 AddColorConversionPass(); 869 AddColorConversionPass();
867 870
868 moved_pixel_passes_.clear(); 871 moved_pixel_passes_.clear();
869 copy_request_passes_.clear(); 872 copy_request_passes_.clear();
870 render_pass_dependencies_.clear(); 873 render_pass_dependencies_.clear();
871 874
872 // Remove all render pass mappings that weren't used in the current frame. 875 // Remove all render pass mappings that weren't used in the current frame.
873 for (auto it = render_pass_allocator_map_.begin(); 876 for (auto it = render_pass_allocator_map_.begin();
874 it != render_pass_allocator_map_.end();) { 877 it != render_pass_allocator_map_.end();) {
875 if (it->second.in_use) { 878 if (it->second.in_use) {
876 it->second.in_use = false; 879 it->second.in_use = false;
877 it++; 880 it++;
878 } else { 881 } else {
879 it = render_pass_allocator_map_.erase(it); 882 it = render_pass_allocator_map_.erase(it);
880 } 883 }
881 } 884 }
882 885
883 DCHECK(referenced_surfaces_.empty()); 886 DCHECK(referenced_surfaces_.empty());
884 887
885 if (dest_pass_list_->empty()) 888 if (dest_pass_list_->empty())
886 return CompositorFrame(); 889 return CompositorFrame();
887 890
888 dest_pass_list_ = NULL; 891 dest_pass_list_ = NULL;
889 ProcessAddedAndRemovedSurfaces(); 892 ProcessAddedAndRemovedSurfaces();
890 contained_surfaces_.swap(previous_contained_surfaces_); 893 contained_surfaces_.swap(previous_contained_surfaces_);
891 contained_surfaces_.clear(); 894 contained_surfaces_.clear();
892 895
893 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); 896 for (auto it : previous_contained_surfaces_) {
894 it != previous_contained_surfaces_.end();
895 ++it) {
896 Surface* surface = manager_->GetSurfaceForId(it->first); 897 Surface* surface = manager_->GetSurfaceForId(it->first);
897 if (surface) 898 if (surface)
898 surface->TakeLatencyInfo(&frame.metadata.latency_info); 899 surface->TakeLatencyInfo(&frame.metadata.latency_info);
899 } 900 }
900 901
901 // TODO(jamesr): Aggregate all resource references into the returned frame's 902 // TODO(jamesr): Aggregate all resource references into the returned frame's
902 // resource list. 903 // resource list.
903 904
904 // Log UMA stats for SurfaceDrawQuads on the number of surfaces that were 905 // Log UMA stats for SurfaceDrawQuads on the number of surfaces that were
905 // aggregated together and any failures. 906 // aggregated together and any failures.
906 UMA_HISTOGRAM_EXACT_LINEAR(kUmaValidSurface, uma_stats_.valid_surface, 907 UMA_HISTOGRAM_EXACT_LINEAR(kUmaValidSurface, uma_stats_.valid_surface,
907 kUmaStatMaxSurfaces); 908 kUmaStatMaxSurfaces);
908 UMA_HISTOGRAM_EXACT_LINEAR(kUmaMissingSurface, uma_stats_.missing_surface, 909 UMA_HISTOGRAM_EXACT_LINEAR(kUmaMissingSurface, uma_stats_.missing_surface,
909 kUmaStatMaxSurfaces); 910 kUmaStatMaxSurfaces);
910 UMA_HISTOGRAM_EXACT_LINEAR(kUmaNoActiveFrame, uma_stats_.no_active_frame, 911 UMA_HISTOGRAM_EXACT_LINEAR(kUmaNoActiveFrame, uma_stats_.no_active_frame,
911 kUmaStatMaxSurfaces); 912 kUmaStatMaxSurfaces);
912 913
913 return frame; 914 return frame;
914 } 915 }
915 916
916 void SurfaceAggregator::ReleaseResources(const SurfaceId& surface_id) { 917 void SurfaceAggregator::ReleaseResources(const SurfaceId& surface_id) {
917 SurfaceToResourceChildIdMap::iterator it = 918 auto it = surface_id_to_resource_child_id_.find(surface_id);
918 surface_id_to_resource_child_id_.find(surface_id);
919 if (it != surface_id_to_resource_child_id_.end()) { 919 if (it != surface_id_to_resource_child_id_.end()) {
920 provider_->DestroyChild(it->second); 920 provider_->DestroyChild(it->second);
921 surface_id_to_resource_child_id_.erase(it); 921 surface_id_to_resource_child_id_.erase(it);
922 } 922 }
923 } 923 }
924 924
925 void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) { 925 void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) {
926 auto it = previous_contained_surfaces_.find(surface_id); 926 auto it = previous_contained_surfaces_.find(surface_id);
927 if (it == previous_contained_surfaces_.end()) 927 if (it == previous_contained_surfaces_.end())
928 return; 928 return;
929 // Set the last drawn index as 0 to ensure full damage next time it's drawn. 929 // Set the last drawn index as 0 to ensure full damage next time it's drawn.
930 it->second = 0; 930 it->second = 0;
931 } 931 }
932 932
933 void SurfaceAggregator::SetOutputColorSpace( 933 void SurfaceAggregator::SetOutputColorSpace(
934 const gfx::ColorSpace& blending_color_space, 934 const gfx::ColorSpace& blending_color_space,
935 const gfx::ColorSpace& output_color_space) { 935 const gfx::ColorSpace& output_color_space) {
936 blending_color_space_ = blending_color_space; 936 blending_color_space_ = blending_color_space;
937 output_color_space_ = output_color_space; 937 output_color_space_ = output_color_space;
938 } 938 }
939 939
940 } // namespace cc 940 } // namespace cc
OLDNEW
« no previous file with comments | « cc/surfaces/surface_aggregator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698