mirror of
https://github.com/servo/servo.git
synced 2025-08-08 06:55:31 +01:00
compositing: Send entire scene's scroll offsets when sending WebRender display lists (#31892)
WebRender does not preserve spatial tree offsets when updating the spatial tree. Updating the spatial tree of a pipeline can also update the spatial tree of child pipelines. This change ensures that WebRender always gets the scroll offsets of the entire scene when modifying display lists in a way that may rebuild the spatial tree. Fixes #31807.
This commit is contained in:
parent
cc082efbfd
commit
8aaff61334
5 changed files with 130 additions and 13 deletions
|
@ -764,19 +764,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
||||||
let mut transaction = Transaction::new();
|
let mut transaction = Transaction::new();
|
||||||
transaction
|
transaction
|
||||||
.set_display_list(display_list_info.epoch, (pipeline_id, built_display_list));
|
.set_display_list(display_list_info.epoch, (pipeline_id, built_display_list));
|
||||||
|
self.update_transaction_with_all_scroll_offsets(&mut transaction);
|
||||||
for node in details.scroll_tree.nodes.iter() {
|
|
||||||
if let (Some(offset), Some(external_id)) = (node.offset(), node.external_id()) {
|
|
||||||
let offset = LayoutVector2D::new(-offset.x, -offset.y);
|
|
||||||
transaction.set_scroll_offsets(
|
|
||||||
external_id,
|
|
||||||
vec![SampledScrollOffset {
|
|
||||||
offset,
|
|
||||||
generation: 0,
|
|
||||||
}],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.generate_frame(&mut transaction, RenderReasons::SCENE);
|
self.generate_frame(&mut transaction, RenderReasons::SCENE);
|
||||||
self.webrender_api
|
self.webrender_api
|
||||||
.send_transaction(self.webrender_document, transaction);
|
.send_transaction(self.webrender_document, transaction);
|
||||||
|
@ -1091,6 +1079,34 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
||||||
// be an issue. WebRender will still update the scene and generate a new
|
// be an issue. WebRender will still update the scene and generate a new
|
||||||
// frame even though the epoch hasn't changed.
|
// frame even though the epoch hasn't changed.
|
||||||
transaction.set_display_list(WebRenderEpoch(0), built_display_list);
|
transaction.set_display_list(WebRenderEpoch(0), built_display_list);
|
||||||
|
self.update_transaction_with_all_scroll_offsets(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the given transaction with the scroll offsets of all active scroll nodes in
|
||||||
|
/// the WebRender scene. This is necessary because WebRender does not preserve scroll
|
||||||
|
/// offsets between scroll tree modifications. If a display list could potentially
|
||||||
|
/// modify a scroll tree branch, WebRender needs to have scroll offsets for that
|
||||||
|
/// branch.
|
||||||
|
///
|
||||||
|
/// TODO(mrobinson): Could we only send offsets for the branch being modified
|
||||||
|
/// and not the entire scene?
|
||||||
|
fn update_transaction_with_all_scroll_offsets(&self, transaction: &mut Transaction) {
|
||||||
|
for details in self.pipeline_details.values() {
|
||||||
|
for node in details.scroll_tree.nodes.iter() {
|
||||||
|
let (Some(offset), Some(external_id)) = (node.offset(), node.external_id()) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let offset = LayoutVector2D::new(-offset.x, -offset.y);
|
||||||
|
transaction.set_scroll_offsets(
|
||||||
|
external_id,
|
||||||
|
vec![SampledScrollOffset {
|
||||||
|
offset,
|
||||||
|
generation: 0,
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_frame_tree(&mut self, frame_tree: &SendableFrameTree) {
|
fn set_frame_tree(&mut self, frame_tree: &SendableFrameTree) {
|
||||||
|
|
|
@ -261166,6 +261166,19 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"transform-iframe-scroll-position.html": [
|
||||||
|
"efb7bab532606cd9893a4cb4223dbf4b7baa6f1d",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/css-transforms/transform-iframe-scroll-position-ref.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"transform-image-001.html": [
|
"transform-image-001.html": [
|
||||||
"0565b8dbeeb86b82993847a139c8f38b66c0b163",
|
"0565b8dbeeb86b82993847a139c8f38b66c0b163",
|
||||||
[
|
[
|
||||||
|
@ -416071,6 +416084,10 @@
|
||||||
"84f079c90bcb590e81ba39753edf723bcb123858",
|
"84f079c90bcb590e81ba39753edf723bcb123858",
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
|
"transform-iframe-scroll-position-contents.html": [
|
||||||
|
"8efcdafc83cde63f89d56ea437a4852dd82cc206",
|
||||||
|
[]
|
||||||
|
],
|
||||||
"transform-lime-square.png": [
|
"transform-lime-square.png": [
|
||||||
"8f939993332e1101b921615723ec6067f3bb90a3",
|
"8f939993332e1101b921615723ec6067f3bb90a3",
|
||||||
[]
|
[]
|
||||||
|
@ -416208,6 +416225,10 @@
|
||||||
"b674c88d82f8a806a8a1cd20040302766d825202",
|
"b674c88d82f8a806a8a1cd20040302766d825202",
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
|
"transform-iframe-scroll-position-ref.html": [
|
||||||
|
"e4d5da75d7a762b6c346640b2c72339a52d350ab",
|
||||||
|
[]
|
||||||
|
],
|
||||||
"transform-image-ref.html": [
|
"transform-image-ref.html": [
|
||||||
"301c0f94bb7806caad2444583f3642d49aa4c969",
|
"301c0f94bb7806caad2444583f3642d49aa4c969",
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CSS Test (Transforms): iframe scroll position</title>
|
||||||
|
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
|
||||||
|
<style>
|
||||||
|
html { background: red; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- Make a large red page with a small green and blue square that is scrolled to immediately. -->
|
||||||
|
<div style="position: absolute; width: 50px; height: 25px; top: 3000px; left: 3000px; background: green;"></div>
|
||||||
|
<div style="position: absolute; width: 50px; height: 25px; top: 3025px; left: 3000px; background: blue;"></div>
|
||||||
|
<div style="width: 10000px; height: 10000px;"></div>
|
||||||
|
<script>
|
||||||
|
window.scrollTo(3000, 3000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CSS Test (Transforms): iframe scroll position</title>
|
||||||
|
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
|
||||||
|
<style>
|
||||||
|
#iframe {
|
||||||
|
border: 0;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border: solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#iframe div {
|
||||||
|
width: 25px;
|
||||||
|
height: 50px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body onload="onLoad();">
|
||||||
|
<div id="iframe">
|
||||||
|
<div style="background: blue;"></div>
|
||||||
|
<div style="background: green;"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CSS Test (Transforms): iframe scroll position</title>
|
||||||
|
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
|
||||||
|
<link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-rendering">
|
||||||
|
<meta name="assert" content="This test ensures that when an iframe element is transformed, the scroll position of the iframe content is preserved.">
|
||||||
|
<link rel="match" href="transform-iframe-scroll-position-ref.html">
|
||||||
|
<style>
|
||||||
|
iframe {
|
||||||
|
border: 0;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border: solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body onload="onLoad();">
|
||||||
|
<iframe id="iframe" src="support/transform-iframe-scroll-position-contents.html"></iframe>
|
||||||
|
<script>
|
||||||
|
function onLoad() {
|
||||||
|
iframe.classList.toggle("rotate");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue