Skip to content
Permalink
Browse files
Reduce the amount of RenderLayer rectangles' update when scrolling
https://bugs.webkit.org/show_bug.cgi?id=66618

Reviewed by David Hyatt.

Source/WebCore:

This patch avoids recomputing the RenderLayers rectangles if not needed.

The current code path for scrolling would update RenderLayers' repaint rectangles
twice. However we do need to update only children of a fixed element as they are
the only type of layers that move during a scroll.

We just change a call to updateLayerPositions for a call to updateLayerPositionsAfterScroll.
updateLayerPositions being pessimist about the layer's state - because it is called after layout -
it is missing some optimization that can be done during scrolling.

Tests: fast/repaint/scroll-absolute-layer-with-reflection.html
       fast/repaint/scroll-fixed-layer-with-reflection.html
       fast/repaint/scroll-fixed-layer-with-transformed-parent-layer.html
       fast/repaint/scroll-fixed-reflected-layer.html
       fast/repaint/scroll-in-clipped-layer.html
       fast/repaint/scroll-in-fixed-layer.html
       fast/repaint/scroll-in-transformed-layer.html
       fast/repaint/scroll-with-transformed-parent-layer.html

* rendering/RenderLayer.h:
* page/FrameView.cpp:
(WebCore::FrameView::repaintFixedElementsAfterScrolling):
Updated those 2 call sites after updateRepaintRectsAfterScroll renaming.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateLayerPositionsAfterScroll): Beefed up the method
to take care of also updating the layer's position (that sounded like a bug in
the previous code that is covered by the tests above). Note that we don't care
if one of our ancestor has a fixed position as we are scrolling *inside* this
ancestor.

(WebCore::RenderLayer::scrollTo): Call updateLayerPositionsAfterScroll instead of
updateLayerPositions.

LayoutTests:

* fast/repaint/resources/default.css:
Added more shortcuts.

* fast/repaint/scroll-absolute-layer-with-reflection-expected.txt: Added.
* fast/repaint/scroll-absolute-layer-with-reflection.html: Added.
* fast/repaint/scroll-fixed-layer-with-reflection-expected.txt: Added.
* fast/repaint/scroll-fixed-layer-with-reflection.html: Added.
* fast/repaint/scroll-fixed-layer-with-transformed-parent-layer-expected.txt: Added.
* fast/repaint/scroll-fixed-layer-with-transformed-parent-layer.html: Added.
* fast/repaint/scroll-fixed-reflected-layer-expected.txt: Added.
* fast/repaint/scroll-fixed-reflected-layer.html: Added.
* fast/repaint/scroll-in-clipped-layer-expected.txt: Added.
* fast/repaint/scroll-in-clipped-layer.html: Added.
* fast/repaint/scroll-in-fixed-layer-expected.txt: Added.
* fast/repaint/scroll-in-fixed-layer.html: Added.
* fast/repaint/scroll-in-transformed-layer-expected.txt: Added.
* fast/repaint/scroll-in-transformed-layer.html: Added.
* fast/repaint/scroll-with-transformed-parent-layer-expected.txt: Added.
* fast/repaint/scroll-with-transformed-parent-layer.html: Added.
Those are a variation on the same theme: scrolling inside a layers (sometimes the layer is itself scrolled)
to show that we are still doing the right thing.

* platform/chromium-cg-mac/scroll-absolute-layer-with-reflection-expected.png: Added.
* platform/chromium-cg-mac/scroll-fixed-layer-with-reflection-expected.png: Added.
* platform/chromium-cg-mac/scroll-fixed-layer-with-transformed-parent-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-fixed-reflected-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-in-clipped-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-in-fixed-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-in-transformed-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-with-transformed-parent-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-absolute-layer-with-reflection-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-fixed-layer-with-reflection-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-fixed-layer-with-transformed-parent-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-fixed-reflected-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-in-clipped-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-in-fixed-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-in-transformed-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-with-transformed-parent-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-absolute-layer-with-reflection-expected.png: Added.
* platform/mac/fast/repaint/scroll-fixed-layer-with-reflection-expected.png: Added.
* platform/mac/fast/repaint/scroll-fixed-layer-with-transformed-parent-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-fixed-reflected-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-in-clipped-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-in-fixed-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-in-transformed-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-with-transformed-parent-layer-expected.png: Added.
Baseline for Chromium and Mac.


Canonical link: https://commits.webkit.org/82591@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@93614 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Julien Chaffraix committed Aug 23, 2011
1 parent 20465fd commit a705cf676a1ed98204e4a92a91f616de0199e970
Showing 46 changed files with 359 additions and 11 deletions.
@@ -1,3 +1,58 @@
2011-08-23 Julien Chaffraix <jchaffraix@webkit.org>

Reduce the amount of RenderLayer rectangles' update when scrolling
https://bugs.webkit.org/show_bug.cgi?id=66618

Reviewed by David Hyatt.

* fast/repaint/resources/default.css:
Added more shortcuts.

* fast/repaint/scroll-absolute-layer-with-reflection-expected.txt: Added.
* fast/repaint/scroll-absolute-layer-with-reflection.html: Added.
* fast/repaint/scroll-fixed-layer-with-reflection-expected.txt: Added.
* fast/repaint/scroll-fixed-layer-with-reflection.html: Added.
* fast/repaint/scroll-fixed-layer-with-transformed-parent-layer-expected.txt: Added.
* fast/repaint/scroll-fixed-layer-with-transformed-parent-layer.html: Added.
* fast/repaint/scroll-fixed-reflected-layer-expected.txt: Added.
* fast/repaint/scroll-fixed-reflected-layer.html: Added.
* fast/repaint/scroll-in-clipped-layer-expected.txt: Added.
* fast/repaint/scroll-in-clipped-layer.html: Added.
* fast/repaint/scroll-in-fixed-layer-expected.txt: Added.
* fast/repaint/scroll-in-fixed-layer.html: Added.
* fast/repaint/scroll-in-transformed-layer-expected.txt: Added.
* fast/repaint/scroll-in-transformed-layer.html: Added.
* fast/repaint/scroll-with-transformed-parent-layer-expected.txt: Added.
* fast/repaint/scroll-with-transformed-parent-layer.html: Added.
Those are a variation on the same theme: scrolling inside a layers (sometimes the layer is itself scrolled)
to show that we are still doing the right thing.

* platform/chromium-cg-mac/scroll-absolute-layer-with-reflection-expected.png: Added.
* platform/chromium-cg-mac/scroll-fixed-layer-with-reflection-expected.png: Added.
* platform/chromium-cg-mac/scroll-fixed-layer-with-transformed-parent-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-fixed-reflected-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-in-clipped-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-in-fixed-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-in-transformed-layer-expected.png: Added.
* platform/chromium-cg-mac/scroll-with-transformed-parent-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-absolute-layer-with-reflection-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-fixed-layer-with-reflection-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-fixed-layer-with-transformed-parent-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-fixed-reflected-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-in-clipped-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-in-fixed-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-in-transformed-layer-expected.png: Added.
* platform/chromium-win/fast/repaint/scroll-with-transformed-parent-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-absolute-layer-with-reflection-expected.png: Added.
* platform/mac/fast/repaint/scroll-fixed-layer-with-reflection-expected.png: Added.
* platform/mac/fast/repaint/scroll-fixed-layer-with-transformed-parent-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-fixed-reflected-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-in-clipped-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-in-fixed-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-in-transformed-layer-expected.png: Added.
* platform/mac/fast/repaint/scroll-with-transformed-parent-layer-expected.png: Added.
Baseline for Chromium and Mac.

2011-08-23 Andrey Kosyakov <caseq@chromium.org>

Unreviewed. Disabled inspector/extensions/extensions-resources.html.
@@ -39,3 +39,17 @@ iframe {
.yellow {
background-color: yellow;
}

.rotated {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
}

.clipped {
overflow: hidden;
}

.reflected {
-webkit-box-reflect: below 0px;
}
@@ -0,0 +1,31 @@
<html>
<head>
<link rel="stylesheet" href="resources/default.css"></style>
<script src="resources/repaint.js" type="text/javascript"></script>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);

function repaintTest()
{
var moveMeElement = document.getElementById('moveMe');
moveMeElement.scrollTop = 250;
moveMeElement.scrollLeft = 150;
}
</script>
</head>
<body style="height:2000px;" onload="runRepaintTest()">
<!-- You should see 1 green rectangle rotated in the output and no red. -->
<div id="moveMe" style="top: 230px; left: 250px;" class="absolute clipped">
<div class="relative reflected" style="height: 50px; top: 250px; left: 150px;">
<div class="green"></div>
</div>
<div class="absolute red" style="top: 0px; left: 0px; height: 250px; width: 150px;"></div>
</div>
<!-- Make sure we are scrolled -->
<div style="top: 0px; left: 0px;" class="absolute red"></div>
<script>
window.scrollTo(100, 180);
</script>
</body>
</html>
@@ -0,0 +1,29 @@
<html>
<head>
<link rel="stylesheet" href="resources/default.css"></style>
<script src="resources/repaint.js" type="text/javascript"></script>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);

function repaintTest()
{
var moveMeElement = document.getElementById('moveMe');
moveMeElement.scrollTop = 250;
moveMeElement.scrollLeft = 150;
}
</script>
</head>
<body style="height:2000px;" onload="runRepaintTest()">
<!-- You should see 1 green rectangle rotated in the output and no red. -->
<div id="moveMe" style="top: 100px; left: 250px;" class="fixed clipped">
<div class="absolute green reflected" style="height: 50px; top: 150px; left: 150px;"></div>
<div class="absolute red" style="top: 0px; left: 0px; height: 250px; width: 150px;"></div>
</div>
<!-- Make sure we are scrolled -->
<div style="top: 0px; left: 0px;" class="absolute red"></div>
<script>
window.scrollTo(100, 180);
</script>
</body>
</html>
@@ -0,0 +1,31 @@
<html>
<head>
<link rel="stylesheet" href="resources/default.css"></style>
<script src="resources/repaint.js" type="text/javascript"></script>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);

function repaintTest()
{
var moveMeElement = document.getElementById('moveMe');
moveMeElement.scrollTop = 250;
moveMeElement.scrollLeft = 150;
}
</script>
</head>
<body style="height:2000px;" onload="runRepaintTest()">
<!-- You should see 1 green rectangle rotated in the output and no red. -->
<div class="rotated">
<div id="moveMe" style="top: 100px; left: 250px;" class="fixed clipped">
<div class="absolute green" style="top: 250px; left: 150px;"></div>
<div class="absolute red" style="top: 0px; left: 0px; height: 250px; width: 150px;"></div>
</div>
</div>
<!-- Make sure we are scrolled -->
<div style="top: 0px; left: 0px;" class="absolute red"></div>
<script>
window.scrollTo(100, 180);
</script>
</body>
</html>
@@ -0,0 +1 @@

@@ -0,0 +1,27 @@
<html>
<head>
<link rel="stylesheet" href="resources/default.css"></style>
<script src="resources/repaint.js" type="text/javascript"></script>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);

function repaintTest()
{
document.getElementById("hideMe").style.zIndex = "-5";
}
</script>
</head>
<body style="height:2000px;" onload="runRepaintTest()">
<!-- You should see 1 green rectangle rotated in the output and no red. -->
<div style="height: 50px; top: 100px; left: 250px;" class="reflected fixed">
<div class="absolute green reflected" style="height: 50px;"></div>
<div id="hideMe" class="absolute red" style="top: 0px; left: 0px;"></div>
</div>
<!-- Make sure we are scrolled -->
<div style="top: 0px; left: 0px;" class="absolute red"></div>
<script>
window.scrollTo(100, 180);
</script>
</body>
</html>
@@ -0,0 +1 @@

@@ -0,0 +1,24 @@
<html>
<head>
<link rel="stylesheet" href="resources/default.css"></style>
<script src="resources/repaint.js" type="text/javascript"></script>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);

function repaintTest()
{
var moveMeElement = document.getElementById('moveMe');
moveMeElement.scrollTop = 100;
moveMeElement.scrollLeft = 150;
}
</script>
</head>
<body style="height:2000px;" onload="runRepaintTest()">
<!-- You should see 1 green rectangle in the output and no red. -->
<div id="moveMe" style="top: 150px; left: 100px;" class="absolute clipped">
<div class="relative green" style="top: 100px; left: 150px; width: 500px; height: 500px;"></div>
<div class="absolute red" style="top:0px; left: 0px;"></div>
</div>
</body>
</html>
@@ -0,0 +1 @@

@@ -0,0 +1,29 @@
<html>
<head>
<link rel="stylesheet" href="resources/default.css"></style>
<script src="resources/repaint.js" type="text/javascript"></script>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);

function repaintTest()
{
var moveMeElement = document.getElementById('moveMe');
moveMeElement.scrollTop = 100;
moveMeElement.scrollLeft = 150;
}
</script>
</head>
<body style="height:2000px;" onload="runRepaintTest()">
<!-- You should see 1 green rectangle in the output and no red. -->
<div id="moveMe" style="top: 150px; left: 100px;" class="fixed clipped">
<div class="absolute green" style="top: 100px; left: 150px;"></div>
<div class="absolute red" style="top:0px; left: 0px;"></div>
</div>
<!-- Make sure we are scrolled -->
<div style="top: 0px; left: 0px;" class="absolute red"></div>
<script>
window.scrollTo(1000, 1000);
</script>
</body>
</html>
@@ -0,0 +1 @@

@@ -0,0 +1,26 @@
<html>
<head>
<link rel="stylesheet" href="resources/default.css"></style>
<script src="resources/repaint.js" type="text/javascript"></script>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);

function repaintTest()
{
var moveMeElement = document.getElementById('moveMe');
moveMeElement.scrollTop = 100;
moveMeElement.scrollLeft = 50;
var classes = moveMeElement.getAttribute("class");
moveMeElement.setAttribute("class", classes + " rotated");
}
</script>
</head>
<body style="height:2000px;" onload="runRepaintTest()">
<!-- You should see 1 green rectangle rotated in the output and no red. -->
<div id="moveMe" style="top: 150px; left: 100px" class="absolute clipped">
<div class="absolute green" style="top: 100px; left: 50px"></div>
<div class="absolute red" style="top: 0px; left: 0px;"></div>
</div>
</body>
</html>
@@ -0,0 +1,26 @@
<html>
<head>
<link rel="stylesheet" href="resources/default.css"></style>
<script src="resources/repaint.js" type="text/javascript"></script>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);

function repaintTest()
{
var moveMeElement = document.getElementById('moveMe');
moveMeElement.scrollTop = 100;
moveMeElement.scrollLeft = 50;
}
</script>
</head>
<body style="height:2000px;" onload="runRepaintTest()">
<!-- You should see 1 green rectangle rotated in the output and no red. -->
<div style="top: 150px; left: 100px" class="absolute clipped rotated">
<div id="moveMe" class="absolute clipped" style="top: 0px; left: 0px;">
<div class="absolute green" style="top: 100px; left: 50px"></div>
<div class="absolute red" style="top: 0px; left: 0px;"></div>
</div>
</div>
</body>
</html>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -1,3 +1,44 @@
2011-08-23 Julien Chaffraix <jchaffraix@webkit.org>

Reduce the amount of RenderLayer rectangles' update when scrolling
https://bugs.webkit.org/show_bug.cgi?id=66618

Reviewed by David Hyatt.

This patch avoids recomputing the RenderLayers rectangles if not needed.

The current code path for scrolling would update RenderLayers' repaint rectangles
twice. However we do need to update only children of a fixed element as they are
the only type of layers that move during a scroll.

We just change a call to updateLayerPositions for a call to updateLayerPositionsAfterScroll.
updateLayerPositions being pessimist about the layer's state - because it is called after layout -
it is missing some optimization that can be done during scrolling.

Tests: fast/repaint/scroll-absolute-layer-with-reflection.html
fast/repaint/scroll-fixed-layer-with-reflection.html
fast/repaint/scroll-fixed-layer-with-transformed-parent-layer.html
fast/repaint/scroll-fixed-reflected-layer.html
fast/repaint/scroll-in-clipped-layer.html
fast/repaint/scroll-in-fixed-layer.html
fast/repaint/scroll-in-transformed-layer.html
fast/repaint/scroll-with-transformed-parent-layer.html

* rendering/RenderLayer.h:
* page/FrameView.cpp:
(WebCore::FrameView::repaintFixedElementsAfterScrolling):
Updated those 2 call sites after updateRepaintRectsAfterScroll renaming.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateLayerPositionsAfterScroll): Beefed up the method
to take care of also updating the layer's position (that sounded like a bug in
the previous code that is covered by the tests above). Note that we don't care
if one of our ancestor has a fixed position as we are scrolling *inside* this
ancestor.

(WebCore::RenderLayer::scrollTo): Call updateLayerPositionsAfterScroll instead of
updateLayerPositions.

2011-08-23 Jeffrey Pfau <jpfau@apple.com>

New XML parser: pretty XML tree viewer
@@ -1617,7 +1617,7 @@ void FrameView::repaintFixedElementsAfterScrolling()
if (!m_nestedLayoutCount && hasFixedObjects()) {
if (RenderView* root = m_frame->contentRenderer()) {
root->updateWidgetPositions();
root->layer()->updateRepaintRectsAfterScroll();
root->layer()->updateLayerPositionsAfterScroll();
#if USE(ACCELERATED_COMPOSITING)
root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
#endif

0 comments on commit a705cf6

Please sign in to comment.