diff --git a/components/compositing/webview.rs b/components/compositing/webview.rs index b6f81258205..e912a9a8a7f 100644 --- a/components/compositing/webview.rs +++ b/components/compositing/webview.rs @@ -16,13 +16,13 @@ use embedder_traits::{ use euclid::{Point2D, Scale, Vector2D}; use fnv::FnvHashSet; use log::{debug, warn}; -use script_traits::{AnimationState, ScriptThreadMessage, ScrollState, TouchEventResult}; +use script_traits::{AnimationState, ScriptThreadMessage, TouchEventResult}; use webrender::Transaction; use webrender_api::units::{DeviceIntPoint, DevicePoint, DeviceRect, LayoutVector2D}; use webrender_api::{ ExternalScrollId, HitTestFlags, RenderReasons, SampledScrollOffset, ScrollLocation, }; -use webrender_traits::CompositorHitTestResult; +use webrender_traits::{CompositorHitTestResult, ScrollState}; use crate::IOCompositor; use crate::compositor::{PipelineDetails, ServoRenderer}; diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index f5b40322c40..6734eb6f46f 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -160,7 +160,7 @@ use webgpu::{self, WebGPU, WebGPURequest, WebGPUResponse}; use webrender::RenderApi; use webrender::RenderApiSender; use webrender_api::{DocumentId, ImageKey}; -use webrender_traits::{CompositorHitTestResult, WebrenderExternalImageRegistry}; +use webrender_traits::{CompositorHitTestResult, ScrollState, WebrenderExternalImageRegistry}; use crate::browsingcontext::{ AllBrowsingContextsIterator, BrowsingContext, FullyActiveBrowsingContextsIterator, @@ -1406,6 +1406,9 @@ where FromCompositorMsg::SetWebViewThrottled(webview_id, throttled) => { self.set_webview_throttled(webview_id, throttled); }, + FromCompositorMsg::SetScrollStates(pipeline_id, scroll_states) => { + self.handle_set_scroll_states(pipeline_id, scroll_states) + }, } } @@ -5562,4 +5565,24 @@ where error!("Got a media session action but no active media session is registered"); } } + + #[cfg_attr( + feature = "tracing", + tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace") + )] + fn handle_set_scroll_states(&self, pipeline_id: PipelineId, scroll_states: Vec) { + let Some(pipeline) = self.pipelines.get(&pipeline_id) else { + warn!("Discarding scroll offset update for unknown pipeline"); + return; + }; + if let Err(error) = pipeline + .event_loop + .send(ScriptThreadMessage::SetScrollStates( + pipeline_id, + scroll_states, + )) + { + warn!("Could not send scroll offsets to pipeline: {pipeline_id:?}: {error:?}"); + } + } } diff --git a/components/constellation/tracing.rs b/components/constellation/tracing.rs index 1ca8df5db44..38dda83538f 100644 --- a/components/constellation/tracing.rs +++ b/components/constellation/tracing.rs @@ -86,6 +86,7 @@ mod from_compositor { Self::ExitFullScreen(_) => target!("ExitFullScreen"), Self::MediaSessionAction(_) => target!("MediaSessionAction"), Self::SetWebViewThrottled(_, _) => target!("SetWebViewThrottled"), + Self::SetScrollStates(..) => target!("SetScrollStates"), } } } diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index 696145598db..a0e7de3081f 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -51,8 +51,8 @@ use script_layout_interface::{ ReflowRequest, ReflowResult, TrustedNodeAddress, }; use script_traits::{ - DrawAPaintImageResult, PaintWorkletError, Painter, ScriptThreadMessage, ScrollState, - UntrustedNodeAddress, WindowSizeData, + DrawAPaintImageResult, PaintWorkletError, Painter, ScriptThreadMessage, UntrustedNodeAddress, + WindowSizeData, }; use servo_arc::Arc as ServoArc; use servo_config::opts::{self, DebugOptions}; @@ -90,7 +90,7 @@ use stylo_atoms::Atom; use url::Url; use webrender_api::units::{DevicePixel, LayoutPixel}; use webrender_api::{ExternalScrollId, HitTestFlags, units}; -use webrender_traits::CrossProcessCompositorApi; +use webrender_traits::{CrossProcessCompositorApi, ScrollState}; // This mutex is necessary due to syncronisation issues between two different types of thread-local storage // which manifest themselves when the layout thread tries to layout iframes in parallel with the main page @@ -456,7 +456,7 @@ impl Layout for LayoutThread { ) { } - fn set_scroll_states(&mut self, scroll_states: &[ScrollState]) { + fn set_scroll_offsets(&mut self, scroll_states: &[ScrollState]) { *self.scroll_offsets.borrow_mut() = scroll_states .iter() .map(|scroll_state| (scroll_state.scroll_id, scroll_state.scroll_offset)) diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index aac4c7d3a73..8f39a0bfe9b 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -61,8 +61,7 @@ use script_layout_interface::{ }; use script_traits::{ DocumentState, LoadData, LoadOrigin, NavigationHistoryBehavior, ScriptMsg, ScriptThreadMessage, - ScriptToConstellationChan, ScrollState, StructuredSerializedData, WindowSizeData, - WindowSizeType, + ScriptToConstellationChan, StructuredSerializedData, WindowSizeData, WindowSizeType, }; use selectors::attr::CaseSensitivity; use servo_arc::Arc as ServoArc; @@ -84,7 +83,7 @@ use stylo_atoms::Atom; use url::Position; use webrender_api::units::{DevicePixel, LayoutPixel}; use webrender_api::{DocumentId, ExternalScrollId}; -use webrender_traits::CrossProcessCompositorApi; +use webrender_traits::{CrossProcessCompositorApi, ScrollState}; use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions; use super::bindings::trace::HashMapTracedValues; diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 94f2cb48ddb..539e9228e36 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -81,7 +81,7 @@ use script_traits::{ ConstellationInputEvent, DiscardBrowsingContext, DocumentActivity, InitialScriptState, JsEvalResult, LoadData, LoadOrigin, NavigationHistoryBehavior, NewLayoutInfo, Painter, ProgressiveWebMetricType, ScriptMsg, ScriptThreadMessage, ScriptToConstellationChan, - ScrollState, StructuredSerializedData, UpdatePipelineIdReason, WindowSizeData, WindowSizeType, + StructuredSerializedData, UpdatePipelineIdReason, WindowSizeData, WindowSizeType, }; use servo_config::opts; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; @@ -93,7 +93,7 @@ use url::Position; #[cfg(feature = "webgpu")] use webgpu::{WebGPUDevice, WebGPUMsg}; use webrender_api::DocumentId; -use webrender_traits::{CompositorHitTestResult, CrossProcessCompositorApi}; +use webrender_traits::{CompositorHitTestResult, CrossProcessCompositorApi, ScrollState}; use crate::document_collection::DocumentCollection; use crate::document_loader::DocumentLoader; @@ -1870,7 +1870,7 @@ impl ScriptThread { panic!("should have handled {:?} already", msg) }, ScriptThreadMessage::SetScrollStates(pipeline_id, scroll_states) => { - self.handle_set_scroll_states_msg(pipeline_id, scroll_states) + self.handle_set_scroll_states_offsets(pipeline_id, scroll_states) }, ScriptThreadMessage::SetEpochPaintTime(pipeline_id, epoch, time) => { self.handle_set_epoch_paint_time(pipeline_id, epoch, time) @@ -1878,7 +1878,7 @@ impl ScriptThread { } } - fn handle_set_scroll_states_msg( + fn handle_set_scroll_states_offsets( &self, pipeline_id: PipelineId, scroll_states: Vec, @@ -1892,7 +1892,7 @@ impl ScriptThread { ScriptThreadEventCategory::SetScrollState, Some(pipeline_id), || { - window.layout_mut().set_scroll_states(&scroll_states); + window.layout_mut().set_scroll_offsets(&scroll_states); let mut scroll_offsets = HashMap::new(); for scroll_state in scroll_states.into_iter() { diff --git a/components/shared/compositing/constellation_msg.rs b/components/shared/compositing/constellation_msg.rs index 30ac38e3137..fd96abcc373 100644 --- a/components/shared/compositing/constellation_msg.rs +++ b/components/shared/compositing/constellation_msg.rs @@ -15,7 +15,7 @@ use ipc_channel::ipc::IpcSender; use script_traits::{AnimationTickType, LogEntry, WindowSizeData, WindowSizeType}; use servo_url::ServoUrl; use strum_macros::IntoStaticStr; -use webrender_traits::CompositorHitTestResult; +use webrender_traits::{CompositorHitTestResult, ScrollState}; /// Messages to the constellation. #[derive(IntoStaticStr)] @@ -69,6 +69,9 @@ pub enum ConstellationMsg { MediaSessionAction(MediaSessionActionType), /// Set whether to use less resources, by stopping animations and running timers at a heavily limited rate. SetWebViewThrottled(WebViewId, bool), + /// The Servo renderer scrolled and is updating the scroll states of the nodes in the + /// given pipeline via the constellation. + SetScrollStates(PipelineId, Vec), } impl fmt::Debug for ConstellationMsg { diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs index 9df9624ebee..dc6df22665c 100644 --- a/components/shared/script/lib.rs +++ b/components/shared/script/lib.rs @@ -33,7 +33,7 @@ use crossbeam_channel::{RecvTimeoutError, Sender}; use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId}; use embedder_traits::input_events::InputEvent; use embedder_traits::{MediaSessionActionType, Theme, WebDriverScriptCommand}; -use euclid::{Rect, Scale, Size2D, UnknownUnit, Vector2D}; +use euclid::{Rect, Scale, Size2D, UnknownUnit}; use http::{HeaderMap, Method}; use ipc_channel::Error as IpcError; use ipc_channel::ipc::{IpcReceiver, IpcSender}; @@ -56,10 +56,10 @@ use style_traits::{CSSPixel, SpeculativePainter}; use stylo_atoms::Atom; #[cfg(feature = "webgpu")] use webgpu::WebGPUMsg; -use webrender_api::units::{DevicePixel, LayoutPixel}; -use webrender_api::{DocumentId, ExternalScrollId, ImageKey}; +use webrender_api::units::DevicePixel; +use webrender_api::{DocumentId, ImageKey}; use webrender_traits::{ - CompositorHitTestResult, CrossProcessCompositorApi, + CompositorHitTestResult, CrossProcessCompositorApi, ScrollState, UntrustedNodeAddress as WebRenderUntrustedNodeAddress, }; @@ -593,15 +593,6 @@ bitflags! { } } -/// The scroll state of a stacking context. -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] -pub struct ScrollState { - /// The ID of the scroll root. - pub scroll_id: ExternalScrollId, - /// The scrolling offset of this stacking context. - pub scroll_offset: Vector2D, -} - /// Data about the window size. #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] pub struct WindowSizeData { diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index caceb776829..24b465d1f0e 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -33,7 +33,7 @@ use net_traits::image_cache::{ImageCache, PendingImageId}; use profile_traits::mem::Report; use profile_traits::time; use script_traits::{ - InitialScriptState, LoadData, Painter, ScriptThreadMessage, ScrollState, UntrustedNodeAddress, + InitialScriptState, LoadData, Painter, ScriptThreadMessage, UntrustedNodeAddress, WindowSizeData, }; use serde::{Deserialize, Serialize}; @@ -53,7 +53,7 @@ use style::selector_parser::{PseudoElement, RestyleDamage, Snapshot}; use style::stylesheets::Stylesheet; use style_traits::CSSPixel; use webrender_api::ImageKey; -use webrender_traits::CrossProcessCompositorApi; +use webrender_traits::{CrossProcessCompositorApi, ScrollState}; pub type GenericLayoutData = dyn Any + Send + Sync; @@ -243,7 +243,7 @@ pub trait Layout { ); /// Set the scroll states of this layout after a compositor scroll. - fn set_scroll_states(&mut self, scroll_states: &[ScrollState]); + fn set_scroll_offsets(&mut self, scroll_states: &[ScrollState]); /// Set the paint time for a specific epoch. fn set_epoch_paint_time(&mut self, epoch: Epoch, paint_time: CrossProcessInstant); diff --git a/components/shared/webrender/lib.rs b/components/shared/webrender/lib.rs index 8d3045e8f67..df1bfb6fcd7 100644 --- a/components/shared/webrender/lib.rs +++ b/components/shared/webrender/lib.rs @@ -14,13 +14,14 @@ use std::sync::{Arc, Mutex}; use base::id::{PipelineId, WebViewId}; use display_list::{CompositorDisplayListInfo, ScrollTreeNodeId}; use embedder_traits::Cursor; +use euclid::Vector2D; use euclid::default::Size2D as UntypedSize2D; use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory}; use libc::c_void; use log::warn; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize}; -use webrender_api::units::{DevicePoint, LayoutPoint, TexelRect}; +use webrender_api::units::{DevicePoint, LayoutPixel, LayoutPoint, TexelRect}; use webrender_api::{ BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData, ExternalImageHandler, ExternalImageId, ExternalImageSource, ExternalScrollId, @@ -530,3 +531,12 @@ pub struct CompositorHitTestResult { /// The scroll tree node associated with this hit test item. pub scroll_tree_node: ScrollTreeNodeId, } + +/// The scroll state of a stacking context. +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] +pub struct ScrollState { + /// The ID of the scroll root. + pub scroll_id: ExternalScrollId, + /// The scrolling offset of this stacking context. + pub scroll_offset: Vector2D, +}