| 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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/containers/adapters.h" | 12 #include "base/containers/adapters.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 17 #include "base/trace_event/trace_event.h" | 18 #include "base/trace_event/trace_event.h" |
| 18 #include "cc/base/math_util.h" | 19 #include "cc/base/math_util.h" |
| 19 #include "cc/output/compositor_frame.h" | 20 #include "cc/output/compositor_frame.h" |
| 20 #include "cc/quads/draw_quad.h" | 21 #include "cc/quads/draw_quad.h" |
| 21 #include "cc/quads/render_pass_draw_quad.h" | 22 #include "cc/quads/render_pass_draw_quad.h" |
| 22 #include "cc/quads/shared_quad_state.h" | 23 #include "cc/quads/shared_quad_state.h" |
| 23 #include "cc/quads/solid_color_draw_quad.h" | 24 #include "cc/quads/solid_color_draw_quad.h" |
| 24 #include "cc/quads/surface_draw_quad.h" | 25 #include "cc/quads/surface_draw_quad.h" |
| 25 #include "cc/quads/texture_draw_quad.h" | 26 #include "cc/quads/texture_draw_quad.h" |
| 26 #include "cc/resources/resource_provider.h" | 27 #include "cc/resources/resource_provider.h" |
| 27 #include "cc/surfaces/surface.h" | 28 #include "cc/surfaces/surface.h" |
| 28 #include "cc/surfaces/surface_factory.h" | 29 #include "cc/surfaces/surface_factory.h" |
| 29 #include "cc/surfaces/surface_manager.h" | 30 #include "cc/surfaces/surface_manager.h" |
| 30 #include "cc/trees/blocking_task_runner.h" | 31 #include "cc/trees/blocking_task_runner.h" |
| 31 | 32 |
| 32 namespace cc { | 33 namespace cc { |
| 33 namespace { | 34 namespace { |
| 34 | 35 |
| 36 // Maximum bucket size for the UMA stats. |
| 37 constexpr int kUmaStatMaxSurfaces = 30; |
| 38 |
| 39 const char kUmaValidSurface[] = |
| 40 "Compositing.SurfaceAggregator.SurfaceDrawQuad.ValidSurface"; |
| 41 const char kUmaMissingSurface[] = |
| 42 "Compositing.SurfaceAggregator.SurfaceDrawQuad.MissingSurface"; |
| 43 const char kUmaNoActiveFrame[] = |
| 44 "Compositing.SurfaceAggregator.SurfaceDrawQuad.NoActiveFrame"; |
| 45 |
| 35 void MoveMatchingRequests( | 46 void MoveMatchingRequests( |
| 36 int render_pass_id, | 47 int render_pass_id, |
| 37 std::multimap<int, std::unique_ptr<CopyOutputRequest>>* copy_requests, | 48 std::multimap<int, std::unique_ptr<CopyOutputRequest>>* copy_requests, |
| 38 std::vector<std::unique_ptr<CopyOutputRequest>>* output_requests) { | 49 std::vector<std::unique_ptr<CopyOutputRequest>>* output_requests) { |
| 39 auto request_range = copy_requests->equal_range(render_pass_id); | 50 auto request_range = copy_requests->equal_range(render_pass_id); |
| 40 for (auto it = request_range.first; it != request_range.second; ++it) { | 51 for (auto it = request_range.first; it != request_range.second; ++it) { |
| 41 DCHECK(it->second); | 52 DCHECK(it->second); |
| 42 output_requests->push_back(std::move(it->second)); | 53 output_requests->push_back(std::move(it->second)); |
| 43 } | 54 } |
| 44 copy_requests->erase(request_range.first, request_range.second); | 55 copy_requests->erase(request_range.first, request_range.second); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 // a cycle in the graph and should be dropped. | 197 // a cycle in the graph and should be dropped. |
| 187 if (referenced_surfaces_.count(surface_id)) | 198 if (referenced_surfaces_.count(surface_id)) |
| 188 return; | 199 return; |
| 189 Surface* surface = manager_->GetSurfaceForId(surface_id); | 200 Surface* surface = manager_->GetSurfaceForId(surface_id); |
| 190 if (!surface || !surface->HasActiveFrame()) { | 201 if (!surface || !surface->HasActiveFrame()) { |
| 191 if (surface_quad->fallback_quad) { | 202 if (surface_quad->fallback_quad) { |
| 192 HandleSurfaceQuad(surface_quad->fallback_quad, target_transform, | 203 HandleSurfaceQuad(surface_quad->fallback_quad, target_transform, |
| 193 clip_rect, dest_pass, ignore_undamaged, | 204 clip_rect, dest_pass, ignore_undamaged, |
| 194 damage_rect_in_quad_space, | 205 damage_rect_in_quad_space, |
| 195 damage_rect_in_quad_space_valid); | 206 damage_rect_in_quad_space_valid); |
| 207 } else if (!surface) { |
| 208 ++uma_stats_.missing_surface; |
| 209 } else { |
| 210 ++uma_stats_.no_active_frame; |
| 196 } | 211 } |
| 197 return; | 212 return; |
| 198 } | 213 } |
| 214 ++uma_stats_.valid_surface; |
| 199 | 215 |
| 200 if (ignore_undamaged) { | 216 if (ignore_undamaged) { |
| 201 gfx::Transform quad_to_target_transform( | 217 gfx::Transform quad_to_target_transform( |
| 202 target_transform, | 218 target_transform, |
| 203 surface_quad->shared_quad_state->quad_to_target_transform); | 219 surface_quad->shared_quad_state->quad_to_target_transform); |
| 204 *damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect( | 220 *damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect( |
| 205 quad_to_target_transform, dest_pass->transform_to_root_target, | 221 quad_to_target_transform, dest_pass->transform_to_root_target, |
| 206 root_damage_rect_, damage_rect_in_quad_space); | 222 root_damage_rect_, damage_rect_in_quad_space); |
| 207 if (*damage_rect_in_quad_space_valid && | 223 if (*damage_rect_in_quad_space_valid && |
| 208 !damage_rect_in_quad_space->Intersects(surface_quad->visible_rect)) { | 224 !damage_rect_in_quad_space->Intersects(surface_quad->visible_rect)) { |
| (...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 continue; | 825 continue; |
| 810 for (auto pass : it->second) { | 826 for (auto pass : it->second) { |
| 811 if (copy_request_passes_.insert(pass).second) { | 827 if (copy_request_passes_.insert(pass).second) { |
| 812 copy_requests_to_iterate.push_back(pass); | 828 copy_requests_to_iterate.push_back(pass); |
| 813 } | 829 } |
| 814 } | 830 } |
| 815 } | 831 } |
| 816 } | 832 } |
| 817 | 833 |
| 818 CompositorFrame SurfaceAggregator::Aggregate(const SurfaceId& surface_id) { | 834 CompositorFrame SurfaceAggregator::Aggregate(const SurfaceId& surface_id) { |
| 835 uma_stats_.Reset(); |
| 836 |
| 819 Surface* surface = manager_->GetSurfaceForId(surface_id); | 837 Surface* surface = manager_->GetSurfaceForId(surface_id); |
| 820 DCHECK(surface); | 838 DCHECK(surface); |
| 821 contained_surfaces_[surface_id] = surface->frame_index(); | 839 contained_surfaces_[surface_id] = surface->frame_index(); |
| 822 | 840 |
| 823 if (!surface->HasActiveFrame()) | 841 if (!surface->HasActiveFrame()) |
| 824 return CompositorFrame(); | 842 return CompositorFrame(); |
| 825 | 843 |
| 826 const CompositorFrame& root_surface_frame = surface->GetActiveFrame(); | 844 const CompositorFrame& root_surface_frame = surface->GetActiveFrame(); |
| 827 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); | 845 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); |
| 828 | 846 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 it != previous_contained_surfaces_.end(); | 891 it != previous_contained_surfaces_.end(); |
| 874 ++it) { | 892 ++it) { |
| 875 Surface* surface = manager_->GetSurfaceForId(it->first); | 893 Surface* surface = manager_->GetSurfaceForId(it->first); |
| 876 if (surface) | 894 if (surface) |
| 877 surface->TakeLatencyInfo(&frame.metadata.latency_info); | 895 surface->TakeLatencyInfo(&frame.metadata.latency_info); |
| 878 } | 896 } |
| 879 | 897 |
| 880 // TODO(jamesr): Aggregate all resource references into the returned frame's | 898 // TODO(jamesr): Aggregate all resource references into the returned frame's |
| 881 // resource list. | 899 // resource list. |
| 882 | 900 |
| 901 // Log UMA stats for SurfaceDrawQuads on the number of surfaces that were |
| 902 // aggregated together and any failures. |
| 903 UMA_HISTOGRAM_EXACT_LINEAR(kUmaValidSurface, uma_stats_.valid_surface, |
| 904 kUmaStatMaxSurfaces); |
| 905 UMA_HISTOGRAM_EXACT_LINEAR(kUmaMissingSurface, uma_stats_.missing_surface, |
| 906 kUmaStatMaxSurfaces); |
| 907 UMA_HISTOGRAM_EXACT_LINEAR(kUmaNoActiveFrame, uma_stats_.no_active_frame, |
| 908 kUmaStatMaxSurfaces); |
| 909 |
| 883 return frame; | 910 return frame; |
| 884 } | 911 } |
| 885 | 912 |
| 886 void SurfaceAggregator::ReleaseResources(const SurfaceId& surface_id) { | 913 void SurfaceAggregator::ReleaseResources(const SurfaceId& surface_id) { |
| 887 SurfaceToResourceChildIdMap::iterator it = | 914 SurfaceToResourceChildIdMap::iterator it = |
| 888 surface_id_to_resource_child_id_.find(surface_id); | 915 surface_id_to_resource_child_id_.find(surface_id); |
| 889 if (it != surface_id_to_resource_child_id_.end()) { | 916 if (it != surface_id_to_resource_child_id_.end()) { |
| 890 provider_->DestroyChild(it->second); | 917 provider_->DestroyChild(it->second); |
| 891 surface_id_to_resource_child_id_.erase(it); | 918 surface_id_to_resource_child_id_.erase(it); |
| 892 } | 919 } |
| 893 } | 920 } |
| 894 | 921 |
| 895 void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) { | 922 void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) { |
| 896 auto it = previous_contained_surfaces_.find(surface_id); | 923 auto it = previous_contained_surfaces_.find(surface_id); |
| 897 if (it == previous_contained_surfaces_.end()) | 924 if (it == previous_contained_surfaces_.end()) |
| 898 return; | 925 return; |
| 899 // Set the last drawn index as 0 to ensure full damage next time it's drawn. | 926 // Set the last drawn index as 0 to ensure full damage next time it's drawn. |
| 900 it->second = 0; | 927 it->second = 0; |
| 901 } | 928 } |
| 902 | 929 |
| 903 void SurfaceAggregator::SetOutputColorSpace( | 930 void SurfaceAggregator::SetOutputColorSpace( |
| 904 const gfx::ColorSpace& blending_color_space, | 931 const gfx::ColorSpace& blending_color_space, |
| 905 const gfx::ColorSpace& output_color_space) { | 932 const gfx::ColorSpace& output_color_space) { |
| 906 blending_color_space_ = blending_color_space; | 933 blending_color_space_ = blending_color_space; |
| 907 output_color_space_ = output_color_space; | 934 output_color_space_ = output_color_space; |
| 908 } | 935 } |
| 909 | 936 |
| 910 } // namespace cc | 937 } // namespace cc |
| OLD | NEW |