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

Unified Diff: cc/trees/layer_tree_host_common.cc

Issue 2834123002: cc: Replace render surface layer list with a render surface list (Closed)
Patch Set: Address review comments Created 3 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/trees/layer_tree_host_common.h ('k') | cc/trees/layer_tree_host_common_perftest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..b845bb9ad23ceb98ded4a2ff487bc5b9c9d34b79 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);
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,76 @@ 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();
+ DCHECK(render_target->is_render_surface_list_member());
+ 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()) {
+ RenderSurfaceImpl* render_target = layer->render_target();
+ if (!render_target->is_render_surface_list_member()) {
+ layer->set_is_drawn_render_surface_layer_list_member(false);
+ render_target->decrement_num_contributors();
+ }
+ }
+ }
}
}
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 +560,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) {
« no previous file with comments | « cc/trees/layer_tree_host_common.h ('k') | cc/trees/layer_tree_host_common_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698