Skip to content

Commit

Permalink
Avoid calling updateCompositingLayers() more than once before each re…
Browse files Browse the repository at this point in the history
…nder.

https://bugs.webkit.org/show_bug.cgi?id=84393
<rdar://11359525>

Reviewed by Simon Fraser.

Calling updateCompositingLayers after each layout causes unnecessary work, since
the layers might change again before rendering.

This change defers this work until Page::updateRendering if possible, and improves
performance on pages that force layout flushes outside of rendering.

* LayoutTests/compositing/overflow/scrolling-without-painting.html:
* LayoutTests/compositing/overflow/updating-scrolling-content.html:
* LayoutTests/compositing/scrolling/touch-scroll-to-clip.html:
* LayoutTests/compositing/updates/no-style-change-updates.html:
* LayoutTests/editing/editable-region/iframe-expected.txt:
* LayoutTests/fast/css/transform-function-perspective-crash.html:
* LayoutTests/fast/scrolling/iframe-scrollable-after-back.html:
* LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hit-test.html:
* LayoutTests/fast/scrolling/mac/scrollbars/overflow-overlay-scrollbar-hovered.html:
* LayoutTests/inspector/layers/layerTreeDidChange.html:
* LayoutTests/platform/gtk/compositing/scrolling/touch-scroll-to-clip-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/updating-scrolling-content-expected.txt.
* LayoutTests/platform/ios/compositing/overflow/updating-scrolling-content-expected.txt:
* LayoutTests/platform/mac-wk1/TestExpectations:
* LayoutTests/platform/wpe/TestExpectations:
* LayoutTests/platform/wpe/fast/text/mark-matches-overflow-clip-expected.txt:
* LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested.html:
* LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow.html:
* LayoutTests/scrollingcoordinator/scrolling-tree/fixed-inside-relative-inside-stacking-overflow-inside-transformed.html:
* LayoutTests/scrollingcoordinator/scrolling-tree/fixed-inside-stacking-overflow-inside-transformed.html:
* LayoutTests/tiled-drawing/scrolling/clamp-out-of-bounds-scrolls.html:
* LayoutTests/tiled-drawing/scrolling/scrolling-tree-after-scroll.html:
* LayoutTests/tiled-drawing/scrolling/slow-scrolling.html:
* Source/WebCore/dom/Document.cpp:
(WebCore::Document::updateLayoutIgnorePendingStylesheets):
(WebCore::Document::updateLayout):
(WebCore::Document::implicitClose):
* Source/WebCore/dom/Document.h:
(WebCore::Document::updateLayout):
(WebCore::Document::updateLayoutIgnorePendingStylesheets):
* Source/WebCore/dom/Element.cpp:
(WebCore::Element::scrollIntoView):
(WebCore::Element::scrollIntoViewIfNeeded):
(WebCore::Element::scrollIntoViewIfNotVisible):
(WebCore::Element::scrollTo):
(WebCore::Element::scrollByUnits):
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::commitProvisionalLoad):
* Source/WebCore/page/LocalDOMWindow.cpp:
(WebCore::LocalDOMWindow::scrollTo const):
* Source/WebCore/page/LocalFrameView.cpp:
(WebCore::LocalFrameView::updateCompositingLayersAfterLayout):
(WebCore::LocalFrameView::updateCompositingLayersAfterLayoutIfNeeded):
(WebCore::LocalFrameView::didLayout):
(WebCore::LocalFrameView::updateLayoutAndStyleIfNeededRecursive):
(WebCore::LocalFrameView::setTracksRepaints):
* Source/WebCore/page/LocalFrameView.h:
* Source/WebCore/page/Page.cpp:
(WebCore::Page::scrollingStateTreeAsText):
(WebCore::Page::setPageScaleFactor):
(WebCore::Page::layoutIfNeeded):
(WebCore::Page::updateRendering):
(WebCore::Page::doAfterUpdateRendering):
* Source/WebCore/page/Page.h:
(WebCore::Page::layoutIfNeeded):
* Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):
(WebCore::AsyncScrollingCoordinator::frameViewEventTrackingRegionsChanged):
(WebCore::AsyncScrollingCoordinator::setEventTrackingRegionsDirty): Deleted.
* Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h:
* Source/WebCore/rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateCompositingForLayerTreeAsTextDump):
* Source/WebCore/rendering/RenderTreeAsText.cpp:
(WebCore::externalRepresentation):
(WebCore::updateLayoutIgnoringPendingStylesheetsIncludingSubframes): Deleted.

Canonical link: https://commits.webkit.org/271261@main
  • Loading branch information
mattwoodrow committed Nov 29, 2023
1 parent 7445f27 commit b6b7455
Show file tree
Hide file tree
Showing 33 changed files with 212 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
-->
<html>
<head>
<script src="../../resources/ui-helper.js"></script>
<style type="text/css">
#scroller {
overflow: scroll;
Expand All @@ -20,17 +21,22 @@
}
</style>
<script type="text/javascript">
window.addEventListener('load', function() {
window.addEventListener('load', async function() {
if (!window.testRunner || !window.internals) {
alert('This test requires testRunner to run!');
return;
}
testRunner.dumpAsText(false);
testRunner.waitUntilDone();

await UIHelper.renderingUpdate();

// First paint the entire view including the scrolling element.
var scroller = document.getElementById('scroller');
scroller.offsetTop;

await UIHelper.renderingUpdate();

// Scroll down. This should not cause any more repaints to the
// scrolling contents.
window.internals.startTrackingRepaints();
Expand All @@ -40,6 +46,8 @@
layerTree.innerText =
window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
window.internals.stopTrackingRepaints();

testRunner.notifyDone();
});
</script>
</head>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
-->
<html>
<head>
<script src="../../resources/ui-helper.js"></script>
<style type="text/css">
#scroller {
overflow: scroll;
Expand All @@ -24,19 +25,24 @@
}
</style>
<script type="text/javascript">
window.addEventListener('load', function() {
window.addEventListener('load', async function() {
if (!window.testRunner || !window.internals) {
alert('This test requires testRunner to run!');
return;
}
testRunner.dumpAsText(false);
testRunner.waitUntilDone();

await UIHelper.renderingUpdate();

var scroller = document.getElementById('scroller');
var indicator = document.getElementById('indicator');

// Make sure the scrolling content is painted before we start.
scroller.offsetTop;

await UIHelper.renderingUpdate();

// Scroll all the way to the bottom and change the color of the
// indicator (which is now outside the overflow clip).
scroller.scrollTop = 1000;
Expand All @@ -49,6 +55,7 @@
layerTree.innerText =
window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
window.internals.stopTrackingRepaints();
testRunner.notifyDone();
});
</script>
</head>
Expand Down
20 changes: 10 additions & 10 deletions LayoutTests/compositing/scrolling/touch-scroll-to-clip.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html>
<head>
<meta name="viewport" content="initial-scale=1.0">
<script src="../../resources/ui-helper.js"></script>
<style>
html {
-webkit-overflow-scrolling: touch;
Expand Down Expand Up @@ -33,20 +34,19 @@
testRunner.dumpAsText();
}

function startTest()
async function startTest()
{
document.body.offsetWidth;
window.setTimeout(function() {
var scroller = document.getElementById('scroller');
scroller.classList.toggle('no-scroll');
await UIHelper.renderingUpdate();

if (window.internals)
document.getElementById('layer-tree').innerText = window.internals.layerTreeAsText(document);
var scroller = document.getElementById('scroller');
scroller.classList.toggle('no-scroll');

if (window.testRunner)
window.testRunner.notifyDone();

}, 0);
if (window.internals)
document.getElementById('layer-tree').innerText = window.internals.layerTreeAsText(document);

if (window.testRunner)
window.testRunner.notifyDone();
}
window.addEventListener('load', startTest, false);
</script>
Expand Down
27 changes: 14 additions & 13 deletions LayoutTests/compositing/updates/no-style-change-updates.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,39 @@

</style>
<script src="../../resources/js-test-pre.js"></script>
<script src="../../resources/ui-helper.js"></script>
<script>
description('Test that compositing updates do not happen for style changes that do not need them.');
window.jsTestIsAsync = true;

var updateCount;

function zeroUpdateCount()
async function zeroUpdateCount()
{
if (window.internals) {
internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
await UIHelper.renderingUpdate();
internals.startTrackingCompositingUpdates();
}
}

function updateLayoutAndCompositingCount()
async function updateLayoutAndCompositingCount()
{
if (window.internals) {
internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
await UIHelper.renderingUpdate();
updateCount = internals.compositingUpdateCount();
}
}

function testForCompositingUpdate(callback)
async function testForCompositingUpdate(callback)
{
zeroUpdateCount();
await zeroUpdateCount();
callback();
updateLayoutAndCompositingCount();
await updateLayoutAndCompositingCount();
}

function runTest()
async function runTest()
{
updateLayoutAndCompositingCount();
await updateLayoutAndCompositingCount();

if (window.internals) {
internals.startTrackingCompositingUpdates();
Expand All @@ -62,27 +63,27 @@

shouldBe('updateCount', '0');

testForCompositingUpdate(function() {
await testForCompositingUpdate(function() {
document.getElementById('box').classList.add('colorchange');
});

shouldBe('updateCount', '1');

testForCompositingUpdate(function() {
await testForCompositingUpdate(function() {
document.getElementById('box').classList.add('dummy');
});

shouldBe('updateCount', '0');

testForCompositingUpdate(function() {
await testForCompositingUpdate(function() {
var div = document.createElement('div');
div.className = 'box';
document.body.appendChild(div);
});

shouldBe('updateCount', '1');

testForCompositingUpdate(function() {
await testForCompositingUpdate(function() {
var stylesheet = document.createElement('style');
stylesheet.type = 'text/css';
stylesheet.rel = 'stylesheet';
Expand Down
3 changes: 3 additions & 0 deletions LayoutTests/editing/editable-region/iframe-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
(contentsOpaque 1)
(drawsContent 1)
(backgroundColor #FFFFFF)
(event region
(rect (0,0) width=800 height=4112)
)
(children 1
(GraphicsLayer
(position 8.00 8.00)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<script>
if (window.testRunner)
testRunner.dumpAsText();

/* This test passes if it doesn't crash */
onload = async () => {
document.createElement('audio').src = 'data:';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
async function pageShowed()
{
if (++showCount == 2) {
await UIHelper.renderingUpdate();
await testScrollability();
testRunner.notifyDone();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
return;
}

await UIHelper.renderingUpdate();

const scroller = document.querySelector('.scroller');
const scrollerBounds = scroller.getBoundingClientRect();
const x = scrollerBounds.left + 90;
Expand All @@ -62,15 +64,15 @@
return expanded;
});

// Flush out scroll events from gesture
// Flush out scroll events from gesture
await UIHelper.renderingUpdate();

scroller.addEventListener("scroll", async () => {
testPassed('Scrolled by dragging the scrollbar');
finishJSTest();
});

// Now try and click and drag the scrollbar
// Now try and click and drag the scrollbar
debug('Attempting to drag the scrollbar');
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
finishJSTest();
return;
}

await UIHelper.renderingUpdate();

const scroller = document.querySelector('.scroller');
const scrollerBounds = scroller.getBoundingClientRect();
Expand Down
4 changes: 3 additions & 1 deletion LayoutTests/inspector/layers/layerTreeDidChange.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
document.body.offsetWidth;

requestAnimationFrame(() => {
TestPage.dispatchEventToFrontend("TestPageDidAppendChild");
setTimeout(() => {
TestPage.dispatchEventToFrontend("TestPageDidAppendChild");
}, 0);
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
(anchor 0.00 0.00)
(bounds 200.00 1200.00)
(drawsContent 1)
(repaint rects
(rect 0.00 0.00 200.00 200.00)
)
)
)
)
Expand Down
2 changes: 2 additions & 0 deletions LayoutTests/platform/mac-wk1/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -2715,3 +2715,5 @@ imported/w3c/web-platform-tests/css/css-backgrounds/background-size/background-s

# webkit.org/b/263870 [scroll-animations] lots of scroll-animations WPT tests are timing out
imported/w3c/web-platform-tests/scroll-animations/scroll-timelines/scroll-timeline-snapshotting.html [ Skip ]

fast/css/transform-function-perspective-crash.html [ Failure ]
3 changes: 3 additions & 0 deletions LayoutTests/platform/wpe/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -1718,3 +1718,6 @@ webkit.org/b/264680 media/track/video-track-configuration-mp4-default-colorspace
webkit.org/b/264680 security/contentSecurityPolicy/video-with-data-url-allowed-by-media-src-star.html [ ImageOnlyFailure Pass ]
webkit.org/b/264680 svg/css/svg-resource-fragment-identifier-img-src.html [ ImageOnlyFailure Pass ]
webkit.org/b/264680 tables/mozilla_expected_failures/bugs/bug2479-5.html [ Failure Missing Pass ]

fast/history/page-cache-execute-script-during-restore.html [ Timeout ]
webanimations/animation-page-cache.html [ Timeout ]
Original file line number Diff line number Diff line change
@@ -1 +1 @@
marker rects: (24.671875, 93, 46, 18)
marker rects: (58, 93, 12.6719, 18)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html>
<head>
<title>Tests clipped layer in overflow in clipped in overflow</title>
<script src="../../resources/ui-helper.js"></script>
<style>
#scroller {
height: 300px;
Expand Down Expand Up @@ -54,14 +55,20 @@
}
</style>
<script>
if (window.testRunner)
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}

window.addEventListener('load', async () => {
await UIHelper.renderingUpdate();

window.addEventListener('load', () => {
scroller.scrollTo(0, 50);
scroller2.scrollTo(0, 150);
if (window.internals)
document.getElementById('scrollingTree').innerText = window.internals.scrollingStateTreeAsText() + "\n";
if (window.testRunner)
testRunner.notifyDone();
}, false);
</script>
</head>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html>
<head>
<title>Tests the bounds of the clipping layer for nested clips in non-stacking context overflow</title>
<script src="../../resources/ui-helper.js"></script>
<style>
#scroller {
overflow-y: scroll;
Expand Down Expand Up @@ -50,13 +51,19 @@
}
</style>
<script>
if (window.testRunner)
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}

window.addEventListener('load', async () => {
await UIHelper.renderingUpdate();

window.addEventListener('load', () => {
scroller.scrollTo(0, 50);
if (window.internals)
document.getElementById('scrollingTree').innerText = window.internals.scrollingStateTreeAsText() + "\n";
if (window.testRunner)
testRunner.notifyDone();
}, false);
</script>
</head>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
<html>
<head>
<script src="../../resources/ui-helper.js"></script>
<style>
body {
height: 5000px;
Expand Down Expand Up @@ -56,6 +57,8 @@
}

window.addEventListener('load', async () => {
await UIHelper.renderingUpdate();

const scroller = document.getElementsByClassName('scroller')[0];
scroller.scrollTo(0, 50);
await UIHelper.renderingUpdate();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
<html>
<head>
<script src="../../resources/ui-helper.js"></script>
<style>
body {
height: 5000px;
Expand Down Expand Up @@ -52,6 +53,8 @@
}

window.addEventListener('load', async () => {
await UIHelper.renderingUpdate();

const scroller = document.getElementsByClassName('scroller')[0];
scroller.scrollTo(0, 50);
await UIHelper.renderingUpdate();
Expand Down
Loading

0 comments on commit b6b7455

Please sign in to comment.