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 |