Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(802)

Side by Side Diff: cc/surfaces/surface_aggregator.cc

Issue 1966073002: Reland: Correctly handle damage involving filters in SurfaceAggregator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/surfaces/surface_aggregator.h ('k') | cc/surfaces/surface_aggregator_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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, &copy_requests, &copy_pass->copy_requests); 232 MoveMatchingRequests(source.id, &copy_requests, &copy_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
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
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, &copy_requests, &copy_pass->copy_requests); 482 MoveMatchingRequests(source.id, &copy_requests, &copy_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
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
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
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
OLDNEW
« no previous file with comments | « cc/surfaces/surface_aggregator.h ('k') | cc/surfaces/surface_aggregator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698