Chromium Code Reviews| Index: cc/surfaces/surface_aggregator.cc |
| diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc |
| index f0e73f8a06a835fdb22d2368cad0415218225dd2..3efea5993650bf21862dfc5920c386ca9eb8ccbe 100644 |
| --- a/cc/surfaces/surface_aggregator.cc |
| +++ b/cc/surfaces/surface_aggregator.cc |
| @@ -73,6 +73,55 @@ bool CalculateQuadSpaceDamageRect( |
| return true; |
| } |
| +// Recursively update the flag |has_damage_on_surface_quad|. |
| +bool UpdateHasDamageOnSurfaceQuadRecursive( |
|
weiliangc
2017/06/07 21:19:01
Since UpdateHasDamageOnSurfaceQuad is called at th
wutao
2017/06/09 02:31:32
Will push the info up in CopyQuadsToPass and Handl
|
| + RenderPass* pass, |
| + base::flat_map<int, std::unique_ptr<RenderPass>>* passes_id_map, |
| + base::flat_set<int>* updated_passes_id) { |
| + if (updated_passes_id->count(pass->id)) |
| + return pass->has_damage_on_surface_quad; |
| + |
| + updated_passes_id->insert(pass->id); |
| + bool has_damage_on_surface_quad = false; |
| + if (pass->has_damage_on_surface_quad) |
| + has_damage_on_surface_quad = true; |
| + for (auto* quad : pass->quad_list) { |
| + if (quad->material == DrawQuad::RENDER_PASS) { |
| + const RenderPassDrawQuad* pass_quad = |
| + RenderPassDrawQuad::MaterialCast(quad); |
| + if (!pass_quad) |
|
jbauman
2017/05/30 22:04:07
DCHECK instead of if
wutao
2017/05/30 23:12:52
Will do.
|
| + continue; |
| + auto iter = passes_id_map->find(pass_quad->render_pass_id); |
| + if (iter == passes_id_map->end()) |
| + continue; |
| + auto* ref_pass = iter->second.get(); |
| + if (!ref_pass) |
| + continue; |
| + |
| + has_damage_on_surface_quad |= UpdateHasDamageOnSurfaceQuadRecursive( |
| + ref_pass, passes_id_map, updated_passes_id); |
|
jbauman
2017/05/30 22:04:07
Could you check the performance on SurfaceAggregat
wutao
2017/05/30 23:12:52
Comparing the changes with ToT:
It is very simila
|
| + } |
| + } |
| + pass->has_damage_on_surface_quad = has_damage_on_surface_quad; |
| + return has_damage_on_surface_quad; |
| +} |
| + |
| +void UpdateHasDamageOnSurfaceQuad( |
| + RenderPassList* dest_pass_list_, |
| + std::vector<int>* dest_pass_id_list, |
| + base::flat_map<int, std::unique_ptr<RenderPass>>* passes_id_map) { |
| + base::flat_set<int> updated_passes_id; |
| + for (int pass_id : *dest_pass_id_list) { |
| + UpdateHasDamageOnSurfaceQuadRecursive( |
|
weiliangc
2017/06/07 21:19:00
We only need the bool has_damage_in_on_surface_qua
wutao
2017/06/09 02:31:32
Yes.
|
| + passes_id_map->find(pass_id)->second.get(), passes_id_map, |
| + &updated_passes_id); |
| + } |
| + |
| + for (int pass_id : *dest_pass_id_list) { |
| + dest_pass_list_->push_back(std::move(passes_id_map->find(pass_id)->second)); |
| + } |
| +} |
| + |
| } // namespace |
| SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager, |
| @@ -266,7 +315,10 @@ void SurfaceAggregator::HandleSurfaceQuad( |
| copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, |
| source.transform_to_root_target, source.filters, |
| source.background_filters, blending_color_space_, |
| - source.has_transparent_background); |
| + source.has_transparent_background, |
| + source.force_render_surface, |
| + source.has_property_change_on_contributing_render_surface, |
| + source.has_damage_on_surface_quad); |
| MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
| @@ -284,6 +336,7 @@ void SurfaceAggregator::HandleSurfaceQuad( |
| copy_pass.get(), surface_id); |
| if (!copy_request_passes_.count(remapped_pass_id) && |
| + !force_render_surface_passes_.count(remapped_pass_id) && |
| !moved_pixel_passes_.count(remapped_pass_id)) { |
| gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); |
| if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { |
| @@ -411,11 +464,12 @@ void SurfaceAggregator::CopyQuadsToPass( |
| const SurfaceId& surface_id) { |
| const SharedQuadState* last_copied_source_shared_quad_state = nullptr; |
| const SharedQuadState* dest_shared_quad_state = nullptr; |
| - // If the current frame has copy requests then aggregate the entire |
| - // thing, as otherwise parts of the copy requests may be ignored. |
| - const bool ignore_undamaged = aggregate_only_damaged_ && |
| - !has_copy_requests_ && |
| - !moved_pixel_passes_.count(dest_pass->id); |
| + // If the current frame has copy requests or force use of render surface, then |
| + // aggregate the entire thing, as otherwise parts of the copy requests or |
| + // render surface may be ignored. |
| + const bool ignore_undamaged = |
| + aggregate_only_damaged_ && !has_copy_requests_ && |
| + !has_force_render_surfaces_ && !moved_pixel_passes_.count(dest_pass->id); |
| // Damage rect in the quad space of the current shared quad state. |
| // TODO(jbauman): This rect may contain unnecessary area if |
| // transform isn't axis-aligned. |
| @@ -448,6 +502,16 @@ void SurfaceAggregator::CopyQuadsToPass( |
| if (surface_quad->surface_draw_quad_type == SurfaceDrawQuadType::FALLBACK) |
| continue; |
| + // Check if the surface_quad has damage. |
| + Surface* surface = manager_->GetSurfaceForId(surface_quad->surface_id); |
| + if (surface->HasActiveFrame()) { |
| + RenderPass* last_pass = |
| + surface->GetActiveFrame().render_pass_list.back().get(); |
| + gfx::Rect damage_rect = |
| + DamageRectForSurface(surface, *last_pass, last_pass->output_rect); |
| + dest_pass->has_damage_on_surface_quad |= !damage_rect.IsEmpty(); |
| + } |
| + |
| HandleSurfaceQuad(surface_quad, target_transform, clip_rect, dest_pass, |
| ignore_undamaged, &damage_rect_in_quad_space, |
| &damage_rect_in_quad_space_valid); |
| @@ -456,7 +520,8 @@ void SurfaceAggregator::CopyQuadsToPass( |
| dest_shared_quad_state = CopySharedQuadState( |
| quad->shared_quad_state, target_transform, clip_rect, dest_pass); |
| last_copied_source_shared_quad_state = quad->shared_quad_state; |
| - if (aggregate_only_damaged_ && !has_copy_requests_) { |
| + if (aggregate_only_damaged_ && !has_copy_requests_ && |
| + !has_force_render_surfaces_) { |
| damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect( |
| dest_shared_quad_state->quad_to_target_transform, |
| dest_pass->transform_to_root_target, root_damage_rect_, |
| @@ -531,6 +596,8 @@ void SurfaceAggregator::CopyPasses(const CompositorFrame& frame, |
| const ResourceProvider::ResourceIdMap& child_to_parent_map = |
| provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) |
| : empty_map; |
| + std::vector<int> temp_dest_pass_id_list; |
| + base::flat_map<int, std::unique_ptr<RenderPass>> passes_id_map; |
| for (size_t i = 0; i < source_pass_list.size(); ++i) { |
| const RenderPass& source = *source_pass_list[i]; |
| @@ -546,12 +613,16 @@ void SurfaceAggregator::CopyPasses(const CompositorFrame& frame, |
| copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect, |
| source.transform_to_root_target, source.filters, |
| source.background_filters, blending_color_space_, |
| - source.has_transparent_background); |
| + source.has_transparent_background, |
| + source.force_render_surface, |
| + source.has_property_change_on_contributing_render_surface, |
| + source.has_damage_on_surface_quad); |
| CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
| child_to_parent_map, gfx::Transform(), ClipData(), |
| copy_pass.get(), surface->surface_id()); |
| if (!copy_request_passes_.count(remapped_pass_id) && |
| + !force_render_surface_passes_.count(remapped_pass_id) && |
| !moved_pixel_passes_.count(remapped_pass_id)) { |
| gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization); |
| if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) { |
| @@ -562,8 +633,12 @@ void SurfaceAggregator::CopyPasses(const CompositorFrame& frame, |
| } |
| } |
| - dest_pass_list_->push_back(std::move(copy_pass)); |
| + temp_dest_pass_id_list.push_back(copy_pass->id); |
| + passes_id_map.insert(std::make_pair(copy_pass->id, std::move(copy_pass))); |
| } |
| + |
| + UpdateHasDamageOnSurfaceQuad(dest_pass_list_, &temp_dest_pass_id_list, |
| + &passes_id_map); |
| } |
| void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { |
| @@ -765,10 +840,11 @@ gfx::Rect SurfaceAggregator::PrewalkTree(const SurfaceId& surface_id, |
| CHECK(debug_weak_this.get()); |
| for (const auto& render_pass : frame.render_pass_list) { |
| - if (!render_pass->copy_requests.empty()) { |
| - int remapped_pass_id = RemapPassId(render_pass->id, surface_id); |
| + int remapped_pass_id = RemapPassId(render_pass->id, surface_id); |
| + if (!render_pass->copy_requests.empty()) |
| copy_request_passes_.insert(remapped_pass_id); |
| - } |
| + if (render_pass->force_render_surface) |
| + force_render_surface_passes_.insert(remapped_pass_id); |
| } |
| referenced_surfaces_.erase(referenced_surfaces_.find(surface->surface_id())); |
| @@ -819,9 +895,8 @@ void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) { |
| } |
| } |
| -void SurfaceAggregator::PropagateCopyRequestPasses() { |
| - std::vector<int> copy_requests_to_iterate(copy_request_passes_.begin(), |
| - copy_request_passes_.end()); |
| +void SurfaceAggregator::PropagatePasses(base::flat_set<int>* passes) { |
| + std::vector<int> copy_requests_to_iterate(passes->begin(), passes->end()); |
| while (!copy_requests_to_iterate.empty()) { |
| int first = copy_requests_to_iterate.back(); |
| copy_requests_to_iterate.pop_back(); |
| @@ -829,7 +904,7 @@ void SurfaceAggregator::PropagateCopyRequestPasses() { |
| if (it == render_pass_dependencies_.end()) |
| continue; |
| for (auto pass : it->second) { |
| - if (copy_request_passes_.insert(pass).second) { |
| + if (passes->insert(pass).second) { |
| copy_requests_to_iterate.push_back(pass); |
| } |
| } |
| @@ -856,8 +931,10 @@ CompositorFrame SurfaceAggregator::Aggregate(const SurfaceId& surface_id) { |
| valid_surfaces_.clear(); |
| PrewalkResult prewalk_result; |
| root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result); |
| - PropagateCopyRequestPasses(); |
| + PropagatePasses(©_request_passes_); |
| + PropagatePasses(&force_render_surface_passes_); |
| has_copy_requests_ = !copy_request_passes_.empty(); |
| + has_force_render_surfaces_ = !force_render_surface_passes_.empty(); |
| frame.metadata.may_contain_video = prewalk_result.may_contain_video; |
| CopyUndrawnSurfaces(&prewalk_result); |
| @@ -869,6 +946,7 @@ CompositorFrame SurfaceAggregator::Aggregate(const SurfaceId& surface_id) { |
| moved_pixel_passes_.clear(); |
| copy_request_passes_.clear(); |
| + force_render_surface_passes_.clear(); |
| render_pass_dependencies_.clear(); |
| // Remove all render pass mappings that weren't used in the current frame. |