Changeset 224612 in webkit


Ignore:
Timestamp:
Nov 8, 2017, 5:32:17 PM (8 years ago)
Author:
Alan Bujtas
Message:

[LayoutState cleanup] LayoutContext should own the stack of LayoutState objects
https://bugs.webkit.org/show_bug.cgi?id=179408
<rdar://problem/35423075>

Reviewed by Antti Koivisto.

No change in functionality.

  • page/LayoutContext.cpp:

(WebCore::LayoutContext::layoutDelta const):
(WebCore::LayoutContext::addLayoutDelta):
(WebCore::LayoutContext::layoutDeltaMatches):
(WebCore::LayoutContext::layoutState const):
(WebCore::LayoutContext::pushLayoutState):
(WebCore::LayoutContext::pushLayoutStateForPaginationIfNeeded):
(WebCore::LayoutContext::popLayoutState):

  • page/LayoutContext.h:

(WebCore::LayoutContext::isPaintOffsetCacheEnabled const):
(WebCore::LayoutContext::layoutState const): Deleted.

  • rendering/LayoutState.cpp:

(WebCore::LayoutState::LayoutState):
(WebCore::LayoutState::computeOffsets):
(WebCore::LayoutState::computeClipRect):
(WebCore::LayoutState::computePaginationInformation):
(WebCore::LayoutState::propagateLineGridInfo):
(WebCore::LayoutState::establishLineGrid):
(WebCore::LayoutState::clearPaginationInformation): Deleted.

  • rendering/LayoutState.h:

(WebCore::LayoutState::setIsPaginated):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r224611 r224612  
     12017-11-08  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LayoutState cleanup] LayoutContext should own the stack of LayoutState objects
     4        https://bugs.webkit.org/show_bug.cgi?id=179408
     5        <rdar://problem/35423075>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        No change in functionality.
     10
     11        * page/LayoutContext.cpp:
     12        (WebCore::LayoutContext::layoutDelta const):
     13        (WebCore::LayoutContext::addLayoutDelta):
     14        (WebCore::LayoutContext::layoutDeltaMatches):
     15        (WebCore::LayoutContext::layoutState const):
     16        (WebCore::LayoutContext::pushLayoutState):
     17        (WebCore::LayoutContext::pushLayoutStateForPaginationIfNeeded):
     18        (WebCore::LayoutContext::popLayoutState):
     19        * page/LayoutContext.h:
     20        (WebCore::LayoutContext::isPaintOffsetCacheEnabled const):
     21        (WebCore::LayoutContext::layoutState const): Deleted.
     22        * rendering/LayoutState.cpp:
     23        (WebCore::LayoutState::LayoutState):
     24        (WebCore::LayoutState::computeOffsets):
     25        (WebCore::LayoutState::computeClipRect):
     26        (WebCore::LayoutState::computePaginationInformation):
     27        (WebCore::LayoutState::propagateLineGridInfo):
     28        (WebCore::LayoutState::establishLineGrid):
     29        (WebCore::LayoutState::clearPaginationInformation): Deleted.
     30        * rendering/LayoutState.h:
     31        (WebCore::LayoutState::setIsPaginated):
     32
    1332017-11-08  Brady Eidson  <beidson@apple.com>
    234
  • trunk/Source/WebCore/page/LayoutContext.cpp

    r224579 r224612  
    531531LayoutSize LayoutContext::layoutDelta() const
    532532{
    533     if (!m_layoutState)
    534         return { };
    535     return m_layoutState->layoutDelta();
     533    if (auto* layoutState = this->layoutState())
     534        return layoutState->layoutDelta();
     535    return { };
    536536}
    537537   
    538538void LayoutContext::addLayoutDelta(const LayoutSize& delta)
    539539{
    540     if (!m_layoutState)
    541         return;
    542     m_layoutState->addLayoutDelta(delta);
     540    if (auto* layoutState = this->layoutState())
     541        layoutState->addLayoutDelta(delta);
    543542}
    544543   
     
    546545bool LayoutContext::layoutDeltaMatches(const LayoutSize& delta)
    547546{
    548     if (!m_layoutState)
     547    if (auto* layoutState = this->layoutState())
     548        return layoutState->layoutDeltaMatches(delta);
     549    return false;
     550}
     551#endif
     552
     553LayoutState* LayoutContext::layoutState() const
     554{
     555    if (m_layoutStateStack.isEmpty())
     556        return nullptr;
     557    return m_layoutStateStack.last().get();
     558}
     559
     560void LayoutContext::pushLayoutState(RenderElement& root)
     561{
     562    ASSERT(!m_paintOffsetCacheDisableCount);
     563    ASSERT(!layoutState());
     564
     565    m_layoutStateStack.append(std::make_unique<LayoutState>(root));
     566}
     567
     568bool LayoutContext::pushLayoutStateForPaginationIfNeeded(RenderBlockFlow& layoutRoot)
     569{
     570    if (layoutState())
    549571        return false;
    550     return m_layoutState->layoutDeltaMatches(delta);
    551 }
    552 #endif
    553    
    554 void LayoutContext::pushLayoutState(RenderElement& root)
    555 {
    556     ASSERT(!m_paintOffsetCacheDisableCount);
    557     ASSERT(!m_layoutState);
    558 
    559     m_layoutState = std::make_unique<LayoutState>(root);
    560 }
    561 
    562 bool LayoutContext::pushLayoutStateForPaginationIfNeeded(RenderBlockFlow& layoutRoot)
    563 {
    564     if (m_layoutState)
    565         return false;
    566     m_layoutState = std::make_unique<LayoutState>(layoutRoot);
    567     m_layoutState->setIsPaginated();
     572    m_layoutStateStack.append(std::make_unique<LayoutState>(layoutRoot));
     573    layoutState()->setIsPaginated();
    568574    // This is just a flag for known page height (see RenderBlockFlow::checkForPaginationLogicalHeightChange).
    569     m_layoutState->setPageLogicalHeight(1);
     575    layoutState()->setPageLogicalHeight(1);
    570576    return true;
    571577}
     
    579585{
    580586    // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
    581     if (!m_layoutState || !needsFullRepaint() || m_layoutState->isPaginated() || renderer.enclosingFragmentedFlow()
    582         || m_layoutState->lineGrid() || (renderer.style().lineGrid() != RenderStyle::initialLineGrid() && renderer.isRenderBlockFlow())) {
    583         m_layoutState = std::make_unique<LayoutState>(WTFMove(m_layoutState), renderer, offset, pageHeight, pageHeightChanged);
     587    auto* layoutState = this->layoutState();
     588    if (!layoutState || !needsFullRepaint() || layoutState->isPaginated() || renderer.enclosingFragmentedFlow()
     589        || layoutState->lineGrid() || (renderer.style().lineGrid() != RenderStyle::initialLineGrid() && renderer.isRenderBlockFlow())) {
     590        m_layoutStateStack.append(std::make_unique<LayoutState>(m_layoutStateStack, renderer, offset, pageHeight, pageHeightChanged));
    584591        return true;
    585592    }
     
    589596void LayoutContext::popLayoutState()
    590597{
    591     m_layoutState = WTFMove(m_layoutState->m_ancestor);
     598    m_layoutStateStack.removeLast();
    592599}
    593600   
  • trunk/Source/WebCore/page/LayoutContext.h

    r224559 r224612  
    2626#pragma once
    2727
     28#include "LayoutUnit.h"
    2829#include "Timer.h"
    2930
     
    3637class FrameView;
    3738class LayoutScope;
     39class LayoutSize;
    3840class LayoutState;
    3941class RenderBlockFlow;
     42class RenderBox;
     43class RenderObject;
    4044class RenderElement;
    4145class RenderView;
     
    9397    bool pushLayoutStateForPaginationIfNeeded(RenderBlockFlow&);
    9498    void popLayoutState(RenderObject&);
    95     LayoutState* layoutState() const { return m_layoutState.get(); }
     99    LayoutState* layoutState() const;
    96100    // Returns true if layoutState should be used for its cached offset and clip.
    97     bool isPaintOffsetCacheEnabled() const { return !m_paintOffsetCacheDisableCount && m_layoutState; }
     101    bool isPaintOffsetCacheEnabled() const { return !m_paintOffsetCacheDisableCount && layoutState(); }
    98102#ifndef NDEBUG
    99103    void checkLayoutState();
     
    107111    bool layoutDeltaMatches(const LayoutSize& delta);
    108112#endif
     113    using LayoutStateStack = Vector<std::unique_ptr<LayoutState>>;
    109114
    110115private:
     
    167172    int m_layoutDisallowedCount { 0 };
    168173    WeakPtr<RenderElement> m_subtreeLayoutRoot;
    169     std::unique_ptr<LayoutState> m_layoutState;
     174    LayoutStateStack m_layoutStateStack;
    170175    unsigned m_paintOffsetCacheDisableCount { 0 };
    171176};
  • trunk/Source/WebCore/rendering/LayoutState.cpp

    r224579 r224612  
    2727#include "LayoutState.h"
    2828
    29 #include "LayoutContext.h"
    3029#include "RenderFragmentedFlow.h"
    3130#include "RenderInline.h"
     
    6160}
    6261
    63 LayoutState::LayoutState(std::unique_ptr<LayoutState> ancestor, RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
    64     : m_ancestor(WTFMove(ancestor))
    65     , m_clipped(false)
     62LayoutState::LayoutState(const LayoutContext::LayoutStateStack& layoutStateStack, RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
     63    : m_clipped(false)
    6664    , m_isPaginated(false)
    6765    , m_pageLogicalHeightChanged(false)
     
    7472#endif
    7573{
    76     if (m_ancestor) {
    77         computeOffsets(renderer, offset);
    78         computeClipRect(renderer);
    79     }
    80     computePaginationInformation(renderer, pageLogicalHeight, pageLogicalHeightChanged);
    81 }
    82 
    83 void LayoutState::computeOffsets(RenderBox& renderer, LayoutSize offset)
    84 {
    85     ASSERT(m_ancestor);
    86 
     74    if (!layoutStateStack.isEmpty()) {
     75        auto& ancestor = *layoutStateStack.last().get();
     76        computeOffsets(ancestor, renderer, offset);
     77        computeClipRect(ancestor, renderer);
     78    }
     79    computePaginationInformation(layoutStateStack, renderer, pageLogicalHeight, pageLogicalHeightChanged);
     80}
     81
     82void LayoutState::computeOffsets(const LayoutState& ancestor, RenderBox& renderer, LayoutSize offset)
     83{
    8784    bool fixed = renderer.isFixedPositioned();
    8885    if (fixed) {
     
    9087        m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset;
    9188    } else
    92         m_paintOffset = m_ancestor->m_paintOffset + offset;
     89        m_paintOffset = ancestor.paintOffset() + offset;
    9390
    9491    if (renderer.isOutOfFlowPositioned() && !fixed) {
     
    107104        m_paintOffset -= toLayoutSize(renderer.scrollPosition());
    108105
    109     m_layoutDelta = m_ancestor->m_layoutDelta;
    110 #if !ASSERT_DISABLED
    111     m_layoutDeltaXSaturated = m_ancestor->m_layoutDeltaXSaturated;
    112     m_layoutDeltaYSaturated = m_ancestor->m_layoutDeltaYSaturated;
    113 #endif
    114 }
    115 
    116 void LayoutState::computeClipRect(RenderBox& renderer)
    117 {
    118     ASSERT(m_ancestor);
    119 
    120     m_clipped = !renderer.isFixedPositioned() && m_ancestor->m_clipped;
     106    m_layoutDelta = ancestor.layoutDelta();
     107#if !ASSERT_DISABLED
     108    m_layoutDeltaXSaturated = ancestor.m_layoutDeltaXSaturated;
     109    m_layoutDeltaYSaturated = ancestor.m_layoutDeltaYSaturated;
     110#endif
     111}
     112
     113void LayoutState::computeClipRect(const LayoutState& ancestor, RenderBox& renderer)
     114{
     115    m_clipped = !renderer.isFixedPositioned() && ancestor.isClipped();
    121116    if (m_clipped)
    122         m_clipRect = m_ancestor->m_clipRect;
     117        m_clipRect = ancestor.clipRect();
    123118    if (!renderer.hasOverflowClip())
    124119        return;
     
    133128}
    134129
    135 void LayoutState::computePaginationInformation(RenderBox& renderer, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
    136 {
     130void LayoutState::computePaginationInformation(const LayoutContext::LayoutStateStack& layoutStateStack, RenderBox& renderer, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
     131{
     132    auto* ancestor = layoutStateStack.isEmpty() ? nullptr : layoutStateStack.last().get();
    137133    // If we establish a new page height, then cache the offset to the top of the first page.
    138     // We can compare this later on to figure out what part of the page we're actually on,
     134    // We can compare this later on to figure out what part of the page we're actually on.
    139135    if (pageLogicalHeight || renderer.isRenderFragmentedFlow()) {
    140136        m_pageLogicalHeight = pageLogicalHeight;
     
    143139        m_pageLogicalHeightChanged = pageLogicalHeightChanged;
    144140        m_isPaginated = true;
    145     } else if (m_ancestor) {
     141    } else if (ancestor) {
    146142        // If we don't establish a new page height, then propagate the old page height and offset down.
    147         m_pageLogicalHeight = m_ancestor->m_pageLogicalHeight;
    148         m_pageLogicalHeightChanged = m_ancestor->m_pageLogicalHeightChanged;
    149         m_pageOffset = m_ancestor->m_pageOffset;
     143        m_pageLogicalHeight = ancestor->pageLogicalHeight();
     144        m_pageLogicalHeightChanged = ancestor->pageLogicalHeightChanged();
     145        m_pageOffset = ancestor->pageOffset();
    150146
    151147        // Disable pagination for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and writing mode roots.
     
    158154
    159155    // Propagate line grid information.
    160     propagateLineGridInfo(renderer);
     156    if (ancestor)
     157        propagateLineGridInfo(*ancestor, renderer);
    161158
    162159    if (lineGrid() && (lineGrid()->style().writingMode() == renderer.style().writingMode()) && is<RenderMultiColumnFlow>(renderer))
     
    165162    // If we have a new grid to track, then add it to our set.
    166163    if (renderer.style().lineGrid() != RenderStyle::initialLineGrid() && is<RenderBlockFlow>(renderer))
    167         establishLineGrid(downcast<RenderBlockFlow>(renderer));
    168 }
    169 
    170 void LayoutState::clearPaginationInformation()
    171 {
    172     m_pageLogicalHeight = m_ancestor->m_pageLogicalHeight;
    173     m_pageOffset = m_ancestor->m_pageOffset;
     164        establishLineGrid(layoutStateStack, downcast<RenderBlockFlow>(renderer));
    174165}
    175166
     
    181172}
    182173
    183 void LayoutState::propagateLineGridInfo(RenderBox& renderer)
     174void LayoutState::propagateLineGridInfo(const LayoutState& ancestor, RenderBox& renderer)
    184175{
    185176    // Disable line grids for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and
    186177    // writing mode roots.
    187     if (!m_ancestor || renderer.isUnsplittableForPagination())
    188         return;
    189 
    190     m_lineGrid = m_ancestor->m_lineGrid;
    191     m_lineGridOffset = m_ancestor->m_lineGridOffset;
    192     m_lineGridPaginationOrigin = m_ancestor->m_lineGridPaginationOrigin;
    193 }
    194 
    195 void LayoutState::establishLineGrid(RenderBlockFlow& renderer)
    196 {
     178    if (renderer.isUnsplittableForPagination())
     179        return;
     180
     181    m_lineGrid = ancestor.lineGrid();
     182    m_lineGridOffset = ancestor.lineGridOffset();
     183    m_lineGridPaginationOrigin = ancestor.lineGridPaginationOrigin();
     184}
     185
     186void LayoutState::establishLineGrid(const LayoutContext::LayoutStateStack& layoutStateStack, RenderBlockFlow& renderer)
     187{
     188    // FIXME: webkit.org/b/179440 This logic should be part of the LayoutContext.
    197189    // First check to see if this grid has been established already.
    198190    if (m_lineGrid) {
     
    200192            return;
    201193        RenderBlockFlow* currentGrid = m_lineGrid;
    202         for (LayoutState* currentState = m_ancestor.get(); currentState; currentState = currentState->m_ancestor.get()) {
    203             if (currentState->m_lineGrid == currentGrid)
     194        for (int i = layoutStateStack.size() - 1; i <= 0; --i) {
     195            auto& currentState = *layoutStateStack[i].get();
     196            if (currentState.m_lineGrid == currentGrid)
    204197                continue;
    205             currentGrid = currentState->m_lineGrid;
     198            currentGrid = currentState.m_lineGrid;
    206199            if (!currentGrid)
    207200                break;
    208201            if (currentGrid->style().lineGrid() == renderer.style().lineGrid()) {
    209202                m_lineGrid = currentGrid;
    210                 m_lineGridOffset = currentState->m_lineGridOffset;
     203                m_lineGridOffset = currentState.m_lineGridOffset;
    211204                return;
    212205            }
  • trunk/Source/WebCore/rendering/LayoutState.h

    r224579 r224612  
    2626#pragma once
    2727
     28#include "LayoutContext.h"
    2829#include "LayoutRect.h"
    2930#include <wtf/Noncopyable.h>
     
    5253    {
    5354    }
    54 
    55     LayoutState(std::unique_ptr<LayoutState> ancestor, RenderBox&, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged);
     55    LayoutState(const LayoutContext::LayoutStateStack&, RenderBox&, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged);
    5656    explicit LayoutState(RenderElement&);
    5757
    5858    bool isPaginated() const { return m_isPaginated; }
    5959    void setIsPaginated() { m_isPaginated = true; }
    60     void clearPaginationInformation();
    6160
    6261    // The page logical offset is the object's offset from the top of the page in the page progression
     
    9493#endif
    9594
    96     // FIXME: webkit.org/b/179408 LayoutContext should own the stack of LayoutState objects
    97     std::unique_ptr<LayoutState> m_ancestor;
    98 
    9995private:
    100     void computeOffsets(RenderBox&, LayoutSize offset);
    101     void computeClipRect(RenderBox&);
    102     void computePaginationInformation(RenderBox&, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged);
    103     void propagateLineGridInfo(RenderBox&);
    104     void establishLineGrid(RenderBlockFlow&);
     96    void computeOffsets(const LayoutState& ancestor, RenderBox&, LayoutSize offset);
     97    void computeClipRect(const LayoutState& ancestor, RenderBox&);
     98    void computePaginationInformation(const LayoutContext::LayoutStateStack&, RenderBox&, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged);
     99    void propagateLineGridInfo(const LayoutState& ancestor, RenderBox&);
     100    void establishLineGrid(const LayoutContext::LayoutStateStack&, RenderBlockFlow&);
    105101
    106102    // Do not add anything apart from bitfields. See https://bugs.webkit.org/show_bug.cgi?id=100173
     
    113109    bool m_layoutDeltaYSaturated : 1;
    114110#endif
    115 
    116111    // The current line grid that we're snapping to and the offset of the start of the grid.
    117112    RenderBlockFlow* m_lineGrid { nullptr };
Note: See TracChangeset for help on using the changeset viewer.