diff options
Diffstat (limited to 'components/shared')
28 files changed, 417 insertions, 394 deletions
diff --git a/components/shared/background_hang_monitor/Cargo.toml b/components/shared/background_hang_monitor/Cargo.toml new file mode 100644 index 00000000000..c8d0685a377 --- /dev/null +++ b/components/shared/background_hang_monitor/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "background_hang_monitor_api" +version = "0.0.1" +authors = ["The Servo Project Developers"] +license = "MPL-2.0" +edition = "2018" +publish = false + +[lib] +name = "background_hang_monitor_api" +path = "lib.rs" +test = false +doctest = false + +[dependencies] +base = { workspace = true } +ipc-channel = { workspace = true } +lazy_static = { workspace = true } +malloc_size_of = { workspace = true } +malloc_size_of_derive = { workspace = true } +parking_lot = { workspace = true } +serde = { workspace = true } +size_of_test = { workspace = true } +webrender_api = { workspace = true } diff --git a/components/shared/background_hang_monitor/lib.rs b/components/shared/background_hang_monitor/lib.rs new file mode 100644 index 00000000000..8fbec70f041 --- /dev/null +++ b/components/shared/background_hang_monitor/lib.rs @@ -0,0 +1,212 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#![deny(unsafe_code)] + +//! An API interface to the BackgroundHangMonitor. + +use std::time::Duration; +use std::{fmt, mem}; + +use base::id::PipelineId; +use ipc_channel::ipc::IpcSender; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Copy, Debug, Deserialize, Serialize)] +/// The equivalent of script::script_runtime::ScriptEventCategory +pub enum ScriptHangAnnotation { + AttachLayout, + ConstellationMsg, + DevtoolsMsg, + DocumentEvent, + DomEvent, + FileRead, + FormPlannedNavigation, + ImageCacheMsg, + InputEvent, + HistoryEvent, + NetworkEvent, + Resize, + ScriptEvent, + SetScrollState, + SetViewport, + StylesheetLoad, + TimerEvent, + UpdateReplacedElement, + WebSocketEvent, + WorkerEvent, + WorkletEvent, + ServiceWorkerEvent, + EnterFullscreen, + ExitFullscreen, + WebVREvent, + PerformanceTimelineTask, + PortMessage, + WebGPUMsg, +} + +#[derive(Clone, Copy, Debug, Deserialize, Serialize)] +pub enum HangAnnotation { + Script(ScriptHangAnnotation), +} + +/// Hang-alerts are sent by the monitor to the constellation. +#[derive(Deserialize, Serialize)] +pub enum HangMonitorAlert { + /// A component hang has been detected. + Hang(HangAlert), + /// Report a completed sampled profile. + Profile(Vec<u8>), +} + +impl fmt::Debug for HangMonitorAlert { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self { + HangMonitorAlert::Hang(..) => write!(fmt, "Hang"), + HangMonitorAlert::Profile(..) => write!(fmt, "Profile"), + } + } +} + +/// Hang-alerts are sent by the monitor to the constellation. +#[derive(Deserialize, Serialize)] +pub enum HangAlert { + /// Report a transient hang. + Transient(MonitoredComponentId, HangAnnotation), + /// Report a permanent hang. + Permanent(MonitoredComponentId, HangAnnotation, Option<HangProfile>), +} + +impl fmt::Debug for HangAlert { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let (annotation, profile) = match self { + HangAlert::Transient(component_id, annotation) => { + write!( + fmt, + "\n The following component is experiencing a transient hang: \n {:?}", + component_id + )?; + (*annotation, None) + }, + HangAlert::Permanent(component_id, annotation, profile) => { + write!( + fmt, + "\n The following component is experiencing a permanent hang: \n {:?}", + component_id + )?; + (*annotation, profile.clone()) + }, + }; + + write!(fmt, "\n Annotation for the hang:\n{:?}", annotation)?; + if let Some(profile) = profile { + write!(fmt, "\n {:?}", profile)?; + } + + Ok(()) + } +} + +#[derive(Clone, Deserialize, Serialize)] +pub struct HangProfileSymbol { + pub name: Option<String>, + pub filename: Option<String>, + pub lineno: Option<u32>, +} + +#[derive(Clone, Deserialize, Serialize)] +/// Info related to the activity of an hanging component. +pub struct HangProfile { + pub backtrace: Vec<HangProfileSymbol>, +} + +impl fmt::Debug for HangProfile { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let hex_width = mem::size_of::<usize>() * 2 + 2; + + write!(fmt, "HangProfile backtrace:")?; + + if self.backtrace.is_empty() { + write!(fmt, "backtrace failed to resolve")?; + return Ok(()); + } + + for symbol in self.backtrace.iter() { + write!(fmt, "\n {:1$}", "", hex_width)?; + + if let Some(ref name) = symbol.name { + write!(fmt, " - {}", name)?; + } else { + write!(fmt, " - <unknown>")?; + } + + if let (Some(ref file), Some(ref line)) = (symbol.filename.as_ref(), symbol.lineno) { + write!(fmt, "\n {:3$}at {}:{}", "", file, line, hex_width)?; + } + } + + Ok(()) + } +} + +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub enum MonitoredComponentType { + Script, +} + +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct MonitoredComponentId(pub PipelineId, pub MonitoredComponentType); + +/// A handle to register components for hang monitoring, +/// and to receive a means to communicate with the underlying hang monitor worker. +pub trait BackgroundHangMonitorRegister: BackgroundHangMonitorClone + Send { + /// Register a component for hang monitoring: + /// to be called from within the thread to be monitored for hangs. + fn register_component( + &self, + component: MonitoredComponentId, + transient_hang_timeout: Duration, + permanent_hang_timeout: Duration, + exit_signal: Option<Box<dyn BackgroundHangMonitorExitSignal>>, + ) -> Box<dyn BackgroundHangMonitor>; +} + +impl Clone for Box<dyn BackgroundHangMonitorRegister> { + fn clone(&self) -> Box<dyn BackgroundHangMonitorRegister> { + self.clone_box() + } +} + +pub trait BackgroundHangMonitorClone { + fn clone_box(&self) -> Box<dyn BackgroundHangMonitorRegister>; +} + +/// Proxy methods to communicate with the background hang monitor +pub trait BackgroundHangMonitor { + /// Notify the start of handling an event. + fn notify_activity(&self, annotation: HangAnnotation); + /// Notify the start of waiting for a new event to come in. + fn notify_wait(&self); + /// Unregister the component from monitor. + fn unregister(&self); +} + +/// A means for the BHM to signal a monitored component to exit. +/// Useful when the component is hanging, and cannot be notified via the usual way. +/// The component should implement this in a way allowing for the signal to be received when hanging, +/// if at all. +pub trait BackgroundHangMonitorExitSignal: Send { + /// Called by the BHM, to notify the monitored component to exit. + fn signal_to_exit(&self); +} + +/// Messages to control the sampling profiler. +#[derive(Deserialize, Serialize)] +pub enum BackgroundHangMonitorControlMsg { + /// Enable the sampler, with a given sampling rate and max total sampling duration. + EnableSampler(Duration, Duration), + DisableSampler, + /// Exit, and propagate the signal to monitored components. + Exit(IpcSender<()>), +} diff --git a/components/shared/msg/Cargo.toml b/components/shared/base/Cargo.toml index 97abd671eef..10cb0939d8c 100644 --- a/components/shared/msg/Cargo.toml +++ b/components/shared/base/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "msg" +name = "base" version = "0.0.1" authors = ["The Servo Project Developers"] license = "MPL-2.0" @@ -7,7 +7,7 @@ edition = "2018" publish = false [lib] -name = "msg" +name = "base" path = "lib.rs" test = false doctest = false diff --git a/components/shared/msg/constellation_msg.rs b/components/shared/base/id.rs index 93c18790255..06f69547bb7 100644 --- a/components/shared/msg/constellation_msg.rs +++ b/components/shared/base/id.rs @@ -2,16 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -//! The high-level interface from script to constellation. Using this abstract interface helps -//! reduce coupling between these two components. +//! Namespaces and ids shared by many crates in Servo. #![allow(clippy::new_without_default)] use std::cell::Cell; +use std::fmt; use std::num::NonZeroU32; use std::sync::Arc; -use std::time::Duration; -use std::{fmt, mem}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use lazy_static::lazy_static; @@ -65,12 +63,6 @@ macro_rules! namespace_id { }; } -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -pub enum TraversalDirection { - Forward(usize), - Back(usize), -} - #[derive(Debug, Deserialize, Serialize)] /// Request a pipeline-namespace id from the constellation. pub struct PipelineNamespaceRequest(pub IpcSender<PipelineNamespaceId>); @@ -444,221 +436,3 @@ pub const TEST_BROWSING_CONTEXT_ID: BrowsingContextId = BrowsingContextId { namespace_id: TEST_NAMESPACE, index: TEST_BROWSING_CONTEXT_INDEX, }; - -// Used to specify the kind of input method editor appropriate to edit a field. -// This is a subset of htmlinputelement::InputType because some variants of InputType -// don't make sense in this context. -#[derive(Debug, Deserialize, Serialize)] -pub enum InputMethodType { - Color, - Date, - DatetimeLocal, - Email, - Month, - Number, - Password, - Search, - Tel, - Text, - Time, - Url, - Week, -} - -#[derive(Clone, Copy, Debug, Deserialize, Serialize)] -/// The equivalent of script::script_runtime::ScriptEventCategory -pub enum ScriptHangAnnotation { - AttachLayout, - ConstellationMsg, - DevtoolsMsg, - DocumentEvent, - DomEvent, - FileRead, - FormPlannedNavigation, - ImageCacheMsg, - InputEvent, - HistoryEvent, - NetworkEvent, - Resize, - ScriptEvent, - SetScrollState, - SetViewport, - StylesheetLoad, - TimerEvent, - UpdateReplacedElement, - WebSocketEvent, - WorkerEvent, - WorkletEvent, - ServiceWorkerEvent, - EnterFullscreen, - ExitFullscreen, - WebVREvent, - PerformanceTimelineTask, - PortMessage, - WebGPUMsg, -} - -#[derive(Clone, Copy, Debug, Deserialize, Serialize)] -pub enum HangAnnotation { - Script(ScriptHangAnnotation), -} - -/// Hang-alerts are sent by the monitor to the constellation. -#[derive(Deserialize, Serialize)] -pub enum HangMonitorAlert { - /// A component hang has been detected. - Hang(HangAlert), - /// Report a completed sampled profile. - Profile(Vec<u8>), -} - -impl fmt::Debug for HangMonitorAlert { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - HangMonitorAlert::Hang(..) => write!(fmt, "Hang"), - HangMonitorAlert::Profile(..) => write!(fmt, "Profile"), - } - } -} - -/// Hang-alerts are sent by the monitor to the constellation. -#[derive(Deserialize, Serialize)] -pub enum HangAlert { - /// Report a transient hang. - Transient(MonitoredComponentId, HangAnnotation), - /// Report a permanent hang. - Permanent(MonitoredComponentId, HangAnnotation, Option<HangProfile>), -} - -impl fmt::Debug for HangAlert { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let (annotation, profile) = match self { - HangAlert::Transient(component_id, annotation) => { - write!( - fmt, - "\n The following component is experiencing a transient hang: \n {:?}", - component_id - )?; - (*annotation, None) - }, - HangAlert::Permanent(component_id, annotation, profile) => { - write!( - fmt, - "\n The following component is experiencing a permanent hang: \n {:?}", - component_id - )?; - (*annotation, profile.clone()) - }, - }; - - write!(fmt, "\n Annotation for the hang:\n{:?}", annotation)?; - if let Some(profile) = profile { - write!(fmt, "\n {:?}", profile)?; - } - - Ok(()) - } -} - -#[derive(Clone, Deserialize, Serialize)] -pub struct HangProfileSymbol { - pub name: Option<String>, - pub filename: Option<String>, - pub lineno: Option<u32>, -} - -#[derive(Clone, Deserialize, Serialize)] -/// Info related to the activity of an hanging component. -pub struct HangProfile { - pub backtrace: Vec<HangProfileSymbol>, -} - -impl fmt::Debug for HangProfile { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let hex_width = mem::size_of::<usize>() * 2 + 2; - - write!(fmt, "HangProfile backtrace:")?; - - if self.backtrace.is_empty() { - write!(fmt, "backtrace failed to resolve")?; - return Ok(()); - } - - for symbol in self.backtrace.iter() { - write!(fmt, "\n {:1$}", "", hex_width)?; - - if let Some(ref name) = symbol.name { - write!(fmt, " - {}", name)?; - } else { - write!(fmt, " - <unknown>")?; - } - - if let (Some(ref file), Some(ref line)) = (symbol.filename.as_ref(), symbol.lineno) { - write!(fmt, "\n {:3$}at {}:{}", "", file, line, hex_width)?; - } - } - - Ok(()) - } -} - -#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -pub enum MonitoredComponentType { - Script, -} - -#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -pub struct MonitoredComponentId(pub PipelineId, pub MonitoredComponentType); - -/// A handle to register components for hang monitoring, -/// and to receive a means to communicate with the underlying hang monitor worker. -pub trait BackgroundHangMonitorRegister: BackgroundHangMonitorClone + Send { - /// Register a component for hang monitoring: - /// to be called from within the thread to be monitored for hangs. - fn register_component( - &self, - component: MonitoredComponentId, - transient_hang_timeout: Duration, - permanent_hang_timeout: Duration, - exit_signal: Option<Box<dyn BackgroundHangMonitorExitSignal>>, - ) -> Box<dyn BackgroundHangMonitor>; -} - -impl Clone for Box<dyn BackgroundHangMonitorRegister> { - fn clone(&self) -> Box<dyn BackgroundHangMonitorRegister> { - self.clone_box() - } -} - -pub trait BackgroundHangMonitorClone { - fn clone_box(&self) -> Box<dyn BackgroundHangMonitorRegister>; -} - -/// Proxy methods to communicate with the background hang monitor -pub trait BackgroundHangMonitor { - /// Notify the start of handling an event. - fn notify_activity(&self, annotation: HangAnnotation); - /// Notify the start of waiting for a new event to come in. - fn notify_wait(&self); - /// Unregister the component from monitor. - fn unregister(&self); -} - -/// A means for the BHM to signal a monitored component to exit. -/// Useful when the component is hanging, and cannot be notified via the usual way. -/// The component should implement this in a way allowing for the signal to be received when hanging, -/// if at all. -pub trait BackgroundHangMonitorExitSignal: Send { - /// Called by the BHM, to notify the monitored component to exit. - fn signal_to_exit(&self); -} - -/// Messages to control the sampling profiler. -#[derive(Deserialize, Serialize)] -pub enum BackgroundHangMonitorControlMsg { - /// Enable the sampler, with a given sampling rate and max total sampling duration. - EnableSampler(Duration, Duration), - DisableSampler, - /// Exit, and propagate the signal to monitored components. - Exit(IpcSender<()>), -} diff --git a/components/shared/base/lib.rs b/components/shared/base/lib.rs new file mode 100644 index 00000000000..2057c9aa8c2 --- /dev/null +++ b/components/shared/base/lib.rs @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#![deny(unsafe_code)] + +//! A crate to hold very common types in Servo. +//! +//! You should almost never need to add a data type to this crate. Instead look for +//! a more shared crate that has fewer dependents. + +use serde::{Deserialize, Serialize}; + +pub mod id; +pub mod print_tree; +use webrender_api::Epoch as WebRenderEpoch; + +/// A struct for denoting the age of messages; prevents race conditions. +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] +pub struct Epoch(pub u32); + +impl Epoch { + pub fn next(&mut self) { + self.0 += 1; + } +} + +impl From<Epoch> for WebRenderEpoch { + fn from(val: Epoch) -> Self { + WebRenderEpoch(val.0) + } +} + +pub trait WebRenderEpochToU16 { + fn as_u16(&self) -> u16; +} + +impl WebRenderEpochToU16 for WebRenderEpoch { + /// The value of this [`Epoch`] as a u16 value. Note that if this Epoch's + /// value is more than u16::MAX, then the return value will be modulo + /// u16::MAX. + fn as_u16(&self) -> u16 { + (self.0 % u16::MAX as u32) as u16 + } +} diff --git a/components/shared/gfx/print_tree.rs b/components/shared/base/print_tree.rs index 03e47b21317..03e47b21317 100644 --- a/components/shared/gfx/print_tree.rs +++ b/components/shared/base/print_tree.rs diff --git a/components/shared/compositing/Cargo.toml b/components/shared/compositing/Cargo.toml index b35e7560f3e..aed9a0e3565 100644 --- a/components/shared/compositing/Cargo.toml +++ b/components/shared/compositing/Cargo.toml @@ -11,6 +11,7 @@ name = "compositing_traits" path = "lib.rs" [dependencies] +base = { workspace = true } canvas = { path = "../../canvas" } crossbeam-channel = { workspace = true } embedder_traits = { workspace = true } @@ -19,7 +20,6 @@ gfx_traits = { workspace = true } ipc-channel = { workspace = true } keyboard-types = { workspace = true } log = { workspace = true } -msg = { workspace = true } net_traits = { workspace = true } script_traits = { workspace = true } servo_url = { path = "../../url" } diff --git a/components/shared/compositing/constellation_msg.rs b/components/shared/compositing/constellation_msg.rs index 2a64db84651..2536a6cfc05 100644 --- a/components/shared/compositing/constellation_msg.rs +++ b/components/shared/compositing/constellation_msg.rs @@ -6,16 +6,14 @@ use std::collections::HashMap; use std::fmt; use std::time::Duration; +use base::id::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId, WebViewId}; +use base::Epoch; use embedder_traits::Cursor; -use gfx_traits::Epoch; use ipc_channel::ipc::IpcSender; use keyboard_types::KeyboardEvent; -use msg::constellation_msg::{ - BrowsingContextId, PipelineId, TopLevelBrowsingContextId, TraversalDirection, WebViewId, -}; use script_traits::{ AnimationTickType, CompositorEvent, GamepadEvent, LogEntry, MediaSessionActionType, - WebDriverCommandMsg, WindowSizeData, WindowSizeType, + TraversalDirection, WebDriverCommandMsg, WindowSizeData, WindowSizeType, }; use servo_url::ServoUrl; diff --git a/components/shared/compositing/lib.rs b/components/shared/compositing/lib.rs index 21f77a4cae6..34c390cca85 100644 --- a/components/shared/compositing/lib.rs +++ b/components/shared/compositing/lib.rs @@ -8,15 +8,15 @@ mod constellation_msg; use std::fmt::{Debug, Error, Formatter}; +use base::id::{PipelineId, TopLevelBrowsingContextId}; +use base::Epoch; use canvas::canvas_paint_thread::ImageUpdate; pub use constellation_msg::ConstellationMsg; use crossbeam_channel::{Receiver, Sender}; use embedder_traits::EventLoopWaker; use euclid::Rect; -use gfx_traits::Epoch; use ipc_channel::ipc::IpcSender; use log::warn; -use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId}; use net_traits::image::base::Image; use net_traits::NetToCompositorMsg; use script_traits::{ diff --git a/components/shared/devtools/Cargo.toml b/components/shared/devtools/Cargo.toml index c3be3bcb01b..d68e3bbb612 100644 --- a/components/shared/devtools/Cargo.toml +++ b/components/shared/devtools/Cargo.toml @@ -11,12 +11,12 @@ name = "devtools_traits" path = "lib.rs" [dependencies] +base = { workspace = true } bitflags = { workspace = true } http = { workspace = true } ipc-channel = { workspace = true } malloc_size_of = { workspace = true } malloc_size_of_derive = { workspace = true } -msg = { workspace = true } serde = { workspace = true } servo_url = { path = "../../url" } time = { workspace = true } diff --git a/components/shared/devtools/lib.rs b/components/shared/devtools/lib.rs index 0726bb48541..f690fb59e0d 100644 --- a/components/shared/devtools/lib.rs +++ b/components/shared/devtools/lib.rs @@ -14,11 +14,11 @@ use std::net::TcpStream; use std::time::{Duration, SystemTime}; +use base::id::{BrowsingContextId, PipelineId}; use bitflags::bitflags; use http::{HeaderMap, Method}; use ipc_channel::ipc::IpcSender; use malloc_size_of_derive::MallocSizeOf; -use msg::constellation_msg::{BrowsingContextId, PipelineId}; use serde::{Deserialize, Serialize}; use servo_url::ServoUrl; use uuid::Uuid; diff --git a/components/shared/embedder/Cargo.toml b/components/shared/embedder/Cargo.toml index c1d7456a156..f68e3b47d2c 100644 --- a/components/shared/embedder/Cargo.toml +++ b/components/shared/embedder/Cargo.toml @@ -11,13 +11,13 @@ name = "embedder_traits" path = "lib.rs" [dependencies] +base = { workspace = true } cfg-if = { workspace = true } crossbeam-channel = { workspace = true } ipc-channel = { workspace = true } keyboard-types = { workspace = true } lazy_static = { workspace = true } log = { workspace = true } -msg = { workspace = true } num-derive = "0.4" num-traits = { workspace = true } serde = { workspace = true } diff --git a/components/shared/embedder/lib.rs b/components/shared/embedder/lib.rs index 0acf7d01ce5..0a5cfdbb479 100644 --- a/components/shared/embedder/lib.rs +++ b/components/shared/embedder/lib.rs @@ -6,11 +6,11 @@ pub mod resources; use std::fmt::{Debug, Error, Formatter}; +use base::id::{PipelineId, TopLevelBrowsingContextId, WebViewId}; use crossbeam_channel::{Receiver, Sender}; use ipc_channel::ipc::IpcSender; use keyboard_types::KeyboardEvent; use log::warn; -use msg::constellation_msg::{InputMethodType, PipelineId, TopLevelBrowsingContextId, WebViewId}; use num_derive::FromPrimitive; use serde::{Deserialize, Serialize}; use servo_url::ServoUrl; @@ -368,3 +368,23 @@ pub enum PermissionRequest { Granted, Denied, } + +/// Used to specify the kind of input method editor appropriate to edit a field. +/// This is a subset of htmlinputelement::InputType because some variants of InputType +/// don't make sense in this context. +#[derive(Debug, Deserialize, Serialize)] +pub enum InputMethodType { + Color, + Date, + DatetimeLocal, + Email, + Month, + Number, + Password, + Search, + Tel, + Text, + Time, + Url, + Week, +} diff --git a/components/shared/gfx/lib.rs b/components/shared/gfx/lib.rs index 2ae2d026fda..e5699f2504a 100644 --- a/components/shared/gfx/lib.rs +++ b/components/shared/gfx/lib.rs @@ -2,71 +2,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#![crate_name = "gfx_traits"] -#![crate_type = "rlib"] #![deny(unsafe_code)] -pub mod print_tree; - -use std::sync::atomic::{AtomicU64, Ordering}; -use std::sync::Arc; - use malloc_size_of_derive::MallocSizeOf; use range::{int_range_index, RangeIndex}; use serde::{Deserialize, Serialize}; -use webrender_api::{ - Epoch as WebRenderEpoch, FontInstanceFlags, FontInstanceKey, FontKey, NativeFontHandle, -}; - -/// A newtype struct for denoting the age of messages; prevents race conditions. -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] -pub struct Epoch(pub u32); - -impl Epoch { - pub fn next(&mut self) { - self.0 += 1; - } -} - -impl From<Epoch> for WebRenderEpoch { - fn from(val: Epoch) -> Self { - WebRenderEpoch(val.0) - } -} - -pub trait WebRenderEpochToU16 { - fn as_u16(&self) -> u16; -} - -impl WebRenderEpochToU16 for WebRenderEpoch { - /// The value of this [`Epoch`] as a u16 value. Note that if this Epoch's - /// value is more than u16::MAX, then the return value will be modulo - /// u16::MAX. - fn as_u16(&self) -> u16 { - (self.0 % u16::MAX as u32) as u16 - } -} - -/// A unique ID for every stacking context. -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)] -pub struct StackingContextId( - /// The identifier for this StackingContext, derived from the Flow's memory address - /// and fragment type. As a space optimization, these are combined into a single word. - pub u64, -); - -impl StackingContextId { - /// Returns the stacking context ID for the outer document/layout root. - #[inline] - pub fn root() -> StackingContextId { - StackingContextId(0) - } - - pub fn next(&self) -> StackingContextId { - let StackingContextId(id) = *self; - StackingContextId(id + 1) - } -} int_range_index! { #[derive(Deserialize, MallocSizeOf, Serialize)] @@ -74,61 +14,3 @@ int_range_index! { /// the middle of a glyph. struct ByteIndex(isize) } - -/// The type of fragment that a scroll root is created for. -/// -/// This can only ever grow to maximum 4 entries. That's because we cram the value of this enum -/// into the lower 2 bits of the `ScrollRootId`, which otherwise contains a 32-bit-aligned -/// heap address. -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)] -pub enum FragmentType { - /// A StackingContext for the fragment body itself. - FragmentBody, - /// A StackingContext created to contain ::before pseudo-element content. - BeforePseudoContent, - /// A StackingContext created to contain ::after pseudo-element content. - AfterPseudoContent, -} - -/// The next ID that will be used for a special scroll root id. -/// -/// A special scroll root is a scroll root that is created for generated content. -static NEXT_SPECIAL_SCROLL_ROOT_ID: AtomicU64 = AtomicU64::new(0); - -/// If none of the bits outside this mask are set, the scroll root is a special scroll root. -/// Note that we assume that the top 16 bits of the address space are unused on the platform. -const SPECIAL_SCROLL_ROOT_ID_MASK: u64 = 0xffff; - -/// Returns a new scroll root ID for a scroll root. -fn next_special_id() -> u64 { - // We shift this left by 2 to make room for the fragment type ID. - ((NEXT_SPECIAL_SCROLL_ROOT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) & - SPECIAL_SCROLL_ROOT_ID_MASK -} - -pub fn combine_id_with_fragment_type(id: usize, fragment_type: FragmentType) -> u64 { - debug_assert_eq!(id & (fragment_type as usize), 0); - if fragment_type == FragmentType::FragmentBody { - id as u64 - } else { - next_special_id() | (fragment_type as u64) - } -} - -pub fn node_id_from_scroll_id(id: usize) -> Option<usize> { - if (id as u64 & !SPECIAL_SCROLL_ROOT_ID_MASK) != 0 { - return Some(id & !3); - } - None -} - -pub trait WebrenderApi { - fn add_font_instance( - &self, - font_key: FontKey, - size: f32, - flags: FontInstanceFlags, - ) -> FontInstanceKey; - fn add_font(&self, data: Arc<Vec<u8>>, index: u32) -> FontKey; - fn add_system_font(&self, handle: NativeFontHandle) -> FontKey; -} diff --git a/components/shared/msg/lib.rs b/components/shared/msg/lib.rs deleted file mode 100644 index b2ce3a52c2c..00000000000 --- a/components/shared/msg/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -#![deny(unsafe_code)] - -pub mod constellation_msg; diff --git a/components/shared/net/Cargo.toml b/components/shared/net/Cargo.toml index 50e9d4eb21d..73db752aba6 100644 --- a/components/shared/net/Cargo.toml +++ b/components/shared/net/Cargo.toml @@ -13,6 +13,7 @@ test = false doctest = false [dependencies] +base = { workspace = true } content-security-policy = { workspace = true } cookie = { workspace = true } embedder_traits = { workspace = true } @@ -27,7 +28,6 @@ log = { workspace = true } malloc_size_of = { workspace = true } malloc_size_of_derive = { workspace = true } mime = { workspace = true } -msg = { workspace = true } num-traits = { workspace = true } percent-encoding = { workspace = true } pixels = { path = "../../pixels" } diff --git a/components/shared/net/lib.rs b/components/shared/net/lib.rs index 95f8856689d..436ccf5d645 100644 --- a/components/shared/net/lib.rs +++ b/components/shared/net/lib.rs @@ -6,6 +6,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; +use base::id::HistoryStateId; use cookie::Cookie; use headers::{ContentType, HeaderMapExt, ReferrerPolicy as ReferrerPolicyHeader}; use http::{Error as HttpError, HeaderMap, StatusCode}; @@ -19,7 +20,6 @@ use log::warn; use malloc_size_of::malloc_size_of_is_0; use malloc_size_of_derive::MallocSizeOf; use mime::Mime; -use msg::constellation_msg::HistoryStateId; use num_traits::Zero; use rustls::Certificate; use serde::{Deserialize, Serialize}; diff --git a/components/shared/net/request.rs b/components/shared/net/request.rs index 346614bc73e..77b37e17b75 100644 --- a/components/shared/net/request.rs +++ b/components/shared/net/request.rs @@ -4,13 +4,13 @@ use std::sync::{Arc, Mutex}; +use base::id::PipelineId; use content_security_policy::{self as csp, CspList}; use http::header::{HeaderName, AUTHORIZATION}; use http::{HeaderMap, Method}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use malloc_size_of_derive::MallocSizeOf; use mime::Mime; -use msg::constellation_msg::PipelineId; use serde::{Deserialize, Serialize}; use servo_url::{ImmutableOrigin, ServoUrl}; diff --git a/components/shared/script/Cargo.toml b/components/shared/script/Cargo.toml index 5cc2b1f8554..f95a0ffdcc9 100644 --- a/components/shared/script/Cargo.toml +++ b/components/shared/script/Cargo.toml @@ -11,6 +11,8 @@ name = "script_traits" path = "lib.rs" [dependencies] +background_hang_monitor_api = { workspace = true } +base = { workspace = true } bitflags = { workspace = true } bluetooth_traits = { workspace = true } canvas_traits = { workspace = true } @@ -29,7 +31,6 @@ log = { workspace = true } malloc_size_of = { workspace = true } malloc_size_of_derive = { workspace = true } media = { path = "../../media" } -msg = { workspace = true } net_traits = { workspace = true } pixels = { path = "../../pixels" } profile_traits = { workspace = true } diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs index 35f7520684e..2f9822d2711 100644 --- a/components/shared/script/lib.rs +++ b/components/shared/script/lib.rs @@ -20,6 +20,12 @@ use std::collections::{HashMap, VecDeque}; use std::fmt; use std::sync::Arc; +use background_hang_monitor_api::BackgroundHangMonitorRegister; +use base::id::{ + BlobId, BrowsingContextId, HistoryStateId, MessagePortId, PipelineId, PipelineNamespaceId, + TopLevelBrowsingContextId, +}; +use base::Epoch; use bitflags::bitflags; use bluetooth_traits::BluetoothRequest; use canvas_traits::webgl::WebGLPipeline; @@ -29,7 +35,6 @@ use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, Worke use embedder_traits::{CompositorEventVariant, Cursor}; use euclid::default::Point2D; use euclid::{Length, Rect, Scale, Size2D, UnknownUnit, Vector2D}; -use gfx_traits::Epoch; use http::{HeaderMap, Method}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::Error as IpcError; @@ -40,10 +45,6 @@ use log::warn; use malloc_size_of::malloc_size_of_is_0; use malloc_size_of_derive::MallocSizeOf; use media::WindowGLContext; -use msg::constellation_msg::{ - BackgroundHangMonitorRegister, BlobId, BrowsingContextId, HistoryStateId, MessagePortId, - PipelineId, PipelineNamespaceId, TopLevelBrowsingContextId, -}; use net_traits::image::base::Image; use net_traits::image_cache::ImageCache; use net_traits::request::{Referrer, RequestBody}; @@ -66,7 +67,7 @@ use crate::compositor::CompositorDisplayListInfo; pub use crate::script_msg::{ DOMMessage, EventResult, HistoryEntryReplacement, IFrameSizeMsg, Job, JobError, JobResult, JobResultValue, JobType, LayoutMsg, LogEntry, SWManagerMsg, SWManagerSenders, ScopeThings, - ScriptMsg, ServiceWorkerMsg, + ScriptMsg, ServiceWorkerMsg, TraversalDirection, }; use crate::serializable::{BlobData, BlobImpl}; use crate::transferable::MessagePortImpl; diff --git a/components/shared/script/script_msg.rs b/components/shared/script/script_msg.rs index a51859231ba..d750d33340d 100644 --- a/components/shared/script/script_msg.rs +++ b/components/shared/script/script_msg.rs @@ -5,18 +5,18 @@ use std::collections::{HashMap, VecDeque}; use std::fmt; +use base::id::{ + BroadcastChannelRouterId, BrowsingContextId, HistoryStateId, MessagePortId, + MessagePortRouterId, PipelineId, ServiceWorkerId, ServiceWorkerRegistrationId, + TopLevelBrowsingContextId, +}; +use base::Epoch; use canvas_traits::canvas::{CanvasId, CanvasMsg}; use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId}; use embedder_traits::{EmbedderMsg, MediaSessionEvent}; use euclid::default::Size2D as UntypedSize2D; use euclid::Size2D; -use gfx_traits::Epoch; use ipc_channel::ipc::{IpcReceiver, IpcSender}; -use msg::constellation_msg::{ - BroadcastChannelRouterId, BrowsingContextId, HistoryStateId, MessagePortId, - MessagePortRouterId, PipelineId, ServiceWorkerId, ServiceWorkerRegistrationId, - TopLevelBrowsingContextId, TraversalDirection, -}; use net_traits::request::RequestBuilder; use net_traits::storage_thread::StorageType; use net_traits::CoreResourceMsg; @@ -492,3 +492,12 @@ pub enum SWManagerMsg { /// <https://github.com/servo/servo/issues/24660> PostMessageToClient, } + +/// The direction of a history traversal +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub enum TraversalDirection { + /// Travel forward the given number of documents. + Forward(usize), + /// Travel backward the given number of documents. + Back(usize), +} diff --git a/components/shared/script/serializable.rs b/components/shared/script/serializable.rs index d186cad621a..d168736f961 100644 --- a/components/shared/script/serializable.rs +++ b/components/shared/script/serializable.rs @@ -11,8 +11,8 @@ use std::cell::RefCell; use std::path::PathBuf; +use base::id::BlobId; use malloc_size_of_derive::MallocSizeOf; -use msg::constellation_msg::BlobId; use net_traits::filemanager_thread::RelativePos; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/components/shared/script/transferable.rs b/components/shared/script/transferable.rs index 2daf4a8d3fd..8344dd493b0 100644 --- a/components/shared/script/transferable.rs +++ b/components/shared/script/transferable.rs @@ -9,8 +9,8 @@ use std::collections::VecDeque; +use base::id::MessagePortId; use malloc_size_of_derive::MallocSizeOf; -use msg::constellation_msg::MessagePortId; use serde::{Deserialize, Serialize}; use crate::PortMessageTask; diff --git a/components/shared/script/webdriver_msg.rs b/components/shared/script/webdriver_msg.rs index d72d93b61cb..9108f2dcbd2 100644 --- a/components/shared/script/webdriver_msg.rs +++ b/components/shared/script/webdriver_msg.rs @@ -6,11 +6,11 @@ use std::collections::HashMap; +use base::id::BrowsingContextId; use cookie::Cookie; use euclid::default::Rect; use hyper_serde::Serde; use ipc_channel::ipc::IpcSender; -use msg::constellation_msg::BrowsingContextId; use serde::{Deserialize, Serialize}; use servo_url::ServoUrl; use webdriver::common::{WebElement, WebFrame, WebWindow}; diff --git a/components/shared/script_layout/Cargo.toml b/components/shared/script_layout/Cargo.toml index df526c9bec9..57c4059b859 100644 --- a/components/shared/script_layout/Cargo.toml +++ b/components/shared/script_layout/Cargo.toml @@ -11,6 +11,7 @@ name = "script_layout_interface" path = "lib.rs" [dependencies] +base = { workspace = true } app_units = { workspace = true } atomic_refcell = { workspace = true } canvas_traits = { workspace = true } @@ -24,12 +25,12 @@ libc = { workspace = true } malloc_size_of = { workspace = true } malloc_size_of_derive = { workspace = true } metrics = { path = "../../metrics" } -msg = { workspace = true } net_traits = { workspace = true } profile_traits = { workspace = true } range = { path = "../../range" } script_traits = { workspace = true } selectors = { workspace = true } +serde = { workspace = true } servo_arc = { workspace = true } servo_atoms = { workspace = true } servo_url = { path = "../../url" } diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index d4ac0185306..7c1f4ee2162 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -12,22 +12,22 @@ pub mod wrapper_traits; use std::any::Any; use std::borrow::Cow; -use std::sync::atomic::AtomicIsize; +use std::sync::atomic::{AtomicIsize, AtomicU64, Ordering}; use std::sync::Arc; use app_units::Au; use atomic_refcell::AtomicRefCell; +use base::id::{BrowsingContextId, PipelineId}; +use base::Epoch; use canvas_traits::canvas::{CanvasId, CanvasMsg}; use crossbeam_channel::Sender; use euclid::default::{Point2D, Rect}; use euclid::Size2D; use gfx::font_cache_thread::FontCacheThread; -use gfx_traits::Epoch; use ipc_channel::ipc::IpcSender; use libc::c_void; use malloc_size_of_derive::MallocSizeOf; use metrics::PaintTimeMetrics; -use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image_cache::{ImageCache, PendingImageId}; use profile_traits::mem::Report; use profile_traits::time; @@ -35,6 +35,7 @@ use script_traits::{ ConstellationControlMsg, InitialScriptState, LayoutControlMsg, LayoutMsg, LoadData, Painter, ScrollState, UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData, }; +use serde::{Deserialize, Serialize}; use servo_arc::Arc as ServoArc; use servo_url::{ImmutableOrigin, ServoUrl}; use style::animation::DocumentAnimationSet; @@ -413,3 +414,50 @@ pub struct PendingRestyle { /// Any explicit restyles damage that have been accumulated for this element. pub damage: RestyleDamage, } + +/// The type of fragment that a scroll root is created for. +/// +/// This can only ever grow to maximum 4 entries. That's because we cram the value of this enum +/// into the lower 2 bits of the `ScrollRootId`, which otherwise contains a 32-bit-aligned +/// heap address. +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)] +pub enum FragmentType { + /// A StackingContext for the fragment body itself. + FragmentBody, + /// A StackingContext created to contain ::before pseudo-element content. + BeforePseudoContent, + /// A StackingContext created to contain ::after pseudo-element content. + AfterPseudoContent, +} + +/// The next ID that will be used for a special scroll root id. +/// +/// A special scroll root is a scroll root that is created for generated content. +static NEXT_SPECIAL_SCROLL_ROOT_ID: AtomicU64 = AtomicU64::new(0); + +/// If none of the bits outside this mask are set, the scroll root is a special scroll root. +/// Note that we assume that the top 16 bits of the address space are unused on the platform. +const SPECIAL_SCROLL_ROOT_ID_MASK: u64 = 0xffff; + +/// Returns a new scroll root ID for a scroll root. +fn next_special_id() -> u64 { + // We shift this left by 2 to make room for the fragment type ID. + ((NEXT_SPECIAL_SCROLL_ROOT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) & + SPECIAL_SCROLL_ROOT_ID_MASK +} + +pub fn combine_id_with_fragment_type(id: usize, fragment_type: FragmentType) -> u64 { + debug_assert_eq!(id & (fragment_type as usize), 0); + if fragment_type == FragmentType::FragmentBody { + id as u64 + } else { + next_special_id() | (fragment_type as u64) + } +} + +pub fn node_id_from_scroll_id(id: usize) -> Option<usize> { + if (id as u64 & !SPECIAL_SCROLL_ROOT_ID_MASK) != 0 { + return Some(id & !3); + } + None +} diff --git a/components/shared/script_layout/wrapper_traits.rs b/components/shared/script_layout/wrapper_traits.rs index 846943414ae..0adb51be244 100644 --- a/components/shared/script_layout/wrapper_traits.rs +++ b/components/shared/script_layout/wrapper_traits.rs @@ -9,9 +9,9 @@ use std::fmt::Debug; use std::sync::Arc as StdArc; use atomic_refcell::AtomicRef; -use gfx_traits::{ByteIndex, FragmentType}; +use base::id::{BrowsingContextId, PipelineId}; +use gfx_traits::ByteIndex; use html5ever::{local_name, namespace_url, ns, LocalName, Namespace}; -use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image::base::{Image, ImageMetadata}; use range::Range; use servo_arc::Arc; @@ -25,7 +25,8 @@ use style::selector_parser::{PseudoElement, PseudoElementCascadeType, SelectorIm use style::stylist::RuleInclusion; use crate::{ - GenericLayoutData, HTMLCanvasData, HTMLMediaData, LayoutNodeType, SVGSVGData, StyleData, + FragmentType, GenericLayoutData, HTMLCanvasData, HTMLMediaData, LayoutNodeType, SVGSVGData, + StyleData, }; pub trait LayoutDataTrait: Default + Send + Sync + 'static {} diff --git a/components/shared/webrender/lib.rs b/components/shared/webrender/lib.rs index a71f9f67760..8af3a17b609 100644 --- a/components/shared/webrender/lib.rs +++ b/components/shared/webrender/lib.rs @@ -9,7 +9,10 @@ use std::sync::{Arc, Mutex}; use euclid::default::Size2D; use webrender_api::units::TexelRect; -use webrender_api::{ExternalImage, ExternalImageHandler, ExternalImageId, ExternalImageSource}; +use webrender_api::{ + ExternalImage, ExternalImageHandler, ExternalImageId, ExternalImageSource, FontInstanceFlags, + FontInstanceKey, FontKey, NativeFontHandle, +}; /// This trait is used as a bridge between the different GL clients /// in Servo that handles WebRender ExternalImages and the WebRender @@ -164,3 +167,14 @@ impl ExternalImageHandler for WebrenderExternalImageHandlers { }; } } + +pub trait WebRenderFontApi { + fn add_font_instance( + &self, + font_key: FontKey, + size: f32, + flags: FontInstanceFlags, + ) -> FontInstanceKey; + fn add_font(&self, data: Arc<Vec<u8>>, index: u32) -> FontKey; + fn add_system_font(&self, handle: NativeFontHandle) -> FontKey; +} |