Commit 06f244ec authored by Tien-Ren Chen's avatar Tien-Ren Chen Committed by Commit Bot

[Blink] Avoid O(d) lookup during scroll parent computation

This CL changes CompositingInputsUpdater to keep track of scrolling
container for different type of positioned descendants, so we won't need
to walk up ancestor chain to look for them. This is similar to the
technique used by PrePaintTreeWalk.

No behavior change is expected.

BUG=818768

Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I2409dd91e5b2903e348bdebca7f6ac2f1544ea94
Reviewed-on: https://chromium-review.googlesource.com/952540
Commit-Queue: Tien-Ren Chen <trchen@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542041}
parent bdb31047
...@@ -60,17 +60,6 @@ static const PaintLayer* FindParentLayerOnClippingContainerChain( ...@@ -60,17 +60,6 @@ static const PaintLayer* FindParentLayerOnClippingContainerChain(
return nullptr; return nullptr;
} }
static const PaintLayer* FindParentLayerOnContainingBlockChain(
const LayoutObject* object) {
for (const LayoutObject* current = object; current;
current = current->ContainingBlock()) {
if (current->HasLayer())
return static_cast<const LayoutBoxModelObject*>(current)->Layer();
}
NOTREACHED();
return nullptr;
}
static bool NeedsToEscapeClipInheritedFromCompositingContainer( static bool NeedsToEscapeClipInheritedFromCompositingContainer(
const PaintLayer* layer, const PaintLayer* layer,
const LayoutObject& desired_clip) { const LayoutObject& desired_clip) {
...@@ -92,11 +81,12 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer, ...@@ -92,11 +81,12 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
return; return;
LayoutBoxModelObject& layout_object = layer->GetLayoutObject(); LayoutBoxModelObject& layout_object = layer->GetLayoutObject();
const ComputedStyle& style = layout_object.StyleRef();
const PaintLayer* previous_overflow_layer = layer->AncestorOverflowLayer(); const PaintLayer* previous_overflow_layer = layer->AncestorOverflowLayer();
layer->UpdateAncestorOverflowLayer(info.last_overflow_clip_layer); layer->UpdateAncestorOverflowLayer(info.last_overflow_clip_layer);
if (info.last_overflow_clip_layer && layer->NeedsCompositingInputsUpdate() && if (info.last_overflow_clip_layer && layer->NeedsCompositingInputsUpdate() &&
layout_object.Style()->HasStickyConstrainedPosition()) { style.HasStickyConstrainedPosition()) {
if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled()) { if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
if (info.last_overflow_clip_layer != previous_overflow_layer) { if (info.last_overflow_clip_layer != previous_overflow_layer) {
// Old ancestor scroller should no longer have these constraints. // Old ancestor scroller should no longer have these constraints.
...@@ -142,23 +132,49 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer, ...@@ -142,23 +132,49 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
update_type = kForceUpdate; update_type = kForceUpdate;
} }
if (style.GetPosition() == EPosition::kAbsolute) {
info.scrolling_ancestor = info.scrolling_ancestor_for_absolute;
info.needs_reparent_scroll = info.needs_reparent_scroll_for_absolute;
} else if (style.GetPosition() == EPosition::kFixed) {
info.scrolling_ancestor = info.scrolling_ancestor_for_fixed;
info.needs_reparent_scroll = info.needs_reparent_scroll_for_fixed;
}
if (update_type == kForceUpdate) if (update_type == kForceUpdate)
UpdateAncestorDependentCompositingInputs(layer, info); UpdateAncestorDependentCompositingInputs(layer, info);
info.enclosing_composited_layer = enclosing_composited_layer; info.enclosing_composited_layer = enclosing_composited_layer;
if (layer->StackingNode()->IsStackingContext())
info.ancestor_stacking_context = layer;
if (layer->IsRootLayer() || layout_object.HasOverflowClip()) if (layer->IsRootLayer() || layout_object.HasOverflowClip())
info.last_overflow_clip_layer = layer; info.last_overflow_clip_layer = layer;
if (layer->ScrollsOverflow())
info.last_scrolling_ancestor = layer;
if (layout_object.HasClipRelatedProperty()) if (layout_object.HasClipRelatedProperty())
info.has_ancestor_with_clip_related_property = true; info.has_ancestor_with_clip_related_property = true;
// Handles sibling scroll problem, i.e. a non-stacking context scroller
// needs to propagate scroll to its descendants that are siblings in
// paint order. For example:
// <div style="overflow:scroll;">
// <div style="position:relative;">Paint sibling.</div>
// </div>
if (layer->ScrollsOverflow()) {
info.scrolling_ancestor = layer;
info.needs_reparent_scroll = true;
}
if (layout_object.CanContainAbsolutePositionObjects()) {
info.scrolling_ancestor_for_absolute = info.scrolling_ancestor;
info.needs_reparent_scroll_for_absolute = info.needs_reparent_scroll;
}
if (layout_object.CanContainFixedPositionObjects() &&
!layout_object.IsLayoutView()) {
info.scrolling_ancestor_for_fixed = info.scrolling_ancestor;
info.needs_reparent_scroll_for_fixed = info.needs_reparent_scroll;
}
if (style.IsStackingContext()) {
info.needs_reparent_scroll = info.needs_reparent_scroll_for_absolute =
info.needs_reparent_scroll_for_fixed = false;
}
for (PaintLayer* child = layer->FirstChild(); child; for (PaintLayer* child = layer->FirstChild(); child;
child = child->NextSibling()) child = child->NextSibling())
UpdateRecursive(child, update_type, info); UpdateRecursive(child, update_type, info);
...@@ -275,24 +291,9 @@ void CompositingInputsUpdater::UpdateAncestorDependentCompositingInputs( ...@@ -275,24 +291,9 @@ void CompositingInputsUpdater::UpdateAncestorDependentCompositingInputs(
} }
} }
if (info.last_scrolling_ancestor) { properties.ancestor_scrolling_layer = info.scrolling_ancestor;
const LayoutObject* containing_block = layout_object.ContainingBlock(); if (info.needs_reparent_scroll && layer->StackingNode()->IsStacked())
const PaintLayer* parent_layer_on_containing_block_chain = properties.scroll_parent = info.scrolling_ancestor;
FindParentLayerOnContainingBlockChain(containing_block);
properties.ancestor_scrolling_layer =
parent_layer_on_containing_block_chain->AncestorScrollingLayer();
if (parent_layer_on_containing_block_chain->ScrollsOverflow()) {
properties.ancestor_scrolling_layer =
parent_layer_on_containing_block_chain;
}
if (layer->StackingNode()->IsStacked() &&
properties.ancestor_scrolling_layer &&
!info.ancestor_stacking_context->GetLayoutObject().IsDescendantOf(
&properties.ancestor_scrolling_layer->GetLayoutObject()))
properties.scroll_parent = properties.ancestor_scrolling_layer;
}
layer->UpdateAncestorDependentCompositingInputs(properties); layer->UpdateAncestorDependentCompositingInputs(properties);
} }
......
...@@ -32,23 +32,20 @@ class CompositingInputsUpdater { ...@@ -32,23 +32,20 @@ class CompositingInputsUpdater {
}; };
struct AncestorInfo { struct AncestorInfo {
AncestorInfo() PaintLayer* enclosing_composited_layer = nullptr;
: ancestor_stacking_context(nullptr), PaintLayer* last_overflow_clip_layer = nullptr;
enclosing_composited_layer(nullptr), bool has_ancestor_with_clip_related_property = false;
last_overflow_clip_layer(nullptr),
last_scrolling_ancestor(nullptr), PaintLayer* scrolling_ancestor = nullptr;
has_ancestor_with_clip_related_property(false) {} PaintLayer* scrolling_ancestor_for_absolute = nullptr;
PaintLayer* scrolling_ancestor_for_fixed = nullptr;
PaintLayer* ancestor_stacking_context; // These flags are set to true if a non-stacking context scroller
PaintLayer* enclosing_composited_layer; // is encountered, so that a descendant element won't inherit scroll
PaintLayer* last_overflow_clip_layer; // translation from its compositing ancestor directly thus having to
// Notice that lastScrollingAncestor isn't the same thing as // setup an alternative scroll parent instead.
// ancestorScrollingLayer. The former is just the nearest scrolling bool needs_reparent_scroll = false;
// along the PaintLayer::parent() chain. The latter is the layer that bool needs_reparent_scroll_for_absolute = false;
// actually controls the scrolling of this layer, which we find on the bool needs_reparent_scroll_for_fixed = false;
// containing block chain.
PaintLayer* last_scrolling_ancestor;
bool has_ancestor_with_clip_related_property;
}; };
void UpdateRecursive(PaintLayer*, UpdateType, AncestorInfo); void UpdateRecursive(PaintLayer*, UpdateType, AncestorInfo);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment