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

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

Issue 1430363002: List all child surfaces (including occluded) in CompositorFrame (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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 <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 aggregate_only_damaged_(aggregate_only_damaged) { 51 aggregate_only_damaged_(aggregate_only_damaged) {
52 DCHECK(manager_); 52 DCHECK(manager_);
53 } 53 }
54 54
55 SurfaceAggregator::~SurfaceAggregator() { 55 SurfaceAggregator::~SurfaceAggregator() {
56 // Notify client of all surfaces being removed. 56 // Notify client of all surfaces being removed.
57 contained_surfaces_.clear(); 57 contained_surfaces_.clear();
58 ProcessAddedAndRemovedSurfaces(); 58 ProcessAddedAndRemovedSurfaces();
59 } 59 }
60 60
61 SurfaceAggregator::PrewalkResult::PrewalkResult() {}
62
63 SurfaceAggregator::PrewalkResult::~PrewalkResult() {}
64
61 // Create a clip rect for an aggregated quad from the original clip rect and 65 // Create a clip rect for an aggregated quad from the original clip rect and
62 // the clip rect from the surface it's on. 66 // the clip rect from the surface it's on.
63 SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect( 67 SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect(
64 const ClipData& surface_clip, 68 const ClipData& surface_clip,
65 const ClipData& quad_clip, 69 const ClipData& quad_clip,
66 const gfx::Transform& target_transform) { 70 const gfx::Transform& target_transform) {
67 ClipData out_clip; 71 ClipData out_clip;
68 if (surface_clip.is_clipped) 72 if (surface_clip.is_clipped)
69 out_clip = surface_clip; 73 out_clip = surface_clip;
70 74
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); 488 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first);
485 if (surface_ptr) 489 if (surface_ptr)
486 client_->AddSurface(surface_ptr); 490 client_->AddSurface(surface_ptr);
487 } 491 }
488 } 492 }
489 } 493 }
490 494
491 // Walk the Surface tree from surface_id. Validate the resources of the current 495 // Walk the Surface tree from surface_id. Validate the resources of the current
492 // surface and its descendants, check if there are any copy requests, and 496 // surface and its descendants, check if there are any copy requests, and
493 // return the combined damage rect. 497 // return the combined damage rect.
494 gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id) { 498 gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id,
499 PrewalkResult* result) {
495 if (referenced_surfaces_.count(surface_id)) 500 if (referenced_surfaces_.count(surface_id))
496 return gfx::Rect(); 501 return gfx::Rect();
497 Surface* surface = manager_->GetSurfaceForId(surface_id); 502 Surface* surface = manager_->GetSurfaceForId(surface_id);
498 if (!surface) { 503 if (!surface) {
499 contained_surfaces_[surface_id] = 0; 504 contained_surfaces_[surface_id] = 0;
500 return gfx::Rect(); 505 return gfx::Rect();
501 } 506 }
502 contained_surfaces_[surface_id] = surface->frame_index(); 507 contained_surfaces_[surface_id] = surface->frame_index();
503 const CompositorFrame* surface_frame = surface->GetEligibleFrame(); 508 const CompositorFrame* surface_frame = surface->GetEligibleFrame();
504 if (!surface_frame) 509 if (!surface_frame)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 } 567 }
563 568
564 if (invalid_frame) 569 if (invalid_frame)
565 return gfx::Rect(); 570 return gfx::Rect();
566 valid_surfaces_.insert(surface->surface_id()); 571 valid_surfaces_.insert(surface->surface_id());
567 572
568 if (provider_) 573 if (provider_)
569 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); 574 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources);
570 575
571 for (const auto& render_pass : frame_data->render_pass_list) 576 for (const auto& render_pass : frame_data->render_pass_list)
572 has_copy_requests_ |= !render_pass->copy_requests.empty(); 577 result->has_copy_requests |= !render_pass->copy_requests.empty();
573 578
574 gfx::Rect damage_rect; 579 gfx::Rect damage_rect;
575 if (!frame_data->render_pass_list.empty()) { 580 if (!frame_data->render_pass_list.empty()) {
576 RenderPass* last_pass = frame_data->render_pass_list.back().get(); 581 RenderPass* last_pass = frame_data->render_pass_list.back().get();
577 damage_rect = 582 damage_rect =
578 DamageRectForSurface(surface, *last_pass, last_pass->output_rect); 583 DamageRectForSurface(surface, *last_pass, last_pass->output_rect);
579 } 584 }
580 585
581 // Avoid infinite recursion by adding current surface to 586 // Avoid infinite recursion by adding current surface to
582 // referenced_surfaces_. 587 // referenced_surfaces_.
583 SurfaceSet::iterator it = 588 SurfaceSet::iterator it =
584 referenced_surfaces_.insert(surface->surface_id()).first; 589 referenced_surfaces_.insert(surface->surface_id()).first;
585 for (const auto& surface_info : child_surfaces) { 590 for (const auto& surface_info : child_surfaces) {
586 gfx::Rect surface_damage = PrewalkTree(surface_info.first); 591 gfx::Rect surface_damage = PrewalkTree(surface_info.first, result);
587 damage_rect.Union( 592 damage_rect.Union(
588 MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage)); 593 MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage));
589 } 594 }
595
596 for (const auto& surface_id : surface_frame->metadata.referenced_surfaces) {
597 if (!contained_surfaces_.count(surface_id)) {
598 result->undrawn_surfaces.insert(surface_id);
599 PrewalkTree(surface_id, result);
600 }
601 }
602
590 referenced_surfaces_.erase(it); 603 referenced_surfaces_.erase(it);
591 return damage_rect; 604 return damage_rect;
592 } 605 }
593 606
607 void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) {
608 // undrawn_surfaces are Surfaces that were identified by prewalk as being
609 // referenced by a drawn Surface, but aren't contained in a SurfaceDrawQuad.
610 // They need to be iterated over to ensure that any copy requests on them
611 // (or on Surfaces they reference) are executed.
612 std::vector<SurfaceId> surfaces_to_copy(
613 prewalk_result->undrawn_surfaces.begin(),
614 prewalk_result->undrawn_surfaces.end());
615
616 for (size_t i = 0; i < surfaces_to_copy.size(); i++) {
617 SurfaceId surface_id = surfaces_to_copy[i];
618 Surface* surface = manager_->GetSurfaceForId(surface_id);
619 const CompositorFrame* surface_frame = surface->GetEligibleFrame();
620 if (!surface_frame)
621 continue;
622 bool surface_has_copy_requests = false;
623 for (const auto& render_pass :
624 surface_frame->delegated_frame_data->render_pass_list) {
625 surface_has_copy_requests |= !render_pass->copy_requests.empty();
626 }
627 if (!surface_has_copy_requests) {
628 // Children are not necessarily included in undrawn_surfaces (because
629 // they weren't referenced directly from a drawn surface), but may have
630 // copy requests, so make sure to check them as well.
631 for (const auto& child_id : surface_frame->metadata.referenced_surfaces) {
632 // Don't iterate over the child Surface if it was already listed as a
633 // child of a different Surface, or in the case where there's infinite
634 // recursion.
635 if (!prewalk_result->undrawn_surfaces.count(child_id)) {
636 surfaces_to_copy.push_back(child_id);
637 prewalk_result->undrawn_surfaces.insert(child_id);
638 }
639 }
640 } else {
641 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
642 CopyPasses(surface_frame->delegated_frame_data.get(), surface);
643 referenced_surfaces_.erase(it);
644 }
645 }
646 }
647
594 scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { 648 scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
595 Surface* surface = manager_->GetSurfaceForId(surface_id); 649 Surface* surface = manager_->GetSurfaceForId(surface_id);
596 DCHECK(surface); 650 DCHECK(surface);
597 contained_surfaces_[surface_id] = surface->frame_index(); 651 contained_surfaces_[surface_id] = surface->frame_index();
598 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); 652 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame();
599 if (!root_surface_frame) 653 if (!root_surface_frame)
600 return nullptr; 654 return nullptr;
601 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); 655 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate");
602 656
603 scoped_ptr<CompositorFrame> frame(new CompositorFrame); 657 scoped_ptr<CompositorFrame> frame(new CompositorFrame);
604 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); 658 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData);
605 659
606 DCHECK(root_surface_frame->delegated_frame_data); 660 DCHECK(root_surface_frame->delegated_frame_data);
607 661
608 dest_resource_list_ = &frame->delegated_frame_data->resource_list; 662 dest_resource_list_ = &frame->delegated_frame_data->resource_list;
609 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; 663 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list;
610 664
611 valid_surfaces_.clear(); 665 valid_surfaces_.clear();
612 has_copy_requests_ = false; 666 PrewalkResult prewalk_result;
613 root_damage_rect_ = PrewalkTree(surface_id); 667 root_damage_rect_ = PrewalkTree(surface_id, &prewalk_result);
668 has_copy_requests_ = prewalk_result.has_copy_requests;
614 669
670 CopyUndrawnSurfaces(&prewalk_result);
615 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; 671 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
616 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); 672 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface);
617 referenced_surfaces_.erase(it); 673 referenced_surfaces_.erase(it);
618 674
619 DCHECK(referenced_surfaces_.empty()); 675 DCHECK(referenced_surfaces_.empty());
620 676
621 if (dest_pass_list_->empty()) 677 if (dest_pass_list_->empty())
622 return nullptr; 678 return nullptr;
623 dest_pass_list_->back()->damage_rect = root_damage_rect_; 679 dest_pass_list_->back()->damage_rect = root_damage_rect_;
624 680
(...skipping 27 matching lines...) Expand all
652 708
653 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { 709 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) {
654 auto it = previous_contained_surfaces_.find(surface_id); 710 auto it = previous_contained_surfaces_.find(surface_id);
655 if (it == previous_contained_surfaces_.end()) 711 if (it == previous_contained_surfaces_.end())
656 return; 712 return;
657 // Set the last drawn index as 0 to ensure full damage next time it's drawn. 713 // Set the last drawn index as 0 to ensure full damage next time it's drawn.
658 it->second = 0; 714 it->second = 0;
659 } 715 }
660 716
661 } // namespace cc 717 } // 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