<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[178531] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/178531">178531</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2015-01-15 14:51:12 -0800 (Thu, 15 Jan 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepageFrameViewcpp">trunk/Source/WebCore/page/FrameView.cpp</a></li>
<li><a href="#trunkSourceWebCorepageFrameViewh">trunk/Source/WebCore/page/FrameView.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollViewcpp">trunk/Source/WebCore/platform/ScrollView.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollViewh">trunk/Source/WebCore/platform/ScrollView.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (178530 => 178531)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2015-01-15  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        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.
+
</ins><span class="cx"> 2015-01-15  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         When building the NFA of the global disjunction, share the prefix subgraph of existing subpatterns
</span></span></pre></div>
<a id="trunkSourceWebCorepageFrameViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/FrameView.cpp (178530 => 178531)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1161,7 +1161,7 @@
</span><span class="cx">     
</span><span class="cx">     if (!allowSubtree &amp;&amp; m_layoutRoot) {
</span><span class="cx">         m_layoutRoot-&gt;markContainingBlocksForLayout(false);
</span><del>-        m_layoutRoot = 0;
</del><ins>+        m_layoutRoot = nullptr;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ASSERT(frame().view() == this);
</span><span class="lines">@@ -1358,7 +1358,9 @@
</span><span class="cx">     layer-&gt;updateLayerPositionsAfterLayout(renderView()-&gt;layer(), updateLayerPositionFlags(layer, subtree, m_needsFullRepaint));
</span><span class="cx"> 
</span><span class="cx">     updateCompositingLayersAfterLayout();
</span><del>-    
</del><ins>+
+    m_layoutPhase = InPostLayerPositionsUpdatedAfterLayout;
+
</ins><span class="cx">     m_layoutCount++;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(EFL)
</span><span class="lines">@@ -1378,6 +1380,8 @@
</span><span class="cx"> 
</span><span class="cx">     updateCanBlitOnScrollRecursively();
</span><span class="cx"> 
</span><ins>+    handleDeferredScrollUpdateAfterContentSizeChange();
+
</ins><span class="cx">     if (document.hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
</span><span class="cx">         updateOverflowStatus(layoutWidth() &lt; contentsWidth(), layoutHeight() &lt; contentsHeight());
</span><span class="cx"> 
</span><span class="lines">@@ -1409,6 +1413,11 @@
</span><span class="cx">     --m_nestedLayoutCount;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool FrameView::shouldDeferScrollUpdateAfterContentSizeChange()
+{
+    return (m_layoutPhase &lt; InPostLayout) &amp;&amp; (m_layoutPhase != OutsideLayout);
+}
+
</ins><span class="cx"> RenderBox* FrameView::embeddedContentBox() const
</span><span class="cx"> {
</span><span class="cx">     RenderView* renderView = this-&gt;renderView();
</span><span class="lines">@@ -2181,6 +2190,8 @@
</span><span class="cx"> 
</span><span class="cx"> void FrameView::updateCompositingLayersAfterScrolling()
</span><span class="cx"> {
</span><ins>+    ASSERT(m_layoutPhase &gt;= InPostLayout || m_layoutPhase == OutsideLayout);
+
</ins><span class="cx">     if (!shouldUpdateCompositingLayersAfterScrolling())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -3812,6 +3823,8 @@
</span><span class="cx"> 
</span><span class="cx"> void FrameView::paintContents(GraphicsContext* context, const IntRect&amp; dirtyRect)
</span><span class="cx"> {
</span><ins>+    ASSERT(m_layoutPhase == InPostLayerPositionsUpdatedAfterLayout || m_layoutPhase == OutsideLayout);
+
</ins><span class="cx"> #ifndef NDEBUG
</span><span class="cx">     bool fillWithRed;
</span><span class="cx">     if (frame().document()-&gt;printing())
</span></span></pre></div>
<a id="trunkSourceWebCorepageFrameViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/FrameView.h (178530 => 178531)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -542,6 +542,7 @@
</span><span class="cx">         InLayout,
</span><span class="cx">         InViewSizeAdjust,
</span><span class="cx">         InPostLayout,
</span><ins>+        InPostLayerPositionsUpdatedAfterLayout,
</ins><span class="cx">     };
</span><span class="cx">     LayoutPhase layoutPhase() const { return m_layoutPhase; }
</span><span class="cx"> 
</span><span class="lines">@@ -558,6 +559,8 @@
</span><span class="cx"> 
</span><span class="cx">     bool shouldUpdateCompositingLayersAfterScrolling() const;
</span><span class="cx"> 
</span><ins>+    virtual bool shouldDeferScrollUpdateAfterContentSizeChange() override;
+
</ins><span class="cx">     void applyOverflowToViewport(RenderElement*, ScrollbarMode&amp; hMode, ScrollbarMode&amp; vMode);
</span><span class="cx">     void applyPaginationToViewport();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollView.cpp (178530 => 178531)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -457,6 +457,19 @@
</span><span class="cx">     scrollTo(newOffset);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScrollView::handleDeferredScrollUpdateAfterContentSizeChange()
+{
+    ASSERT(!shouldDeferScrollUpdateAfterContentSizeChange());
+    if (m_deferredScrollDelta.isZero())
+        return;
+
+    updateLayerPositionsAfterScrolling();
+    scrollContents(m_deferredScrollDelta);
+    updateCompositingLayersAfterScrolling();
+
+    m_deferredScrollDelta = IntSize();
+}
+
</ins><span class="cx"> void ScrollView::scrollTo(const IntSize&amp; newOffset)
</span><span class="cx"> {
</span><span class="cx">     IntSize scrollDelta = newOffset - m_scrollOffset;
</span><span class="lines">@@ -473,6 +486,14 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><ins>+    // 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;
+    }
+
</ins><span class="cx">     updateLayerPositionsAfterScrolling();
</span><span class="cx">     scrollContents(scrollDelta);
</span><span class="cx">     updateCompositingLayersAfterScrolling();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollView.h (178530 => 178531)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -417,6 +417,10 @@
</span><span class="cx">     float platformTopContentInset() const;
</span><span class="cx">     void platformSetTopContentInset(float);
</span><span class="cx"> 
</span><ins>+    void handleDeferredScrollUpdateAfterContentSizeChange();
+
+    virtual bool shouldDeferScrollUpdateAfterContentSizeChange() { return false; }
+
</ins><span class="cx"> private:
</span><span class="cx">     virtual IntRect visibleContentRectInternal(VisibleContentRectIncludesScrollbars, VisibleContentRectBehavior) const override;
</span><span class="cx">     WEBCORE_EXPORT IntRect unobscuredContentRectInternal(VisibleContentRectIncludesScrollbars = ExcludeScrollbars) const;
</span><span class="lines">@@ -449,6 +453,7 @@
</span><span class="cx">     IntPoint m_cachedScrollPosition;
</span><span class="cx">     IntSize m_fixedLayoutSize;
</span><span class="cx">     IntSize m_contentsSize;
</span><ins>+    IntSize m_deferredScrollDelta;
</ins><span class="cx"> 
</span><span class="cx">     int m_scrollbarsAvoidingResizer;
</span><span class="cx">     bool m_scrollbarsSuppressed;
</span></span></pre>
</div>
</div>

</body>
</html>