Diff
Modified: trunk/LayoutTests/ChangeLog (245601 => 245602)
--- trunk/LayoutTests/ChangeLog 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/LayoutTests/ChangeLog 2019-05-22 00:12:49 UTC (rev 245602)
@@ -19,6 +19,33 @@
* fast/text/variations/resources/Amstelvar/COPYRIGHT.md: Added.
* fast/text/variations/resources/Amstelvar/OFL.txt: Added.
+2019-05-21 Simon Fraser <[email protected]>
+
+ Layer flashing and poor perf during scrolling of message list on gmail.com and hotmail.com - overlap testing needs to constrained to clipping scopes
+ https://bugs.webkit.org/show_bug.cgi?id=198091
+ <rdar://problem/49403082>
+
+ Reviewed by Antti Koivisto.
+
+ * TestExpectations:
+ * compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt: Added.
+ * compositing/layer-creation/clipping-scope/nested-scroller-overlap.html: Added.
+ * compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt: Added.
+ * compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html: Added.
+ * compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt: Added.
+ * compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html: Added.
+ * compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt: Added.
+ * compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html: Added.
+ * compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt: Added.
+ * compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html: Added.
+ * platform/ios-wk2/TestExpectations:
+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt: Added.
+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt: Added.
+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt: Added.
+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt: Added.
+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt: Added.
+ * platform/mac-wk2/TestExpectations:
+
2019-05-21 Antti Koivisto <[email protected]>
RTL/overflow scroll tests fail with async overflow enabled
Modified: trunk/LayoutTests/TestExpectations (245601 => 245602)
--- trunk/LayoutTests/TestExpectations 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/LayoutTests/TestExpectations 2019-05-22 00:12:49 UTC (rev 245602)
@@ -63,6 +63,7 @@
# Requires async overflow scrolling
compositing/shared-backing/overflow-scroll [ Skip ]
compositing/scrolling/async-overflow-scrolling [ Skip ]
+compositing/layer-creation/clipping-scope [ Skip ]
# WebKit2 only.
printing/printing-events.html [ Skip ]
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,112 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 7
+ (GraphicsLayer
+ (position 23.00 105.00)
+ (bounds 402.00 352.00)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (position 1.00 1.00)
+ (bounds 385.00 350.00)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 385.00 832.00)
+ (children 1
+ (GraphicsLayer
+ (position 20.00 110.00)
+ (bounds 302.00 202.00)
+ (contentsOpaque 1)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (position 1.00 1.00)
+ (bounds 285.00 200.00)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 285.00 280.00)
+ (drawsContent 1)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-10)
+ (position 24.00 106.00)
+ (bounds 385.00 350.00)
+ (children 1
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 60.00 550.00)
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-10)
+ (position 45.00 217.00)
+ (bounds 285.00 200.00)
+ (children 1
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-100)
+ (position 45.00 217.00)
+ (bounds 285.00 200.00)
+ (children 1
+ (GraphicsLayer
+ (position 10.00 100.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-190)
+ (position 45.00 217.00)
+ (bounds 285.00 200.00)
+ (children 1
+ (GraphicsLayer
+ (position 10.00 190.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 18.00 472.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap.html (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap.html (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap.html 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,71 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ .scroller {
+ overflow-y: scroll;
+ margin: 15px;
+ height: 350px;
+ width: 400px;
+ border: 1px solid black;
+ }
+
+ .inner {
+ width: 300px;
+ height: 200px;
+ margin: 20px;
+ background-color: white;
+ }
+
+ .box {
+ position: relative;
+ width: 100px;
+ height: 80px;
+ margin: 10px;
+ background-color: green;
+ }
+
+ .trigger {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ width: 60px;
+ height: 550px;
+ transform: translateZ(0);
+ background-color: rgba(128, 128, 200, 0.7);
+ }
+
+ .outside {
+ background-color: gray;
+ }
+
+ .spacer {
+ height: 500px;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ window.addEventListener('load', () => {
+ if (window.testRunner)
+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="outside box"></div>
+ <div class="scroller">
+ <div class="inner box"></div>
+ <div class="inner scroller">
+ <div class="trigger"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ </div>
+ <div class="spacer"></div>
+ </div>
+ <div class="outside box"></div>
+<pre id="layers">Layer tree goes here</pre>
+</body>
+</html>
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,80 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 5
+ (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)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 285.00 500.00)
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-10)
+ (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)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-20)
+ (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)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-140)
+ (position 9.00 9.00)
+ (bounds 285.00 300.00)
+ (children 1
+ (GraphicsLayer
+ (position 40.00 140.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-260)
+ (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)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,64 @@
+<!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;
+ }
+
+ .box {
+ position: relative;
+ margin: 20px;
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+
+ .inside {
+ left: 20px;
+ }
+
+ .outside {
+ position: relative;
+ margin: 20px;
+ width: 100px;
+ height: 100px;
+ background-color: silver;
+ }
+
+ .trigger {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ width: 50px;
+ height: 200px;
+ background-color: silver;
+ transform: translateZ(0);
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ window.addEventListener('load', () => {
+ if (window.testRunner)
+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="trigger"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ </div>
+ <div class="outside"></div>
+<pre id="layers">Layer tree goes here</pre>
+</body>
+</html>
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,50 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (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)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 285.00 500.00)
+ (drawsContent 1)
+ (children 3
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 50.00 200.00)
+ (contentsOpaque 1)
+ )
+ (GraphicsLayer
+ (position 40.00 20.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ )
+ (GraphicsLayer
+ (position 40.00 140.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,65 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ .scroller {
+ position: relative;
+ z-index: 0;
+ overflow-y: scroll;
+ width: 300px;
+ height: 300px;
+ border: 1px solid black;
+ }
+
+ .box {
+ position: relative;
+ margin: 20px;
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+
+ .inside {
+ left: 20px;
+ }
+
+ .outside {
+ position: relative;
+ margin: 20px;
+ width: 100px;
+ height: 100px;
+ background-color: silver;
+ }
+
+ .trigger {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ width: 50px;
+ height: 200px;
+ background-color: silver;
+ transform: translateZ(0);
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ window.addEventListener('load', () => {
+ if (window.testRunner)
+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="trigger"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ </div>
+ <div class="outside"></div>
+<pre id="layers">Layer tree goes here</pre>
+</body>
+</html>
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,68 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 4
+ (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)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 285.00 500.00)
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-10)
+ (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)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-20)
+ (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)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-260)
+ (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)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,68 @@
+<!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;
+ }
+
+ .box {
+ position: relative;
+ margin: 20px;
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+
+ .inside {
+ left: 20px;
+ }
+
+ .negative {
+ z-index: -1;
+ }
+
+ .outside {
+ position: relative;
+ margin: 20px;
+ width: 100px;
+ height: 100px;
+ background-color: silver;
+ }
+
+ .trigger {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ width: 50px;
+ height: 200px;
+ background-color: silver;
+ transform: translateZ(0);
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ window.addEventListener('load', () => {
+ if (window.testRunner)
+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="trigger"></div>
+ <div class="inside box"></div>
+ <div class="inside negative box"></div>
+ <div class="inside box"></div>
+ <div class="inside box"></div>
+ </div>
+ <div class="outside"></div>
+<pre id="layers">Layer tree goes here</pre>
+</body>
+</html>
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,38 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 2
+ (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)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 285.00 500.00)
+ (drawsContent 1)
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 78.00 300.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html (0 => 245602)
--- trunk/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,54 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ .scroller {
+ overflow-y: scroll;
+ width: 300px;
+ height: 300px;
+ border: 1px solid black;
+ }
+
+ .box {
+ position: relative;
+ margin: 20px;
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+
+ .spacer {
+ height: 200px;
+ width: 10px;
+ background-color: silver;
+ }
+
+ .outside {
+ position: relative;
+ top: -30px;
+ left: 50px;
+ background-color: gray;
+ }
+
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ window.addEventListener('load', () => {
+ if (window.testRunner)
+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="box"></div>
+ <div class="box"></div>
+ <div class="box"></div>
+ <div class="box"></div>
+ </div>
+ <div class="outside box"></div>
+<pre id="layers">Layer tree goes here</pre>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/ios-wk2/TestExpectations (245601 => 245602)
--- trunk/LayoutTests/platform/ios-wk2/TestExpectations 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/LayoutTests/platform/ios-wk2/TestExpectations 2019-05-22 00:12:49 UTC (rev 245602)
@@ -9,6 +9,7 @@
compositing/ios [ Pass ]
compositing/shared-backing/overflow-scroll [ Pass ]
compositing/scrolling/async-overflow-scrolling [ Pass ]
+compositing/layer-creation/clipping-scope [ Pass ]
fast/device-orientation [ Pass ]
fast/history/ios [ Pass ]
fast/scrolling/ios [ Pass ]
Added: trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt (0 => 245602)
--- trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,112 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 7
+ (GraphicsLayer
+ (position 23.00 105.00)
+ (bounds 402.00 352.00)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (position 1.00 1.00)
+ (bounds 400.00 350.00)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 400.00 832.00)
+ (children 1
+ (GraphicsLayer
+ (position 20.00 110.00)
+ (bounds 302.00 202.00)
+ (contentsOpaque 1)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (position 1.00 1.00)
+ (bounds 300.00 200.00)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 300.00 280.00)
+ (drawsContent 1)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-10)
+ (position 24.00 106.00)
+ (bounds 400.00 350.00)
+ (children 1
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 60.00 550.00)
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-10)
+ (position 45.00 217.00)
+ (bounds 300.00 200.00)
+ (children 1
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-100)
+ (position 45.00 217.00)
+ (bounds 300.00 200.00)
+ (children 1
+ (GraphicsLayer
+ (position 10.00 100.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-190)
+ (position 45.00 217.00)
+ (bounds 300.00 200.00)
+ (children 1
+ (GraphicsLayer
+ (position 10.00 190.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 18.00 472.00)
+ (bounds 100.00 80.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt (0 => 245602)
--- trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,80 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 5
+ (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)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 300.00 500.00)
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-10)
+ (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)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-20)
+ (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)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-140)
+ (position 9.00 9.00)
+ (bounds 300.00 300.00)
+ (children 1
+ (GraphicsLayer
+ (position 40.00 140.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-260)
+ (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)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt (0 => 245602)
--- trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,50 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (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)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 300.00 500.00)
+ (drawsContent 1)
+ (children 3
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 50.00 200.00)
+ (contentsOpaque 1)
+ )
+ (GraphicsLayer
+ (position 40.00 20.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ )
+ (GraphicsLayer
+ (position 40.00 140.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt (0 => 245602)
--- trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,68 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 4
+ (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)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 300.00 500.00)
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-10 height=-10)
+ (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)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-20)
+ (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)
+ )
+ )
+ )
+ (GraphicsLayer
+ (offsetFromRenderer width=-40 height=-260)
+ (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)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt (0 => 245602)
--- trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt 2019-05-22 00:12:49 UTC (rev 245602)
@@ -0,0 +1,38 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 2
+ (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)
+ (children 1
+ (GraphicsLayer
+ (offsetFromRenderer width=1 height=1)
+ (anchor 0.00 0.00)
+ (bounds 300.00 500.00)
+ (drawsContent 1)
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 78.00 300.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ )
+)
+
Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (245601 => 245602)
--- trunk/LayoutTests/platform/mac-wk2/TestExpectations 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations 2019-05-22 00:12:49 UTC (rev 245602)
@@ -7,6 +7,7 @@
compositing/shared-backing/overflow-scroll [ Pass ]
compositing/scrolling/async-overflow-scrolling [ Pass ]
+compositing/layer-creation/clipping-scope [ Pass ]
editing/find [ Pass ]
editing/undo-manager [ Pass ]
fast/forms/select/mac-wk2 [ Pass ]
Modified: trunk/Source/WebCore/ChangeLog (245601 => 245602)
--- trunk/Source/WebCore/ChangeLog 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/Source/WebCore/ChangeLog 2019-05-22 00:12:49 UTC (rev 245602)
@@ -38,6 +38,84 @@
* platform/graphics/mac/FontCustomPlatformData.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):
+2019-05-21 Simon Fraser <[email protected]>
+
+ Layer flashing and poor perf during scrolling of message list on gmail.com and hotmail.com - overlap testing needs to constrained to clipping scopes
+ https://bugs.webkit.org/show_bug.cgi?id=198091
+ <rdar://problem/49403082>
+
+ Reviewed by Antti Koivisto.
+
+ When overflow:scroll is scrolled asynchronously, we need to have already created compositing layers where necessary
+ for clipped-out layers in the scrolled content so that we have something to reveal. We also have ensure
+ that layers inside the scroller (but scrolled out of view) don't trigger overlap with layers outside the scroller.
+ All this has to work when the containing block hierarchy (clipping/scrolling) doesn't match the paint order hierarchy (structure
+ of the z-order and compositing trees).
+
+ Overlap testing previously simply used a list of rectangles per compositing container (OverlapMapContainer). This is
+ a series of layer bounds, built up as we traver the layer tree in z-order. Layers contribute to container N-2, and test
+ against container N-1.
+
+ To handle overlap with non-stacking-context scrollers, introduce the concept of a ClippingScope, which encompasses
+ a set of layers sharing the same composited-scrolling containing-block ancestor. Within a ClippingScope, layer bounds
+ are computed unclipped. Between them, bounds are tested clipped.
+
+ Conceptually, each OverlapMapContainer has a tree of ClippingScopes (reflecting the containing-block order tree of
+ composited overflow scroll), and rects are added to the appropriate ClippingScope. This tree is currently always
+ root-relative; the root node is the RenderView's RenderLayer, and will accumulate the bounds of layers not inside
+ composited overflow scroll (just like the old code).
+
+ When a OverlapMapContainer is popped, the list of rectangles in its ClippingScope tree is merged with that of the previous
+ container.
+
+ Tests: compositing/layer-creation/clipping-scope/nested-scroller-overlap.html
+ compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html
+ compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html
+ compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html
+ compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html
+
+ * rendering/LayerOverlapMap.cpp:
+ (WebCore::operator<<):
+ (WebCore::OverlapMapContainer::OverlapMapContainer):
+ (WebCore::OverlapMapContainer::ClippingScope::ClippingScope):
+ (WebCore::OverlapMapContainer::ClippingScope::childWithLayer const):
+ (WebCore::OverlapMapContainer::ClippingScope::addChildWithLayerAndBounds):
+ (WebCore::OverlapMapContainer::ClippingScope::addChild):
+ (WebCore::OverlapMapContainer::ClippingScope::appendRect):
+ (WebCore::OverlapMapContainer::clippingScopeContainingLayerChildRecursive):
+ (WebCore::OverlapMapContainer::scopeContainingLayer const):
+ (WebCore::OverlapMapContainer::rootScope const):
+ (WebCore::OverlapMapContainer::rootScope):
+ (WebCore::OverlapMapContainer::add):
+ (WebCore::OverlapMapContainer::overlapsLayers const):
+ (WebCore::OverlapMapContainer::mergeClippingScopesRecursive):
+ (WebCore::OverlapMapContainer::append):
+ (WebCore::OverlapMapContainer::ensureClippingScopeForLayers):
+ (WebCore::OverlapMapContainer::findClippingScopeForLayers const):
+ (WebCore::OverlapMapContainer::recursiveOutputToStream const):
+ (WebCore::OverlapMapContainer::dump const):
+ (WebCore::LayerOverlapMap::LayerOverlapMap):
+ (WebCore::LayerOverlapMap::add):
+ (WebCore::LayerOverlapMap::overlapsLayers const):
+ (WebCore::LayerOverlapMap::pushCompositingContainer):
+ (WebCore::LayerOverlapMap::popCompositingContainer):
+ (WebCore::OverlapMapContainer::unite): Deleted.
+ (WebCore::OverlapMapContainer::rectList const): Deleted.
+ * rendering/LayerOverlapMap.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::BackingSharingState::appendSharingLayer):
+ (WebCore::RenderLayerCompositor::BackingSharingState::updateBeforeDescendantTraversal):
+ (WebCore::RenderLayerCompositor::updateCompositingLayers):
+ (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+ (WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
+ (WebCore::RenderLayerCompositor::computeExtent const):
+ (WebCore::createsClippingScope):
+ (WebCore::enclosingClippingScopes):
+ (WebCore::RenderLayerCompositor::addToOverlapMap const):
+ (WebCore::RenderLayerCompositor::updateOverlapMap const):
+ (WebCore::RenderLayerCompositor::layerOverlaps const):
+ * rendering/RenderLayerCompositor.h:
+
2019-05-21 Antoine Quint <[email protected]>
[macOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
Modified: trunk/Source/WebCore/rendering/LayerOverlapMap.cpp (245601 => 245602)
--- trunk/Source/WebCore/rendering/LayerOverlapMap.cpp 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/Source/WebCore/rendering/LayerOverlapMap.cpp 2019-05-22 00:12:49 UTC (rev 245602)
@@ -25,6 +25,7 @@
#include "config.h"
#include "LayerOverlapMap.h"
+#include "RenderLayer.h"
#include <wtf/text/TextStream.h>
namespace WebCore {
@@ -58,31 +59,215 @@
}
};
+static TextStream& operator<<(TextStream& ts, const RectList& rectList)
+{
+ ts << "bounds " << rectList.boundingRect << " (" << rectList.rects << " rects)";
+ return ts;
+}
+
+// Used to store overlap rects in a way that takes overflow into account.
+// It stores a tree whose nodes are layers with composited scrolling. The tree is built lazily as layers are added whose containing block
+// chains contain composited scrollers. The tree always starts at the root layer.
+// Checking for overlap involves finding the node for the clipping layer enclosing the given layer (or the root),
+// and comparing against the bounds of earlier siblings.
class OverlapMapContainer {
public:
- void add(const LayoutRect& bounds)
+ OverlapMapContainer(const RenderLayer& rootLayer)
+ : m_rootScope(rootLayer)
{
- m_rectList.append(bounds);
}
- bool overlapsLayers(const LayoutRect& bounds) const
+ // Layers are added in z-order, lazily creating clipping scopes as necessary.
+ void add(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers);
+ bool overlapsLayers(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) const;
+ void append(std::unique_ptr<OverlapMapContainer>&&);
+
+ String dump(unsigned) const;
+
+private:
+ struct ClippingScope {
+ ClippingScope(const RenderLayer& inLayer)
+ : layer(inLayer)
+ {
+ }
+
+ ClippingScope(const LayerOverlapMap::LayerAndBounds& layerAndBounds)
+ : layer(layerAndBounds.layer)
+ , bounds(layerAndBounds.bounds)
+ {
+ }
+
+ ClippingScope* childWithLayer(const RenderLayer& layer) const
+ {
+ for (auto& child : children) {
+ if (&child.layer == &layer)
+ return const_cast<ClippingScope*>(&child);
+ }
+ return nullptr;
+ }
+
+ ClippingScope* addChildWithLayerAndBounds(const LayerOverlapMap::LayerAndBounds& layerAndBounds)
+ {
+ children.append({ layerAndBounds });
+ return &children.last();
+ }
+
+ ClippingScope* addChild(const ClippingScope& child)
+ {
+ children.append(child);
+ return &children.last();
+ }
+
+ void appendRect(const LayoutRect& bounds)
+ {
+ rectList.append(bounds);
+ }
+
+ const RenderLayer& layer;
+ LayoutRect bounds; // Bounds of the composited clip.
+ Vector<ClippingScope> children;
+ RectList rectList;
+ };
+
+ static ClippingScope* clippingScopeContainingLayerChildRecursive(const ClippingScope& currNode, const RenderLayer& layer)
{
- return m_rectList.intersects(bounds);
+ for (auto& child : currNode.children) {
+ if (&layer == &child.layer)
+ return const_cast<ClippingScope*>(&currNode);
+
+ if (auto* foundNode = clippingScopeContainingLayerChildRecursive(child, layer))
+ return foundNode;
+ }
+
+ return nullptr;
}
- void unite(const OverlapMapContainer& otherContainer)
+ ClippingScope* scopeContainingLayer(const RenderLayer& layer) const
{
- m_rectList.append(otherContainer.m_rectList);
+ return clippingScopeContainingLayerChildRecursive(m_rootScope, layer);
}
- const RectList& rectList() const { return m_rectList; }
+ static void mergeClippingScopesRecursive(const ClippingScope& sourceScope, ClippingScope& destScope);
-private:
- RectList m_rectList;
+ ClippingScope* ensureClippingScopeForLayers(const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers);
+ ClippingScope* findClippingScopeForLayers(const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) const;
+
+ void recursiveOutputToStream(TextStream&, const ClippingScope&, unsigned depth) const;
+
+ const ClippingScope& rootScope() const { return m_rootScope; }
+ ClippingScope& rootScope() { return m_rootScope; }
+
+ ClippingScope m_rootScope;
};
-LayerOverlapMap::LayerOverlapMap()
+void OverlapMapContainer::add(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers)
+{
+ auto* layerScope = ensureClippingScopeForLayers(enclosingClippingLayers);
+ layerScope->appendRect(bounds);
+}
+
+bool OverlapMapContainer::overlapsLayers(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) const
+{
+ if (m_rootScope.rectList.intersects(bounds))
+ return true;
+
+ if (m_rootScope.children.isEmpty())
+ return false;
+
+ // Find the ClippingScope for which this layer is a child.
+ auto* clippingScope = findClippingScopeForLayers(enclosingClippingLayers);
+ if (!clippingScope)
+ return false;
+
+ if (clippingScope->rectList.intersects(bounds))
+ return true;
+
+ // FIXME: In some cases do we have to walk up the ancestor clipping scope chain?
+ return false;
+}
+
+void OverlapMapContainer::mergeClippingScopesRecursive(const ClippingScope& sourceScope, ClippingScope& destScope)
+{
+ ASSERT(&sourceScope.layer == &destScope.layer);
+ destScope.rectList.append(sourceScope.rectList);
+
+ for (auto& sourceChildScope : sourceScope.children) {
+ ClippingScope* destChild = destScope.childWithLayer(sourceChildScope.layer);
+ if (destChild) {
+ destChild->rectList.append(sourceChildScope.rectList);
+ mergeClippingScopesRecursive(sourceChildScope, *destChild);
+ } else {
+ // New child, just copy the whole subtree.
+ destScope.addChild(sourceScope);
+ }
+ }
+}
+
+void OverlapMapContainer::append(std::unique_ptr<OverlapMapContainer>&& otherContainer)
+{
+ mergeClippingScopesRecursive(otherContainer->rootScope(), m_rootScope);
+}
+
+OverlapMapContainer::ClippingScope* OverlapMapContainer::ensureClippingScopeForLayers(const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers)
+{
+ ASSERT(enclosingClippingLayers.size());
+ ASSERT(enclosingClippingLayers[0].layer.isRenderViewLayer());
+
+ auto* currScope = &m_rootScope;
+ for (unsigned i = 1; i < enclosingClippingLayers.size(); ++i) {
+ auto& scopeLayerAndBounds = enclosingClippingLayers[i];
+ auto* childScope = currScope->childWithLayer(scopeLayerAndBounds.layer);
+ if (!childScope) {
+ currScope = currScope->addChildWithLayerAndBounds(scopeLayerAndBounds);
+ break;
+ }
+
+ currScope = childScope;
+ }
+
+ return const_cast<ClippingScope*>(currScope);
+}
+
+OverlapMapContainer::ClippingScope* OverlapMapContainer::findClippingScopeForLayers(const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) const
+{
+ ASSERT(enclosingClippingLayers.size());
+ ASSERT(enclosingClippingLayers[0].layer.isRenderViewLayer());
+
+ const auto* currScope = &m_rootScope;
+ for (unsigned i = 1; i < enclosingClippingLayers.size(); ++i) {
+ auto& scopeLayerAndBounds = enclosingClippingLayers[i];
+ auto* childScope = currScope->childWithLayer(scopeLayerAndBounds.layer);
+ if (!childScope)
+ return nullptr;
+
+ currScope = childScope;
+ }
+
+ return const_cast<ClippingScope*>(currScope);
+}
+
+void OverlapMapContainer::recursiveOutputToStream(TextStream& ts, const ClippingScope& scope, unsigned depth) const
+{
+ ts << "\n" << indent << TextStream::Repeat { 2 * depth, ' ' } << " scope for layer " << &scope.layer << " rects " << scope.rectList;
+ for (auto& childScope : scope.children)
+ recursiveOutputToStream(ts, childScope, depth + 1);
+}
+
+String OverlapMapContainer::dump(unsigned indent) const
+{
+ TextStream multilineStream;
+ multilineStream.increaseIndent(indent);
+ multilineStream << "overlap container - root scope layer " << &m_rootScope.layer << " rects " << m_rootScope.rectList;
+
+ for (auto& childScope : m_rootScope.children)
+ recursiveOutputToStream(multilineStream, childScope, 1);
+
+ return multilineStream.release();
+}
+
+LayerOverlapMap::LayerOverlapMap(const RenderLayer& rootLayer)
: m_geometryMap(UseTransforms)
+ , m_rootLayer(rootLayer)
{
// Begin assuming the root layer will be composited so that there is
// something on the stack. The root layer should also never get an
@@ -92,41 +277,36 @@
LayerOverlapMap::~LayerOverlapMap() = default;
-void LayerOverlapMap::add(const LayoutRect& bounds)
+void LayerOverlapMap::add(const RenderLayer& layer, const LayoutRect& bounds, const Vector<LayerAndBounds>& enclosingClippingLayers)
{
// Layers do not contribute to overlap immediately--instead, they will
// contribute to overlap as soon as their composited ancestor has been
// recursively processed and popped off the stack.
ASSERT(m_overlapStack.size() >= 2);
- m_overlapStack[m_overlapStack.size() - 2]->add(bounds);
+ m_overlapStack[m_overlapStack.size() - 2]->add(layer, bounds, enclosingClippingLayers);
+
m_isEmpty = false;
}
-bool LayerOverlapMap::overlapsLayers(const LayoutRect& bounds) const
+bool LayerOverlapMap::overlapsLayers(const RenderLayer& layer, const LayoutRect& bounds, const Vector<LayerAndBounds>& enclosingClippingLayers) const
{
- return m_overlapStack.last()->overlapsLayers(bounds);
+ return m_overlapStack.last()->overlapsLayers(layer, bounds, enclosingClippingLayers);
}
void LayerOverlapMap::pushCompositingContainer()
{
- m_overlapStack.append(std::make_unique<OverlapMapContainer>());
+ m_overlapStack.append(std::make_unique<OverlapMapContainer>(m_rootLayer));
}
void LayerOverlapMap::popCompositingContainer()
{
- m_overlapStack[m_overlapStack.size() - 2]->unite(*m_overlapStack.last());
+ m_overlapStack[m_overlapStack.size() - 2]->append(WTFMove(m_overlapStack.last()));
m_overlapStack.removeLast();
}
-static TextStream& operator<<(TextStream& ts, const RectList& rectList)
-{
- ts << "bounds " << rectList.boundingRect << " (" << rectList.rects << " rects)";
- return ts;
-}
-
static TextStream& operator<<(TextStream& ts, const OverlapMapContainer& container)
{
- ts << container.rectList();
+ ts << container.dump(ts.indent());
return ts;
}
@@ -135,10 +315,17 @@
TextStream multilineStream;
TextStream::GroupScope scope(ts);
- multilineStream << indent << "LayerOverlapMap\n";
+ multilineStream << "LayerOverlapMap\n";
+ multilineStream.increaseIndent(2);
- for (auto& container : overlapMap.overlapStack())
- multilineStream << " " << *container << "\n";
+ bool needNewline = false;
+ for (auto& container : overlapMap.overlapStack()) {
+ if (needNewline)
+ multilineStream << "\n";
+ else
+ needNewline = true;
+ multilineStream << indent << *container;
+ }
ts << multilineStream.release();
return ts;
@@ -145,3 +332,4 @@
}
} // namespace WebCore
+
Modified: trunk/Source/WebCore/rendering/LayerOverlapMap.h (245601 => 245602)
--- trunk/Source/WebCore/rendering/LayerOverlapMap.h 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/Source/WebCore/rendering/LayerOverlapMap.h 2019-05-22 00:12:49 UTC (rev 245602)
@@ -34,16 +34,23 @@
namespace WebCore {
+class OverflowAwareOverlapContainer;
class OverlapMapContainer;
+class RenderLayer;
class LayerOverlapMap {
WTF_MAKE_NONCOPYABLE(LayerOverlapMap);
public:
- LayerOverlapMap();
+ LayerOverlapMap(const RenderLayer& rootLayer);
~LayerOverlapMap();
+
+ struct LayerAndBounds {
+ RenderLayer& layer;
+ LayoutRect bounds;
+ };
- void add(const LayoutRect& bounds);
- bool overlapsLayers(const LayoutRect&) const;
+ void add(const RenderLayer&, const LayoutRect&, const Vector<LayerAndBounds>& enclosingClippingLayers);
+ bool overlapsLayers(const RenderLayer&, const LayoutRect&, const Vector<LayerAndBounds>& enclosingClippingLayers) const;
bool isEmpty() const { return m_isEmpty; }
void pushCompositingContainer();
@@ -57,6 +64,7 @@
private:
Vector<std::unique_ptr<OverlapMapContainer>> m_overlapStack;
RenderGeometryMap m_geometryMap;
+ const RenderLayer& m_rootLayer;
bool m_isEmpty { true };
};
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (245601 => 245602)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2019-05-22 00:12:49 UTC (rev 245602)
@@ -205,7 +205,6 @@
void appendSharingLayer(RenderLayer& layer)
{
- LOG_WITH_STREAM(Compositing, stream << &layer << " appendSharingLayer " << &layer << " for backing provider " << m_backingProviderCandidate);
m_backingSharingLayers.append(makeWeakPtr(layer));
}
@@ -249,7 +248,6 @@
// A layer that composites resets backing-sharing, since subsequent layers need to composite to overlap it.
if (willBeComposited) {
m_backingSharingLayers.removeAll(&layer);
- LOG_WITH_STREAM(Compositing, stream << "Pre-descendant compositing of " << &layer << ", ending sharing sequence for " << m_backingProviderCandidate << " with " << m_backingSharingLayers.size() << " sharing layers");
endBackingSharingSequence();
}
}
@@ -768,12 +766,13 @@
// FIXME: optimize root-only update.
if (updateRoot->hasDescendantNeedingCompositingRequirementsTraversal() || updateRoot->needsCompositingRequirementsTraversal()) {
+ auto& rootLayer = rootRenderLayer();
CompositingState compositingState(updateRoot);
BackingSharingState backingSharingState;
- LayerOverlapMap overlapMap;
+ LayerOverlapMap overlapMap(rootLayer);
bool descendantHas3DTransform = false;
- computeCompositingRequirements(nullptr, rootRenderLayer(), overlapMap, compositingState, backingSharingState, descendantHas3DTransform);
+ computeCompositingRequirements(nullptr, rootLayer, overlapMap, compositingState, backingSharingState, descendantHas3DTransform);
}
LOG(Compositing, "\nRenderLayerCompositor::updateCompositingLayers - mid");
@@ -883,10 +882,8 @@
// If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
if (!willBeComposited && !overlapMap.isEmpty() && compositingState.testingOverlap) {
- computeExtent(overlapMap, layer, layerExtent);
-
// If we're testing for overlap, we only need to composite if we overlap something that is already composited.
- if (overlapMap.overlapsLayers(layerExtent.bounds)) {
+ 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());
@@ -1786,7 +1783,6 @@
if (extent.bounds.isEmpty())
extent.bounds.setSize(LayoutSize(1, 1));
-
RenderLayerModelObject& renderer = layer.renderer();
if (renderer.isFixedPositioned() && renderer.container() == &m_renderView) {
// Because fixed elements get moved around without re-computing overlap, we have to compute an overlap
@@ -1798,6 +1794,44 @@
extent.extentComputed = true;
}
+static bool createsClippingScope(const RenderLayer& layer)
+{
+ return layer.hasCompositedScrollableOverflow();
+}
+
+static Vector<LayerOverlapMap::LayerAndBounds> enclosingClippingScopes(const RenderLayer& layer, const RenderLayer& rootLayer)
+{
+ Vector<LayerOverlapMap::LayerAndBounds> clippingScopes;
+ clippingScopes.append({ const_cast<RenderLayer&>(rootLayer), { } });
+
+ if (!layer.hasCompositedScrollingAncestor())
+ return clippingScopes;
+
+ bool containingBlockCanSkipLayers = layer.renderer().isAbsolutelyPositioned();
+ for (const auto* ancestorLayer = layer.parent(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) {
+ bool inContainingBlockChain = true;
+ if (containingBlockCanSkipLayers) {
+ inContainingBlockChain = ancestorLayer->renderer().canContainAbsolutelyPositionedObjects();
+ if (inContainingBlockChain)
+ containingBlockCanSkipLayers = ancestorLayer->renderer().isAbsolutelyPositioned();
+ }
+
+ if (inContainingBlockChain && createsClippingScope(*ancestorLayer)) {
+ LayoutRect clipRect;
+ if (is<RenderBox>(ancestorLayer->renderer())) {
+ // FIXME: This is expensive. Broken with transforms.
+ LayoutPoint offsetFromRoot = ancestorLayer->convertToLayerCoords(&rootLayer, { });
+ clipRect = downcast<RenderBox>(ancestorLayer->renderer()).overflowClipRect(offsetFromRoot);
+ }
+
+ LayerOverlapMap::LayerAndBounds layerAndBounds { const_cast<RenderLayer&>(*ancestorLayer), clipRect };
+ clippingScopes.insert(1, layerAndBounds); // Order is roots to leaves.
+ }
+ }
+
+ return clippingScopes;
+}
+
void RenderLayerCompositor::addToOverlapMap(LayerOverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& extent) const
{
if (layer.isRenderViewLayer())
@@ -1805,13 +1839,29 @@
computeExtent(overlapMap, layer, extent);
- LayoutRect clipRect = layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), AbsoluteClipRects)).rect(); // FIXME: Incorrect for CSS regions.
+ // FIXME: constrain the scopes (by composited stacking context ancestor I think).
+ auto clippingScopes = enclosingClippingScopes(layer, rootRenderLayer());
- // On iOS, pageScaleFactor() is not applied by RenderView, so we should not scale here.
- if (!m_renderView.settings().delegatesPageScaling())
- clipRect.scale(pageScaleFactor());
- clipRect.intersect(extent.bounds);
- overlapMap.add(clipRect);
+ LayoutRect clipRect;
+ if (layer.hasCompositedScrollingAncestor()) {
+ // Compute a clip up to the composited scrolling ancestor, then convert it to absolute coordinates.
+ auto& scrollingScope = clippingScopes.last();
+ clipRect = layer.backgroundClipRect(RenderLayer::ClipRectsContext(&scrollingScope.layer, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip)).rect();
+ if (!clipRect.isInfinite())
+ clipRect.setLocation(layer.convertToLayerCoords(&rootRenderLayer(), clipRect.location()));
+ } else
+ clipRect = layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), AbsoluteClipRects)).rect(); // FIXME: Incorrect for CSS regions.
+
+ auto clippedBounds = extent.bounds;
+ if (!clipRect.isInfinite()) {
+ // On iOS, pageScaleFactor() is not applied by RenderView, so we should not scale here.
+ if (!m_renderView.settings().delegatesPageScaling())
+ clipRect.scale(pageScaleFactor());
+
+ clippedBounds.intersect(clipRect);
+ }
+
+ overlapMap.add(layer, clippedBounds, clippingScopes);
}
void RenderLayerCompositor::addDescendantsToOverlapMapRecursive(LayerOverlapMap& overlapMap, const RenderLayer& layer, const RenderLayer* ancestorLayer) const
@@ -1847,6 +1897,7 @@
void RenderLayerCompositor::updateOverlapMap(LayerOverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& layerExtent, bool didPushContainer, bool addLayerToOverlap, bool addDescendantsToOverlap) const
{
if (addLayerToOverlap) {
+ auto clippingScopes = enclosingClippingScopes(layer, rootRenderLayer());
addToOverlapMap(overlapMap, layer, layerExtent);
LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " contributes to overlap, added to map " << overlapMap);
}
@@ -1863,6 +1914,14 @@
}
}
+bool RenderLayerCompositor::layerOverlaps(const LayerOverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& layerExtent) const
+{
+ computeExtent(overlapMap, layer, layerExtent);
+
+ auto clippingScopes = enclosingClippingScopes(layer, rootRenderLayer());
+ return overlapMap.overlapsLayers(layer, layerExtent.bounds, clippingScopes);
+}
+
#if ENABLE(VIDEO)
bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo& video) const
{
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (245601 => 245602)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h 2019-05-21 23:44:16 UTC (rev 245601)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h 2019-05-22 00:12:49 UTC (rev 245602)
@@ -409,6 +409,7 @@
void addToOverlapMap(LayerOverlapMap&, const RenderLayer&, OverlapExtent&) const;
void addDescendantsToOverlapMapRecursive(LayerOverlapMap&, const RenderLayer&, const RenderLayer* ancestorLayer = nullptr) const;
void updateOverlapMap(LayerOverlapMap&, const RenderLayer&, OverlapExtent&, bool didPushContainer, bool addLayerToOverlap, bool addDescendantsToOverlap = false) const;
+ bool layerOverlaps(const LayerOverlapMap&, const RenderLayer&, OverlapExtent&) const;
void updateCompositingLayersTimerFired();