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