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