Chromium Code Reviews| Index: cc/surfaces/surface_aggregator.cc |
| diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc |
| index a0108b7d09c99a6e135a0049d80ef881f8fedb21..98aac33823adc64fc99423bbd8c87624f2ad754f 100644 |
| --- a/cc/surfaces/surface_aggregator.cc |
| +++ b/cc/surfaces/surface_aggregator.cc |
| @@ -59,6 +59,10 @@ SurfaceAggregator::~SurfaceAggregator() { |
| ProcessAddedAndRemovedSurfaces(); |
| } |
| +SurfaceAggregator::PrewalkResult::PrewalkResult() : has_copy_requests(false) {} |
| + |
| +SurfaceAggregator::PrewalkResult::~PrewalkResult() {} |
| + |
| // Create a clip rect for an aggregated quad from the original clip rect and |
| // the clip rect from the surface it's on. |
| SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect( |
| @@ -494,7 +498,8 @@ void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { |
| // Walk the Surface tree from surface_id. Validate the resources of the current |
| // surface and its descendants, check if there are any copy requests, and |
| // return the combined damage rect. |
| -gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id) { |
| +gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id, |
| + PrewalkResult* result) { |
| if (referenced_surfaces_.count(surface_id)) |
| return gfx::Rect(); |
| Surface* surface = manager_->GetSurfaceForId(surface_id); |
| @@ -572,7 +577,7 @@ gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id) { |
| provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); |
| for (const auto& render_pass : frame_data->render_pass_list) |
| - has_copy_requests_ |= !render_pass->copy_requests.empty(); |
| + result->has_copy_requests |= !render_pass->copy_requests.empty(); |
| gfx::Rect damage_rect; |
| if (!frame_data->render_pass_list.empty()) { |
| @@ -586,14 +591,57 @@ gfx::Rect SurfaceAggregator::PrewalkTree(SurfaceId surface_id) { |
| SurfaceSet::iterator it = |
| referenced_surfaces_.insert(surface->surface_id()).first; |
| for (const auto& surface_info : child_surfaces) { |
| - gfx::Rect surface_damage = PrewalkTree(surface_info.first); |
| + gfx::Rect surface_damage = PrewalkTree(surface_info.first, result); |
| damage_rect.Union( |
| MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage)); |
| } |
| + |
| + for (const SurfaceId surface_id : |
|
danakj
2015/11/16 21:45:46
did you mean const&?
or maybe just auto&?
|
| + surface_frame->metadata.referenced_surfaces) { |
| + if (!contained_surfaces_.count(surface_id)) { |
| + result->undrawn_surfaces.insert(surface_id); |
| + PrewalkTree(surface_id, result); |
| + } |
| + } |
| + |
| referenced_surfaces_.erase(it); |
| return damage_rect; |
| } |
| +void SurfaceAggregator::CopyUnreferencedSurfaces( |
|
danakj
2015/11/16 21:45:45
CopyUndrawnSurfaces?
|
| + PrewalkResult* prewalk_result) { |
| + std::vector<SurfaceId> surfaces_to_copy( |
|
danakj
2015/11/16 21:45:45
Can you leave a comment here to the effect of how
|
| + prewalk_result->undrawn_surfaces.begin(), |
| + prewalk_result->undrawn_surfaces.end()); |
| + |
| + for (size_t i = 0; i < surfaces_to_copy.size(); i++) { |
| + SurfaceId surface_id = surfaces_to_copy[i]; |
| + Surface* surface = manager_->GetSurfaceForId(surface_id); |
| + const CompositorFrame* surface_frame = surface->GetEligibleFrame(); |
| + if (!surface_frame) |
| + continue; |
| + bool has_copy_requests = false; |
|
danakj
2015/11/16 21:45:45
can you name this somehow differently to not almos
|
| + for (const auto& render_pass : |
| + surface_frame->delegated_frame_data->render_pass_list) { |
| + has_copy_requests |= !render_pass->copy_requests.empty(); |
| + } |
| + if (!has_copy_requests) { |
| + // Children may have copy requests, so make sure to check them as well. |
| + for (const SurfaceId child_id : |
|
danakj
2015/11/16 21:45:45
ditto?
|
| + surface_frame->metadata.referenced_surfaces) { |
| + if (!prewalk_result->undrawn_surfaces.count(child_id)) { |
|
danakj
2015/11/16 21:45:45
Why this if? How could a child of an undrawn surfa
|
| + surfaces_to_copy.push_back(child_id); |
| + prewalk_result->undrawn_surfaces.insert(child_id); |
| + } |
| + } |
| + } else { |
| + SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
| + CopyPasses(surface_frame->delegated_frame_data.get(), surface); |
| + referenced_surfaces_.erase(it); |
| + } |
| + } |
| +} |
| + |
| scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { |
| Surface* surface = manager_->GetSurfaceForId(surface_id); |
| DCHECK(surface); |
| @@ -612,9 +660,11 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { |
| dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; |
| valid_surfaces_.clear(); |
| - has_copy_requests_ = false; |
| - root_damage_rect_ = PrewalkTree(surface_id); |
| + PrewalkResult prewalk_result; |
| + root_damage_rect_ = PrewalkTree(surface_id, &prewalk_result); |
| + has_copy_requests_ = prewalk_result.has_copy_requests; |
| + CopyUnreferencedSurfaces(&prewalk_result); |
| SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
| CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); |
| referenced_surfaces_.erase(it); |