mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
layout: Store scroll offsets in the ScrollTree
(#37428)
There are currently five places that scroll offsets are stored: - DOM: A set of scroll offsets used for script. - Layout: An array of scroll offsets that is used for tracking layout-side scroll offsets. - Layout: The scroll offsets stored in the `ScrollTree`. These are currently unset and unused. - Compositor: The scroll offsets stored in the `ScrollTree` mirrored from layout. - WebRender: The scrolled offsets stored in the WebRender spatial tree. This change is the first step in combining the first three into the layout `ScrollTree`. It eliminates the extra array of scroll offsets stored in layout in favor of the storing them in the `ScrollTree`. A followup change will eliminate the ones stored in the DOM. - In addition the `ScrollState` data structure is eliminated as these are now stored in a `HashMap` everywhere when passing them via IPC. - The offsests stored in layout can now never scroll past the boundaries of the scrolled content. Testing: This should not change behavior and is thus covered by existing WPT tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: stevennovaryo <steven.novaryo@gmail.com>
This commit is contained in:
parent
6cac782fb1
commit
f451dccd0b
11 changed files with 182 additions and 122 deletions
|
@ -30,7 +30,6 @@ use embedder_traits::{
|
|||
TouchEventType, UntrustedNodeAddress, ViewportDetails, WheelDelta, WheelEvent, WheelMode,
|
||||
};
|
||||
use euclid::{Point2D, Rect, Scale, Size2D, Transform3D, Vector2D};
|
||||
use fnv::FnvHashMap;
|
||||
use ipc_channel::ipc::{self, IpcSharedMemory};
|
||||
use libc::c_void;
|
||||
use log::{debug, info, trace, warn};
|
||||
|
@ -48,10 +47,10 @@ use webrender_api::units::{
|
|||
};
|
||||
use webrender_api::{
|
||||
self, BuiltDisplayList, DirtyRect, DisplayListPayload, DocumentId, Epoch as WebRenderEpoch,
|
||||
ExternalScrollId, FontInstanceFlags, FontInstanceKey, FontInstanceOptions, FontKey,
|
||||
HitTestFlags, PipelineId as WebRenderPipelineId, PropertyBinding, ReferenceFrameKind,
|
||||
RenderReasons, SampledScrollOffset, ScrollLocation, SpaceAndClipInfo, SpatialId,
|
||||
SpatialTreeItemKey, TransformStyle,
|
||||
FontInstanceFlags, FontInstanceKey, FontInstanceOptions, FontKey, HitTestFlags,
|
||||
PipelineId as WebRenderPipelineId, PropertyBinding, ReferenceFrameKind, RenderReasons,
|
||||
SampledScrollOffset, ScrollLocation, SpaceAndClipInfo, SpatialId, SpatialTreeItemKey,
|
||||
TransformStyle,
|
||||
};
|
||||
|
||||
use crate::InitialCompositorState;
|
||||
|
@ -260,26 +259,9 @@ impl PipelineDetails {
|
|||
}
|
||||
|
||||
fn install_new_scroll_tree(&mut self, new_scroll_tree: ScrollTree) {
|
||||
let old_scroll_offsets: FnvHashMap<ExternalScrollId, LayoutVector2D> = self
|
||||
.scroll_tree
|
||||
.nodes
|
||||
.drain(..)
|
||||
.filter_map(|node| match (node.external_id(), node.offset()) {
|
||||
(Some(external_id), Some(offset)) => Some((external_id, offset)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let old_scroll_offsets = self.scroll_tree.scroll_offsets();
|
||||
self.scroll_tree = new_scroll_tree;
|
||||
for node in self.scroll_tree.nodes.iter_mut() {
|
||||
match node.external_id() {
|
||||
Some(external_id) => match old_scroll_offsets.get(&external_id) {
|
||||
Some(new_offset) => node.set_offset(*new_offset),
|
||||
None => continue,
|
||||
},
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
self.scroll_tree.set_all_scroll_offsets(&old_scroll_offsets);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -728,7 +710,7 @@ impl IOCompositor {
|
|||
self.global.borrow_mut().send_transaction(txn);
|
||||
},
|
||||
|
||||
CompositorMsg::SendScrollNode(webview_id, pipeline_id, point, external_scroll_id) => {
|
||||
CompositorMsg::SendScrollNode(webview_id, pipeline_id, offset, external_scroll_id) => {
|
||||
let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
|
||||
return;
|
||||
};
|
||||
|
@ -739,15 +721,17 @@ impl IOCompositor {
|
|||
return;
|
||||
};
|
||||
|
||||
let offset = LayoutVector2D::new(point.x, point.y);
|
||||
let Some(offset) = pipeline_details
|
||||
.scroll_tree
|
||||
.set_scroll_offsets_for_node_with_external_scroll_id(
|
||||
.set_scroll_offset_for_node_with_external_scroll_id(
|
||||
external_scroll_id,
|
||||
-offset,
|
||||
offset,
|
||||
ScrollType::Script,
|
||||
)
|
||||
else {
|
||||
// The renderer should be fully up-to-date with script at this point and script
|
||||
// should never try to scroll to an invalid location.
|
||||
warn!("Could not scroll node with id: {external_scroll_id:?}");
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue