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 |