Commit ef3740f6 authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

Optimize performance of containing block chain for subtree layout.

A previous patch regressed performance due to the need to walk the
containing block chain to find containing scrollable areas, in order
to notify them of anchor adjustments.

This patch iterates over all ScrollableAreas and notifies each of them.

Bug: 1024434

Change-Id: Ibee4d9383ec1456c5e020c95aea941124fca048b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1931148
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720361}
parent afdfb3ff
...@@ -605,17 +605,14 @@ void LocalFrameView::PerformPreLayoutTasks() { ...@@ -605,17 +605,14 @@ void LocalFrameView::PerformPreLayoutTasks() {
void LocalFrameView::LayoutFromRootObject(LayoutObject& root) { void LocalFrameView::LayoutFromRootObject(LayoutObject& root) {
LayoutState layout_state(root); LayoutState layout_state(root);
// Since we are starting layout from an arbitrary node, we need to notify all if (scrollable_areas_) {
// possible scroll anchors above us, as they aren't notified during layout. for (auto& scrollable_area : *scrollable_areas_) {
for (auto* ancestor = root.Container(); ancestor; if (scrollable_area->GetScrollAnchor() &&
ancestor = ancestor->Container()) { scrollable_area->ShouldPerformScrollAnchoring())
if (ancestor->HasOverflowClip() && ancestor->IsLayoutBlock()) { scrollable_area->GetScrollAnchor()->NotifyBeforeLayout();
auto* scrollable_area =
ToLayoutBoxModelObject(ancestor)->GetScrollableArea();
DCHECK(scrollable_area);
scrollable_area->GetScrollAnchor()->NotifyBeforeLayout();
} }
} }
root.UpdateLayout(); root.UpdateLayout();
} }
......
...@@ -448,7 +448,7 @@ WebInputEventResult GestureManager::HandleGestureShowPress() { ...@@ -448,7 +448,7 @@ WebInputEventResult GestureManager::HandleGestureShowPress() {
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
for (const PaintLayerScrollableArea* scrollable_area : *areas) { for (const PaintLayerScrollableArea* scrollable_area : *areas) {
ScrollAnimatorBase* animator = scrollable_area->ExistingScrollAnimator(); ScrollAnimatorBase* animator = scrollable_area->ExistingScrollAnimator();
if (animator) if (scrollable_area->ScrollsOverflow() && animator)
animator->CancelAnimation(); animator->CancelAnimation();
} }
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
......
...@@ -742,9 +742,11 @@ void Page::SettingsChanged(SettingsDelegate::ChangeType change_type) { ...@@ -742,9 +742,11 @@ void Page::SettingsChanged(SettingsDelegate::ChangeType change_type) {
if (LocalFrameView* view = local_frame->View()) { if (LocalFrameView* view = local_frame->View()) {
if (const auto* scrollable_areas = view->ScrollableAreas()) { if (const auto* scrollable_areas = view->ScrollableAreas()) {
for (const auto& scrollable_area : *scrollable_areas) { for (const auto& scrollable_area : *scrollable_areas) {
if (auto* layout_box = scrollable_area->GetLayoutBox()) { if (scrollable_area->ScrollsOverflow()) {
layout_box->SetNeedsLayout( if (auto* layout_box = scrollable_area->GetLayoutBox()) {
layout_invalidation_reason::kScrollbarChanged); layout_box->SetNeedsLayout(
layout_invalidation_reason::kScrollbarChanged);
}
} }
} }
} }
......
...@@ -147,6 +147,16 @@ PaintLayerScrollableArea::PaintLayerScrollableArea(PaintLayer& layer) ...@@ -147,6 +147,16 @@ PaintLayerScrollableArea::PaintLayerScrollableArea(PaintLayer& layer)
GetLayoutBox()->GetDocument().GetSnapCoordinator().AddSnapContainer( GetLayoutBox()->GetDocument().GetSnapCoordinator().AddSnapContainer(
*GetLayoutBox()); *GetLayoutBox());
LocalFrame* frame = GetLayoutBox()->GetFrame();
if (!frame)
return;
LocalFrameView* frame_view = frame->View();
if (!frame_view)
return;
frame_view->AddScrollableArea(this);
} }
PaintLayerScrollableArea::~PaintLayerScrollableArea() { PaintLayerScrollableArea::~PaintLayerScrollableArea() {
...@@ -2199,6 +2209,7 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() { ...@@ -2199,6 +2209,7 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
v_mode == ScrollbarMode::kAlwaysOff) v_mode == ScrollbarMode::kAlwaysOff)
has_overflow = false; has_overflow = false;
} }
scrolls_overflow_ = has_overflow && is_visible_to_hit_test; scrolls_overflow_ = has_overflow && is_visible_to_hit_test;
if (did_scroll_overflow == ScrollsOverflow()) if (did_scroll_overflow == ScrollsOverflow())
return; return;
...@@ -2237,13 +2248,6 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() { ...@@ -2237,13 +2248,6 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
// (see: BoxPainter::PaintBoxDecorationBackground). // (see: BoxPainter::PaintBoxDecorationBackground).
GetLayoutBox()->SetBackgroundNeedsFullPaintInvalidation(); GetLayoutBox()->SetBackgroundNeedsFullPaintInvalidation();
if (scrolls_overflow_) {
DCHECK(CanHaveOverflowScrollbars(*GetLayoutBox()));
frame_view->AddScrollableArea(this);
} else {
frame_view->RemoveScrollableArea(this);
}
layer_->DidUpdateScrollsOverflow(); layer_->DidUpdateScrollsOverflow();
} }
......
...@@ -2065,15 +2065,24 @@ unsigned Internals::numberOfScrollableAreas(Document* document) { ...@@ -2065,15 +2065,24 @@ unsigned Internals::numberOfScrollableAreas(Document* document) {
unsigned count = 0; unsigned count = 0;
LocalFrame* frame = document->GetFrame(); LocalFrame* frame = document->GetFrame();
if (frame->View()->ScrollableAreas()) if (frame->View()->ScrollableAreas()) {
count += frame->View()->ScrollableAreas()->size(); for (const auto& scrollable_area : *frame->View()->ScrollableAreas()) {
if (scrollable_area->ScrollsOverflow())
count++;
}
}
for (Frame* child = frame->Tree().FirstChild(); child; for (Frame* child = frame->Tree().FirstChild(); child;
child = child->Tree().NextSibling()) { child = child->Tree().NextSibling()) {
auto* child_local_frame = DynamicTo<LocalFrame>(child); auto* child_local_frame = DynamicTo<LocalFrame>(child);
if (child_local_frame && child_local_frame->View() && if (child_local_frame && child_local_frame->View() &&
child_local_frame->View()->ScrollableAreas()) child_local_frame->View()->ScrollableAreas()) {
count += child_local_frame->View()->ScrollableAreas()->size(); for (const auto& scrollable_area :
*child_local_frame->View()->ScrollableAreas()) {
if (scrollable_area->ScrollsOverflow())
count++;
}
}
} }
return count; return count;
......
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