- Revision
- 178531
- Author
- [email protected]
- Date
- 2015-01-15 14:51:12 -0800 (Thu, 15 Jan 2015)
Log Message
Layers need to be already updated before we call adjustViewSize
https://bugs.webkit.org/show_bug.cgi?id=135514
Reviewed by Simon Fraser.
Tested by 'fast/dynamic/layer-no-longer-paginated.html'
Defer updating scrollbars until we have finished layout. This
has a couple of benefits:
(1) We do not attempt to modify render layers during layout.
(2) In WK1 we do not attempt to paint during layout.
Add a new virtual predicate to ScrollView indicating when we are in
layout so that calls to setContentsSize do not attempt
to adjust scrollbars.
Modify FrameView to set its ScrollView state to block drawing
scrollbar updates during layout. Also add a post-layout
handler to complete the scrollbar updates after layout is
finished.
* page/FrameView.cpp:
(WebCore::FrameView::layout):
(WebCore::FrameView::shouldDeferScrollUpdateAfterContentSizeChange): Added.
* page/FrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::handleDeferredScrollUpdateAfterContentSizeChange): Added.
(WebCore::ScrollView::scrollTo): If we should defer painting, cache the
the scroll delta and apply it after the layout is complete.
* platform/ScrollView.h:
(WebCore::ScrollView::shouldDeferScrollUpdateAfterContentSizeChange): Added.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (178530 => 178531)
--- trunk/Source/WebCore/ChangeLog 2015-01-15 22:49:26 UTC (rev 178530)
+++ trunk/Source/WebCore/ChangeLog 2015-01-15 22:51:12 UTC (rev 178531)
@@ -1,3 +1,37 @@
+2015-01-15 Brent Fulgham <[email protected]>
+
+ Layers need to be already updated before we call adjustViewSize
+ https://bugs.webkit.org/show_bug.cgi?id=135514
+
+ Reviewed by Simon Fraser.
+
+ Tested by 'fast/dynamic/layer-no-longer-paginated.html'
+
+ Defer updating scrollbars until we have finished layout. This
+ has a couple of benefits:
+ (1) We do not attempt to modify render layers during layout.
+ (2) In WK1 we do not attempt to paint during layout.
+
+ Add a new virtual predicate to ScrollView indicating when we are in
+ layout so that calls to setContentsSize do not attempt
+ to adjust scrollbars.
+
+ Modify FrameView to set its ScrollView state to block drawing
+ scrollbar updates during layout. Also add a post-layout
+ handler to complete the scrollbar updates after layout is
+ finished.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::layout):
+ (WebCore::FrameView::shouldDeferScrollUpdateAfterContentSizeChange): Added.
+ * page/FrameView.h:
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::handleDeferredScrollUpdateAfterContentSizeChange): Added.
+ (WebCore::ScrollView::scrollTo): If we should defer painting, cache the
+ the scroll delta and apply it after the layout is complete.
+ * platform/ScrollView.h:
+ (WebCore::ScrollView::shouldDeferScrollUpdateAfterContentSizeChange): Added.
+
2015-01-15 Benjamin Poulain <[email protected]>
When building the NFA of the global disjunction, share the prefix subgraph of existing subpatterns
Modified: trunk/Source/WebCore/page/FrameView.cpp (178530 => 178531)
--- trunk/Source/WebCore/page/FrameView.cpp 2015-01-15 22:49:26 UTC (rev 178530)
+++ trunk/Source/WebCore/page/FrameView.cpp 2015-01-15 22:51:12 UTC (rev 178531)
@@ -1161,7 +1161,7 @@
if (!allowSubtree && m_layoutRoot) {
m_layoutRoot->markContainingBlocksForLayout(false);
- m_layoutRoot = 0;
+ m_layoutRoot = nullptr;
}
ASSERT(frame().view() == this);
@@ -1358,7 +1358,9 @@
layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, subtree, m_needsFullRepaint));
updateCompositingLayersAfterLayout();
-
+
+ m_layoutPhase = InPostLayerPositionsUpdatedAfterLayout;
+
m_layoutCount++;
#if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(EFL)
@@ -1378,6 +1380,8 @@
updateCanBlitOnScrollRecursively();
+ handleDeferredScrollUpdateAfterContentSizeChange();
+
if (document.hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < contentsHeight());
@@ -1409,6 +1413,11 @@
--m_nestedLayoutCount;
}
+bool FrameView::shouldDeferScrollUpdateAfterContentSizeChange()
+{
+ return (m_layoutPhase < InPostLayout) && (m_layoutPhase != OutsideLayout);
+}
+
RenderBox* FrameView::embeddedContentBox() const
{
RenderView* renderView = this->renderView();
@@ -2181,6 +2190,8 @@
void FrameView::updateCompositingLayersAfterScrolling()
{
+ ASSERT(m_layoutPhase >= InPostLayout || m_layoutPhase == OutsideLayout);
+
if (!shouldUpdateCompositingLayersAfterScrolling())
return;
@@ -3812,6 +3823,8 @@
void FrameView::paintContents(GraphicsContext* context, const IntRect& dirtyRect)
{
+ ASSERT(m_layoutPhase == InPostLayerPositionsUpdatedAfterLayout || m_layoutPhase == OutsideLayout);
+
#ifndef NDEBUG
bool fillWithRed;
if (frame().document()->printing())
Modified: trunk/Source/WebCore/page/FrameView.h (178530 => 178531)
--- trunk/Source/WebCore/page/FrameView.h 2015-01-15 22:49:26 UTC (rev 178530)
+++ trunk/Source/WebCore/page/FrameView.h 2015-01-15 22:51:12 UTC (rev 178531)
@@ -542,6 +542,7 @@
InLayout,
InViewSizeAdjust,
InPostLayout,
+ InPostLayerPositionsUpdatedAfterLayout,
};
LayoutPhase layoutPhase() const { return m_layoutPhase; }
@@ -558,6 +559,8 @@
bool shouldUpdateCompositingLayersAfterScrolling() const;
+ virtual bool shouldDeferScrollUpdateAfterContentSizeChange() override;
+
void applyOverflowToViewport(RenderElement*, ScrollbarMode& hMode, ScrollbarMode& vMode);
void applyPaginationToViewport();
Modified: trunk/Source/WebCore/platform/ScrollView.cpp (178530 => 178531)
--- trunk/Source/WebCore/platform/ScrollView.cpp 2015-01-15 22:49:26 UTC (rev 178530)
+++ trunk/Source/WebCore/platform/ScrollView.cpp 2015-01-15 22:51:12 UTC (rev 178531)
@@ -457,6 +457,19 @@
scrollTo(newOffset);
}
+void ScrollView::handleDeferredScrollUpdateAfterContentSizeChange()
+{
+ ASSERT(!shouldDeferScrollUpdateAfterContentSizeChange());
+ if (m_deferredScrollDelta.isZero())
+ return;
+
+ updateLayerPositionsAfterScrolling();
+ scrollContents(m_deferredScrollDelta);
+ updateCompositingLayersAfterScrolling();
+
+ m_deferredScrollDelta = IntSize();
+}
+
void ScrollView::scrollTo(const IntSize& newOffset)
{
IntSize scrollDelta = newOffset - m_scrollOffset;
@@ -473,6 +486,14 @@
return;
}
#endif
+ // We should not attempt to actually modify layer contents if the layout phase
+ // is not complete. Instead, defer the scroll event until the layout finishes.
+ if (shouldDeferScrollUpdateAfterContentSizeChange()) {
+ ASSERT(m_deferredScrollDelta.isZero());
+ m_deferredScrollDelta = scrollDelta;
+ return;
+ }
+
updateLayerPositionsAfterScrolling();
scrollContents(scrollDelta);
updateCompositingLayersAfterScrolling();
Modified: trunk/Source/WebCore/platform/ScrollView.h (178530 => 178531)
--- trunk/Source/WebCore/platform/ScrollView.h 2015-01-15 22:49:26 UTC (rev 178530)
+++ trunk/Source/WebCore/platform/ScrollView.h 2015-01-15 22:51:12 UTC (rev 178531)
@@ -417,6 +417,10 @@
float platformTopContentInset() const;
void platformSetTopContentInset(float);
+ void handleDeferredScrollUpdateAfterContentSizeChange();
+
+ virtual bool shouldDeferScrollUpdateAfterContentSizeChange() { return false; }
+
private:
virtual IntRect visibleContentRectInternal(VisibleContentRectIncludesScrollbars, VisibleContentRectBehavior) const override;
WEBCORE_EXPORT IntRect unobscuredContentRectInternal(VisibleContentRectIncludesScrollbars = ExcludeScrollbars) const;
@@ -449,6 +453,7 @@
IntPoint m_cachedScrollPosition;
IntSize m_fixedLayoutSize;
IntSize m_contentsSize;
+ IntSize m_deferredScrollDelta;
int m_scrollbarsAvoidingResizer;
bool m_scrollbarsSuppressed;