Diff
Modified: trunk/Source/WebCore/ChangeLog (224611 => 224612)
--- trunk/Source/WebCore/ChangeLog 2017-11-09 01:13:27 UTC (rev 224611)
+++ trunk/Source/WebCore/ChangeLog 2017-11-09 01:32:17 UTC (rev 224612)
@@ -1,3 +1,35 @@
+2017-11-08 Zalan Bujtas <za...@apple.com>
+
+ [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):
+
2017-11-08 Brady Eidson <beid...@apple.com>
ServiceWorkerRegistration::updateStateFromServer fix! (Don't always create a new ServiceWorker every time).
Modified: trunk/Source/WebCore/page/LayoutContext.cpp (224611 => 224612)
--- trunk/Source/WebCore/page/LayoutContext.cpp 2017-11-09 01:13:27 UTC (rev 224611)
+++ trunk/Source/WebCore/page/LayoutContext.cpp 2017-11-09 01:32:17 UTC (rev 224612)
@@ -530,43 +530,49 @@
LayoutSize LayoutContext::layoutDelta() const
{
- if (!m_layoutState)
- return { };
- return m_layoutState->layoutDelta();
+ if (auto* layoutState = this->layoutState())
+ return layoutState->layoutDelta();
+ return { };
}
void LayoutContext::addLayoutDelta(const LayoutSize& delta)
{
- if (!m_layoutState)
- return;
- m_layoutState->addLayoutDelta(delta);
+ if (auto* layoutState = this->layoutState())
+ layoutState->addLayoutDelta(delta);
}
#if !ASSERT_DISABLED
bool LayoutContext::layoutDeltaMatches(const LayoutSize& delta)
{
- if (!m_layoutState)
- return false;
- return m_layoutState->layoutDeltaMatches(delta);
+ if (auto* layoutState = this->layoutState())
+ return layoutState->layoutDeltaMatches(delta);
+ return false;
}
#endif
-
+
+LayoutState* LayoutContext::layoutState() const
+{
+ if (m_layoutStateStack.isEmpty())
+ return nullptr;
+ return m_layoutStateStack.last().get();
+}
+
void LayoutContext::pushLayoutState(RenderElement& root)
{
ASSERT(!m_paintOffsetCacheDisableCount);
- ASSERT(!m_layoutState);
+ ASSERT(!layoutState());
- m_layoutState = std::make_unique<LayoutState>(root);
+ m_layoutStateStack.append(std::make_unique<LayoutState>(root));
}
bool LayoutContext::pushLayoutStateForPaginationIfNeeded(RenderBlockFlow& layoutRoot)
{
- if (m_layoutState)
+ if (layoutState())
return false;
- m_layoutState = std::make_unique<LayoutState>(layoutRoot);
- m_layoutState->setIsPaginated();
+ m_layoutStateStack.append(std::make_unique<LayoutState>(layoutRoot));
+ layoutState()->setIsPaginated();
// This is just a flag for known page height (see RenderBlockFlow::checkForPaginationLogicalHeightChange).
- m_layoutState->setPageLogicalHeight(1);
+ layoutState()->setPageLogicalHeight(1);
return true;
}
@@ -578,9 +584,10 @@
bool LayoutContext::pushLayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged)
{
// We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
- if (!m_layoutState || !needsFullRepaint() || m_layoutState->isPaginated() || renderer.enclosingFragmentedFlow()
- || m_layoutState->lineGrid() || (renderer.style().lineGrid() != RenderStyle::initialLineGrid() && renderer.isRenderBlockFlow())) {
- m_layoutState = std::make_unique<LayoutState>(WTFMove(m_layoutState), renderer, offset, pageHeight, pageHeightChanged);
+ auto* layoutState = this->layoutState();
+ if (!layoutState || !needsFullRepaint() || layoutState->isPaginated() || renderer.enclosingFragmentedFlow()
+ || layoutState->lineGrid() || (renderer.style().lineGrid() != RenderStyle::initialLineGrid() && renderer.isRenderBlockFlow())) {
+ m_layoutStateStack.append(std::make_unique<LayoutState>(m_layoutStateStack, renderer, offset, pageHeight, pageHeightChanged));
return true;
}
return false;
@@ -588,7 +595,7 @@
void LayoutContext::popLayoutState()
{
- m_layoutState = WTFMove(m_layoutState->m_ancestor);
+ m_layoutStateStack.removeLast();
}
#ifndef NDEBUG
Modified: trunk/Source/WebCore/page/LayoutContext.h (224611 => 224612)
--- trunk/Source/WebCore/page/LayoutContext.h 2017-11-09 01:13:27 UTC (rev 224611)
+++ trunk/Source/WebCore/page/LayoutContext.h 2017-11-09 01:32:17 UTC (rev 224612)
@@ -25,6 +25,7 @@
#pragma once
+#include "LayoutUnit.h"
#include "Timer.h"
#include <wtf/WeakPtr.h>
@@ -35,8 +36,11 @@
class Frame;
class FrameView;
class LayoutScope;
+class LayoutSize;
class LayoutState;
class RenderBlockFlow;
+class RenderBox;
+class RenderObject;
class RenderElement;
class RenderView;
@@ -92,9 +96,9 @@
void pushLayoutState(RenderElement&);
bool pushLayoutStateForPaginationIfNeeded(RenderBlockFlow&);
void popLayoutState(RenderObject&);
- LayoutState* layoutState() const { return m_layoutState.get(); }
+ LayoutState* layoutState() const;
// Returns true if layoutState should be used for its cached offset and clip.
- bool isPaintOffsetCacheEnabled() const { return !m_paintOffsetCacheDisableCount && m_layoutState; }
+ bool isPaintOffsetCacheEnabled() const { return !m_paintOffsetCacheDisableCount && layoutState(); }
#ifndef NDEBUG
void checkLayoutState();
#endif
@@ -106,6 +110,7 @@
#if !ASSERT_DISABLED
bool layoutDeltaMatches(const LayoutSize& delta);
#endif
+ using LayoutStateStack = Vector<std::unique_ptr<LayoutState>>;
private:
friend class LayoutScope;
@@ -166,7 +171,7 @@
unsigned m_disableSetNeedsLayoutCount { 0 };
int m_layoutDisallowedCount { 0 };
WeakPtr<RenderElement> m_subtreeLayoutRoot;
- std::unique_ptr<LayoutState> m_layoutState;
+ LayoutStateStack m_layoutStateStack;
unsigned m_paintOffsetCacheDisableCount { 0 };
};
Modified: trunk/Source/WebCore/rendering/LayoutState.cpp (224611 => 224612)
--- trunk/Source/WebCore/rendering/LayoutState.cpp 2017-11-09 01:13:27 UTC (rev 224611)
+++ trunk/Source/WebCore/rendering/LayoutState.cpp 2017-11-09 01:32:17 UTC (rev 224612)
@@ -26,7 +26,6 @@
#include "config.h"
#include "LayoutState.h"
-#include "LayoutContext.h"
#include "RenderFragmentedFlow.h"
#include "RenderInline.h"
#include "RenderLayer.h"
@@ -60,9 +59,8 @@
}
}
-LayoutState::LayoutState(std::unique_ptr<LayoutState> ancestor, RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
- : m_ancestor(WTFMove(ancestor))
- , m_clipped(false)
+LayoutState::LayoutState(const LayoutContext::LayoutStateStack& layoutStateStack, RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
+ : m_clipped(false)
, m_isPaginated(false)
, m_pageLogicalHeightChanged(false)
#if !ASSERT_DISABLED
@@ -73,23 +71,22 @@
, m_renderer(&renderer)
#endif
{
- if (m_ancestor) {
- computeOffsets(renderer, offset);
- computeClipRect(renderer);
+ if (!layoutStateStack.isEmpty()) {
+ auto& ancestor = *layoutStateStack.last().get();
+ computeOffsets(ancestor, renderer, offset);
+ computeClipRect(ancestor, renderer);
}
- computePaginationInformation(renderer, pageLogicalHeight, pageLogicalHeightChanged);
+ computePaginationInformation(layoutStateStack, renderer, pageLogicalHeight, pageLogicalHeightChanged);
}
-void LayoutState::computeOffsets(RenderBox& renderer, LayoutSize offset)
+void LayoutState::computeOffsets(const LayoutState& ancestor, RenderBox& renderer, LayoutSize offset)
{
- ASSERT(m_ancestor);
-
bool fixed = renderer.isFixedPositioned();
if (fixed) {
FloatPoint fixedOffset = renderer.view().localToAbsolute(FloatPoint(), IsFixed);
m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset;
} else
- m_paintOffset = m_ancestor->m_paintOffset + offset;
+ m_paintOffset = ancestor.paintOffset() + offset;
if (renderer.isOutOfFlowPositioned() && !fixed) {
if (auto* container = renderer.container()) {
@@ -106,20 +103,18 @@
if (renderer.hasOverflowClip())
m_paintOffset -= toLayoutSize(renderer.scrollPosition());
- m_layoutDelta = m_ancestor->m_layoutDelta;
+ m_layoutDelta = ancestor.layoutDelta();
#if !ASSERT_DISABLED
- m_layoutDeltaXSaturated = m_ancestor->m_layoutDeltaXSaturated;
- m_layoutDeltaYSaturated = m_ancestor->m_layoutDeltaYSaturated;
+ m_layoutDeltaXSaturated = ancestor.m_layoutDeltaXSaturated;
+ m_layoutDeltaYSaturated = ancestor.m_layoutDeltaYSaturated;
#endif
}
-void LayoutState::computeClipRect(RenderBox& renderer)
+void LayoutState::computeClipRect(const LayoutState& ancestor, RenderBox& renderer)
{
- ASSERT(m_ancestor);
-
- m_clipped = !renderer.isFixedPositioned() && m_ancestor->m_clipped;
+ m_clipped = !renderer.isFixedPositioned() && ancestor.isClipped();
if (m_clipped)
- m_clipRect = m_ancestor->m_clipRect;
+ m_clipRect = ancestor.clipRect();
if (!renderer.hasOverflowClip())
return;
@@ -132,10 +127,11 @@
// FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
}
-void LayoutState::computePaginationInformation(RenderBox& renderer, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
+void LayoutState::computePaginationInformation(const LayoutContext::LayoutStateStack& layoutStateStack, RenderBox& renderer, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged)
{
+ auto* ancestor = layoutStateStack.isEmpty() ? nullptr : layoutStateStack.last().get();
// If we establish a new page height, then cache the offset to the top of the first page.
- // We can compare this later on to figure out what part of the page we're actually on,
+ // We can compare this later on to figure out what part of the page we're actually on.
if (pageLogicalHeight || renderer.isRenderFragmentedFlow()) {
m_pageLogicalHeight = pageLogicalHeight;
bool isFlipped = renderer.style().isFlippedBlocksWritingMode();
@@ -142,11 +138,11 @@
m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? renderer.borderLeft() + renderer.paddingLeft() : renderer.borderRight() + renderer.paddingRight()), m_layoutOffset.height() + (!isFlipped ? renderer.borderTop() + renderer.paddingTop() : renderer.borderBottom() + renderer.paddingBottom()));
m_pageLogicalHeightChanged = pageLogicalHeightChanged;
m_isPaginated = true;
- } else if (m_ancestor) {
+ } else if (ancestor) {
// If we don't establish a new page height, then propagate the old page height and offset down.
- m_pageLogicalHeight = m_ancestor->m_pageLogicalHeight;
- m_pageLogicalHeightChanged = m_ancestor->m_pageLogicalHeightChanged;
- m_pageOffset = m_ancestor->m_pageOffset;
+ m_pageLogicalHeight = ancestor->pageLogicalHeight();
+ m_pageLogicalHeightChanged = ancestor->pageLogicalHeightChanged();
+ m_pageOffset = ancestor->pageOffset();
// Disable pagination for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and writing mode roots.
if (renderer.isUnsplittableForPagination()) {
@@ -157,7 +153,8 @@
}
// Propagate line grid information.
- propagateLineGridInfo(renderer);
+ if (ancestor)
+ propagateLineGridInfo(*ancestor, renderer);
if (lineGrid() && (lineGrid()->style().writingMode() == renderer.style().writingMode()) && is<RenderMultiColumnFlow>(renderer))
downcast<RenderMultiColumnFlow>(renderer).computeLineGridPaginationOrigin(*this);
@@ -164,15 +161,9 @@
// If we have a new grid to track, then add it to our set.
if (renderer.style().lineGrid() != RenderStyle::initialLineGrid() && is<RenderBlockFlow>(renderer))
- establishLineGrid(downcast<RenderBlockFlow>(renderer));
+ establishLineGrid(layoutStateStack, downcast<RenderBlockFlow>(renderer));
}
-void LayoutState::clearPaginationInformation()
-{
- m_pageLogicalHeight = m_ancestor->m_pageLogicalHeight;
- m_pageOffset = m_ancestor->m_pageOffset;
-}
-
LayoutUnit LayoutState::pageLogicalOffset(RenderBox* child, LayoutUnit childLogicalOffset) const
{
if (child->isHorizontalWritingMode())
@@ -180,34 +171,36 @@
return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width();
}
-void LayoutState::propagateLineGridInfo(RenderBox& renderer)
+void LayoutState::propagateLineGridInfo(const LayoutState& ancestor, RenderBox& renderer)
{
// Disable line grids for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and
// writing mode roots.
- if (!m_ancestor || renderer.isUnsplittableForPagination())
+ if (renderer.isUnsplittableForPagination())
return;
- m_lineGrid = m_ancestor->m_lineGrid;
- m_lineGridOffset = m_ancestor->m_lineGridOffset;
- m_lineGridPaginationOrigin = m_ancestor->m_lineGridPaginationOrigin;
+ m_lineGrid = ancestor.lineGrid();
+ m_lineGridOffset = ancestor.lineGridOffset();
+ m_lineGridPaginationOrigin = ancestor.lineGridPaginationOrigin();
}
-void LayoutState::establishLineGrid(RenderBlockFlow& renderer)
+void LayoutState::establishLineGrid(const LayoutContext::LayoutStateStack& layoutStateStack, RenderBlockFlow& renderer)
{
+ // FIXME: webkit.org/b/179440 This logic should be part of the LayoutContext.
// First check to see if this grid has been established already.
if (m_lineGrid) {
if (m_lineGrid->style().lineGrid() == renderer.style().lineGrid())
return;
RenderBlockFlow* currentGrid = m_lineGrid;
- for (LayoutState* currentState = m_ancestor.get(); currentState; currentState = currentState->m_ancestor.get()) {
- if (currentState->m_lineGrid == currentGrid)
+ for (int i = layoutStateStack.size() - 1; i <= 0; --i) {
+ auto& currentState = *layoutStateStack[i].get();
+ if (currentState.m_lineGrid == currentGrid)
continue;
- currentGrid = currentState->m_lineGrid;
+ currentGrid = currentState.m_lineGrid;
if (!currentGrid)
break;
if (currentGrid->style().lineGrid() == renderer.style().lineGrid()) {
m_lineGrid = currentGrid;
- m_lineGridOffset = currentState->m_lineGridOffset;
+ m_lineGridOffset = currentState.m_lineGridOffset;
return;
}
}
Modified: trunk/Source/WebCore/rendering/LayoutState.h (224611 => 224612)
--- trunk/Source/WebCore/rendering/LayoutState.h 2017-11-09 01:13:27 UTC (rev 224611)
+++ trunk/Source/WebCore/rendering/LayoutState.h 2017-11-09 01:32:17 UTC (rev 224612)
@@ -25,6 +25,7 @@
#pragma once
+#include "LayoutContext.h"
#include "LayoutRect.h"
#include <wtf/Noncopyable.h>
@@ -51,13 +52,11 @@
#endif
{
}
-
- LayoutState(std::unique_ptr<LayoutState> ancestor, RenderBox&, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged);
+ LayoutState(const LayoutContext::LayoutStateStack&, RenderBox&, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged);
explicit LayoutState(RenderElement&);
bool isPaginated() const { return m_isPaginated; }
void setIsPaginated() { m_isPaginated = true; }
- void clearPaginationInformation();
// The page logical offset is the object's offset from the top of the page in the page progression
// direction (so an x-offset in vertical text and a y-offset for horizontal text).
@@ -93,15 +92,12 @@
bool layoutDeltaMatches(LayoutSize);
#endif
- // FIXME: webkit.org/b/179408 LayoutContext should own the stack of LayoutState objects
- std::unique_ptr<LayoutState> m_ancestor;
-
private:
- void computeOffsets(RenderBox&, LayoutSize offset);
- void computeClipRect(RenderBox&);
- void computePaginationInformation(RenderBox&, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged);
- void propagateLineGridInfo(RenderBox&);
- void establishLineGrid(RenderBlockFlow&);
+ void computeOffsets(const LayoutState& ancestor, RenderBox&, LayoutSize offset);
+ void computeClipRect(const LayoutState& ancestor, RenderBox&);
+ void computePaginationInformation(const LayoutContext::LayoutStateStack&, RenderBox&, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged);
+ void propagateLineGridInfo(const LayoutState& ancestor, RenderBox&);
+ void establishLineGrid(const LayoutContext::LayoutStateStack&, RenderBlockFlow&);
// Do not add anything apart from bitfields. See https://bugs.webkit.org/show_bug.cgi?id=100173
bool m_clipped : 1;
@@ -112,7 +108,6 @@
bool m_layoutDeltaXSaturated : 1;
bool m_layoutDeltaYSaturated : 1;
#endif
-
// The current line grid that we're snapping to and the offset of the start of the grid.
RenderBlockFlow* m_lineGrid { nullptr };