Chromium Code Reviews| Index: cc/trees/layer_tree_host_common.cc |
| diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc |
| index 973885887424b18c70560375d5585bb2c6e992ee..986abd5750b63829cb5fab61e9212c4a4095e2a7 100644 |
| --- a/cc/trees/layer_tree_host_common.cc |
| +++ b/cc/trees/layer_tree_host_common.cc |
| @@ -79,7 +79,7 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( |
| int max_texture_size, |
| bool can_render_to_separate_surface, |
| bool can_adjust_raster_scales, |
| - LayerImplList* render_surface_layer_list, |
| + RenderSurfaceList* render_surface_list, |
| PropertyTrees* property_trees) |
| : root_layer(root_layer), |
| device_viewport_size(device_viewport_size), |
| @@ -95,7 +95,7 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( |
| max_texture_size(max_texture_size), |
| can_render_to_separate_surface(can_render_to_separate_surface), |
| can_adjust_raster_scales(can_adjust_raster_scales), |
| - render_surface_layer_list(render_surface_layer_list), |
| + render_surface_list(render_surface_list), |
| property_trees(property_trees) {} |
| LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: |
| @@ -103,7 +103,7 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: |
| const gfx::Size& device_viewport_size, |
| const gfx::Transform& device_transform, |
| float device_scale_factor, |
| - LayerImplList* render_surface_layer_list) |
| + RenderSurfaceList* render_surface_list) |
| : CalcDrawPropsImplInputs(root_layer, |
| device_viewport_size, |
| device_transform, |
| @@ -117,43 +117,43 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: |
| std::numeric_limits<int>::max() / 2, |
| true, |
| false, |
| - render_surface_layer_list, |
| + render_surface_list, |
| GetPropertyTrees(root_layer)) { |
| DCHECK(root_layer); |
| - DCHECK(render_surface_layer_list); |
| + DCHECK(render_surface_list); |
| } |
| LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: |
| CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, |
| const gfx::Size& device_viewport_size, |
| const gfx::Transform& device_transform, |
| - LayerImplList* render_surface_layer_list) |
| + RenderSurfaceList* render_surface_list) |
| : CalcDrawPropsImplInputsForTesting(root_layer, |
| device_viewport_size, |
| device_transform, |
| 1.f, |
| - render_surface_layer_list) {} |
| + render_surface_list) {} |
| LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: |
| CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, |
| const gfx::Size& device_viewport_size, |
| - LayerImplList* render_surface_layer_list) |
| + RenderSurfaceList* render_surface_list) |
| : CalcDrawPropsImplInputsForTesting(root_layer, |
| device_viewport_size, |
| gfx::Transform(), |
| 1.f, |
| - render_surface_layer_list) {} |
| + render_surface_list) {} |
| LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: |
| CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, |
| const gfx::Size& device_viewport_size, |
| float device_scale_factor, |
| - LayerImplList* render_surface_layer_list) |
| + RenderSurfaceList* render_surface_list) |
| : CalcDrawPropsImplInputsForTesting(root_layer, |
| device_viewport_size, |
| gfx::Transform(), |
| device_scale_factor, |
| - render_surface_layer_list) {} |
| + render_surface_list) {} |
| LayerTreeHostCommon::ScrollUpdateInfo::ScrollUpdateInfo() |
| : layer_id(Layer::INVALID_ID) {} |
| @@ -200,13 +200,6 @@ static inline void ClearMaskLayersAreDrawnRenderSurfaceLayerListMembers( |
| mask_layer->set_is_drawn_render_surface_layer_list_member(false); |
| } |
| -static inline void ClearIsDrawnRenderSurfaceLayerListMember( |
| - LayerImplList* layer_list, |
| - ScrollTree* scroll_tree) { |
| - for (LayerImpl* layer : *layer_list) |
| - layer->set_is_drawn_render_surface_layer_list_member(false); |
| -} |
| - |
| static bool CdpPerfTracingEnabled() { |
| bool tracing_enabled; |
| TRACE_EVENT_CATEGORY_GROUP_ENABLED("cdp.perf", &tracing_enabled); |
| @@ -277,20 +270,81 @@ enum PropertyTreeOption { |
| DONT_BUILD_PROPERTY_TREES |
| }; |
| -static void ComputeInitialRenderSurfaceLayerList( |
| +static void AddSurfaceToRenderSurfaceList( |
| + RenderSurfaceImpl* render_surface, |
| + RenderSurfaceList* render_surface_list, |
| + PropertyTrees* property_trees) { |
| + // |render_surface| must appear after its target, so first make sure its |
| + // target is in the list. |
| + RenderSurfaceImpl* target = render_surface->render_target(); |
| + bool is_root = |
| + render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; |
| + if (!is_root && !target->is_render_surface_list_member()) { |
| + AddSurfaceToRenderSurfaceList(target, render_surface_list, property_trees); |
| + } |
| + render_surface->ClearAccumulatedContentRect(); |
| + render_surface_list->push_back(render_surface); |
| + render_surface->set_is_render_surface_list_member(true); |
| + if (is_root) { |
| + // The root surface does not contribute to any other surface, it has no |
| + // target. |
| + render_surface->set_contributes_to_drawn_surface(false); |
| + } else { |
| + bool contributes_to_drawn_surface = |
| + property_trees->effect_tree.ContributesToDrawnSurface( |
| + render_surface->EffectTreeIndex()); |
| + render_surface->set_contributes_to_drawn_surface( |
| + contributes_to_drawn_surface); |
| + } |
| + |
| + draw_property_utils::ComputeSurfaceDrawProperties(property_trees, |
| + render_surface); |
| + |
| + // Ignore occlusion from outside the surface when surface contents need to be |
| + // fully drawn. Layers with copy-request need to be complete. We could be |
| + // smarter about layers with filters that move pixels and exclude regions |
| + // where both layers and the filters are occluded, but this seems like |
| + // overkill. |
| + // TODO(senorblanco): make this smarter for the SkImageFilter case (check for |
| + // pixel-moving filters) |
| + const FilterOperations& filters = render_surface->Filters(); |
| + bool is_occlusion_immune = render_surface->HasCopyRequest() || |
| + filters.HasReferenceFilter() || |
| + filters.HasFilterThatMovesPixels(); |
| + if (is_occlusion_immune) { |
| + render_surface->SetNearestOcclusionImmuneAncestor(render_surface); |
| + } else if (is_root) { |
| + render_surface->SetNearestOcclusionImmuneAncestor(nullptr); |
| + } else { |
| + render_surface->SetNearestOcclusionImmuneAncestor( |
| + render_surface->render_target()->nearest_occlusion_immune_ancestor()); |
| + } |
| +} |
| + |
| +static void ComputeInitialRenderSurfaceList( |
| LayerTreeImpl* layer_tree_impl, |
| PropertyTrees* property_trees, |
| - LayerImplList* render_surface_layer_list, |
| + RenderSurfaceList* render_surface_list, |
| bool can_render_to_separate_surface) { |
| - // Add all non-skipped surfaces to the initial render surface layer list. Add |
| - // all non-skipped layers to the layer list of their target surface, and |
| - // add their content rect to their target surface's accumulated content rect. |
| - for (LayerImpl* layer : *layer_tree_impl) { |
| - RenderSurfaceImpl* render_surface = layer->GetRenderSurface(); |
| - if (render_surface) { |
| - render_surface->ClearLayerLists(); |
| + EffectTree& effect_tree = property_trees->effect_tree; |
| + for (int i = EffectTree::kContentsRootNodeId; |
| + i < static_cast<int>(effect_tree.size()); ++i) { |
| + if (RenderSurfaceImpl* render_surface = effect_tree.GetRenderSurface(i)) { |
| + render_surface->set_is_render_surface_list_member(false); |
| + render_surface->reset_num_contributors(); |
| ClearMaskLayersAreDrawnRenderSurfaceLayerListMembers(render_surface); |
| } |
| + } |
| + |
| + RenderSurfaceImpl* root_surface = |
| + effect_tree.GetRenderSurface(EffectTree::kContentsRootNodeId); |
| + // The root surface always gets added to the render surface list. |
| + AddSurfaceToRenderSurfaceList(root_surface, render_surface_list, |
| + property_trees); |
| + // For all non-skipped layers, add their target to the render surface list if |
| + // it's not already been added, and add their content rect to the target |
| + // surface's accumulated content rect. |
| + for (LayerImpl* layer : *layer_tree_impl) { |
| layer->set_is_drawn_render_surface_layer_list_member(false); |
|
ajuma
2017/04/27 23:35:23
LayerImpl::is_drawn_render_surface_layer_list_memb
|
| bool is_root = layer_tree_impl->IsRootLayer(layer); |
| @@ -300,51 +354,6 @@ static void ComputeInitialRenderSurfaceLayerList( |
| if (skip_layer) |
| continue; |
| - bool render_to_separate_surface = |
| - is_root || (can_render_to_separate_surface && render_surface); |
| - |
| - if (render_to_separate_surface) { |
| - DCHECK(render_surface); |
| - DCHECK(layer->render_target() == render_surface); |
| - render_surface->ClearAccumulatedContentRect(); |
| - render_surface_layer_list->push_back(layer); |
| - if (is_root) { |
| - // The root surface does not contribute to any other surface, it has no |
| - // target. |
| - render_surface->set_contributes_to_drawn_surface(false); |
| - } else { |
| - render_surface->render_target()->layer_list().push_back(layer); |
| - bool contributes_to_drawn_surface = |
| - property_trees->effect_tree.ContributesToDrawnSurface( |
| - layer->effect_tree_index()); |
| - render_surface->set_contributes_to_drawn_surface( |
| - contributes_to_drawn_surface); |
| - } |
| - |
| - draw_property_utils::ComputeSurfaceDrawProperties(property_trees, |
| - render_surface); |
| - |
| - // Ignore occlusion from outside the surface when surface contents need to |
| - // be fully drawn. Layers with copy-request need to be complete. We could |
| - // be smarter about layers with filters that move pixels and exclude |
| - // regions where both layers and the filters are occluded, but this seems |
| - // like overkill. |
| - // TODO(senorblanco): make this smarter for the SkImageFilter case (check |
| - // for pixel-moving filters) |
| - const FilterOperations& filters = render_surface->Filters(); |
| - bool is_occlusion_immune = render_surface->HasCopyRequest() || |
| - filters.HasReferenceFilter() || |
| - filters.HasFilterThatMovesPixels(); |
| - if (is_occlusion_immune) { |
| - render_surface->SetNearestOcclusionImmuneAncestor(render_surface); |
| - } else if (is_root) { |
| - render_surface->SetNearestOcclusionImmuneAncestor(nullptr); |
| - } else { |
| - render_surface->SetNearestOcclusionImmuneAncestor( |
| - render_surface->render_target() |
| - ->nearest_occlusion_immune_ancestor()); |
| - } |
| - } |
| bool layer_is_drawn = |
| property_trees->effect_tree.Node(layer->effect_tree_index())->is_drawn; |
| bool layer_should_be_drawn = draw_property_utils::LayerNeedsUpdate( |
| @@ -352,24 +361,30 @@ static void ComputeInitialRenderSurfaceLayerList( |
| if (!layer_should_be_drawn) |
| continue; |
| + RenderSurfaceImpl* render_target = layer->render_target(); |
| + if (!render_target->is_render_surface_list_member()) { |
| + AddSurfaceToRenderSurfaceList(render_target, render_surface_list, |
| + property_trees); |
| + } |
| + |
| layer->set_is_drawn_render_surface_layer_list_member(true); |
| - layer->render_target()->layer_list().push_back(layer); |
| // The layer contributes its drawable content rect to its render target. |
| - layer->render_target()->AccumulateContentRectFromContributingLayer(layer); |
| + render_target->AccumulateContentRectFromContributingLayer(layer); |
| + render_target->increment_num_contributors(); |
| } |
| } |
| static void ComputeSurfaceContentRects(LayerTreeImpl* layer_tree_impl, |
| PropertyTrees* property_trees, |
| - LayerImplList* render_surface_layer_list, |
| + RenderSurfaceList* render_surface_list, |
| int max_texture_size) { |
| // Walk the list backwards, accumulating each surface's content rect into its |
| // target's content rect. |
| - for (LayerImpl* layer : base::Reversed(*render_surface_layer_list)) { |
| - RenderSurfaceImpl* render_surface = layer->GetRenderSurface(); |
| - if (layer_tree_impl->IsRootLayer(layer)) { |
| - // The root layer's surface content rect is always the entire viewport. |
| + for (RenderSurfaceImpl* render_surface : |
| + base::Reversed(*render_surface_list)) { |
| + if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { |
| + // The root surface's content rect is always the entire viewport. |
| render_surface->SetContentRectToViewport(); |
| continue; |
| } |
| @@ -381,76 +396,72 @@ static void ComputeSurfaceContentRects(LayerTreeImpl* layer_tree_impl, |
| // Now the render surface's content rect is calculated correctly, it could |
| // contribute to its render target. |
| - render_surface->render_target() |
| - ->AccumulateContentRectFromContributingRenderSurface(render_surface); |
| + RenderSurfaceImpl* render_target = render_surface->render_target(); |
|
jaydasika
2017/04/28 18:27:18
Can you DCHECK here for render_target->is_render_s
ajuma
2017/04/28 21:11:21
Done.
|
| + render_target->AccumulateContentRectFromContributingRenderSurface( |
| + render_surface); |
| + render_target->increment_num_contributors(); |
| } |
| } |
| -static void ComputeListOfNonEmptySurfaces(LayerTreeImpl* layer_tree_impl, |
| - PropertyTrees* property_trees, |
| - LayerImplList* initial_surface_list, |
| - LayerImplList* final_surface_list) { |
| +static void ComputeListOfNonEmptySurfaces( |
| + LayerTreeImpl* layer_tree_impl, |
| + PropertyTrees* property_trees, |
| + RenderSurfaceList* initial_surface_list, |
| + RenderSurfaceList* final_surface_list) { |
| // Walk the initial surface list forwards. The root surface and each |
| // surface with a non-empty content rect go into the final render surface |
| // layer list. Surfaces with empty content rects or whose target isn't in |
| // the final list do not get added to the final list. |
| - for (LayerImpl* layer : *initial_surface_list) { |
| - bool is_root = layer_tree_impl->IsRootLayer(layer); |
| - RenderSurfaceImpl* surface = layer->GetRenderSurface(); |
| + bool removed_surface = false; |
| + for (RenderSurfaceImpl* surface : *initial_surface_list) { |
| + bool is_root = |
| + surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; |
| RenderSurfaceImpl* target_surface = surface->render_target(); |
| if (!is_root && (surface->content_rect().IsEmpty() || |
| - target_surface->layer_list().empty())) { |
| - ClearIsDrawnRenderSurfaceLayerListMember(&surface->layer_list(), |
| - &property_trees->scroll_tree); |
| - surface->ClearLayerLists(); |
| - LayerImplList& target_list = target_surface->layer_list(); |
| - auto it = std::find(target_list.begin(), target_list.end(), layer); |
| - if (it != target_list.end()) { |
| - target_list.erase(it); |
| - // This surface has an empty content rect. If its target's layer list |
| - // had no other layers, then its target would also have had an empty |
| - // content rect, meaning it would have been removed and had its layer |
| - // list cleared when we visited it, unless the target surface is the |
| - // root surface. |
| - DCHECK(!target_surface->layer_list().empty() || |
| - target_surface->render_target() == target_surface); |
| - } |
| + !target_surface->is_render_surface_list_member())) { |
| + surface->set_is_render_surface_list_member(false); |
| + removed_surface = true; |
| + target_surface->decrement_num_contributors(); |
| continue; |
| } |
| SetMaskLayersAreDrawnRenderSurfaceLayerListMembers(surface, property_trees); |
| - final_surface_list->push_back(layer); |
| + final_surface_list->push_back(surface); |
| + } |
| + if (removed_surface) { |
| + for (LayerImpl* layer : *layer_tree_impl) { |
| + if (layer->is_drawn_render_surface_layer_list_member() && |
| + !layer->render_target()->is_render_surface_list_member()) { |
| + layer->set_is_drawn_render_surface_layer_list_member(false); |
|
jaydasika
2017/04/28 18:27:18
Should we also have layer->render_target()->decrem
ajuma
2017/04/28 21:11:21
Done.
|
| + } |
| + } |
| } |
| } |
| static void CalculateRenderSurfaceLayerList( |
| LayerTreeImpl* layer_tree_impl, |
| PropertyTrees* property_trees, |
| - LayerImplList* render_surface_layer_list, |
| + RenderSurfaceList* render_surface_list, |
| const bool can_render_to_separate_surface, |
| const int max_texture_size) { |
| - // This calculates top level Render Surface Layer List, and Layer List for all |
| - // Render Surfaces. |
| - // |render_surface_layer_list| is the top level RenderSurfaceLayerList. |
| - |
| - LayerImplList initial_render_surface_list; |
| + RenderSurfaceList initial_render_surface_list; |
| - // First compute an RSLL that might include surfaces that later turn out to |
| + // First compute a list that might include surfaces that later turn out to |
| // have an empty content rect. After surface content rects are computed, |
| - // produce a final RSLL that omits empty surfaces. |
| - ComputeInitialRenderSurfaceLayerList(layer_tree_impl, property_trees, |
| - &initial_render_surface_list, |
| - can_render_to_separate_surface); |
| + // produce a final list that omits empty surfaces. |
| + ComputeInitialRenderSurfaceList(layer_tree_impl, property_trees, |
| + &initial_render_surface_list, |
| + can_render_to_separate_surface); |
| ComputeSurfaceContentRects(layer_tree_impl, property_trees, |
| &initial_render_surface_list, max_texture_size); |
| ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, |
| &initial_render_surface_list, |
| - render_surface_layer_list); |
| + render_surface_list); |
| } |
| void CalculateDrawPropertiesInternal( |
| LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs, |
| PropertyTreeOption property_tree_option) { |
| - inputs->render_surface_layer_list->clear(); |
| + inputs->render_surface_list->clear(); |
| const bool should_measure_property_tree_performance = |
| property_tree_option == BUILD_PROPERTY_TREES_IF_NEEDED; |
| @@ -545,7 +556,7 @@ void CalculateDrawPropertiesInternal( |
| CalculateRenderSurfaceLayerList( |
| inputs->root_layer->layer_tree_impl(), inputs->property_trees, |
| - inputs->render_surface_layer_list, inputs->can_render_to_separate_surface, |
| + inputs->render_surface_list, inputs->can_render_to_separate_surface, |
| inputs->max_texture_size); |
| if (should_measure_property_tree_performance) { |