| 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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 size_t sqs_size = source.shared_quad_state_list.size(); | 256 size_t sqs_size = source.shared_quad_state_list.size(); |
| 257 size_t dq_size = source.quad_list.size(); | 257 size_t dq_size = source.quad_list.size(); |
| 258 std::unique_ptr<RenderPass> copy_pass( | 258 std::unique_ptr<RenderPass> copy_pass( |
| 259 RenderPass::Create(sqs_size, dq_size)); | 259 RenderPass::Create(sqs_size, dq_size)); |
| 260 | 260 |
| 261 int remapped_pass_id = RemapPassId(source.id, surface_id); | 261 int remapped_pass_id = RemapPassId(source.id, surface_id); |
| 262 | 262 |
| 263 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, | 263 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, |
| 264 source.transform_to_root_target, source.filters, | 264 source.transform_to_root_target, source.filters, |
| 265 source.background_filters, blending_color_space_, | 265 source.background_filters, blending_color_space_, |
| 266 source.has_transparent_background); | 266 source.has_transparent_background, |
| 267 source.force_render_surface); |
| 267 | 268 |
| 268 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | 269 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
| 269 | 270 |
| 270 // Contributing passes aggregated in to the pass list need to take the | 271 // Contributing passes aggregated in to the pass list need to take the |
| 271 // transform of the surface quad into account to update their transform to | 272 // transform of the surface quad into account to update their transform to |
| 272 // the root surface. | 273 // the root surface. |
| 273 copy_pass->transform_to_root_target.ConcatTransform( | 274 copy_pass->transform_to_root_target.ConcatTransform( |
| 274 surface_quad->shared_quad_state->quad_to_target_transform); | 275 surface_quad->shared_quad_state->quad_to_target_transform); |
| 275 copy_pass->transform_to_root_target.ConcatTransform(target_transform); | 276 copy_pass->transform_to_root_target.ConcatTransform(target_transform); |
| 276 copy_pass->transform_to_root_target.ConcatTransform( | 277 copy_pass->transform_to_root_target.ConcatTransform( |
| 277 dest_pass->transform_to_root_target); | 278 dest_pass->transform_to_root_target); |
| 278 | 279 |
| 279 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, | 280 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
| 280 child_to_parent_map, gfx::Transform(), ClipData(), | 281 child_to_parent_map, gfx::Transform(), ClipData(), |
| 281 copy_pass.get(), surface_id); | 282 copy_pass.get(), surface_id); |
| 282 | 283 |
| 283 if (!copy_request_passes_.count(remapped_pass_id) && | 284 if (!copy_request_passes_.count(remapped_pass_id) && |
| 285 !force_render_surface_passes_.count(remapped_pass_id) && |
| 284 !moved_pixel_passes_.count(remapped_pass_id)) { | 286 !moved_pixel_passes_.count(remapped_pass_id)) { |
| 285 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); | 287 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); |
| 286 if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { | 288 if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { |
| 287 gfx::Rect damage_rect_in_render_pass_space = | 289 gfx::Rect damage_rect_in_render_pass_space = |
| 288 MathUtil::ProjectEnclosingClippedRect(inverse_transform, | 290 MathUtil::ProjectEnclosingClippedRect(inverse_transform, |
| 289 root_damage_rect_); | 291 root_damage_rect_); |
| 290 copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space); | 292 copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space); |
| 291 } | 293 } |
| 292 } | 294 } |
| 293 | 295 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 void SurfaceAggregator::CopyQuadsToPass( | 403 void SurfaceAggregator::CopyQuadsToPass( |
| 402 const QuadList& source_quad_list, | 404 const QuadList& source_quad_list, |
| 403 const SharedQuadStateList& source_shared_quad_state_list, | 405 const SharedQuadStateList& source_shared_quad_state_list, |
| 404 const ResourceProvider::ResourceIdMap& child_to_parent_map, | 406 const ResourceProvider::ResourceIdMap& child_to_parent_map, |
| 405 const gfx::Transform& target_transform, | 407 const gfx::Transform& target_transform, |
| 406 const ClipData& clip_rect, | 408 const ClipData& clip_rect, |
| 407 RenderPass* dest_pass, | 409 RenderPass* dest_pass, |
| 408 const SurfaceId& surface_id) { | 410 const SurfaceId& surface_id) { |
| 409 const SharedQuadState* last_copied_source_shared_quad_state = nullptr; | 411 const SharedQuadState* last_copied_source_shared_quad_state = nullptr; |
| 410 const SharedQuadState* dest_shared_quad_state = nullptr; | 412 const SharedQuadState* dest_shared_quad_state = nullptr; |
| 411 // If the current frame has copy requests then aggregate the entire | 413 // If the current frame has copy requests or force use of render surface, then |
| 412 // thing, as otherwise parts of the copy requests may be ignored. | 414 // aggregate the entire thing, as otherwise parts of the copy requests may be |
| 413 const bool ignore_undamaged = aggregate_only_damaged_ && | 415 // ignored. |
| 414 !has_copy_requests_ && | 416 const bool ignore_undamaged = |
| 415 !moved_pixel_passes_.count(dest_pass->id); | 417 aggregate_only_damaged_ && !has_copy_requests_ && |
| 418 !has_force_render_surfaces_ && !moved_pixel_passes_.count(dest_pass->id); |
| 416 // Damage rect in the quad space of the current shared quad state. | 419 // Damage rect in the quad space of the current shared quad state. |
| 417 // TODO(jbauman): This rect may contain unnecessary area if | 420 // TODO(jbauman): This rect may contain unnecessary area if |
| 418 // transform isn't axis-aligned. | 421 // transform isn't axis-aligned. |
| 419 gfx::Rect damage_rect_in_quad_space; | 422 gfx::Rect damage_rect_in_quad_space; |
| 420 bool damage_rect_in_quad_space_valid = false; | 423 bool damage_rect_in_quad_space_valid = false; |
| 421 | 424 |
| 422 #if DCHECK_IS_ON() | 425 #if DCHECK_IS_ON() |
| 423 // If quads have come in with SharedQuadState out of order, or when quads have | 426 // If quads have come in with SharedQuadState out of order, or when quads have |
| 424 // invalid SharedQuadState pointer, it should DCHECK. | 427 // invalid SharedQuadState pointer, it should DCHECK. |
| 425 SharedQuadStateList::ConstIterator sqs_iter = | 428 SharedQuadStateList::ConstIterator sqs_iter = |
| (...skipping 20 matching lines...) Expand all Loading... |
| 446 continue; | 449 continue; |
| 447 | 450 |
| 448 HandleSurfaceQuad(surface_quad, target_transform, clip_rect, dest_pass, | 451 HandleSurfaceQuad(surface_quad, target_transform, clip_rect, dest_pass, |
| 449 ignore_undamaged, &damage_rect_in_quad_space, | 452 ignore_undamaged, &damage_rect_in_quad_space, |
| 450 &damage_rect_in_quad_space_valid); | 453 &damage_rect_in_quad_space_valid); |
| 451 } else { | 454 } else { |
| 452 if (quad->shared_quad_state != last_copied_source_shared_quad_state) { | 455 if (quad->shared_quad_state != last_copied_source_shared_quad_state) { |
| 453 dest_shared_quad_state = CopySharedQuadState( | 456 dest_shared_quad_state = CopySharedQuadState( |
| 454 quad->shared_quad_state, target_transform, clip_rect, dest_pass); | 457 quad->shared_quad_state, target_transform, clip_rect, dest_pass); |
| 455 last_copied_source_shared_quad_state = quad->shared_quad_state; | 458 last_copied_source_shared_quad_state = quad->shared_quad_state; |
| 456 if (aggregate_only_damaged_ && !has_copy_requests_) { | 459 if (aggregate_only_damaged_ && !has_copy_requests_ && |
| 460 !has_force_render_surfaces_) { |
| 457 damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect( | 461 damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect( |
| 458 dest_shared_quad_state->quad_to_target_transform, | 462 dest_shared_quad_state->quad_to_target_transform, |
| 459 dest_pass->transform_to_root_target, root_damage_rect_, | 463 dest_pass->transform_to_root_target, root_damage_rect_, |
| 460 &damage_rect_in_quad_space); | 464 &damage_rect_in_quad_space); |
| 461 } | 465 } |
| 462 } | 466 } |
| 463 | 467 |
| 464 if (ignore_undamaged) { | 468 if (ignore_undamaged) { |
| 465 if (damage_rect_in_quad_space_valid && | 469 if (damage_rect_in_quad_space_valid && |
| 466 !damage_rect_in_quad_space.Intersects(quad->visible_rect)) | 470 !damage_rect_in_quad_space.Intersects(quad->visible_rect)) |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 std::unique_ptr<RenderPass> copy_pass( | 540 std::unique_ptr<RenderPass> copy_pass( |
| 537 RenderPass::Create(sqs_size, dq_size)); | 541 RenderPass::Create(sqs_size, dq_size)); |
| 538 | 542 |
| 539 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | 543 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
| 540 | 544 |
| 541 int remapped_pass_id = RemapPassId(source.id, surface->surface_id()); | 545 int remapped_pass_id = RemapPassId(source.id, surface->surface_id()); |
| 542 | 546 |
| 543 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, | 547 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, |
| 544 source.transform_to_root_target, source.filters, | 548 source.transform_to_root_target, source.filters, |
| 545 source.background_filters, blending_color_space_, | 549 source.background_filters, blending_color_space_, |
| 546 source.has_transparent_background); | 550 source.has_transparent_background, |
| 551 source.force_render_surface); |
| 547 | 552 |
| 548 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, | 553 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
| 549 child_to_parent_map, gfx::Transform(), ClipData(), | 554 child_to_parent_map, gfx::Transform(), ClipData(), |
| 550 copy_pass.get(), surface->surface_id()); | 555 copy_pass.get(), surface->surface_id()); |
| 551 if (!copy_request_passes_.count(remapped_pass_id) && | 556 if (!copy_request_passes_.count(remapped_pass_id) && |
| 557 !force_render_surface_passes_.count(remapped_pass_id) && |
| 552 !moved_pixel_passes_.count(remapped_pass_id)) { | 558 !moved_pixel_passes_.count(remapped_pass_id)) { |
| 553 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); | 559 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); |
| 554 if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { | 560 if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { |
| 555 gfx::Rect damage_rect_in_render_pass_space = | 561 gfx::Rect damage_rect_in_render_pass_space = |
| 556 MathUtil::ProjectEnclosingClippedRect(inverse_transform, | 562 MathUtil::ProjectEnclosingClippedRect(inverse_transform, |
| 557 root_damage_rect_); | 563 root_damage_rect_); |
| 558 copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space); | 564 copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space); |
| 559 } | 565 } |
| 560 } | 566 } |
| 561 | 567 |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 } | 760 } |
| 755 | 761 |
| 756 CHECK(debug_weak_this.get()); | 762 CHECK(debug_weak_this.get()); |
| 757 // TODO(staraz): It shouldn't need to call the callback when the damage is | 763 // TODO(staraz): It shouldn't need to call the callback when the damage is |
| 758 // from |surface| and not from |child_surfaces|. | 764 // from |surface| and not from |child_surfaces|. |
| 759 if (!damage_rect.IsEmpty()) | 765 if (!damage_rect.IsEmpty()) |
| 760 surface->RunWillDrawCallback(damage_rect); | 766 surface->RunWillDrawCallback(damage_rect); |
| 761 | 767 |
| 762 CHECK(debug_weak_this.get()); | 768 CHECK(debug_weak_this.get()); |
| 763 for (const auto& render_pass : frame.render_pass_list) { | 769 for (const auto& render_pass : frame.render_pass_list) { |
| 764 if (!render_pass->copy_requests.empty()) { | 770 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); |
| 765 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); | 771 if (!render_pass->copy_requests.empty()) |
| 766 copy_request_passes_.insert(remapped_pass_id); | 772 copy_request_passes_.insert(remapped_pass_id); |
| 767 } | 773 if (render_pass->force_render_surface) |
| 774 force_render_surface_passes_.insert(remapped_pass_id); |
| 768 } | 775 } |
| 769 | 776 |
| 770 referenced_surfaces_.erase(referenced_surfaces_.find(surface->surface_id())); | 777 referenced_surfaces_.erase(referenced_surfaces_.find(surface->surface_id())); |
| 771 if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video) | 778 if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video) |
| 772 result->may_contain_video = true; | 779 result->may_contain_video = true; |
| 773 return damage_rect; | 780 return damage_rect; |
| 774 } | 781 } |
| 775 | 782 |
| 776 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { | 783 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { |
| 777 // undrawn_surfaces are Surfaces that were identified by prewalk as being | 784 // undrawn_surfaces are Surfaces that were identified by prewalk as being |
| (...skipping 30 matching lines...) Expand all Loading... |
| 808 } | 815 } |
| 809 } | 816 } |
| 810 } else { | 817 } else { |
| 811 auto it = referenced_surfaces_.insert(surface_id).first; | 818 auto it = referenced_surfaces_.insert(surface_id).first; |
| 812 CopyPasses(frame, surface); | 819 CopyPasses(frame, surface); |
| 813 referenced_surfaces_.erase(it); | 820 referenced_surfaces_.erase(it); |
| 814 } | 821 } |
| 815 } | 822 } |
| 816 } | 823 } |
| 817 | 824 |
| 818 void SurfaceAggregator::PropagateCopyRequestPasses() { | 825 void SurfaceAggregator::PropagatePasses(base::flat_set<int>* passes) { |
| 819 std::vector<int> copy_requests_to_iterate(copy_request_passes_.begin(), | 826 std::vector<int> copy_requests_to_iterate(passes->begin(), passes->end()); |
| 820 copy_request_passes_.end()); | |
| 821 while (!copy_requests_to_iterate.empty()) { | 827 while (!copy_requests_to_iterate.empty()) { |
| 822 int first = copy_requests_to_iterate.back(); | 828 int first = copy_requests_to_iterate.back(); |
| 823 copy_requests_to_iterate.pop_back(); | 829 copy_requests_to_iterate.pop_back(); |
| 824 auto it = render_pass_dependencies_.find(first); | 830 auto it = render_pass_dependencies_.find(first); |
| 825 if (it == render_pass_dependencies_.end()) | 831 if (it == render_pass_dependencies_.end()) |
| 826 continue; | 832 continue; |
| 827 for (auto pass : it->second) { | 833 for (auto pass : it->second) { |
| 828 if (copy_request_passes_.insert(pass).second) { | 834 if (passes->insert(pass).second) { |
| 829 copy_requests_to_iterate.push_back(pass); | 835 copy_requests_to_iterate.push_back(pass); |
| 830 } | 836 } |
| 831 } | 837 } |
| 832 } | 838 } |
| 833 } | 839 } |
| 834 | 840 |
| 835 CompositorFrame SurfaceAggregator::Aggregate(const SurfaceId& surface_id) { | 841 CompositorFrame SurfaceAggregator::Aggregate(const SurfaceId& surface_id) { |
| 836 uma_stats_.Reset(); | 842 uma_stats_.Reset(); |
| 837 | 843 |
| 838 Surface* surface = manager_->GetSurfaceForId(surface_id); | 844 Surface* surface = manager_->GetSurfaceForId(surface_id); |
| 839 DCHECK(surface); | 845 DCHECK(surface); |
| 840 contained_surfaces_[surface_id] = surface->frame_index(); | 846 contained_surfaces_[surface_id] = surface->frame_index(); |
| 841 | 847 |
| 842 if (!surface->HasActiveFrame()) | 848 if (!surface->HasActiveFrame()) |
| 843 return CompositorFrame(); | 849 return CompositorFrame(); |
| 844 | 850 |
| 845 const CompositorFrame& root_surface_frame = surface->GetActiveFrame(); | 851 const CompositorFrame& root_surface_frame = surface->GetActiveFrame(); |
| 846 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); | 852 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); |
| 847 | 853 |
| 848 CompositorFrame frame; | 854 CompositorFrame frame; |
| 849 | 855 |
| 850 dest_resource_list_ = &frame.resource_list; | 856 dest_resource_list_ = &frame.resource_list; |
| 851 dest_pass_list_ = &frame.render_pass_list; | 857 dest_pass_list_ = &frame.render_pass_list; |
| 852 | 858 |
| 853 valid_surfaces_.clear(); | 859 valid_surfaces_.clear(); |
| 854 PrewalkResult prewalk_result; | 860 PrewalkResult prewalk_result; |
| 855 root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result); | 861 root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result); |
| 856 PropagateCopyRequestPasses(); | 862 PropagatePasses(©_request_passes_); |
| 863 PropagatePasses(&force_render_surface_passes_); |
| 857 has_copy_requests_ = !copy_request_passes_.empty(); | 864 has_copy_requests_ = !copy_request_passes_.empty(); |
| 865 has_force_render_surfaces_ = !force_render_surface_passes_.empty(); |
| 858 frame.metadata.may_contain_video = prewalk_result.may_contain_video; | 866 frame.metadata.may_contain_video = prewalk_result.may_contain_video; |
| 859 | 867 |
| 860 CopyUndrawnSurfaces(&prewalk_result); | 868 CopyUndrawnSurfaces(&prewalk_result); |
| 861 referenced_surfaces_.insert(surface_id); | 869 referenced_surfaces_.insert(surface_id); |
| 862 CopyPasses(root_surface_frame, surface); | 870 CopyPasses(root_surface_frame, surface); |
| 863 // CopyPasses may have mutated container, need to re-query to erase. | 871 // CopyPasses may have mutated container, need to re-query to erase. |
| 864 referenced_surfaces_.erase(referenced_surfaces_.find(surface_id)); | 872 referenced_surfaces_.erase(referenced_surfaces_.find(surface_id)); |
| 865 AddColorConversionPass(); | 873 AddColorConversionPass(); |
| 866 | 874 |
| 867 moved_pixel_passes_.clear(); | 875 moved_pixel_passes_.clear(); |
| 868 copy_request_passes_.clear(); | 876 copy_request_passes_.clear(); |
| 877 force_render_surface_passes_.clear(); |
| 869 render_pass_dependencies_.clear(); | 878 render_pass_dependencies_.clear(); |
| 870 | 879 |
| 871 // Remove all render pass mappings that weren't used in the current frame. | 880 // Remove all render pass mappings that weren't used in the current frame. |
| 872 for (auto it = render_pass_allocator_map_.begin(); | 881 for (auto it = render_pass_allocator_map_.begin(); |
| 873 it != render_pass_allocator_map_.end();) { | 882 it != render_pass_allocator_map_.end();) { |
| 874 if (it->second.in_use) { | 883 if (it->second.in_use) { |
| 875 it->second.in_use = false; | 884 it->second.in_use = false; |
| 876 it++; | 885 it++; |
| 877 } else { | 886 } else { |
| 878 it = render_pass_allocator_map_.erase(it); | 887 it = render_pass_allocator_map_.erase(it); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 } | 936 } |
| 928 | 937 |
| 929 void SurfaceAggregator::SetOutputColorSpace( | 938 void SurfaceAggregator::SetOutputColorSpace( |
| 930 const gfx::ColorSpace& blending_color_space, | 939 const gfx::ColorSpace& blending_color_space, |
| 931 const gfx::ColorSpace& output_color_space) { | 940 const gfx::ColorSpace& output_color_space) { |
| 932 blending_color_space_ = blending_color_space; | 941 blending_color_space_ = blending_color_space; |
| 933 output_color_space_ = output_color_space; | 942 output_color_space_ = output_color_space; |
| 934 } | 943 } |
| 935 | 944 |
| 936 } // namespace cc | 945 } // namespace cc |
| OLD | NEW |