| 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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/containers/adapters.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "base/macros.h" | 14 #include "base/macros.h" |
| 14 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 15 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 16 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
| 17 #include "cc/base/math_util.h" | 18 #include "cc/base/math_util.h" |
| 18 #include "cc/output/compositor_frame.h" | 19 #include "cc/output/compositor_frame.h" |
| 19 #include "cc/output/delegated_frame_data.h" | 20 #include "cc/output/delegated_frame_data.h" |
| 20 #include "cc/quads/draw_quad.h" | 21 #include "cc/quads/draw_quad.h" |
| 21 #include "cc/quads/render_pass_draw_quad.h" | 22 #include "cc/quads/render_pass_draw_quad.h" |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 for (size_t j = 0; j < passes_to_copy; ++j) { | 210 for (size_t j = 0; j < passes_to_copy; ++j) { |
| 210 const RenderPass& source = *referenced_passes[j]; | 211 const RenderPass& source = *referenced_passes[j]; |
| 211 | 212 |
| 212 size_t sqs_size = source.shared_quad_state_list.size(); | 213 size_t sqs_size = source.shared_quad_state_list.size(); |
| 213 size_t dq_size = source.quad_list.size(); | 214 size_t dq_size = source.quad_list.size(); |
| 214 std::unique_ptr<RenderPass> copy_pass( | 215 std::unique_ptr<RenderPass> copy_pass( |
| 215 RenderPass::Create(sqs_size, dq_size)); | 216 RenderPass::Create(sqs_size, dq_size)); |
| 216 | 217 |
| 217 RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); | 218 RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); |
| 218 | 219 |
| 219 copy_pass->SetAll(remapped_pass_id, source.output_rect, gfx::Rect(), | 220 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, |
| 220 source.transform_to_root_target, | 221 source.transform_to_root_target, |
| 221 source.has_transparent_background); | 222 source.has_transparent_background); |
| 222 | 223 |
| 223 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | 224 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
| 224 | 225 |
| 225 // Contributing passes aggregated in to the pass list need to take the | 226 // Contributing passes aggregated in to the pass list need to take the |
| 226 // transform of the surface quad into account to update their transform to | 227 // transform of the surface quad into account to update their transform to |
| 227 // the root surface. | 228 // the root surface. |
| 228 copy_pass->transform_to_root_target.ConcatTransform( | 229 copy_pass->transform_to_root_target.ConcatTransform( |
| 229 surface_quad->shared_quad_state->quad_to_target_transform); | 230 surface_quad->shared_quad_state->quad_to_target_transform); |
| 230 copy_pass->transform_to_root_target.ConcatTransform(target_transform); | 231 copy_pass->transform_to_root_target.ConcatTransform(target_transform); |
| 231 copy_pass->transform_to_root_target.ConcatTransform( | 232 copy_pass->transform_to_root_target.ConcatTransform( |
| 232 dest_pass->transform_to_root_target); | 233 dest_pass->transform_to_root_target); |
| 233 | 234 |
| 234 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, | 235 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
| 235 child_to_parent_map, gfx::Transform(), ClipData(), | 236 child_to_parent_map, gfx::Transform(), ClipData(), |
| 236 copy_pass.get(), surface_id); | 237 copy_pass.get(), surface_id); |
| 237 | 238 |
| 239 if (!copy_request_passes_.count(remapped_pass_id) && |
| 240 !moved_pixel_passes_.count(remapped_pass_id)) { |
| 241 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); |
| 242 if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { |
| 243 gfx::Rect damage_rect_in_render_pass_space = |
| 244 MathUtil::ProjectEnclosingClippedRect(inverse_transform, |
| 245 root_damage_rect_); |
| 246 copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space); |
| 247 } |
| 248 } |
| 249 |
| 238 dest_pass_list_->push_back(std::move(copy_pass)); | 250 dest_pass_list_->push_back(std::move(copy_pass)); |
| 239 } | 251 } |
| 240 | 252 |
| 241 gfx::Transform surface_transform = | 253 gfx::Transform surface_transform = |
| 242 surface_quad->shared_quad_state->quad_to_target_transform; | 254 surface_quad->shared_quad_state->quad_to_target_transform; |
| 243 surface_transform.ConcatTransform(target_transform); | 255 surface_transform.ConcatTransform(target_transform); |
| 244 | 256 |
| 245 const RenderPass& last_pass = *render_pass_list.back(); | 257 const RenderPass& last_pass = *render_pass_list.back(); |
| 246 if (merge_pass) { | 258 if (merge_pass) { |
| 247 // TODO(jamesr): Clean up last pass special casing. | 259 // TODO(jamesr): Clean up last pass special casing. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 const SharedQuadStateList& source_shared_quad_state_list, | 348 const SharedQuadStateList& source_shared_quad_state_list, |
| 337 const ResourceProvider::ResourceIdMap& child_to_parent_map, | 349 const ResourceProvider::ResourceIdMap& child_to_parent_map, |
| 338 const gfx::Transform& target_transform, | 350 const gfx::Transform& target_transform, |
| 339 const ClipData& clip_rect, | 351 const ClipData& clip_rect, |
| 340 RenderPass* dest_pass, | 352 RenderPass* dest_pass, |
| 341 SurfaceId surface_id) { | 353 SurfaceId surface_id) { |
| 342 const SharedQuadState* last_copied_source_shared_quad_state = nullptr; | 354 const SharedQuadState* last_copied_source_shared_quad_state = nullptr; |
| 343 const SharedQuadState* dest_shared_quad_state = nullptr; | 355 const SharedQuadState* dest_shared_quad_state = nullptr; |
| 344 // If the current frame has copy requests then aggregate the entire | 356 // If the current frame has copy requests then aggregate the entire |
| 345 // thing, as otherwise parts of the copy requests may be ignored. | 357 // thing, as otherwise parts of the copy requests may be ignored. |
| 346 const bool ignore_undamaged = aggregate_only_damaged_ && !has_copy_requests_; | 358 const bool ignore_undamaged = aggregate_only_damaged_ && |
| 359 !has_copy_requests_ && |
| 360 !moved_pixel_passes_.count(dest_pass->id); |
| 347 // Damage rect in the quad space of the current shared quad state. | 361 // Damage rect in the quad space of the current shared quad state. |
| 348 // TODO(jbauman): This rect may contain unnecessary area if | 362 // TODO(jbauman): This rect may contain unnecessary area if |
| 349 // transform isn't axis-aligned. | 363 // transform isn't axis-aligned. |
| 350 gfx::Rect damage_rect_in_quad_space; | 364 gfx::Rect damage_rect_in_quad_space; |
| 351 bool damage_rect_in_quad_space_valid = false; | 365 bool damage_rect_in_quad_space_valid = false; |
| 352 | 366 |
| 353 #if DCHECK_IS_ON() | 367 #if DCHECK_IS_ON() |
| 354 // If quads have come in with SharedQuadState out of order, or when quads have | 368 // If quads have come in with SharedQuadState out of order, or when quads have |
| 355 // invalid SharedQuadState pointer, it should DCHECK. | 369 // invalid SharedQuadState pointer, it should DCHECK. |
| 356 SharedQuadStateList::ConstIterator sqs_iter = | 370 SharedQuadStateList::ConstIterator sqs_iter = |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 size_t sqs_size = source.shared_quad_state_list.size(); | 469 size_t sqs_size = source.shared_quad_state_list.size(); |
| 456 size_t dq_size = source.quad_list.size(); | 470 size_t dq_size = source.quad_list.size(); |
| 457 std::unique_ptr<RenderPass> copy_pass( | 471 std::unique_ptr<RenderPass> copy_pass( |
| 458 RenderPass::Create(sqs_size, dq_size)); | 472 RenderPass::Create(sqs_size, dq_size)); |
| 459 | 473 |
| 460 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | 474 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
| 461 | 475 |
| 462 RenderPassId remapped_pass_id = | 476 RenderPassId remapped_pass_id = |
| 463 RemapPassId(source.id, surface->surface_id()); | 477 RemapPassId(source.id, surface->surface_id()); |
| 464 | 478 |
| 465 copy_pass->SetAll(remapped_pass_id, source.output_rect, gfx::Rect(), | 479 copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, |
| 466 source.transform_to_root_target, | 480 source.transform_to_root_target, |
| 467 source.has_transparent_background); | 481 source.has_transparent_background); |
| 468 | 482 |
| 469 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, | 483 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
| 470 child_to_parent_map, gfx::Transform(), ClipData(), | 484 child_to_parent_map, gfx::Transform(), ClipData(), |
| 471 copy_pass.get(), surface->surface_id()); | 485 copy_pass.get(), surface->surface_id()); |
| 486 if (!copy_request_passes_.count(remapped_pass_id) && |
| 487 !moved_pixel_passes_.count(remapped_pass_id)) { |
| 488 gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); |
| 489 if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { |
| 490 gfx::Rect damage_rect_in_render_pass_space = |
| 491 MathUtil::ProjectEnclosingClippedRect(inverse_transform, |
| 492 root_damage_rect_); |
| 493 copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space); |
| 494 } |
| 495 } |
| 472 | 496 |
| 473 dest_pass_list_->push_back(std::move(copy_pass)); | 497 dest_pass_list_->push_back(std::move(copy_pass)); |
| 474 } | 498 } |
| 475 } | 499 } |
| 476 | 500 |
| 477 void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { | 501 void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { |
| 478 for (const auto& surface : previous_contained_surfaces_) { | 502 for (const auto& surface : previous_contained_surfaces_) { |
| 479 if (!contained_surfaces_.count(surface.first)) { | 503 if (!contained_surfaces_.count(surface.first)) { |
| 480 // Release resources of removed surface. | 504 // Release resources of removed surface. |
| 481 SurfaceToResourceChildIdMap::iterator it = | 505 SurfaceToResourceChildIdMap::iterator it = |
| 482 surface_id_to_resource_child_id_.find(surface.first); | 506 surface_id_to_resource_child_id_.find(surface.first); |
| 483 if (it != surface_id_to_resource_child_id_.end()) { | 507 if (it != surface_id_to_resource_child_id_.end()) { |
| 484 provider_->DestroyChild(it->second); | 508 provider_->DestroyChild(it->second); |
| 485 surface_id_to_resource_child_id_.erase(it); | 509 surface_id_to_resource_child_id_.erase(it); |
| 486 } | 510 } |
| 487 | 511 |
| 488 // Notify client of removed surface. | 512 // Notify client of removed surface. |
| 489 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); | 513 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); |
| 490 if (surface_ptr) { | 514 if (surface_ptr) { |
| 491 surface_ptr->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); | 515 surface_ptr->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); |
| 492 } | 516 } |
| 493 } | 517 } |
| 494 } | 518 } |
| 495 } | 519 } |
| 496 | 520 |
| 497 // Walk the Surface tree from surface_id. Validate the resources of the current | 521 // Walk the Surface tree from surface_id. Validate the resources of the current |
| 498 // surface and its descendants, check if there are any copy requests, and | 522 // surface and its descendants, check if there are any copy requests, and |
| 499 // return the combined damage rect. | 523 // return the combined damage rect. |
| 500 gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, | 524 gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, |
| 525 bool in_moved_pixel_pass, |
| 526 RenderPassId parent_pass, |
| 501 PrewalkResult* result) { | 527 PrewalkResult* result) { |
| 502 // This is for debugging a possible use after free. | 528 // This is for debugging a possible use after free. |
| 503 // TODO(jbauman): Remove this once we have enough information. | 529 // TODO(jbauman): Remove this once we have enough information. |
| 504 // http://crbug.com/560181 | 530 // http://crbug.com/560181 |
| 505 base::WeakPtr<SurfaceAggregator> debug_weak_this = weak_factory_.GetWeakPtr(); | 531 base::WeakPtr<SurfaceAggregator> debug_weak_this = weak_factory_.GetWeakPtr(); |
| 506 | 532 |
| 507 if (referenced_surfaces_.count(surface_id)) | 533 if (referenced_surfaces_.count(surface_id)) |
| 508 return gfx::Rect(); | 534 return gfx::Rect(); |
| 509 Surface* surface = manager_->GetSurfaceForId(surface_id); | 535 Surface* surface = manager_->GetSurfaceForId(surface_id); |
| 510 if (!surface) { | 536 if (!surface) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 532 ResourceProvider::ResourceIdSet referenced_resources; | 558 ResourceProvider::ResourceIdSet referenced_resources; |
| 533 size_t reserve_size = frame_data->resource_list.size(); | 559 size_t reserve_size = frame_data->resource_list.size(); |
| 534 referenced_resources.reserve(reserve_size); | 560 referenced_resources.reserve(reserve_size); |
| 535 | 561 |
| 536 bool invalid_frame = false; | 562 bool invalid_frame = false; |
| 537 ResourceProvider::ResourceIdMap empty_map; | 563 ResourceProvider::ResourceIdMap empty_map; |
| 538 const ResourceProvider::ResourceIdMap& child_to_parent_map = | 564 const ResourceProvider::ResourceIdMap& child_to_parent_map = |
| 539 provider_ ? provider_->GetChildToParentMap(child_id) : empty_map; | 565 provider_ ? provider_->GetChildToParentMap(child_id) : empty_map; |
| 540 | 566 |
| 541 CHECK(debug_weak_this.get()); | 567 CHECK(debug_weak_this.get()); |
| 542 // Each pair in the vector is a child surface and the transform from its | 568 if (!frame_data->render_pass_list.empty()) { |
| 543 // target to the root target of this surface. | 569 RenderPassId remapped_pass_id = |
| 544 std::vector<std::pair<SurfaceId, gfx::Transform>> child_surfaces; | 570 RemapPassId(frame_data->render_pass_list.back()->id, surface_id); |
| 545 for (const auto& render_pass : frame_data->render_pass_list) { | 571 if (in_moved_pixel_pass) |
| 572 moved_pixel_passes_.insert(remapped_pass_id); |
| 573 if (parent_pass.IsValid()) |
| 574 render_pass_dependencies_[parent_pass].insert(remapped_pass_id); |
| 575 } |
| 576 |
| 577 struct SurfaceInfo { |
| 578 SurfaceId id; |
| 579 bool has_moved_pixels; |
| 580 RenderPassId parent_pass; |
| 581 gfx::Transform target_to_surface_transform; |
| 582 }; |
| 583 std::vector<SurfaceInfo> child_surfaces; |
| 584 |
| 585 for (const auto& render_pass : base::Reversed(frame_data->render_pass_list)) { |
| 586 RenderPassId remapped_pass_id = RemapPassId(render_pass->id, surface_id); |
| 587 bool in_moved_pixel_pass = !!moved_pixel_passes_.count(remapped_pass_id); |
| 546 for (const auto& quad : render_pass->quad_list) { | 588 for (const auto& quad : render_pass->quad_list) { |
| 547 if (quad->material == DrawQuad::SURFACE_CONTENT) { | 589 if (quad->material == DrawQuad::SURFACE_CONTENT) { |
| 548 const SurfaceDrawQuad* surface_quad = | 590 const SurfaceDrawQuad* surface_quad = |
| 549 SurfaceDrawQuad::MaterialCast(quad); | 591 SurfaceDrawQuad::MaterialCast(quad); |
| 550 gfx::Transform target_to_surface_transform( | 592 gfx::Transform target_to_surface_transform( |
| 551 render_pass->transform_to_root_target, | 593 render_pass->transform_to_root_target, |
| 552 surface_quad->shared_quad_state->quad_to_target_transform); | 594 surface_quad->shared_quad_state->quad_to_target_transform); |
| 553 child_surfaces.push_back(std::make_pair(surface_quad->surface_id, | 595 child_surfaces.push_back( |
| 554 target_to_surface_transform)); | 596 SurfaceInfo{surface_quad->surface_id, in_moved_pixel_pass, |
| 597 remapped_pass_id, target_to_surface_transform}); |
| 598 } else if (quad->material == DrawQuad::RENDER_PASS) { |
| 599 const RenderPassDrawQuad* render_pass_quad = |
| 600 RenderPassDrawQuad::MaterialCast(quad); |
| 601 if (in_moved_pixel_pass || |
| 602 render_pass_quad->filters.HasFilterThatMovesPixels()) { |
| 603 moved_pixel_passes_.insert( |
| 604 RemapPassId(render_pass_quad->render_pass_id, surface_id)); |
| 605 } |
| 606 if (render_pass_quad->background_filters.HasFilterThatMovesPixels()) { |
| 607 in_moved_pixel_pass = true; |
| 608 } |
| 609 render_pass_dependencies_[remapped_pass_id].insert( |
| 610 RemapPassId(render_pass_quad->render_pass_id, surface_id)); |
| 555 } | 611 } |
| 556 | 612 |
| 557 if (!provider_) | 613 if (!provider_) |
| 558 continue; | 614 continue; |
| 559 for (ResourceId resource_id : quad->resources) { | 615 for (ResourceId resource_id : quad->resources) { |
| 560 if (!child_to_parent_map.count(resource_id)) { | 616 if (!child_to_parent_map.count(resource_id)) { |
| 561 invalid_frame = true; | 617 invalid_frame = true; |
| 562 break; | 618 break; |
| 563 } | 619 } |
| 564 referenced_resources.insert(resource_id); | 620 referenced_resources.insert(resource_id); |
| 565 } | 621 } |
| 566 } | 622 } |
| 567 } | 623 } |
| 568 | 624 |
| 569 if (invalid_frame) | 625 if (invalid_frame) |
| 570 return gfx::Rect(); | 626 return gfx::Rect(); |
| 571 CHECK(debug_weak_this.get()); | 627 CHECK(debug_weak_this.get()); |
| 572 valid_surfaces_.insert(surface->surface_id()); | 628 valid_surfaces_.insert(surface->surface_id()); |
| 573 | 629 |
| 574 if (provider_) | 630 if (provider_) |
| 575 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); | 631 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); |
| 576 CHECK(debug_weak_this.get()); | 632 CHECK(debug_weak_this.get()); |
| 577 | 633 |
| 578 gfx::Rect damage_rect; | 634 gfx::Rect damage_rect; |
| 635 gfx::Rect full_damage; |
| 579 if (!frame_data->render_pass_list.empty()) { | 636 if (!frame_data->render_pass_list.empty()) { |
| 580 RenderPass* last_pass = frame_data->render_pass_list.back().get(); | 637 RenderPass* last_pass = frame_data->render_pass_list.back().get(); |
| 638 full_damage = last_pass->output_rect; |
| 581 damage_rect = | 639 damage_rect = |
| 582 DamageRectForSurface(surface, *last_pass, last_pass->output_rect); | 640 DamageRectForSurface(surface, *last_pass, last_pass->output_rect); |
| 583 } | 641 } |
| 584 | 642 |
| 585 // Avoid infinite recursion by adding current surface to | 643 // Avoid infinite recursion by adding current surface to |
| 586 // referenced_surfaces_. | 644 // referenced_surfaces_. |
| 587 SurfaceSet::iterator it = | 645 SurfaceSet::iterator it = |
| 588 referenced_surfaces_.insert(surface->surface_id()).first; | 646 referenced_surfaces_.insert(surface->surface_id()).first; |
| 589 for (const auto& surface_info : child_surfaces) { | 647 for (const auto& surface_info : child_surfaces) { |
| 590 gfx::Rect surface_damage = PrewalkTree(surface_info.first, result); | 648 gfx::Rect surface_damage = |
| 591 damage_rect.Union( | 649 PrewalkTree(surface_info.id, surface_info.has_moved_pixels, |
| 592 MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage)); | 650 surface_info.parent_pass, result); |
| 651 if (surface_damage.IsEmpty()) |
| 652 continue; |
| 653 if (surface_info.has_moved_pixels) { |
| 654 // Areas outside the rect hit by target_to_surface_transform may be |
| 655 // modified if there is a filter that moves pixels. |
| 656 damage_rect = full_damage; |
| 657 continue; |
| 658 } |
| 659 |
| 660 damage_rect.Union(MathUtil::MapEnclosingClippedRect( |
| 661 surface_info.target_to_surface_transform, surface_damage)); |
| 593 } | 662 } |
| 594 | 663 |
| 595 CHECK(debug_weak_this.get()); | 664 CHECK(debug_weak_this.get()); |
| 596 for (const auto& surface_id : surface_frame->metadata.referenced_surfaces) { | 665 for (const auto& surface_id : surface_frame->metadata.referenced_surfaces) { |
| 597 if (!contained_surfaces_.count(surface_id)) { | 666 if (!contained_surfaces_.count(surface_id)) { |
| 598 result->undrawn_surfaces.insert(surface_id); | 667 result->undrawn_surfaces.insert(surface_id); |
| 599 PrewalkTree(surface_id, result); | 668 PrewalkTree(surface_id, false, RenderPassId(), result); |
| 600 } | 669 } |
| 601 } | 670 } |
| 602 | 671 |
| 603 CHECK(debug_weak_this.get()); | 672 CHECK(debug_weak_this.get()); |
| 604 if (surface->factory()) | 673 if (surface->factory()) |
| 605 surface->factory()->WillDrawSurface(surface->surface_id(), damage_rect); | 674 surface->factory()->WillDrawSurface(surface->surface_id(), damage_rect); |
| 606 | 675 |
| 607 CHECK(debug_weak_this.get()); | 676 CHECK(debug_weak_this.get()); |
| 608 for (const auto& render_pass : frame_data->render_pass_list) | 677 for (const auto& render_pass : frame_data->render_pass_list) { |
| 609 result->has_copy_requests |= !render_pass->copy_requests.empty(); | 678 if (!render_pass->copy_requests.empty()) { |
| 679 RenderPassId remapped_pass_id = RemapPassId(render_pass->id, surface_id); |
| 680 copy_request_passes_.insert(remapped_pass_id); |
| 681 } |
| 682 } |
| 610 | 683 |
| 611 referenced_surfaces_.erase(it); | 684 referenced_surfaces_.erase(it); |
| 612 return damage_rect; | 685 return damage_rect; |
| 613 } | 686 } |
| 614 | 687 |
| 615 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { | 688 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { |
| 616 // undrawn_surfaces are Surfaces that were identified by prewalk as being | 689 // undrawn_surfaces are Surfaces that were identified by prewalk as being |
| 617 // referenced by a drawn Surface, but aren't contained in a SurfaceDrawQuad. | 690 // referenced by a drawn Surface, but aren't contained in a SurfaceDrawQuad. |
| 618 // They need to be iterated over to ensure that any copy requests on them | 691 // They need to be iterated over to ensure that any copy requests on them |
| 619 // (or on Surfaces they reference) are executed. | 692 // (or on Surfaces they reference) are executed. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 648 } | 721 } |
| 649 } | 722 } |
| 650 } else { | 723 } else { |
| 651 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 724 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
| 652 CopyPasses(surface_frame->delegated_frame_data.get(), surface); | 725 CopyPasses(surface_frame->delegated_frame_data.get(), surface); |
| 653 referenced_surfaces_.erase(it); | 726 referenced_surfaces_.erase(it); |
| 654 } | 727 } |
| 655 } | 728 } |
| 656 } | 729 } |
| 657 | 730 |
| 731 void SurfaceAggregator::PropagateCopyRequestPasses() { |
| 732 std::vector<RenderPassId> copy_requests_to_iterate( |
| 733 copy_request_passes_.begin(), copy_request_passes_.end()); |
| 734 while (!copy_requests_to_iterate.empty()) { |
| 735 RenderPassId first = copy_requests_to_iterate.back(); |
| 736 copy_requests_to_iterate.pop_back(); |
| 737 auto it = render_pass_dependencies_.find(first); |
| 738 if (it == render_pass_dependencies_.end()) |
| 739 continue; |
| 740 for (auto pass : it->second) { |
| 741 if (copy_request_passes_.insert(pass).second) { |
| 742 copy_requests_to_iterate.push_back(pass); |
| 743 } |
| 744 } |
| 745 } |
| 746 } |
| 747 |
| 658 std::unique_ptr<CompositorFrame> SurfaceAggregator::Aggregate( | 748 std::unique_ptr<CompositorFrame> SurfaceAggregator::Aggregate( |
| 659 SurfaceId surface_id) { | 749 SurfaceId surface_id) { |
| 660 Surface* surface = manager_->GetSurfaceForId(surface_id); | 750 Surface* surface = manager_->GetSurfaceForId(surface_id); |
| 661 DCHECK(surface); | 751 DCHECK(surface); |
| 662 contained_surfaces_[surface_id] = surface->frame_index(); | 752 contained_surfaces_[surface_id] = surface->frame_index(); |
| 663 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); | 753 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); |
| 664 if (!root_surface_frame) | 754 if (!root_surface_frame) |
| 665 return nullptr; | 755 return nullptr; |
| 666 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); | 756 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); |
| 667 | 757 |
| 668 std::unique_ptr<CompositorFrame> frame(new CompositorFrame); | 758 std::unique_ptr<CompositorFrame> frame(new CompositorFrame); |
| 669 frame->delegated_frame_data = base::WrapUnique(new DelegatedFrameData); | 759 frame->delegated_frame_data = base::WrapUnique(new DelegatedFrameData); |
| 670 | 760 |
| 671 DCHECK(root_surface_frame->delegated_frame_data); | 761 DCHECK(root_surface_frame->delegated_frame_data); |
| 672 | 762 |
| 673 dest_resource_list_ = &frame->delegated_frame_data->resource_list; | 763 dest_resource_list_ = &frame->delegated_frame_data->resource_list; |
| 674 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; | 764 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; |
| 675 | 765 |
| 676 valid_surfaces_.clear(); | 766 valid_surfaces_.clear(); |
| 677 PrewalkResult prewalk_result; | 767 PrewalkResult prewalk_result; |
| 678 root_damage_rect_ = PrewalkTree(surface_id, &prewalk_result); | 768 root_damage_rect_ = |
| 679 has_copy_requests_ = prewalk_result.has_copy_requests; | 769 PrewalkTree(surface_id, false, RenderPassId(), &prewalk_result); |
| 770 PropagateCopyRequestPasses(); |
| 771 has_copy_requests_ = !copy_request_passes_.empty(); |
| 680 | 772 |
| 681 CopyUndrawnSurfaces(&prewalk_result); | 773 CopyUndrawnSurfaces(&prewalk_result); |
| 682 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 774 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
| 683 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); | 775 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); |
| 684 referenced_surfaces_.erase(it); | 776 referenced_surfaces_.erase(it); |
| 685 | 777 |
| 778 moved_pixel_passes_.clear(); |
| 779 copy_request_passes_.clear(); |
| 780 render_pass_dependencies_.clear(); |
| 781 |
| 686 DCHECK(referenced_surfaces_.empty()); | 782 DCHECK(referenced_surfaces_.empty()); |
| 687 | 783 |
| 688 if (dest_pass_list_->empty()) | 784 if (dest_pass_list_->empty()) |
| 689 return nullptr; | 785 return nullptr; |
| 690 dest_pass_list_->back()->damage_rect = root_damage_rect_; | |
| 691 | 786 |
| 692 dest_pass_list_ = NULL; | 787 dest_pass_list_ = NULL; |
| 693 ProcessAddedAndRemovedSurfaces(); | 788 ProcessAddedAndRemovedSurfaces(); |
| 694 contained_surfaces_.swap(previous_contained_surfaces_); | 789 contained_surfaces_.swap(previous_contained_surfaces_); |
| 695 contained_surfaces_.clear(); | 790 contained_surfaces_.clear(); |
| 696 | 791 |
| 697 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); | 792 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); |
| 698 it != previous_contained_surfaces_.end(); | 793 it != previous_contained_surfaces_.end(); |
| 699 ++it) { | 794 ++it) { |
| 700 Surface* surface = manager_->GetSurfaceForId(it->first); | 795 Surface* surface = manager_->GetSurfaceForId(it->first); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 719 | 814 |
| 720 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { | 815 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { |
| 721 auto it = previous_contained_surfaces_.find(surface_id); | 816 auto it = previous_contained_surfaces_.find(surface_id); |
| 722 if (it == previous_contained_surfaces_.end()) | 817 if (it == previous_contained_surfaces_.end()) |
| 723 return; | 818 return; |
| 724 // Set the last drawn index as 0 to ensure full damage next time it's drawn. | 819 // Set the last drawn index as 0 to ensure full damage next time it's drawn. |
| 725 it->second = 0; | 820 it->second = 0; |
| 726 } | 821 } |
| 727 | 822 |
| 728 } // namespace cc | 823 } // namespace cc |
| OLD | NEW |