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 painting operations 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 paint
operations during layout. Also add a post-layout handler to
complete the scrollbar updates after layout is finished.

* WebCore.exp.in: Move linker symbol to ScrollView (from FrameView).
* page/FrameView.cpp:
(WebCore::FrameView::layout):
(WebCore::FrameView::shouldDeferScrollUpdateAfterContentSizeChange): Added.
(WebCore::FrameView::scrollPositionChangedViaPlatformWidget): Removed (Renamed).
(WebCore::FrameView::scrollPositionChangedViaPlatformWidgetImpl): Added (Renamed)
(WebCore::FrameView::paintContents): Do not paint if we are inside view size adjustment.
* page/FrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::scrollPositionChangedViaPlatformWidget): Added. Checks whether we need to defer
painting, and calls virtual scrollPositionChangedViaPlatformWidgetImpl if we do not.
(WebCore::FrameView::scrollPositionChangedViaPlatformWidgetImpl): Added.
(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.
(WebCore::ScrollView::completeUpdatesAfterScrollTo): Split off part of 'scrollTo' into its own method
so we can reuse it in handleDeferredScrollUpdateAfterContentSizeChange.
* platform/ScrollView.h:
(WebCore::ScrollView::shouldDeferScrollUpdateAfterContentSizeChange): Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@178661 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp
index 46d1b6b..7eb94c3 100644
--- a/Source/WebCore/platform/ScrollView.cpp
+++ b/Source/WebCore/platform/ScrollView.cpp
@@ -457,10 +457,41 @@
     scrollTo(newOffset);
 }
 
+void ScrollView::scrollPositionChangedViaPlatformWidget(const IntPoint& oldPosition, const IntPoint& newPosition)
+{
+    // We should not attempt to actually modify (paint) platform widgets if the layout phase
+    // is not complete. Instead, defer the scroll event until the layout finishes.
+    if (shouldDeferScrollUpdateAfterContentSizeChange()) {
+        // We only care about the most recent scroll position change request
+        m_deferredScrollPositions = std::make_unique<std::pair<IntPoint, IntPoint>>(std::make_pair(oldPosition, newPosition));
+        return;
+    }
+
+    scrollPositionChangedViaPlatformWidgetImpl(oldPosition, newPosition);
+}
+
+void ScrollView::handleDeferredScrollUpdateAfterContentSizeChange()
+{
+    ASSERT(!shouldDeferScrollUpdateAfterContentSizeChange());
+
+    if (!m_deferredScrollDelta && !m_deferredScrollPositions)
+        return;
+
+    ASSERT(static_cast<bool>(m_deferredScrollDelta) != static_cast<bool>(m_deferredScrollPositions));
+
+    if (m_deferredScrollDelta)
+        completeUpdatesAfterScrollTo(*m_deferredScrollDelta);
+    else if (m_deferredScrollPositions)
+        scrollPositionChangedViaPlatformWidgetImpl(m_deferredScrollPositions->first, m_deferredScrollPositions->second);
+    
+    m_deferredScrollDelta = nullptr;
+    m_deferredScrollPositions = nullptr;
+}
+
 void ScrollView::scrollTo(const IntSize& newOffset)
 {
     IntSize scrollDelta = newOffset - m_scrollOffset;
-    if (scrollDelta == IntSize())
+    if (scrollDelta.isZero())
         return;
     m_scrollOffset = newOffset;
 
@@ -473,6 +504,19 @@
         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);
+        m_deferredScrollDelta = std::make_unique<IntSize>(scrollDelta);
+        return;
+    }
+
+    completeUpdatesAfterScrollTo(scrollDelta);
+}
+
+void ScrollView::completeUpdatesAfterScrollTo(const IntSize& scrollDelta)
+{
     updateLayerPositionsAfterScrolling();
     scrollContents(scrollDelta);
     updateCompositingLayersAfterScrolling();