| Index: Source/core/page/FrameView.cpp
|
| diff --git a/Source/core/page/FrameView.cpp b/Source/core/page/FrameView.cpp
|
| index f49395957c7544622562574de7c461f37297215c..d44d727d4a59019c253b1da72423d371ad95d617 100644
|
| --- a/Source/core/page/FrameView.cpp
|
| +++ b/Source/core/page/FrameView.cpp
|
| @@ -180,6 +180,7 @@ FrameView::FrameView(Frame* frame)
|
| , m_didRunAutosize(false)
|
| , m_hasSoftwareFilters(false)
|
| , m_visibleContentScaleFactor(1)
|
| + , m_partialLayout()
|
| {
|
| ASSERT(m_frame);
|
| init();
|
| @@ -277,6 +278,7 @@ void FrameView::reset()
|
| m_firstVisuallyNonEmptyLayoutCallbackPending = true;
|
| m_maintainScrollPositionAnchor = 0;
|
| m_disableRepaints = 0;
|
| + m_partialLayout.reset();
|
| }
|
|
|
| void FrameView::removeFromAXObjectCache()
|
| @@ -865,20 +867,25 @@ void FrameView::performLayout(RenderObject* rootForThisLayout, bool inSubtreeLay
|
| // performLayout is the actual guts of layout().
|
| // FIXME: The 300 other lines in layout() probably belong in other helper functions
|
| // so that a single human could understand what layout() is actually doing.
|
| + {
|
| + bool disableLayoutState = false;
|
| + if (inSubtreeLayout) {
|
| + RenderView* view = rootForThisLayout->view();
|
| + disableLayoutState = view->shouldDisableLayoutStateForSubtree(rootForThisLayout);
|
| + view->pushLayoutState(rootForThisLayout);
|
| + }
|
| + LayoutStateDisabler layoutStateDisabler(disableLayoutState ? rootForThisLayout->view() : 0);
|
|
|
| - bool disableLayoutState = false;
|
| - if (inSubtreeLayout) {
|
| - RenderView* view = rootForThisLayout->view();
|
| - disableLayoutState = view->shouldDisableLayoutStateForSubtree(rootForThisLayout);
|
| - view->pushLayoutState(rootForThisLayout);
|
| - }
|
| - LayoutStateDisabler layoutStateDisabler(disableLayoutState ? rootForThisLayout->view() : 0);
|
| -
|
| - m_inLayout = true;
|
| - beginDeferredRepaints();
|
| - forceLayoutParentViewIfNeeded();
|
| + m_inLayout = true;
|
| + beginDeferredRepaints();
|
| + forceLayoutParentViewIfNeeded();
|
|
|
| - rootForThisLayout->layout(); // THIS IS WHERE LAYOUT ACTUALLY HAPPENS.
|
| + // Text Autosizing requires two-pass layout which is incompatible with partial layout.
|
| + // If enabled, only do partial layout for the second layout.
|
| + // FIXME (crbug.com/256657): Do not do two layouts for text autosizing.
|
| + PartialLayoutDisabler partialLayoutDisabler(partialLayout(), m_frame->settings() && m_frame->settings()->textAutosizingEnabled());
|
| + rootForThisLayout->layout(); // THIS IS WHERE LAYOUT ACTUALLY HAPPENS.
|
| + }
|
|
|
| bool autosized = frame().document()->textAutosizer()->processSubtree(rootForThisLayout);
|
| if (autosized && rootForThisLayout->needsLayout()) {
|
| @@ -900,6 +907,9 @@ void FrameView::scheduleOrPerformPostLayoutTasks()
|
| return;
|
| }
|
|
|
| + // Partial layouts should not happen with synchronous post layouts.
|
| + ASSERT(!(m_inSynchronousPostLayout && partialLayout().isStopping()));
|
| +
|
| if (!m_inSynchronousPostLayout) {
|
| if (frame().document()->shouldDisplaySeamlesslyWithParent()) {
|
| if (RenderView* renderView = this->renderView())
|
| @@ -918,7 +928,7 @@ void FrameView::scheduleOrPerformPostLayoutTasks()
|
| // can make us need to update again, and we can get stuck in a nasty cycle unless
|
| // we call it through the timer here.
|
| m_postLayoutTasksTimer.startOneShot(0);
|
| - if (needsLayout()) {
|
| + if (!partialLayout().isStopping() && needsLayout()) {
|
| m_actionScheduler->pause();
|
| layout();
|
| }
|
| @@ -935,6 +945,8 @@ void FrameView::layout(bool allowSubtree)
|
| if (m_inLayout)
|
| return;
|
|
|
| + ASSERT(!partialLayout().isStopping());
|
| +
|
| TRACE_EVENT0("webkit", "FrameView::layout");
|
| TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "Layout");
|
|
|
| @@ -976,6 +988,8 @@ void FrameView::layout(bool allowSubtree)
|
| return;
|
| }
|
|
|
| + bool isPartialLayout = partialLayout().isPartialLayout();
|
| +
|
| FontCachePurgePreventer fontCachePurgePreventer;
|
| RenderLayer* layer;
|
| {
|
| @@ -990,9 +1004,9 @@ void FrameView::layout(bool allowSubtree)
|
| ScrollbarMode vMode;
|
| calculateScrollbarModesForLayout(hMode, vMode);
|
|
|
| - m_doFullRepaint = !inSubtreeLayout && (m_firstLayout || toRenderView(rootForThisLayout)->printing());
|
| + m_doFullRepaint = !inSubtreeLayout && !isPartialLayout && (m_firstLayout || toRenderView(rootForThisLayout)->printing());
|
|
|
| - if (!inSubtreeLayout) {
|
| + if (!inSubtreeLayout && !isPartialLayout) {
|
| // Now set our scrollbar state for the layout.
|
| ScrollbarMode currentHMode = horizontalScrollbarMode();
|
| ScrollbarMode currentVMode = verticalScrollbarMode();
|
| @@ -1039,13 +1053,14 @@ void FrameView::layout(bool allowSubtree)
|
| layer = rootForThisLayout->enclosingLayer();
|
|
|
| m_actionScheduler->pause();
|
| +
|
| performLayout(rootForThisLayout, inSubtreeLayout);
|
| m_layoutRoot = 0;
|
| } // Reset m_layoutSchedulingEnabled to its previous value.
|
|
|
| bool neededFullRepaint = m_doFullRepaint;
|
|
|
| - if (!inSubtreeLayout && !toRenderView(rootForThisLayout)->printing())
|
| + if (!inSubtreeLayout && !isPartialLayout && !toRenderView(rootForThisLayout)->printing())
|
| adjustViewSize();
|
|
|
| m_doFullRepaint = neededFullRepaint;
|
| @@ -1071,7 +1086,7 @@ void FrameView::layout(bool allowSubtree)
|
| cache->postNotification(rootForThisLayout, AXObjectCache::AXLayoutComplete, true);
|
| updateAnnotatedRegions();
|
|
|
| - ASSERT(!rootForThisLayout->needsLayout());
|
| + ASSERT(partialLayout().isStopping() || !rootForThisLayout->needsLayout());
|
|
|
| updateCanBlitOnScrollRecursively();
|
|
|
| @@ -1088,6 +1103,9 @@ void FrameView::layout(bool allowSubtree)
|
| if (m_nestedLayoutCount)
|
| return;
|
|
|
| + if (partialLayout().isStopping())
|
| + return;
|
| +
|
| #ifndef NDEBUG
|
| // Post-layout assert that nobody was re-marked as needing layout during layout.
|
| for (RenderObject* renderer = document->renderer(); renderer; renderer = renderer->nextInPreOrder())
|
|
|