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
+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
--- /dev/null
+
+(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)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+<!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>
--- /dev/null
+
+(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)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+<!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>
--- /dev/null
+
+(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)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+<!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>
--- /dev/null
+<!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>
--- /dev/null
+<!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>
--- /dev/null
+<!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>
--- /dev/null
+
+(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)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+
+(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)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+
+(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)
+ )
+ )
+ )
+ )
+)
+
-(repaint rects
- (rect 0 0 785 600)
-)
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 785.00 2021.00)
--- /dev/null
+We should only repaint the bounds of the element with a fixed background.
+
+(repaint rects
+ (rect 8 -50 252 202)
+)
+
--- /dev/null
+<!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>
+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
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;
}