<!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>[246869] trunk</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/246869">246869</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2019-06-26 21:13:15 -0700 (Wed, 26 Jun 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Async overflow scrolling] Fix missing or misplaced content inside overflow:scroll
https://bugs.webkit.org/show_bug.cgi?id=199253
Source/WebCore:

rdar://problem/51855156, rdar://problem/51934514

Reviewed by Zalan Bujtas.

This patch fixes a couple of related issues triggered by failing to composite layers inside non-stacking-context
overflow scroll.

First, we relied on overlap testing to composite position:relative layers inside overflow:scroll, but this only
worked when they came later in z-order, so didn't work for layers with negative z-index.
RenderLayerCompositor::requiresCompositingForIndirectReason() was intended to trigger compositing in such cases,
but it only did so for position:absolute inside stacking-context scroller, because
isNonScrolledLayerInsideScrolledCompositedAncestor() tested ancestorMovedByScroller && !layerMovedByScroller.

I fixed this by sharing code between the three places that ask whether compositing crosses a containing-block
boundary to call a single function, RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor(),
that returns a ScrollPositioningBehavior. We now do compositing for both "moves" and "stationary" behaviors (but
not "none"), ensuring that position:relative inside non-stacking scroller is always composited.

However, this would trigger compositing on layers that should be using backing sharing; if they were outside the
visible part of the scroller, the overlap code would not trigger, but the
"IndirectCompositingReason::OverflowScrollPositioning" code would. This is undesirable; any layer that can use
backing sharing should, because that's fewer composited layers, so smaller layer trees and less backing store.
To fix this, I moved the backing-sharing check before the overlap check in
RenderLayerCompositor::computeCompositingRequirements().

The "layer.setHasCompositingDescendant(currentState.subtreeIsCompositing)" line was in the wrong place,
triggering assertions on some content; "subtreeIsCompositing" only refers to child layers, so this bit needs to
be set right after we've traversed the z-order lists.

Tests: compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller.html
       compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller.html
       compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller.html

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
(WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
(WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const):
(WebCore::isScrolledByOverflowScrollLayer):
(WebCore::enclosingCompositedScrollingLayer):
(WebCore::RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor):
(WebCore::RenderLayerCompositor::computeCoordinatedPositioningForLayer const):
(WebCore::isNonScrolledLayerInsideScrolledCompositedAncestor): Deleted.
(WebCore::RenderLayerCompositor::layerContainingBlockCrossesCoordinatedScrollingBoundary): Deleted.
* rendering/RenderLayerCompositor.h:

LayoutTests:

Reviewed by Zalan Bujtas.

* compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
* compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt:
* compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt:
* compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
* compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller-expected.html: Added.
* compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller.html: Added.
* compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller.html: Added.
* compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller-expected.html: Added.
* compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller.html: Added.
* compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt:
* platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt:
* platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt:
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt: Added.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt:
* platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestscompositinggeometrylimitlayerboundsclippingancestorexpectedtxt">trunk/LayoutTests/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt</a></li>
<li><a href="#trunkLayoutTestscompositinglayercreationclippingscopeoverlapconstrainedinsidescrollerexpectedtxt">trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt</a></li>
<li><a href="#trunkLayoutTestscompositinglayercreationclippingscopescrollerwithnegativezchildrenexpectedtxt">trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt</a></li>
<li><a href="#trunkLayoutTestscompositingrtlrtlscrollingwithtransformeddescendantsexpectedtxt">trunk/LayoutTests/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt</a></li>
<li><a href="#trunkLayoutTestscompositingsharedbackingoverflowscrollnestedabsolutewithclippinginstackingoverflowexpectedtxt">trunk/LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformioscompositinggeometrylimitlayerboundsclippingancestorexpectedtxt">trunk/LayoutTests/platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformioswk2compositinglayercreationclippingscopeoverlapconstrainedinsidescrollerexpectedtxt">trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformioswk2compositinglayercreationclippingscopescrollerwithnegativezchildrenexpectedtxt">trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformioswk2compositingsharedbackingoverflowscrollnestedabsolutewithclippinginstackingoverflowexpectedtxt">trunk/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerCompositorcpp">trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerCompositorh">trunk/Source/WebCore/rendering/RenderLayerCompositor.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscompositingscrollingasyncoverflowscrollinghiddenrelativelayercontentinscrollerexpectedhtml">trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller-expected.html</a></li>
<li><a href="#trunkLayoutTestscompositingscrollingasyncoverflowscrollinghiddenrelativelayercontentinscrollerhtml">trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller.html</a></li>
<li><a href="#trunkLayoutTestscompositingscrollingasyncoverflowscrollinglayerfornegativezinscrollerexpectedtxt">trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt</a></li>
<li><a href="#trunkLayoutTestscompositingscrollingasyncoverflowscrollinglayerfornegativezinscrollerhtml">trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller.html</a></li>
<li><a href="#trunkLayoutTestscompositingscrollingasyncoverflowscrollingnegativezinscrollerexpectedhtml">trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller-expected.html</a></li>
<li><a href="#trunkLayoutTestscompositingscrollingasyncoverflowscrollingnegativezinscrollerhtml">trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller.html</a></li>
<li><a href="#trunkLayoutTestsplatformioswk2compositingscrollingasyncoverflowscrollinglayerfornegativezinscrollerexpectedtxt">trunk/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/ChangeLog 2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2019-06-26  Simon Fraser  <simon.fraser@apple.com>
+
+        [Async overflow scrolling] Fix missing or misplaced content inside overflow:scroll
+        https://bugs.webkit.org/show_bug.cgi?id=199253
+
+        Reviewed by Zalan Bujtas.
+
+        * compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
+        * compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt:
+        * compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt:
+        * compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
+        * compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller-expected.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller-expected.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller.html: Added.
+        * compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt:
+        * platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt:
+        * platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt:
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt: Added.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt:
+        * platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
+
</ins><span class="cx"> 2019-06-26  Ryosuke Niwa  <rniwa@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         ReplacementFragment should not have script observable side effects
</span></span></pre></div>
<a id="trunkLayoutTestscompositinggeometrylimitlayerboundsclippingancestorexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt 2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt    2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -27,7 +27,8 @@
</span><span class="cx">           (children 1
</span><span class="cx">             (GraphicsLayer
</span><span class="cx">               (offsetFromRenderer width=0 height=100)
</span><del>-              (bounds 149.00 200.00)
</del><ins>+              (bounds 149.00 2086.00)
+              (usingTiledLayer 1)
</ins><span class="cx">               (drawsContent 1)
</span><span class="cx">             )
</span><span class="cx">           )
</span></span></pre></div>
<a id="trunkLayoutTestscompositinglayercreationclippingscopeoverlapconstrainedinsidescrollerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt     2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt        2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -5,7 +5,7 @@
</span><span class="cx">     (GraphicsLayer
</span><span class="cx">       (bounds 800.00 600.00)
</span><span class="cx">       (contentsOpaque 1)
</span><del>-      (children 5
</del><ins>+      (children 6
</ins><span class="cx">         (GraphicsLayer
</span><span class="cx">           (position 8.00 8.00)
</span><span class="cx">           (bounds 302.00 302.00)
</span><span class="lines">@@ -69,6 +69,17 @@
</span><span class="cx">             )
</span><span class="cx">           )
</span><span class="cx">         )
</span><ins>+        (GraphicsLayer
+          (position 9.00 9.00)
+          (bounds 285.00 300.00)
+          (children 1
+            (GraphicsLayer
+              (position 40.00 380.00)
+              (bounds 100.00 100.00)
+              (contentsOpaque 1)
+            )
+          )
+        )
</ins><span class="cx">       )
</span><span class="cx">     )
</span><span class="cx">   )
</span></span></pre></div>
<a id="trunkLayoutTestscompositinglayercreationclippingscopescrollerwithnegativezchildrenexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt       2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt  2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -5,57 +5,89 @@
</span><span class="cx">     (GraphicsLayer
</span><span class="cx">       (bounds 800.00 600.00)
</span><span class="cx">       (contentsOpaque 1)
</span><del>-      (children 4
</del><ins>+      (children 1
</ins><span class="cx">         (GraphicsLayer
</span><del>-          (position 8.00 8.00)
-          (bounds 302.00 302.00)
</del><ins>+          (bounds 800.00 600.00)
</ins><span class="cx">           (drawsContent 1)
</span><del>-          (children 1
</del><ins>+          (children 7
</ins><span class="cx">             (GraphicsLayer
</span><del>-              (offsetFromRenderer width=1 height=1)
-              (position 1.00 1.00)
</del><ins>+              (position 9.00 9.00)
</ins><span class="cx">               (bounds 285.00 300.00)
</span><span class="cx">               (children 1
</span><span class="cx">                 (GraphicsLayer
</span><ins>+                  (position 40.00 140.00)
+                  (bounds 100.00 100.00)
+                  (contentsOpaque 1)
+                )
+              )
+            )
+            (GraphicsLayer
+              (bounds 800.00 600.00)
+              (drawsContent 1)
+            )
+            (GraphicsLayer
+              (position 8.00 8.00)
+              (bounds 302.00 302.00)
+              (drawsContent 1)
+              (children 1
+                (GraphicsLayer
</ins><span class="cx">                   (offsetFromRenderer width=1 height=1)
</span><del>-                  (anchor 0.00 0.00)
-                  (bounds 285.00 500.00)
</del><ins>+                  (position 1.00 1.00)
+                  (bounds 285.00 300.00)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=1 height=1)
+                      (anchor 0.00 0.00)
+                      (bounds 285.00 500.00)
+                    )
+                  )
</ins><span class="cx">                 )
</span><span class="cx">               )
</span><span class="cx">             )
</span><del>-          )
-        )
-        (GraphicsLayer
-          (position 9.00 9.00)
-          (bounds 285.00 300.00)
-          (children 1
</del><span class="cx">             (GraphicsLayer
</span><del>-              (position 10.00 10.00)
-              (bounds 50.00 200.00)
-              (contentsOpaque 1)
</del><ins>+              (position 9.00 9.00)
+              (bounds 285.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 50.00 200.00)
+                  (contentsOpaque 1)
+                )
+              )
</ins><span class="cx">             )
</span><del>-          )
-        )
-        (GraphicsLayer
-          (position 9.00 9.00)
-          (bounds 285.00 300.00)
-          (children 1
</del><span class="cx">             (GraphicsLayer
</span><del>-              (position 40.00 20.00)
-              (bounds 100.00 100.00)
-              (contentsOpaque 1)
</del><ins>+              (position 9.00 9.00)
+              (bounds 285.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (position 40.00 20.00)
+                  (bounds 100.00 100.00)
+                  (contentsOpaque 1)
+                )
+              )
</ins><span class="cx">             )
</span><del>-          )
-        )
-        (GraphicsLayer
-          (position 9.00 9.00)
-          (bounds 285.00 300.00)
-          (children 1
</del><span class="cx">             (GraphicsLayer
</span><del>-              (position 40.00 260.00)
-              (bounds 100.00 100.00)
-              (contentsOpaque 1)
</del><ins>+              (position 9.00 9.00)
+              (bounds 285.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (position 40.00 260.00)
+                  (bounds 100.00 100.00)
+                  (contentsOpaque 1)
+                )
+              )
</ins><span class="cx">             )
</span><ins>+            (GraphicsLayer
+              (position 9.00 9.00)
+              (bounds 285.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (position 40.00 380.00)
+                  (bounds 100.00 100.00)
+                  (contentsOpaque 1)
+                )
+              )
+            )
</ins><span class="cx">           )
</span><span class="cx">         )
</span><span class="cx">       )
</span></span></pre></div>
<a id="trunkLayoutTestscompositingrtlrtlscrollingwithtransformeddescendantsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt        2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt   2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -7,7 +7,7 @@
</span><span class="cx">     (GraphicsLayer
</span><span class="cx">       (bounds 800.00 600.00)
</span><span class="cx">       (contentsOpaque 1)
</span><del>-      (children 3
</del><ins>+      (children 5
</ins><span class="cx">         (GraphicsLayer
</span><span class="cx">           (position 8.00 8.00)
</span><span class="cx">           (bounds 404.00 223.00)
</span><span class="lines">@@ -58,6 +58,31 @@
</span><span class="cx">             )
</span><span class="cx">           )
</span><span class="cx">         )
</span><ins>+        (GraphicsLayer
+          (position 10.00 10.00)
+          (bounds origin 366.00 0.00)
+          (bounds 400.00 204.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 154.00 0.00)
+              (bounds 150.00 200.00)
+              (contentsOpaque 1)
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 10.00 10.00)
+          (bounds origin 366.00 0.00)
+          (bounds 400.00 204.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (bounds 150.00 200.00)
+              (contentsOpaque 1)
+            )
+          )
+        )
</ins><span class="cx">       )
</span><span class="cx">     )
</span><span class="cx">   )
</span></span></pre></div>
<a id="trunkLayoutTestscompositingscrollingasyncoverflowscrollinghiddenrelativelayercontentinscrollerexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller-expected.html (0 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller-expected.html                         (rev 0)
+++ trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller-expected.html    2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .page-scroller {
+            height: 500px;
+            width: 500px;
+            overflow: hidden;
+            border: 1px solid black;
+        }
+
+        .relative {
+            position: relative;
+            height: 500px;
+            width: 100%;
+        }
+                
+        .absolute {
+            position: absolute;
+            z-index: 1;
+            top: 20px;
+            left: 20px;
+            right: 20px;
+            bottom: 20px;
+        }
+
+        .scroller {
+            overflow-y: auto;
+            width: 100%;
+            height: 100%;
+            background: white;
+            border: 1px solid black;
+        }
+
+        .relative-content {
+            position: relative;
+            width: 100%;
+            height: 600px;
+            background-color: green;
+        }
+        .content-sizer {
+            width: 100%;
+            height: 750px;
+            background-color: silver;
+        }
+        
+        .scrollbars-hider {
+            position: absolute;
+            z-index: 2;
+            top: 6px;
+            left: 458px;
+            width: 56px;
+            height: 510px;
+            background-color: gray;
+        }
+    </style>
+</head>
+<body>
+    <div class="page-scroller">
+        <div class="relative">
+            <div class="content-sizer"></div>
+            <div class="absolute">
+                <div class="scroller">
+                    <div class="relative-content"></div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="scrollbars-hider"></div>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingscrollingasyncoverflowscrollinghiddenrelativelayercontentinscrollerhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller.html (0 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller.html                          (rev 0)
+++ trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller.html     2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .page-scroller {
+            height: 500px;
+            width: 500px;
+            overflow-y:auto;
+            overflow-x: hidden;
+            border: 1px solid black;
+        }
+
+        .relative {
+            position: relative;
+            height: 500px;
+            width: 100%;
+        }
+                
+        .absolute {
+            position: absolute;
+            z-index: 1;
+            top: 20px;
+            left: 20px;
+            right: 20px;
+            bottom: 20px;
+        }
+
+        .scroller {
+            overflow-y: auto;
+            width: 100%;
+            height: 100%;
+            background: white;
+            border: 1px solid black;
+        }
+
+        .relative-content {
+            position: relative;
+            width: 100%;
+            height: 600px;
+            background-color: green;
+        }
+        .content-sizer {
+            width: 100%;
+            height: 750px;
+            background-color: silver;
+        }
+        
+        .scrollbars-hider {
+            position: absolute;
+            z-index: 2;
+            top: 6px;
+            left: 458px;
+            width: 56px;
+            height: 510px;
+            background-color: gray;
+        }
+    </style>
+</head>
+<body>
+    <div class="page-scroller">
+        <div class="relative">
+            <div class="content-sizer"></div>
+            <div class="absolute">
+                <div class="scroller">
+                    <div class="relative-content"></div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="scrollbars-hider"></div>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingscrollingasyncoverflowscrollinglayerfornegativezinscrollerexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt (0 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt                           (rev 0)
+++ trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt      2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 302.00 302.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=1 height=1)
+              (position 1.00 1.00)
+              (bounds 285.00 300.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=1 height=1)
+                  (anchor 0.00 0.00)
+                  (bounds 285.00 1240.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingscrollingasyncoverflowscrollinglayerfornegativezinscrollerhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller.html (0 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller.html                           (rev 0)
+++ trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller.html      2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+               #scroller {
+                       position: relative;
+                       overflow-y: scroll;
+                       width: 300px;
+                       height: 300px;
+                       border: 1px solid black;
+               }
+
+               .negative {
+                       position: relative;
+                       z-index: -1;
+                       margin: 20px;
+                   width: 200px;
+                   height: 200px;
+                   background-color: green;
+               }
+
+        .spacer {
+            height: 1000px;
+            width: 10px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+        }, false);
+    </script>
+</head>
+<body>
+       <div id="scroller">
+        <div class="negative box"></div>
+        <div class="spacer"></div>
+       </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingscrollingasyncoverflowscrollingnegativezinscrollerexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller-expected.html (0 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller-expected.html                            (rev 0)
+++ trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller-expected.html       2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+               #scroller {
+                       position: relative;
+                       overflow-y: scroll;
+                       width: 300px;
+                       height: 300px;
+                       border: 1px solid black;
+               }
+
+               .negative {
+                       position: relative;
+                       z-index: 1;
+                       margin: 20px;
+                   width: 200px;
+                   height: 200px;
+                   background-color: green;
+               }
+
+        .spacer {
+            height: 1000px;
+            width: 10px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        window.addEventListener('load', () => {
+            setTimeout(() => {
+                scroller.scrollTo(0, 300);
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0)
+        }, false);
+    </script>
+</head>
+<body>
+       <div id="scroller">
+        <div class="negative box"></div>
+        <div class="spacer"></div>
+       </div>
+</body>
+</html>
+
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingscrollingasyncoverflowscrollingnegativezinscrollerhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller.html (0 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller.html                             (rev 0)
+++ trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller.html        2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+               #scroller {
+                       position: relative;
+                       overflow-y: scroll;
+                       width: 300px;
+                       height: 300px;
+                       border: 1px solid black;
+               }
+
+               .negative {
+                       position: relative;
+                       z-index: -1;
+                       margin: 20px;
+                   width: 200px;
+                   height: 200px;
+                   background-color: green;
+               }
+
+        .spacer {
+            height: 1000px;
+            width: 10px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        window.addEventListener('load', () => {
+            setTimeout(() => {
+                scroller.scrollTo(0, 300);
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0)
+        }, false);
+    </script>
+</head>
+<body>
+       <div id="scroller">
+        <div class="negative box"></div>
+        <div class="spacer"></div>
+       </div>
+</body>
+</html>
+
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingsharedbackingoverflowscrollnestedabsolutewithclippinginstackingoverflowexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt     2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt        2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -28,11 +28,6 @@
</span><span class="cx">                       (bounds 140.00 140.00)
</span><span class="cx">                       (contentsOpaque 1)
</span><span class="cx">                       (drawsContent 1)
</span><del>-                      (children 1
-                        (GraphicsLayer
-                          (bounds 140.00 140.00)
-                        )
-                      )
</del><span class="cx">                     )
</span><span class="cx">                   )
</span><span class="cx">                 )
</span></span></pre></div>
<a id="trunkLayoutTestsplatformioscompositinggeometrylimitlayerboundsclippingancestorexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt    2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt       2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -27,7 +27,8 @@
</span><span class="cx">           (children 1
</span><span class="cx">             (GraphicsLayer
</span><span class="cx">               (offsetFromRenderer width=0 height=100)
</span><del>-              (bounds 149.00 200.00)
</del><ins>+              (bounds 149.00 2086.00)
+              (usingTiledLayer 1)
</ins><span class="cx">               (drawsContent 1)
</span><span class="cx">             )
</span><span class="cx">           )
</span></span></pre></div>
<a id="trunkLayoutTestsplatformioswk2compositinglayercreationclippingscopeoverlapconstrainedinsidescrollerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt    2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt       2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -5,7 +5,7 @@
</span><span class="cx">     (GraphicsLayer
</span><span class="cx">       (bounds 800.00 600.00)
</span><span class="cx">       (contentsOpaque 1)
</span><del>-      (children 5
</del><ins>+      (children 6
</ins><span class="cx">         (GraphicsLayer
</span><span class="cx">           (position 8.00 8.00)
</span><span class="cx">           (bounds 302.00 302.00)
</span><span class="lines">@@ -69,6 +69,17 @@
</span><span class="cx">             )
</span><span class="cx">           )
</span><span class="cx">         )
</span><ins>+        (GraphicsLayer
+          (position 9.00 9.00)
+          (bounds 300.00 300.00)
+          (children 1
+            (GraphicsLayer
+              (position 40.00 380.00)
+              (bounds 100.00 100.00)
+              (contentsOpaque 1)
+            )
+          )
+        )
</ins><span class="cx">       )
</span><span class="cx">     )
</span><span class="cx">   )
</span></span></pre></div>
<a id="trunkLayoutTestsplatformioswk2compositinglayercreationclippingscopescrollerwithnegativezchildrenexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt      2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt 2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -5,57 +5,89 @@
</span><span class="cx">     (GraphicsLayer
</span><span class="cx">       (bounds 800.00 600.00)
</span><span class="cx">       (contentsOpaque 1)
</span><del>-      (children 4
</del><ins>+      (children 1
</ins><span class="cx">         (GraphicsLayer
</span><del>-          (position 8.00 8.00)
-          (bounds 302.00 302.00)
</del><ins>+          (bounds 800.00 600.00)
</ins><span class="cx">           (drawsContent 1)
</span><del>-          (children 1
</del><ins>+          (children 7
</ins><span class="cx">             (GraphicsLayer
</span><del>-              (offsetFromRenderer width=1 height=1)
-              (position 1.00 1.00)
</del><ins>+              (position 9.00 9.00)
</ins><span class="cx">               (bounds 300.00 300.00)
</span><span class="cx">               (children 1
</span><span class="cx">                 (GraphicsLayer
</span><ins>+                  (position 40.00 140.00)
+                  (bounds 100.00 100.00)
+                  (contentsOpaque 1)
+                )
+              )
+            )
+            (GraphicsLayer
+              (bounds 800.00 600.00)
+              (drawsContent 1)
+            )
+            (GraphicsLayer
+              (position 8.00 8.00)
+              (bounds 302.00 302.00)
+              (drawsContent 1)
+              (children 1
+                (GraphicsLayer
</ins><span class="cx">                   (offsetFromRenderer width=1 height=1)
</span><del>-                  (anchor 0.00 0.00)
-                  (bounds 300.00 500.00)
</del><ins>+                  (position 1.00 1.00)
+                  (bounds 300.00 300.00)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=1 height=1)
+                      (anchor 0.00 0.00)
+                      (bounds 300.00 500.00)
+                    )
+                  )
</ins><span class="cx">                 )
</span><span class="cx">               )
</span><span class="cx">             )
</span><del>-          )
-        )
-        (GraphicsLayer
-          (position 9.00 9.00)
-          (bounds 300.00 300.00)
-          (children 1
</del><span class="cx">             (GraphicsLayer
</span><del>-              (position 10.00 10.00)
-              (bounds 50.00 200.00)
-              (contentsOpaque 1)
</del><ins>+              (position 9.00 9.00)
+              (bounds 300.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 50.00 200.00)
+                  (contentsOpaque 1)
+                )
+              )
</ins><span class="cx">             )
</span><del>-          )
-        )
-        (GraphicsLayer
-          (position 9.00 9.00)
-          (bounds 300.00 300.00)
-          (children 1
</del><span class="cx">             (GraphicsLayer
</span><del>-              (position 40.00 20.00)
-              (bounds 100.00 100.00)
-              (contentsOpaque 1)
</del><ins>+              (position 9.00 9.00)
+              (bounds 300.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (position 40.00 20.00)
+                  (bounds 100.00 100.00)
+                  (contentsOpaque 1)
+                )
+              )
</ins><span class="cx">             )
</span><del>-          )
-        )
-        (GraphicsLayer
-          (position 9.00 9.00)
-          (bounds 300.00 300.00)
-          (children 1
</del><span class="cx">             (GraphicsLayer
</span><del>-              (position 40.00 260.00)
-              (bounds 100.00 100.00)
-              (contentsOpaque 1)
</del><ins>+              (position 9.00 9.00)
+              (bounds 300.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (position 40.00 260.00)
+                  (bounds 100.00 100.00)
+                  (contentsOpaque 1)
+                )
+              )
</ins><span class="cx">             )
</span><ins>+            (GraphicsLayer
+              (position 9.00 9.00)
+              (bounds 300.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (position 40.00 380.00)
+                  (bounds 100.00 100.00)
+                  (contentsOpaque 1)
+                )
+              )
+            )
</ins><span class="cx">           )
</span><span class="cx">         )
</span><span class="cx">       )
</span></span></pre></div>
<a id="trunkLayoutTestsplatformioswk2compositingscrollingasyncoverflowscrollinglayerfornegativezinscrollerexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt (0 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt                          (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller-expected.txt     2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 302.00 302.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=1 height=1)
+              (position 1.00 1.00)
+              (bounds 300.00 300.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=1 height=1)
+                  (anchor 0.00 0.00)
+                  (bounds 300.00 1240.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformioswk2compositingsharedbackingoverflowscrollnestedabsolutewithclippinginstackingoverflowexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt    2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt       2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -28,11 +28,6 @@
</span><span class="cx">                       (bounds 140.00 140.00)
</span><span class="cx">                       (contentsOpaque 1)
</span><span class="cx">                       (drawsContent 1)
</span><del>-                      (children 1
-                        (GraphicsLayer
-                          (bounds 140.00 140.00)
-                        )
-                      )
</del><span class="cx">                     )
</span><span class="cx">                   )
</span><span class="cx">                 )
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/Source/WebCore/ChangeLog      2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -1,3 +1,52 @@
</span><ins>+2019-06-26  Simon Fraser  <simon.fraser@apple.com>
+
+        [Async overflow scrolling] Fix missing or misplaced content inside overflow:scroll
+        https://bugs.webkit.org/show_bug.cgi?id=199253
+        rdar://problem/51855156, rdar://problem/51934514
+
+        Reviewed by Zalan Bujtas.
+
+        This patch fixes a couple of related issues triggered by failing to composite layers inside non-stacking-context
+        overflow scroll.
+
+        First, we relied on overlap testing to composite position:relative layers inside overflow:scroll, but this only
+        worked when they came later in z-order, so didn't work for layers with negative z-index.
+        RenderLayerCompositor::requiresCompositingForIndirectReason() was intended to trigger compositing in such cases,
+        but it only did so for position:absolute inside stacking-context scroller, because
+        isNonScrolledLayerInsideScrolledCompositedAncestor() tested ancestorMovedByScroller && !layerMovedByScroller.
+
+        I fixed this by sharing code between the three places that ask whether compositing crosses a containing-block
+        boundary to call a single function, RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor(),
+        that returns a ScrollPositioningBehavior. We now do compositing for both "moves" and "stationary" behaviors (but
+        not "none"), ensuring that position:relative inside non-stacking scroller is always composited.
+
+        However, this would trigger compositing on layers that should be using backing sharing; if they were outside the
+        visible part of the scroller, the overlap code would not trigger, but the
+        "IndirectCompositingReason::OverflowScrollPositioning" code would. This is undesirable; any layer that can use
+        backing sharing should, because that's fewer composited layers, so smaller layer trees and less backing store.
+        To fix this, I moved the backing-sharing check before the overlap check in
+        RenderLayerCompositor::computeCompositingRequirements().
+
+        The "layer.setHasCompositingDescendant(currentState.subtreeIsCompositing)" line was in the wrong place,
+        triggering assertions on some content; "subtreeIsCompositing" only refers to child layers, so this bit needs to
+        be set right after we've traversed the z-order lists.
+
+        Tests: compositing/scrolling/async-overflow-scrolling/hidden-relative-layer-content-in-scroller.html
+               compositing/scrolling/async-overflow-scrolling/layer-for-negative-z-in-scroller.html
+               compositing/scrolling/async-overflow-scrolling/negative-z-in-scroller.html
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+        (WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
+        (WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const):
+        (WebCore::isScrolledByOverflowScrollLayer):
+        (WebCore::enclosingCompositedScrollingLayer):
+        (WebCore::RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor):
+        (WebCore::RenderLayerCompositor::computeCoordinatedPositioningForLayer const):
+        (WebCore::isNonScrolledLayerInsideScrolledCompositedAncestor): Deleted.
+        (WebCore::RenderLayerCompositor::layerContainingBlockCrossesCoordinatedScrollingBoundary): Deleted.
+        * rendering/RenderLayerCompositor.h:
+
</ins><span class="cx"> 2019-06-26  Ryosuke Niwa  <rniwa@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         ReplacementFragment should not have script observable side effects
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerCompositorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp    2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -863,6 +863,7 @@
</span><span class="cx">     RequiresCompositingData queryData;
</span><span class="cx">     bool willBeComposited = layer.isComposited();
</span><span class="cx">     bool becameCompositedAfterDescendantTraversal = false;
</span><ins>+    IndirectCompositingReason compositingReason = compositingState.subtreeIsCompositing ? IndirectCompositingReason::Stacking : IndirectCompositingReason::None;
</ins><span class="cx"> 
</span><span class="cx">     if (layer.needsPostLayoutCompositingUpdate() || compositingState.fullPaintOrderTraversalRequired || compositingState.descendantsRequireCompositingUpdate) {
</span><span class="cx">         layer.setIndirectCompositingReason(IndirectCompositingReason::None);
</span><span class="lines">@@ -869,6 +870,14 @@
</span><span class="cx">         willBeComposited = needsToBeComposited(layer, queryData);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    bool layerPaintsIntoProvidedBacking = false;
+    if (!willBeComposited && compositingState.subtreeIsCompositing && backingSharingState.backingProviderCandidate() && canBeComposited(layer) && backingProviderLayerCanIncludeLayer(*backingSharingState.backingProviderCandidate(), layer)) {
+        backingSharingState.appendSharingLayer(layer);
+        LOG(Compositing, " layer %p can share with %p", &layer, backingSharingState.backingProviderCandidate());
+        compositingReason = IndirectCompositingReason::None;
+        layerPaintsIntoProvidedBacking = true;
+    }
+
</ins><span class="cx">     compositingState.fullPaintOrderTraversalRequired |= layer.subsequentLayersNeedCompositingRequirementsTraversal();
</span><span class="cx"> 
</span><span class="cx">     OverlapExtent layerExtent;
</span><span class="lines">@@ -880,22 +889,12 @@
</span><span class="cx">     bool respectTransforms = !layerExtent.hasTransformAnimation;
</span><span class="cx">     overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer, respectTransforms);
</span><span class="cx"> 
</span><del>-    IndirectCompositingReason compositingReason = compositingState.subtreeIsCompositing ? IndirectCompositingReason::Stacking : IndirectCompositingReason::None;
-    bool layerPaintsIntoProvidedBacking = false;
-    bool didPushOverlapContainer = false;
-
</del><span class="cx">     // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
</span><del>-    if (!willBeComposited && !overlapMap.isEmpty() && compositingState.testingOverlap) {
</del><ins>+    if (!willBeComposited && !layerPaintsIntoProvidedBacking && !overlapMap.isEmpty() && compositingState.testingOverlap) {
</ins><span class="cx">         // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
</span><del>-        if (layerOverlaps(overlapMap, layer, layerExtent)) {
-            if (backingSharingState.backingProviderCandidate() && canBeComposited(layer) && backingProviderLayerCanIncludeLayer(*backingSharingState.backingProviderCandidate(), layer)) {
-                backingSharingState.appendSharingLayer(layer);
-                LOG(Compositing, " layer %p can share with %p", &layer, backingSharingState.backingProviderCandidate());
-                compositingReason = IndirectCompositingReason::None;
-                layerPaintsIntoProvidedBacking = true;
-            } else
-                compositingReason = IndirectCompositingReason::Overlap;
-        } else
</del><ins>+        if (layerOverlaps(overlapMap, layer, layerExtent))
+            compositingReason = IndirectCompositingReason::Overlap;
+        else
</ins><span class="cx">             compositingReason = IndirectCompositingReason::None;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -922,6 +921,7 @@
</span><span class="cx">     // a compositing layer among them, so start by inheriting the compositing
</span><span class="cx">     // ancestor with subtreeIsCompositing set to false.
</span><span class="cx">     CompositingState currentState = compositingState.stateForPaintOrderChildren(layer);
</span><ins>+    bool didPushOverlapContainer = false;
</ins><span class="cx"> 
</span><span class="cx">     auto layerWillComposite = [&] {
</span><span class="cx">         // This layer is going to be composited, so children can safely ignore the fact that there's an
</span><span class="lines">@@ -993,6 +993,9 @@
</span><span class="cx">     for (auto* childLayer : layer.positiveZOrderLayers())
</span><span class="cx">         computeCompositingRequirements(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform);
</span><span class="cx"> 
</span><ins>+    // Set the flag to say that this layer has compositing children.
+    layer.setHasCompositingDescendant(currentState.subtreeIsCompositing);
+
</ins><span class="cx">     // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
</span><span class="cx">     if (layer.isRenderViewLayer()) {
</span><span class="cx">         if (usesCompositing() && m_hasAcceleratedCompositing)
</span><span class="lines">@@ -1022,9 +1025,6 @@
</span><span class="cx">         layer.reflectionLayer()->setIndirectCompositingReason(willBeComposited ? IndirectCompositingReason::Stacking : IndirectCompositingReason::None);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Set the flag to say that this layer has compositing children.
-    layer.setHasCompositingDescendant(currentState.subtreeIsCompositing);
-
</del><span class="cx">     // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that now.
</span><span class="cx">     bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer);
</span><span class="cx">     if (isCompositedClippingLayer & !willBeComposited)
</span><span class="lines">@@ -1150,7 +1150,7 @@
</span><span class="cx">         if (currentState.subtreeIsCompositing)
</span><span class="cx">             ASSERT(layerIsComposited);
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     for (auto* childLayer : layer.normalFlowLayers())
</span><span class="cx">         traverseUnchangedSubtree(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform);
</span><span class="cx"> 
</span><span class="lines">@@ -2992,43 +2992,6 @@
</span><span class="cx">     return layer.hasCompositedScrollableOverflow();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static RenderLayer* enclosingCompositedScrollingLayer(const RenderLayer& layer, const RenderLayer& intermediateLayer, bool& sawIntermediateLayer)
-{
-    const auto* ancestorLayer = layer.parent();
-    while (ancestorLayer) {
-        if (ancestorLayer == &intermediateLayer)
-            sawIntermediateLayer = true;
-
-        if (ancestorLayer->hasCompositedScrollableOverflow())
-            return const_cast<RenderLayer*>(ancestorLayer);
-
-        ancestorLayer = ancestorLayer->parent();
-    }
-
-    return nullptr;
-}
-
-static bool isScrolledByOverflowScrollLayer(const RenderLayer& layer, const RenderLayer& overflowScrollLayer)
-{
-    bool scrolledByOverflowScroll = false;
-    traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool inContainingBlockChain, bool) {
-        if (&ancestorLayer == &overflowScrollLayer) {
-            scrolledByOverflowScroll = inContainingBlockChain;
-            return AncestorTraversal::Stop;
-        }
-        return AncestorTraversal::Continue;
-    });
-    return scrolledByOverflowScroll;
-}
-
-static bool isNonScrolledLayerInsideScrolledCompositedAncestor(const RenderLayer& layer, const RenderLayer& compositedAncestor, const RenderLayer& scrollingAncestor)
-{
-    bool ancestorMovedByScroller = &compositedAncestor == &scrollingAncestor || isScrolledByOverflowScrollLayer(compositedAncestor, scrollingAncestor);
-    bool layerMovedByScroller = isScrolledByOverflowScrollLayer(layer, scrollingAncestor);
-
-    return ancestorMovedByScroller && !layerMovedByScroller;
-}
-
</del><span class="cx"> // FIXME: why doesn't this handle the clipping cases?
</span><span class="cx"> bool RenderLayerCompositor::requiresCompositingForIndirectReason(const RenderLayer& layer, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason& reason) const
</span><span class="cx"> {
</span><span class="lines">@@ -3057,9 +3020,7 @@
</span><span class="cx">     // If this layer scrolls independently from the layer that it would paint into, it needs to get composited.
</span><span class="cx">     if (!paintsIntoProvidedBacking && layer.hasCompositedScrollingAncestor()) {
</span><span class="cx">         auto* paintDestination = layer.paintOrderParent();
</span><del>-        bool paintDestinationIsScrolling = false;
-        auto* scrollingAncestor = enclosingCompositedScrollingLayer(layer, *paintDestination, paintDestinationIsScrolling);
-        if (isNonScrolledLayerInsideScrolledCompositedAncestor(layer, *paintDestination, *scrollingAncestor)) {
</del><ins>+        if (paintDestination && layerScrollBehahaviorRelativeToCompositedAncestor(layer, *paintDestination) != ScrollPositioningBehavior::None) {
</ins><span class="cx">             reason = IndirectCompositingReason::OverflowScrollPositioning;
</span><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="lines">@@ -3164,19 +3125,54 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool RenderLayerCompositor::layerContainingBlockCrossesCoordinatedScrollingBoundary(const RenderLayer& layer, const RenderLayer& compositedAncestor)
</del><ins>+static bool isScrolledByOverflowScrollLayer(const RenderLayer& layer, const RenderLayer& overflowScrollLayer)
</ins><span class="cx"> {
</span><ins>+    bool scrolledByOverflowScroll = false;
+    traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool inContainingBlockChain, bool) {
+        if (&ancestorLayer == &overflowScrollLayer) {
+            scrolledByOverflowScroll = inContainingBlockChain;
+            return AncestorTraversal::Stop;
+        }
+        return AncestorTraversal::Continue;
+    });
+    return scrolledByOverflowScroll;
+}
+
+static RenderLayer* enclosingCompositedScrollingLayer(const RenderLayer& layer, const RenderLayer& intermediateLayer, bool& sawIntermediateLayer)
+{
+    const auto* ancestorLayer = layer.parent();
+    while (ancestorLayer) {
+        if (ancestorLayer == &intermediateLayer)
+            sawIntermediateLayer = true;
+
+        if (ancestorLayer->hasCompositedScrollableOverflow())
+            return const_cast<RenderLayer*>(ancestorLayer);
+
+        ancestorLayer = ancestorLayer->parent();
+    }
+
+    return nullptr;
+}
+
+ScrollPositioningBehavior RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor(const RenderLayer& layer, const RenderLayer& compositedAncestor)
+{
+    if (!layer.hasCompositedScrollingAncestor())
+        return ScrollPositioningBehavior::None;
+
</ins><span class="cx">     bool compositedAncestorIsInsideScroller = false;
</span><span class="cx">     auto* scrollingAncestor = enclosingCompositedScrollingLayer(layer, compositedAncestor, compositedAncestorIsInsideScroller);
</span><span class="cx">     if (!scrollingAncestor) {
</span><span class="cx">         ASSERT_NOT_REACHED(); // layer.hasCompositedScrollingAncestor() should guarantee we have one.
</span><del>-        return false;
</del><ins>+        return ScrollPositioningBehavior::None;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (!compositedAncestorIsInsideScroller)
-        return false;
</del><ins>+    bool ancestorMovedByScroller = &compositedAncestor == scrollingAncestor || (compositedAncestorIsInsideScroller && isScrolledByOverflowScrollLayer(compositedAncestor, *scrollingAncestor));
+    bool layerMovedByScroller = isScrolledByOverflowScrollLayer(layer, *scrollingAncestor);
</ins><span class="cx"> 
</span><del>-    return isNonScrolledLayerInsideScrolledCompositedAncestor(layer, compositedAncestor, *scrollingAncestor);
</del><ins>+    if (ancestorMovedByScroller == layerMovedByScroller)
+        return ScrollPositioningBehavior::None;
+
+    return layerMovedByScroller ? ScrollPositioningBehavior::Moves : ScrollPositioningBehavior::Stationary;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void collectStationaryLayerRelatedOverflowNodes(const RenderLayer& layer, const RenderLayer&, Vector<ScrollingNodeID>& scrollingNodes)
</span><span class="lines">@@ -3227,27 +3223,7 @@
</span><span class="cx">         return ScrollPositioningBehavior::None;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool compositedAncestorIsScrolling = false;
-    auto* scrollingAncestor = enclosingCompositedScrollingLayer(layer, *compositedAncestor, compositedAncestorIsScrolling);
-    if (!scrollingAncestor) {
-        ASSERT_NOT_REACHED(); // layer.hasCompositedScrollingAncestor() should guarantee we have one.
-        return ScrollPositioningBehavior::None;
-    }
-
-    // There are two cases we have to deal with here:
-    // 1. There's a composited overflow:scroll in the parent chain between the renderer and its containing block, and the layer's
-    //    composited (z-order) ancestor is inside the scroller or is the scroller. In this case, we have to compensate for scroll position
-    //    changes to make the positioned layer stay in the same place. This only applies to position:absolute or descendants of position:absolute.
-    if (compositedAncestorIsScrolling && isNonScrolledLayerInsideScrolledCompositedAncestor(layer, *compositedAncestor, *scrollingAncestor))
-        return ScrollPositioningBehavior::Stationary;
-
-    // 2. The layer's containing block is the overflow or inside the overflow:scroll, but its z-order ancestor is
-    //    outside the overflow:scroll. In that case, we have to move the layer via the scrolling tree to make
-    //    it move along with the overflow scrolling.
-    if (!compositedAncestorIsScrolling && isScrolledByOverflowScrollLayer(layer, *scrollingAncestor))
-        return ScrollPositioningBehavior::Moves;
-
-    return ScrollPositioningBehavior::None;
</del><ins>+    return layerScrollBehahaviorRelativeToCompositedAncestor(layer, *compositedAncestor);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static Vector<ScrollingNodeID> collectRelatedCoordinatedScrollingNodes(const RenderLayer& layer, ScrollPositioningBehavior positioningBehavior)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerCompositorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (246868 => 246869)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h   2019-06-27 02:55:58 UTC (rev 246868)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h      2019-06-27 04:13:15 UTC (rev 246869)
</span><span class="lines">@@ -497,7 +497,7 @@
</span><span class="cx">     bool requiresCompositingForEditableImage(RenderLayerModelObject&) const;
</span><span class="cx">     bool requiresCompositingForIndirectReason(const RenderLayer&, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason&) const;
</span><span class="cx"> 
</span><del>-    static bool layerContainingBlockCrossesCoordinatedScrollingBoundary(const RenderLayer&, const RenderLayer& compositedAncestor);
</del><ins>+    static ScrollPositioningBehavior layerScrollBehahaviorRelativeToCompositedAncestor(const RenderLayer&, const RenderLayer& compositedAncestor);
</ins><span class="cx"> 
</span><span class="cx">     static bool styleChangeMayAffectIndirectCompositingReasons(const RenderStyle& oldStyle, const RenderStyle& newStyle);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>