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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 const RenderPass& source = *referenced_passes[j]; | 200 const RenderPass& source = *referenced_passes[j]; |
201 | 201 |
202 size_t sqs_size = source.shared_quad_state_list.size(); | 202 size_t sqs_size = source.shared_quad_state_list.size(); |
203 size_t dq_size = source.quad_list.size(); | 203 size_t dq_size = source.quad_list.size(); |
204 std::unique_ptr<RenderPass> copy_pass( | 204 std::unique_ptr<RenderPass> copy_pass( |
205 RenderPass::Create(sqs_size, dq_size)); | 205 RenderPass::Create(sqs_size, dq_size)); |
206 | 206 |
207 int remapped_pass_id = RemapPassId(source.id, surface_id); | 207 int remapped_pass_id = RemapPassId(source.id, surface_id); |
208 | 208 |
209 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, | 209 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, |
210 source.transform_to_root_target, | 210 source.transform_to_root_target, source.filters, |
| 211 source.background_filters, |
211 source.has_transparent_background); | 212 source.has_transparent_background); |
212 | 213 |
213 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | 214 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
214 | 215 |
215 // Contributing passes aggregated in to the pass list need to take the | 216 // Contributing passes aggregated in to the pass list need to take the |
216 // transform of the surface quad into account to update their transform to | 217 // transform of the surface quad into account to update their transform to |
217 // the root surface. | 218 // the root surface. |
218 copy_pass->transform_to_root_target.ConcatTransform( | 219 copy_pass->transform_to_root_target.ConcatTransform( |
219 surface_quad->shared_quad_state->quad_to_target_transform); | 220 surface_quad->shared_quad_state->quad_to_target_transform); |
220 copy_pass->transform_to_root_target.ConcatTransform(target_transform); | 221 copy_pass->transform_to_root_target.ConcatTransform(target_transform); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 int remapped_pass_id = RemapPassId(last_pass.id, surface_id); | 270 int remapped_pass_id = RemapPassId(last_pass.id, surface_id); |
270 | 271 |
271 SharedQuadState* shared_quad_state = | 272 SharedQuadState* shared_quad_state = |
272 CopySharedQuadState(surface_quad->shared_quad_state, target_transform, | 273 CopySharedQuadState(surface_quad->shared_quad_state, target_transform, |
273 clip_rect, dest_pass); | 274 clip_rect, dest_pass); |
274 | 275 |
275 RenderPassDrawQuad* quad = | 276 RenderPassDrawQuad* quad = |
276 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 277 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); |
277 quad->SetNew(shared_quad_state, surface_quad->rect, | 278 quad->SetNew(shared_quad_state, surface_quad->rect, |
278 surface_quad->visible_rect, remapped_pass_id, 0, | 279 surface_quad->visible_rect, remapped_pass_id, 0, |
279 gfx::Vector2dF(), gfx::Size(), FilterOperations(), | 280 gfx::Vector2dF(), gfx::Size(), gfx::Vector2dF(), |
280 gfx::Vector2dF(), gfx::PointF(), FilterOperations()); | 281 gfx::PointF()); |
281 } | 282 } |
282 | 283 |
283 referenced_surfaces_.erase(it); | 284 referenced_surfaces_.erase(it); |
284 } | 285 } |
285 | 286 |
286 SharedQuadState* SurfaceAggregator::CopySharedQuadState( | 287 SharedQuadState* SurfaceAggregator::CopySharedQuadState( |
287 const SharedQuadState* source_sqs, | 288 const SharedQuadState* source_sqs, |
288 const gfx::Transform& target_transform, | 289 const gfx::Transform& target_transform, |
289 const ClipData& clip_rect, | 290 const ClipData& clip_rect, |
290 RenderPass* dest_render_pass) { | 291 RenderPass* dest_render_pass) { |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 size_t sqs_size = source.shared_quad_state_list.size(); | 467 size_t sqs_size = source.shared_quad_state_list.size(); |
467 size_t dq_size = source.quad_list.size(); | 468 size_t dq_size = source.quad_list.size(); |
468 std::unique_ptr<RenderPass> copy_pass( | 469 std::unique_ptr<RenderPass> copy_pass( |
469 RenderPass::Create(sqs_size, dq_size)); | 470 RenderPass::Create(sqs_size, dq_size)); |
470 | 471 |
471 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | 472 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
472 | 473 |
473 int remapped_pass_id = RemapPassId(source.id, surface->surface_id()); | 474 int remapped_pass_id = RemapPassId(source.id, surface->surface_id()); |
474 | 475 |
475 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, | 476 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, |
476 source.transform_to_root_target, | 477 source.transform_to_root_target, source.filters, |
| 478 source.background_filters, |
477 source.has_transparent_background); | 479 source.has_transparent_background); |
478 | 480 |
479 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, | 481 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
480 child_to_parent_map, gfx::Transform(), ClipData(), | 482 child_to_parent_map, gfx::Transform(), ClipData(), |
481 copy_pass.get(), surface->surface_id()); | 483 copy_pass.get(), surface->surface_id()); |
482 if (!copy_request_passes_.count(remapped_pass_id) && | 484 if (!copy_request_passes_.count(remapped_pass_id) && |
483 !moved_pixel_passes_.count(remapped_pass_id)) { | 485 !moved_pixel_passes_.count(remapped_pass_id)) { |
484 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); | 486 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); |
485 if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { | 487 if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { |
486 gfx::Rect damage_rect_in_render_pass_space = | 488 gfx::Rect damage_rect_in_render_pass_space = |
(...skipping 24 matching lines...) Expand all Loading... |
511 surface_ptr->RunDrawCallbacks(); | 513 surface_ptr->RunDrawCallbacks(); |
512 } | 514 } |
513 } | 515 } |
514 } | 516 } |
515 } | 517 } |
516 | 518 |
517 // Walk the Surface tree from surface_id. Validate the resources of the current | 519 // Walk the Surface tree from surface_id. Validate the resources of the current |
518 // surface and its descendants, check if there are any copy requests, and | 520 // surface and its descendants, check if there are any copy requests, and |
519 // return the combined damage rect. | 521 // return the combined damage rect. |
520 gfx::Rect SurfaceAggregator::PrewalkTree(const SurfaceId& surface_id, | 522 gfx::Rect SurfaceAggregator::PrewalkTree(const SurfaceId& surface_id, |
521 bool in_moved_pixel_pass, | 523 bool in_moved_pixel_surface, |
522 int parent_pass_id, | 524 int parent_pass_id, |
523 PrewalkResult* result) { | 525 PrewalkResult* result) { |
524 // This is for debugging a possible use after free. | 526 // This is for debugging a possible use after free. |
525 // TODO(jbauman): Remove this once we have enough information. | 527 // TODO(jbauman): Remove this once we have enough information. |
526 // http://crbug.com/560181 | 528 // http://crbug.com/560181 |
527 base::WeakPtr<SurfaceAggregator> debug_weak_this = weak_factory_.GetWeakPtr(); | 529 base::WeakPtr<SurfaceAggregator> debug_weak_this = weak_factory_.GetWeakPtr(); |
528 | 530 |
529 if (referenced_surfaces_.count(surface_id)) | 531 if (referenced_surfaces_.count(surface_id)) |
530 return gfx::Rect(); | 532 return gfx::Rect(); |
531 Surface* surface = manager_->GetSurfaceForId(surface_id); | 533 Surface* surface = manager_->GetSurfaceForId(surface_id); |
(...skipping 21 matching lines...) Expand all Loading... |
553 | 555 |
554 bool invalid_frame = false; | 556 bool invalid_frame = false; |
555 ResourceProvider::ResourceIdMap empty_map; | 557 ResourceProvider::ResourceIdMap empty_map; |
556 const ResourceProvider::ResourceIdMap& child_to_parent_map = | 558 const ResourceProvider::ResourceIdMap& child_to_parent_map = |
557 provider_ ? provider_->GetChildToParentMap(child_id) : empty_map; | 559 provider_ ? provider_->GetChildToParentMap(child_id) : empty_map; |
558 | 560 |
559 CHECK(debug_weak_this.get()); | 561 CHECK(debug_weak_this.get()); |
560 if (!frame.render_pass_list.empty()) { | 562 if (!frame.render_pass_list.empty()) { |
561 int remapped_pass_id = | 563 int remapped_pass_id = |
562 RemapPassId(frame.render_pass_list.back()->id, surface_id); | 564 RemapPassId(frame.render_pass_list.back()->id, surface_id); |
563 if (in_moved_pixel_pass) | 565 if (in_moved_pixel_surface) |
564 moved_pixel_passes_.insert(remapped_pass_id); | 566 moved_pixel_passes_.insert(remapped_pass_id); |
565 if (parent_pass_id) | 567 if (parent_pass_id) |
566 render_pass_dependencies_[parent_pass_id].insert(remapped_pass_id); | 568 render_pass_dependencies_[parent_pass_id].insert(remapped_pass_id); |
567 } | 569 } |
568 | 570 |
569 struct SurfaceInfo { | 571 struct SurfaceInfo { |
| 572 SurfaceInfo(const SurfaceId& id, |
| 573 bool has_moved_pixels, |
| 574 int parent_pass_id, |
| 575 const gfx::Transform& target_to_surface_transform) |
| 576 : id(id), |
| 577 has_moved_pixels(has_moved_pixels), |
| 578 parent_pass_id(parent_pass_id), |
| 579 target_to_surface_transform(target_to_surface_transform) {} |
| 580 |
570 SurfaceId id; | 581 SurfaceId id; |
571 bool has_moved_pixels; | 582 bool has_moved_pixels; |
572 int parent_pass_id; | 583 int parent_pass_id; |
573 gfx::Transform target_to_surface_transform; | 584 gfx::Transform target_to_surface_transform; |
574 }; | 585 }; |
575 std::vector<SurfaceInfo> child_surfaces; | 586 std::vector<SurfaceInfo> child_surfaces; |
576 | 587 |
| 588 std::unordered_set<int> pixel_moving_background_filter_passes; |
| 589 for (const auto& render_pass : frame.render_pass_list) { |
| 590 if (render_pass->background_filters.HasFilterThatMovesPixels()) { |
| 591 pixel_moving_background_filter_passes.insert( |
| 592 RemapPassId(render_pass->id, surface_id)); |
| 593 } |
| 594 } |
| 595 |
577 for (const auto& render_pass : base::Reversed(frame.render_pass_list)) { | 596 for (const auto& render_pass : base::Reversed(frame.render_pass_list)) { |
578 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); | 597 int remapped_pass_id = RemapPassId(render_pass->id, surface_id); |
579 bool in_moved_pixel_pass = !!moved_pixel_passes_.count(remapped_pass_id); | 598 bool has_pixel_moving_filter = |
| 599 render_pass->filters.HasFilterThatMovesPixels(); |
| 600 if (has_pixel_moving_filter) |
| 601 moved_pixel_passes_.insert(remapped_pass_id); |
| 602 bool in_moved_pixel_pass = has_pixel_moving_filter || |
| 603 !!moved_pixel_passes_.count(remapped_pass_id); |
580 for (auto* quad : render_pass->quad_list) { | 604 for (auto* quad : render_pass->quad_list) { |
581 if (quad->material == DrawQuad::SURFACE_CONTENT) { | 605 if (quad->material == DrawQuad::SURFACE_CONTENT) { |
582 const SurfaceDrawQuad* surface_quad = | 606 const SurfaceDrawQuad* surface_quad = |
583 SurfaceDrawQuad::MaterialCast(quad); | 607 SurfaceDrawQuad::MaterialCast(quad); |
584 gfx::Transform target_to_surface_transform( | 608 gfx::Transform target_to_surface_transform( |
585 render_pass->transform_to_root_target, | 609 render_pass->transform_to_root_target, |
586 surface_quad->shared_quad_state->quad_to_target_transform); | 610 surface_quad->shared_quad_state->quad_to_target_transform); |
587 child_surfaces.push_back( | 611 child_surfaces.emplace_back(surface_quad->surface_id, |
588 SurfaceInfo{surface_quad->surface_id, in_moved_pixel_pass, | 612 in_moved_pixel_pass, remapped_pass_id, |
589 remapped_pass_id, target_to_surface_transform}); | 613 target_to_surface_transform); |
590 } else if (quad->material == DrawQuad::RENDER_PASS) { | 614 } else if (quad->material == DrawQuad::RENDER_PASS) { |
591 const RenderPassDrawQuad* render_pass_quad = | 615 const RenderPassDrawQuad* render_pass_quad = |
592 RenderPassDrawQuad::MaterialCast(quad); | 616 RenderPassDrawQuad::MaterialCast(quad); |
593 if (in_moved_pixel_pass || | 617 if (in_moved_pixel_pass) { |
594 render_pass_quad->filters.HasFilterThatMovesPixels()) { | |
595 moved_pixel_passes_.insert( | 618 moved_pixel_passes_.insert( |
596 RemapPassId(render_pass_quad->render_pass_id, surface_id)); | 619 RemapPassId(render_pass_quad->render_pass_id, surface_id)); |
597 } | 620 } |
598 if (render_pass_quad->background_filters.HasFilterThatMovesPixels()) { | 621 if (pixel_moving_background_filter_passes.count( |
| 622 render_pass_quad->render_pass_id)) { |
599 in_moved_pixel_pass = true; | 623 in_moved_pixel_pass = true; |
600 } | 624 } |
601 render_pass_dependencies_[remapped_pass_id].insert( | 625 render_pass_dependencies_[remapped_pass_id].insert( |
602 RemapPassId(render_pass_quad->render_pass_id, surface_id)); | 626 RemapPassId(render_pass_quad->render_pass_id, surface_id)); |
603 } | 627 } |
604 | 628 |
605 if (!provider_) | 629 if (!provider_) |
606 continue; | 630 continue; |
607 for (ResourceId resource_id : quad->resources) { | 631 for (ResourceId resource_id : quad->resources) { |
608 if (!child_to_parent_map.count(resource_id)) { | 632 if (!child_to_parent_map.count(resource_id)) { |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 | 842 |
819 void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) { | 843 void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) { |
820 auto it = previous_contained_surfaces_.find(surface_id); | 844 auto it = previous_contained_surfaces_.find(surface_id); |
821 if (it == previous_contained_surfaces_.end()) | 845 if (it == previous_contained_surfaces_.end()) |
822 return; | 846 return; |
823 // Set the last drawn index as 0 to ensure full damage next time it's drawn. | 847 // Set the last drawn index as 0 to ensure full damage next time it's drawn. |
824 it->second = 0; | 848 it->second = 0; |
825 } | 849 } |
826 | 850 |
827 } // namespace cc | 851 } // namespace cc |
OLD | NEW |