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:
Martin Robinson 2025-06-13 14:01:27 +02:00 committed by GitHub
parent 6cac782fb1
commit f451dccd0b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 182 additions and 122 deletions

View file

@ -11,6 +11,7 @@
pub mod wrapper_traits;
use std::any::Any;
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::atomic::{AtomicIsize, AtomicU64, Ordering};
@ -19,7 +20,7 @@ use atomic_refcell::AtomicRefCell;
use base::Epoch;
use base::id::{BrowsingContextId, PipelineId, WebViewId};
use compositing_traits::CrossProcessCompositorApi;
use constellation_traits::{LoadData, ScrollState};
use constellation_traits::LoadData;
use embedder_traits::{Theme, UntrustedNodeAddress, ViewportDetails};
use euclid::default::{Point2D, Rect};
use fnv::FnvHashMap;
@ -48,8 +49,8 @@ use style::properties::PropertyId;
use style::properties::style_structs::Font;
use style::selector_parser::{PseudoElement, RestyleDamage, Snapshot};
use style::stylesheets::Stylesheet;
use webrender_api::ImageKey;
use webrender_api::units::DeviceIntSize;
use webrender_api::units::{DeviceIntSize, LayoutVector2D};
use webrender_api::{ExternalScrollId, ImageKey};
pub trait GenericLayoutDataTrait: Any + MallocSizeOfTrait {
fn as_any(&self) -> &dyn Any;
@ -245,7 +246,10 @@ pub trait Layout {
);
/// Set the scroll states of this layout after a compositor scroll.
fn set_scroll_offsets(&mut self, scroll_states: &[ScrollState]);
fn set_scroll_offsets_from_renderer(
&mut self,
scroll_states: &HashMap<ExternalScrollId, LayoutVector2D>,
);
fn query_content_box(&self, node: TrustedNodeAddress) -> Option<Rect<Au>>;
fn query_content_boxes(&self, node: TrustedNodeAddress) -> Vec<Rect<Au>>;
@ -333,7 +337,7 @@ pub enum ReflowGoal {
/// Tells layout about a single new scrolling offset from the script. The rest will
/// remain untouched and layout won't forward this back to script.
UpdateScrollNode(ScrollState),
UpdateScrollNode(ExternalScrollId, LayoutVector2D),
}
impl ReflowGoal {
@ -341,7 +345,7 @@ impl ReflowGoal {
/// be present or false if it only needs stacking-relative positions.
pub fn needs_display_list(&self) -> bool {
match *self {
ReflowGoal::UpdateTheRendering | ReflowGoal::UpdateScrollNode(_) => true,
ReflowGoal::UpdateTheRendering | ReflowGoal::UpdateScrollNode(..) => true,
ReflowGoal::LayoutQuery(ref querymsg) => match *querymsg {
QueryMsg::ElementInnerOuterTextQuery |
QueryMsg::InnerWindowDimensionsQuery |
@ -363,7 +367,7 @@ impl ReflowGoal {
/// false if a layout_thread display list is sufficient.
pub fn needs_display(&self) -> bool {
match *self {
ReflowGoal::UpdateTheRendering | ReflowGoal::UpdateScrollNode(_) => true,
ReflowGoal::UpdateTheRendering | ReflowGoal::UpdateScrollNode(..) => true,
ReflowGoal::LayoutQuery(ref querymsg) => match *querymsg {
QueryMsg::NodesFromPointQuery |
QueryMsg::TextIndexQuery |