Too much repainting on scrolling with fixed backgrounds
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 12 Apr 2015 17:30:58 +0000 (17:30 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 12 Apr 2015 17:30:58 +0000 (17:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=143637
rdar://problem/20245243

Reviewed by Darin Adler.

Source/WebCore:

FrameView::scrollContentsSlowPath() would repaint the entire viewport if there were
any slow-repaint objects (those with background-attachment: fixed) and the contents
were using compositing for scrolling.

This is wrong; we only need to issue repaint for the slow-repaint renderers,
and, if the frame is hosted in a compositing layer and not using compositing for scrolling,
repaint that hosting layer.

Tests: compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint.html
       compositing/repaint/iframes/compositing-iframe-scroll-repaint.html
       compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint.html
       platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint.html

* page/FrameView.cpp:
(WebCore::FrameView::scrollContentsSlowPath):

LayoutTests:

Tests with various configurations of iframes and compositing, which dump layer trees with
repaint rectangles.

Also tiled-scrolling test that exercises the simple case.

Put WebKit1-specific results in platform/mac-wk1, since they are very different from
WK2 and other platforms, due to WK1-specific layer hosting and repaint behaviors.

* compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt: Added.
* compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint.html: Added.
* compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt: Added.
* compositing/repaint/iframes/compositing-iframe-scroll-repaint.html: Added.
* compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt: Added.
* compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint.html: Added.
* compositing/repaint/iframes/resources/compositing-document.html: Added.
* compositing/repaint/iframes/resources/compositing-fixed-background-document.html: Added.
* compositing/repaint/iframes/resources/fixed-background-document.html: Added.
* platform/mac-wk1/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt: Added.
* platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt: Added.
* platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt: Added.
* platform/mac-wk2/compositing/repaint/fixed-background-scroll-expected.txt:
* platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182669 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt [new file with mode: 0644]
LayoutTests/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint.html [new file with mode: 0644]
LayoutTests/compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt [new file with mode: 0644]
LayoutTests/compositing/repaint/iframes/compositing-iframe-scroll-repaint.html [new file with mode: 0644]
LayoutTests/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt [new file with mode: 0644]
LayoutTests/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint.html [new file with mode: 0644]
LayoutTests/compositing/repaint/iframes/resources/compositing-document.html [new file with mode: 0644]
LayoutTests/compositing/repaint/iframes/resources/compositing-fixed-background-document.html [new file with mode: 0644]
LayoutTests/compositing/repaint/iframes/resources/fixed-background-document.html [new file with mode: 0644]
LayoutTests/platform/mac-wk1/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/compositing/repaint/fixed-background-scroll-expected.txt
LayoutTests/platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp

index e1ebbb1..9d318f2 100644 (file)
@@ -1,3 +1,35 @@
+2015-04-12  Simon Fraser  <simon.fraser@apple.com>
+
+        Too much repainting on scrolling with fixed backgrounds
+        https://bugs.webkit.org/show_bug.cgi?id=143637
+        rdar://problem/20245243
+
+        Reviewed by Darin Adler.
+        
+        Tests with various configurations of iframes and compositing, which dump layer trees with
+        repaint rectangles.
+        
+        Also tiled-scrolling test that exercises the simple case.
+        
+        Put WebKit1-specific results in platform/mac-wk1, since they are very different from
+        WK2 and other platforms, due to WK1-specific layer hosting and repaint behaviors.
+
+        * compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt: Added.
+        * compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint.html: Added.
+        * compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt: Added.
+        * compositing/repaint/iframes/compositing-iframe-scroll-repaint.html: Added.
+        * compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt: Added.
+        * compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint.html: Added.
+        * compositing/repaint/iframes/resources/compositing-document.html: Added.
+        * compositing/repaint/iframes/resources/compositing-fixed-background-document.html: Added.
+        * compositing/repaint/iframes/resources/fixed-background-document.html: Added.
+        * platform/mac-wk1/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt: Added.
+        * platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt: Added.
+        * platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt: Added.
+        * platform/mac-wk2/compositing/repaint/fixed-background-scroll-expected.txt:
+        * platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint.html: Added.
+
 2015-04-12  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [ES6] Implement Array.prototype.values
diff --git a/LayoutTests/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt b/LayoutTests/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt
new file mode 100644 (file)
index 0000000..4d7730a
--- /dev/null
@@ -0,0 +1,28 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 2016.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2016.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 14.00 14.00)
+          (bounds 432.00 332.00)
+          (drawsContent 1)
+          (repaint rects
+            (rect 24.00 16.00 100.00 8.00)
+            (rect 16.00 16.00 400.00 300.00)
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 369.00)
+          (anchor 1.00 1.00)
+          (bounds 1.00 1.00)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint.html b/LayoutTests/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint.html
new file mode 100644 (file)
index 0000000..7ce1c3b
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+        }
+        iframe {
+            height: 300px;
+            width: 400px;
+            margin: 20px;
+            box-shadow: 0 0 10px black;
+            -webkit-transform: translateZ(0);
+        }
+        .composited {
+            -webkit-transform: translateZ(0);
+            width: 1px;
+            height: 1px;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        var expectedLoads = 2;
+        function documentLoaded()
+        {
+            if (!--expectedLoads) {
+                // Timeout is required to allow layer to paint before the scroll.
+                window.setTimeout(doTest, 0);
+            }
+        }
+        
+        function doTest()
+        {
+            if (window.testRunner)
+                testRunner.display(); // Flush pending compositing repaints.
+            
+            if (window.internals)
+                window.internals.startTrackingRepaints();
+
+            document.getElementById('frame').contentWindow.scrollTo(0, 100);
+
+            if (window.internals)
+                document.getElementById('repaintRects').textContent = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+            
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+                
+        window.addEventListener('load', documentLoaded, false);
+    </script>
+</head>
+<body>
+
+<iframe id="frame" onload="documentLoaded()" src="resources/fixed-background-document.html"></iframe>
+<pre id="repaintRects"></pre>
+<div class="composited"></div> <!-- To get the root composited in WebKit1 -->
+
+</body>
+</html>
diff --git a/LayoutTests/compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt b/LayoutTests/compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt
new file mode 100644 (file)
index 0000000..3c3a849
--- /dev/null
@@ -0,0 +1,59 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 2016.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2016.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 14.00 14.00)
+          (bounds 432.00 332.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (position 16.00 16.00)
+              (children 1
+                (GraphicsLayer
+                  (anchor 0.00 0.00)
+                  (bounds 400.00 300.00)
+                  (children 1
+                    (GraphicsLayer
+                      (position 0.00 -100.00)
+                      (children 1
+                        (GraphicsLayer
+                          (anchor 0.00 0.00)
+                          (bounds 400.00 1016.00)
+                          (children 1
+                            (GraphicsLayer
+                              (bounds 400.00 1016.00)
+                              (drawsContent 1)
+                              (children 1
+                                (GraphicsLayer
+                                  (position 8.00 8.00)
+                                  (bounds 100.00 100.00)
+                                  (contentsOpaque 1)
+                                )
+                              )
+                            )
+                          )
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 369.00)
+          (anchor 1.00 1.00)
+          (bounds 1.00 1.00)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/repaint/iframes/compositing-iframe-scroll-repaint.html b/LayoutTests/compositing/repaint/iframes/compositing-iframe-scroll-repaint.html
new file mode 100644 (file)
index 0000000..13045e4
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+        }
+        iframe {
+            height: 300px;
+            width: 400px;
+            margin: 20px;
+            box-shadow: 0 0 10px black;
+        }
+        .composited {
+            -webkit-transform: translateZ(0);
+            width: 1px;
+            height: 1px;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        var expectedLoads = 2;
+        function documentLoaded()
+        {
+            if (!--expectedLoads) {
+                // Timeout is required to allow layer to paint before the scroll.
+                window.setTimeout(doTest, 0);
+            }
+        }
+        
+        function doTest()
+        {
+            if (window.testRunner)
+                testRunner.display(); // Flush pending compositing repaints.
+
+            if (window.internals)
+                window.internals.startTrackingRepaints();
+
+            document.getElementById('frame').contentWindow.scrollTo(0, 100);
+
+            if (window.internals)
+                document.getElementById('repaintRects').textContent = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+            
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+                
+        window.addEventListener('load', documentLoaded, false);
+    </script>
+</head>
+<body>
+
+<iframe id="frame" onload="documentLoaded()" src="resources/compositing-document.html"></iframe>
+<pre id="repaintRects"></pre>
+<div class="composited"></div> <!-- To get the root composited in WebKit1 -->
+
+</body>
+</html>
diff --git a/LayoutTests/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt b/LayoutTests/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt
new file mode 100644 (file)
index 0000000..b255fe6
--- /dev/null
@@ -0,0 +1,63 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 2016.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2016.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 14.00 14.00)
+          (bounds 432.00 332.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (position 16.00 16.00)
+              (children 1
+                (GraphicsLayer
+                  (anchor 0.00 0.00)
+                  (bounds 400.00 300.00)
+                  (children 1
+                    (GraphicsLayer
+                      (position 0.00 -100.00)
+                      (children 1
+                        (GraphicsLayer
+                          (anchor 0.00 0.00)
+                          (bounds 400.00 1016.00)
+                          (children 1
+                            (GraphicsLayer
+                              (bounds 400.00 1016.00)
+                              (drawsContent 1)
+                              (repaint rects
+                                (rect 8.00 8.00 100.00 100.00)
+                              )
+                              (children 1
+                                (GraphicsLayer
+                                  (position 8.00 108.00)
+                                  (bounds 100.00 100.00)
+                                  (contentsOpaque 1)
+                                  (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [100.00 0.00 0.00 1.00])
+                                )
+                              )
+                            )
+                          )
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 369.00)
+          (anchor 1.00 1.00)
+          (bounds 1.00 1.00)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint.html b/LayoutTests/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint.html
new file mode 100644 (file)
index 0000000..2194dd3
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+        }
+        iframe {
+            height: 300px;
+            width: 400px;
+            margin: 20px;
+            box-shadow: 0 0 10px black;
+        }
+        
+        .composited {
+            -webkit-transform: translateZ(0);
+            width: 1px;
+            height: 1px;
+        }        
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        var expectedLoads = 2;
+        function documentLoaded()
+        {
+            if (!--expectedLoads) {
+                // Timeout is required to allow layer to paint before the scroll.
+                window.setTimeout(doTest, 0);
+            }
+        }
+        
+        function doTest()
+        {
+            if (window.testRunner)
+                testRunner.display(); // Flush pending compositing repaints.
+
+            if (window.internals)
+                window.internals.startTrackingRepaints();
+
+            document.getElementById('frame').contentWindow.scrollTo(0, 100);
+
+            if (window.internals)
+                document.getElementById('repaintRects').textContent = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+            
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+                
+        window.addEventListener('load', documentLoaded, false);
+    </script>
+</head>
+<body>
+
+<iframe id="frame" onload="documentLoaded()" src="resources/compositing-fixed-background-document.html"></iframe>
+<pre id="repaintRects"></pre>
+<div class="composited"></div> <!-- To get the root composited in WebKit1 -->
+
+</body>
+</html>
diff --git a/LayoutTests/compositing/repaint/iframes/resources/compositing-document.html b/LayoutTests/compositing/repaint/iframes/resources/compositing-document.html
new file mode 100644 (file)
index 0000000..adbca31
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            overflow: hidden;
+            height: 1000px;
+        }
+        .box {
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            -webkit-transform: translateZ(0);
+        }
+    </style>
+</head>
+<body>
+<div class="composited box">
+</div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/repaint/iframes/resources/compositing-fixed-background-document.html b/LayoutTests/compositing/repaint/iframes/resources/compositing-fixed-background-document.html
new file mode 100644 (file)
index 0000000..f8c277b
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            overflow: hidden;
+            height: 1000px;
+        }
+        .box {
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .background-fixed {
+               background-image: linear-gradient(blue, green);
+               background-size: 100% 100px;
+            background-attachment: fixed;
+        }
+        
+        .composited {
+            -webkit-transform: translate3d(100px, 0, 0);
+        }
+    </style>
+</head>
+<body>
+<div class="background-fixed box">
+</div>
+<div class="composited box">
+</div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/repaint/iframes/resources/fixed-background-document.html b/LayoutTests/compositing/repaint/iframes/resources/fixed-background-document.html
new file mode 100644 (file)
index 0000000..c498020
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            overflow: hidden;
+            height: 1000px;
+        }
+        .box {
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .background-fixed {
+               background-image: linear-gradient(blue, green);
+               background-size: 100% 100px;
+            background-attachment: fixed;
+        }
+    </style>
+</head>
+<body>
+<div class="background-fixed box">
+</div>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk1/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt b/LayoutTests/platform/mac-wk1/compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint-expected.txt
new file mode 100644 (file)
index 0000000..4d7730a
--- /dev/null
@@ -0,0 +1,28 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 2016.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2016.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 14.00 14.00)
+          (bounds 432.00 332.00)
+          (drawsContent 1)
+          (repaint rects
+            (rect 24.00 16.00 100.00 8.00)
+            (rect 16.00 16.00 400.00 300.00)
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 369.00)
+          (anchor 1.00 1.00)
+          (bounds 1.00 1.00)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt b/LayoutTests/platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-scroll-repaint-expected.txt
new file mode 100644 (file)
index 0000000..49a2867
--- /dev/null
@@ -0,0 +1,62 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 2016.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2016.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 14.00 14.00)
+          (bounds 432.00 332.00)
+          (drawsContent 1)
+          (repaint rects
+            (rect 16.00 16.00 400.00 300.00)
+          )
+          (children 1
+            (GraphicsLayer
+              (position 16.00 16.00)
+              (children 1
+                (GraphicsLayer
+                  (anchor 0.00 0.00)
+                  (bounds 400.00 300.00)
+                  (children 1
+                    (GraphicsLayer
+                      (position 0.00 -100.00)
+                      (children 1
+                        (GraphicsLayer
+                          (anchor 0.00 0.00)
+                          (bounds 400.00 1016.00)
+                          (children 1
+                            (GraphicsLayer
+                              (bounds 400.00 1016.00)
+                              (drawsContent 1)
+                              (children 1
+                                (GraphicsLayer
+                                  (position 8.00 8.00)
+                                  (bounds 100.00 100.00)
+                                  (contentsOpaque 1)
+                                )
+                              )
+                            )
+                          )
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 369.00)
+          (anchor 1.00 1.00)
+          (bounds 1.00 1.00)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt b/LayoutTests/platform/mac-wk1/compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint-expected.txt
new file mode 100644 (file)
index 0000000..57579cb
--- /dev/null
@@ -0,0 +1,66 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 2016.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2016.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 14.00 14.00)
+          (bounds 432.00 332.00)
+          (drawsContent 1)
+          (repaint rects
+            (rect 16.00 16.00 400.00 300.00)
+          )
+          (children 1
+            (GraphicsLayer
+              (position 16.00 16.00)
+              (children 1
+                (GraphicsLayer
+                  (anchor 0.00 0.00)
+                  (bounds 400.00 300.00)
+                  (children 1
+                    (GraphicsLayer
+                      (position 0.00 -100.00)
+                      (children 1
+                        (GraphicsLayer
+                          (anchor 0.00 0.00)
+                          (bounds 400.00 1016.00)
+                          (children 1
+                            (GraphicsLayer
+                              (bounds 400.00 1016.00)
+                              (drawsContent 1)
+                              (repaint rects
+                                (rect 8.00 8.00 100.00 100.00)
+                              )
+                              (children 1
+                                (GraphicsLayer
+                                  (position 8.00 108.00)
+                                  (bounds 100.00 100.00)
+                                  (contentsOpaque 1)
+                                  (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [100.00 0.00 0.00 1.00])
+                                )
+                              )
+                            )
+                          )
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 369.00)
+          (anchor 1.00 1.00)
+          (bounds 1.00 1.00)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint-expected.txt
new file mode 100644 (file)
index 0000000..11610d4
--- /dev/null
@@ -0,0 +1,6 @@
+We should only repaint the bounds of the element with a fixed background.
+
+(repaint rects
+  (rect 8 -50 252 202)
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint.html
new file mode 100644 (file)
index 0000000..bb859e5
--- /dev/null
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+        }
+          #test {
+              height: 200px;
+              width: 250px;
+              border: 1px solid black;
+              background-image: linear-gradient(blue, green);
+              background-size: 100% 300px;
+           background-attachment: fixed;
+          }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function documentLoaded()
+        {
+            // Timeout is required to allow layers to paint before the scroll.
+            window.setTimeout(doTest, 0);
+        }
+        
+        function doTest()
+        {
+            if (window.internals)
+                window.internals.startTrackingRepaints();
+
+            window.scrollTo(0, 100);
+
+            if (window.internals)
+                document.getElementById('repaintRects').textContent = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+            
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+                
+        window.addEventListener('load', documentLoaded, false);
+    </script>
+</head>
+<body>
+
+<p>We should only repaint the bounds of the element with a fixed background.</p>
+<div id="test"></div>
+<pre id="repaintRects"></pre>
+
+</body>
+</html>
index cbc13f5..caf8e31 100644 (file)
@@ -1,3 +1,27 @@
+2015-04-12  Simon Fraser  <simon.fraser@apple.com>
+
+        Too much repainting on scrolling with fixed backgrounds
+        https://bugs.webkit.org/show_bug.cgi?id=143637
+        rdar://problem/20245243
+
+        Reviewed by Darin Adler.
+        
+        FrameView::scrollContentsSlowPath() would repaint the entire viewport if there were
+        any slow-repaint objects (those with background-attachment: fixed) and the contents
+        were using compositing for scrolling.
+        
+        This is wrong; we only need to issue repaint for the slow-repaint renderers,
+        and, if the frame is hosted in a compositing layer and not using compositing for scrolling,
+        repaint that hosting layer.
+
+        Tests: compositing/repaint/iframes/composited-iframe-with-fixed-background-doc-repaint.html
+               compositing/repaint/iframes/compositing-iframe-scroll-repaint.html
+               compositing/repaint/iframes/compositing-iframe-with-fixed-background-doc-repaint.html
+               platform/mac-wk2/tiled-drawing/fixed-background-scroll-repaint.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollContentsSlowPath):
+
 2015-04-11  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: create content view and details sidebar for Frames timeline
index eb17a28..9b3a2b1 100644 (file)
@@ -1867,25 +1867,12 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
 
 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
 {
-    if (usesCompositedScrolling()) {
-        // FIXME: respect paintsEntireContents()?
-        IntRect updateRect = visibleContentRect(LegacyIOSDocumentVisibleRect);
-
-        // Make sure to "apply" the scale factor here since we're converting from frame view
-        // coordinates to layer backing coordinates.
-        updateRect.scale(1 / frame().frameScaleFactor());
-
-        ASSERT(renderView());
-        renderView()->layer()->setBackingNeedsRepaintInRect(updateRect, GraphicsLayer::DoNotClipToLayer);
-    }
-
     repaintSlowRepaintObjects();
 
-    if (RenderWidget* frameRenderer = frame().ownerRenderer()) {
-        if (isEnclosedInCompositingLayer()) {
-            LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
-                            frameRenderer->borderTop() + frameRenderer->paddingTop(),
-                            visibleWidth(), visibleHeight());
+    if (!usesCompositedScrolling() && isEnclosedInCompositingLayer()) {
+        if (RenderWidget* frameRenderer = frame().ownerRenderer()) {
+            LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(), frameRenderer->borderTop() + frameRenderer->paddingTop(),
+                visibleWidth(), visibleHeight());
             frameRenderer->repaintRectangle(rect);
             return;
         }