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) { |