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

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

Issue 1927413002: 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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
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, &copy_requests, &copy_pass->copy_requests); 224 MoveMatchingRequests(source.id, &copy_requests, &copy_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
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
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, &copy_requests, &copy_pass->copy_requests); 474 MoveMatchingRequests(source.id, &copy_requests, &copy_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
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
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
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
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