61a36e37d623bec884ff411c4833a37e3172c5f4
[WebKit-https.git] / Source / WebCore / page / LayoutContext.h
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "Timer.h"
29
30 #include <wtf/WeakPtr.h>
31
32 namespace WebCore {
33
34 class Document;
35 class Frame;
36 class FrameView;
37 class LayoutScope;
38 class LayoutState;
39 class RenderBlockFlow;
40 class RenderElement;
41 class RenderView;
42     
43 class LayoutContext {
44 public:
45     LayoutContext(FrameView&);
46
47     void layout();
48
49     void setNeedsLayout();
50     bool needsLayout() const;
51
52     void scheduleLayout();
53     void scheduleSubtreeLayout(RenderElement& layoutRoot);
54     void unscheduleLayout();
55
56     void startDisallowingLayout() { ++m_layoutDisallowedCount; }
57     void endDisallowingLayout() { ASSERT(m_layoutDisallowedCount > 0); --m_layoutDisallowedCount; }
58     
59     void disableSetNeedsLayout();
60     void enableSetNeedsLayout();
61
62     enum class LayoutPhase {
63         OutsideLayout,
64         InPreLayout,
65         InRenderTreeLayout,
66         InViewSizeAdjust,
67         InPostLayout
68     };
69     LayoutPhase layoutPhase() const { return m_layoutPhase; }
70     bool isLayoutNested() const { return m_layoutNestedState == LayoutNestedState::Nested; }
71     bool isLayoutPending() const { return m_layoutTimer.isActive(); }
72     bool isInLayout() const { return layoutPhase() != LayoutPhase::OutsideLayout; }
73     bool isInRenderTreeLayout() const { return layoutPhase() == LayoutPhase::InRenderTreeLayout; }
74     bool inPaintableState() const { return layoutPhase() != LayoutPhase::InRenderTreeLayout && layoutPhase() != LayoutPhase::InViewSizeAdjust && (layoutPhase() != LayoutPhase::InPostLayout || inAsynchronousTasks()); }
75
76     unsigned layoutCount() const { return m_layoutCount; }
77
78     RenderElement* subtreeLayoutRoot() const { return m_subtreeLayoutRoot.get(); }
79     void clearSubtreeLayoutRoot() { m_subtreeLayoutRoot.clear(); }
80     void convertSubtreeLayoutToFullLayout();
81
82     void reset();
83     void resetFirstLayoutFlag() { m_firstLayout = true; }
84     bool didFirstLayout() const { return !m_firstLayout; }
85
86     void setNeedsFullRepaint() { m_needsFullRepaint = true; }
87     bool needsFullRepaint() const { return m_needsFullRepaint; }
88
89     void flushAsynchronousTasks();
90
91     // Subtree push/pop
92     void pushLayoutState(RenderElement&);
93     bool pushLayoutStateForPaginationIfNeeded(RenderBlockFlow&);
94     void popLayoutState(RenderObject&);
95     LayoutState* layoutState() const { return m_layoutState.get(); }
96     // Returns true if layoutState should be used for its cached offset and clip.
97     bool isPaintOffsetCacheEnabled() const { return !m_paintOffsetCacheDisableCount && m_layoutState; }
98 #ifndef NDEBUG
99     void checkLayoutState();
100 #endif
101     // layoutDelta is used transiently during layout to store how far an object has moved from its
102     // last layout location, in order to repaint correctly.
103     // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter.
104     LayoutSize layoutDelta() const;
105     void addLayoutDelta(const LayoutSize& delta);
106 #if !ASSERT_DISABLED
107     bool layoutDeltaMatches(const LayoutSize& delta);
108 #endif
109
110 private:
111     friend class LayoutScope;
112     friend class LayoutStateMaintainer;
113     friend class LayoutStateDisabler;
114     friend class SubtreeLayoutStateMaintainer;
115
116     bool canPerformLayout() const;
117     bool layoutDisallowed() const { return m_layoutDisallowedCount; }
118     bool isLayoutSchedulingEnabled() const { return m_layoutSchedulingIsEnabled; }
119
120     void layoutTimerFired();
121     void runAsynchronousTasks();
122     void runOrScheduleAsynchronousTasks();
123     bool inAsynchronousTasks() const { return m_inAsynchronousTasks; }
124
125     void setSubtreeLayoutRoot(RenderElement&);
126
127 #if ENABLE(TEXT_AUTOSIZING)
128     void applyTextSizingIfNeeded(RenderElement& layoutRoot);
129 #endif
130     void updateStyleForLayout();
131
132     bool handleLayoutWithFrameFlatteningIfNeeded();
133     void startLayoutAtMainFrameViewIfNeeded();
134
135     // These functions may only be accessed by LayoutStateMaintainer.
136     bool pushLayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false);
137     void popLayoutState();
138
139     // Suspends the LayoutState optimization. Used under transforms that cannot be represented by
140     // LayoutState (common in SVG) and when manipulating the render tree during layout in ways
141     // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around).
142     // Note that even when disabled, LayoutState is still used to store layoutDelta.
143     // These functions may only be accessed by LayoutStateMaintainer or LayoutStateDisabler.
144     void disablePaintOffsetCache() { m_paintOffsetCacheDisableCount++; }
145     void enablePaintOffsetCache() { ASSERT(m_paintOffsetCacheDisableCount > 0); m_paintOffsetCacheDisableCount--; }
146
147     Frame& frame() const;
148     FrameView& view() const;
149     RenderView* renderView() const;
150     Document* document() const;
151
152     FrameView& m_frameView;
153     Timer m_layoutTimer;
154     Timer m_asynchronousTasksTimer;
155
156     bool m_layoutSchedulingIsEnabled { true };
157     bool m_delayedLayout { false };
158     bool m_firstLayout { true };
159     bool m_needsFullRepaint { true };
160     bool m_inAsynchronousTasks { false };
161     bool m_setNeedsLayoutWasDeferred { false };
162     LayoutPhase m_layoutPhase { LayoutPhase::OutsideLayout };
163     enum class LayoutNestedState { NotInLayout, NotNested, Nested };
164     LayoutNestedState m_layoutNestedState { LayoutNestedState::NotInLayout };
165     unsigned m_layoutCount { 0 };
166     unsigned m_disableSetNeedsLayoutCount { 0 };
167     int m_layoutDisallowedCount { 0 };
168     WeakPtr<RenderElement> m_subtreeLayoutRoot;
169     std::unique_ptr<LayoutState> m_layoutState;
170     unsigned m_paintOffsetCacheDisableCount { 0 };
171 };
172
173 } // namespace WebCore