Create a constellation_traits crate (#36088)

This change creates a `constellation_traits` crate. Previously messages
to the `Constellation` were in the `compositing_traits` crate, which
came about organically. This change moves these to a new crate which
also contains data types that are used in both compositing/libservo and
script (ie types that cross the process boundary). The idea is similar
to `embedding_traits`, but this is meant for types not exposed to the
API.

This change allows deduplicating `UntrustedNodeAddress`, which
previously had two versions to avoid circular dependencies.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-03-22 16:49:08 +01:00 committed by GitHub
parent 02375809b0
commit 7c574141c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 399 additions and 270 deletions

View file

@ -16,7 +16,7 @@ use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use webrender_api::{ExternalScrollId, PipelineId as WebRenderPipelineId};
use webrender_api::{ExternalScrollId, PipelineId as WebRenderPipelineId, SpatialId};
/// Asserts the size of a type at compile time.
macro_rules! size_of_test {
@ -442,3 +442,15 @@ pub const TEST_BROWSING_CONTEXT_ID: BrowsingContextId = BrowsingContextId {
};
pub const TEST_WEBVIEW_ID: WebViewId = WebViewId(TEST_BROWSING_CONTEXT_ID);
/// An id for a ScrollTreeNode in the ScrollTree. This contains both the index
/// to the node in the tree's array of nodes as well as the corresponding SpatialId
/// for the SpatialNode in the WebRender display list.
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct ScrollTreeNodeId {
/// The index of this scroll tree node in the tree's array of nodes.
pub index: usize,
/// The WebRender spatial id of this scroll tree node.
pub spatial_id: SpatialId,
}

View file

@ -17,11 +17,9 @@ crossbeam-channel = { workspace = true }
embedder_traits = { workspace = true }
euclid = { workspace = true }
ipc-channel = { workspace = true }
keyboard-types = { workspace = true }
log = { workspace = true }
pixels = { path = '../../pixels' }
script_traits = { workspace = true }
servo_url = { path = "../../url" }
strum_macros = { workspace = true }
stylo_traits = { workspace = true }
webrender_api = { workspace = true }

View file

@ -2,14 +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/. */
//! Communication with the compositor thread.
mod constellation_msg;
//! The interface to the `compositing` crate.
use std::fmt::{Debug, Error, Formatter};
use base::id::{PipelineId, WebViewId};
pub use constellation_msg::{ConstellationMsg, PaintMetricEvent};
use crossbeam_channel::{Receiver, Sender};
use embedder_traits::{EventLoopWaker, MouseButton, MouseButtonAction};
use euclid::Rect;

View file

@ -0,0 +1,26 @@
[package]
name = "constellation_traits"
version.workspace = true
authors.workspace = true
license.workspace = true
edition.workspace = true
publish.workspace = true
rust-version.workspace = true
[lib]
name = "constellation_traits"
path = "lib.rs"
[dependencies]
base = { workspace = true }
bitflags = { workspace = true }
embedder_traits = { workspace = true }
euclid = { workspace = true }
ipc-channel = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
serde = { workspace = true }
servo_url = { path = "../../url" }
strum_macros = { workspace = true }
stylo_traits = { workspace = true }
webrender_api = { workspace = true }

View file

@ -0,0 +1,224 @@
/* 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/. */
//! The interface to the `Constellation`, which prevents other crates from depending directly on
//! the `constellation` crate itself. In addition to all messages to the `Constellation`, this
//! crate is responsible for defining types that cross the process boundary from the
//! embedding/rendering layer all the way to script, thus it should have very minimal dependencies
//! on other parts of Servo.
use std::collections::HashMap;
use std::ffi::c_void;
use std::fmt;
use std::time::Duration;
use base::Epoch;
use base::cross_process_instant::CrossProcessInstant;
use base::id::{PipelineId, ScrollTreeNodeId, WebViewId};
use bitflags::bitflags;
use embedder_traits::{Cursor, InputEvent, MediaSessionActionType, Theme, WebDriverCommandMsg};
use euclid::{Scale, Size2D, Vector2D};
use ipc_channel::ipc::IpcSender;
use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use servo_url::ServoUrl;
use strum_macros::IntoStaticStr;
use style_traits::CSSPixel;
use webrender_api::ExternalScrollId;
use webrender_api::units::{DevicePixel, LayoutPixel};
/// Messages to the constellation.
#[derive(IntoStaticStr)]
pub enum ConstellationMsg {
/// Exit the constellation.
Exit,
/// Request that the constellation send the current focused top-level browsing context id,
/// over a provided channel.
GetFocusTopLevelBrowsingContext(IpcSender<Option<WebViewId>>),
/// Query the constellation to see if the current compositor output is stable
IsReadyToSaveImage(HashMap<PipelineId, Epoch>),
/// Whether to allow script to navigate.
AllowNavigationResponse(PipelineId, bool),
/// Request to load a page.
LoadUrl(WebViewId, ServoUrl),
/// Clear the network cache.
ClearCache,
/// Request to traverse the joint session history of the provided browsing context.
TraverseHistory(WebViewId, TraversalDirection),
/// Inform the constellation of a window being resized.
WindowSize(WebViewId, WindowSizeData, WindowSizeType),
/// Inform the constellation of a theme change.
ThemeChange(Theme),
/// Requests that the constellation instruct layout to begin a new tick of the animation.
TickAnimation(PipelineId, AnimationTickType),
/// Dispatch a webdriver command
WebDriverCommand(WebDriverCommandMsg),
/// Reload a top-level browsing context.
Reload(WebViewId),
/// A log entry, with the top-level browsing context id and thread name
LogEntry(Option<WebViewId>, Option<String>, LogEntry),
/// Create a new top level browsing context.
NewWebView(ServoUrl, WebViewId),
/// Close a top level browsing context.
CloseWebView(WebViewId),
/// Panic a top level browsing context.
SendError(Option<WebViewId>, String),
/// Make a webview focused.
FocusWebView(WebViewId),
/// Make none of the webviews focused.
BlurWebView,
/// Forward an input event to an appropriate ScriptTask.
ForwardInputEvent(WebViewId, InputEvent, Option<CompositorHitTestResult>),
/// Requesting a change to the onscreen cursor.
SetCursor(WebViewId, Cursor),
/// Enable the sampling profiler, with a given sampling rate and max total sampling duration.
ToggleProfiler(Duration, Duration),
/// Request to exit from fullscreen mode
ExitFullScreen(WebViewId),
/// Media session action.
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<ScrollState>),
/// Notify the constellation that a particular paint metric event has happened for the given pipeline.
PaintMetric(PipelineId, PaintMetricEvent),
}
/// A description of a paint metric that is sent from the Servo renderer to the
/// constellation.
pub enum PaintMetricEvent {
FirstPaint(CrossProcessInstant, bool /* first_reflow */),
FirstContentfulPaint(CrossProcessInstant, bool /* first_reflow */),
}
impl fmt::Debug for ConstellationMsg {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let variant_string: &'static str = self.into();
write!(formatter, "ConstellationMsg::{variant_string}")
}
}
/// A log entry reported to the constellation
/// We don't report all log entries, just serious ones.
/// We need a separate type for this because `LogLevel` isn't serializable.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum LogEntry {
/// Panic, with a reason and backtrace
Panic(String, String),
/// Error, with a reason
Error(String),
/// warning, with a reason
Warn(String),
}
/// Data about the window size.
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct WindowSizeData {
/// The size of the initial layout viewport, before parsing an
/// <http://www.w3.org/TR/css-device-adapt/#initial-viewport>
pub initial_viewport: Size2D<f32, CSSPixel>,
/// The resolution of the window in dppx, not including any "pinch zoom" factor.
pub device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
}
/// The type of window size change.
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
pub enum WindowSizeType {
/// Initial load.
Initial,
/// Window resize.
Resize,
}
bitflags! {
#[derive(Debug, Default, Deserialize, Serialize)]
/// Specifies if rAF should be triggered and/or CSS Animations and Transitions.
pub struct AnimationTickType: u8 {
/// Trigger a call to requestAnimationFrame.
const REQUEST_ANIMATION_FRAME = 0b001;
/// Trigger restyles for CSS Animations and Transitions.
const CSS_ANIMATIONS_AND_TRANSITIONS = 0b010;
}
}
/// The result of a hit test in the compositor.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CompositorHitTestResult {
/// The pipeline id of the resulting item.
pub pipeline_id: PipelineId,
/// The hit test point in the item's viewport.
pub point_in_viewport: euclid::default::Point2D<f32>,
/// The hit test point relative to the item itself.
pub point_relative_to_item: euclid::default::Point2D<f32>,
/// The node address of the hit test result.
pub node: UntrustedNodeAddress,
/// The cursor that should be used when hovering the item hit by the hit test.
pub cursor: Option<Cursor>,
/// 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<f32, LayoutPixel>,
}
/// The address of a node. Layout sends these back. They must be validated via
/// `from_untrusted_node_address` before they can be used, because we do not trust layout.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct UntrustedNodeAddress(pub *const c_void);
malloc_size_of_is_0!(UntrustedNodeAddress);
#[allow(unsafe_code)]
unsafe impl Send for UntrustedNodeAddress {}
impl From<style_traits::dom::OpaqueNode> for UntrustedNodeAddress {
fn from(o: style_traits::dom::OpaqueNode) -> Self {
UntrustedNodeAddress(o.0 as *const c_void)
}
}
impl Serialize for UntrustedNodeAddress {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
(self.0 as usize).serialize(s)
}
}
impl<'de> Deserialize<'de> for UntrustedNodeAddress {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<UntrustedNodeAddress, D::Error> {
let value: usize = Deserialize::deserialize(d)?;
Ok(UntrustedNodeAddress::from_id(value))
}
}
impl UntrustedNodeAddress {
/// Creates an `UntrustedNodeAddress` from the given pointer address value.
#[inline]
pub fn from_id(id: usize) -> UntrustedNodeAddress {
UntrustedNodeAddress(id as *const c_void)
}
}
/// 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),
}

View file

@ -2,6 +2,12 @@
* 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/. */
//! Types used by the embedding layer and/or exposed to the API. This crate is responsible for
//! defining types that cross the process boundary from the embedding/rendering layer all the way
//! to script, thus it should have very minimal dependencies on other parts of Servo. If a type
//! is not exposed in the API or doesn't involve messages sent to the embedding/libservo layer, it
//! is probably a better fit for the `constellation_traits` crate.
pub mod input_events;
pub mod resources;
mod webdriver;
@ -526,15 +532,6 @@ impl WebResourceResponse {
}
}
/// 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),
}
/// The type of platform theme.
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
pub enum Theme {

View file

@ -21,6 +21,7 @@ base = { workspace = true }
bitflags = { workspace = true }
bluetooth_traits = { workspace = true, optional = true }
canvas_traits = { workspace = true }
constellation_traits = { workspace = true }
cookie = { workspace = true }
crossbeam-channel = { workspace = true }
devtools_traits = { workspace = true }

View file

@ -24,10 +24,12 @@ use base::id::{
BlobId, BrowsingContextId, HistoryStateId, MessagePortId, PipelineId, PipelineNamespaceId,
WebViewId,
};
use bitflags::bitflags;
#[cfg(feature = "bluetooth")]
use bluetooth_traits::BluetoothRequest;
use canvas_traits::webgl::WebGLPipeline;
use constellation_traits::{
AnimationTickType, CompositorHitTestResult, ScrollState, WindowSizeData, WindowSizeType,
};
use crossbeam_channel::{RecvTimeoutError, Sender};
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
use embedder_traits::input_events::InputEvent;
@ -36,9 +38,7 @@ use euclid::{Rect, Scale, Size2D, UnknownUnit};
use http::{HeaderMap, Method};
use ipc_channel::Error as IpcError;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use libc::c_void;
use log::warn;
use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;
use media::WindowGLContext;
use net_traits::image_cache::ImageCache;
@ -47,7 +47,7 @@ use net_traits::storage_thread::StorageType;
use net_traits::{ReferrerPolicy, ResourceThreads};
use pixels::PixelFormat;
use profile_traits::{mem, time as profile_time};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::{Deserialize, Serialize};
use servo_url::{ImmutableOrigin, ServoUrl};
use strum::{EnumIter, IntoEnumIterator};
use strum_macros::IntoStaticStr;
@ -57,61 +57,15 @@ use stylo_atoms::Atom;
use webgpu::WebGPUMsg;
use webrender_api::units::DevicePixel;
use webrender_api::{DocumentId, ImageKey};
use webrender_traits::{
CompositorHitTestResult, CrossProcessCompositorApi, ScrollState,
UntrustedNodeAddress as WebRenderUntrustedNodeAddress,
};
use webrender_traits::CrossProcessCompositorApi;
pub use crate::script_msg::{
DOMMessage, IFrameSizeMsg, Job, JobError, JobResult, JobResultValue, JobType, LogEntry,
SWManagerMsg, SWManagerSenders, ScopeThings, ScriptMsg, ServiceWorkerMsg, TouchEventResult,
DOMMessage, IFrameSizeMsg, Job, JobError, JobResult, JobResultValue, JobType, SWManagerMsg,
SWManagerSenders, ScopeThings, ScriptMsg, ServiceWorkerMsg, TouchEventResult,
};
use crate::serializable::BlobImpl;
use crate::transferable::MessagePortImpl;
/// The address of a node. Layout sends these back. They must be validated via
/// `from_untrusted_node_address` before they can be used, because we do not trust layout.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct UntrustedNodeAddress(pub *const c_void);
malloc_size_of_is_0!(UntrustedNodeAddress);
#[allow(unsafe_code)]
unsafe impl Send for UntrustedNodeAddress {}
impl From<WebRenderUntrustedNodeAddress> for UntrustedNodeAddress {
fn from(o: WebRenderUntrustedNodeAddress) -> Self {
UntrustedNodeAddress(o.0)
}
}
impl From<style_traits::dom::OpaqueNode> for UntrustedNodeAddress {
fn from(o: style_traits::dom::OpaqueNode) -> Self {
UntrustedNodeAddress(o.0 as *const c_void)
}
}
impl Serialize for UntrustedNodeAddress {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
(self.0 as usize).serialize(s)
}
}
impl<'de> Deserialize<'de> for UntrustedNodeAddress {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<UntrustedNodeAddress, D::Error> {
let value: usize = Deserialize::deserialize(d)?;
Ok(UntrustedNodeAddress::from_id(value))
}
}
impl UntrustedNodeAddress {
/// Creates an `UntrustedNodeAddress` from the given pointer address value.
#[inline]
pub fn from_id(id: usize) -> UntrustedNodeAddress {
UntrustedNodeAddress(id as *const c_void)
}
}
/// The origin where a given load was initiated.
/// Useful for origin checks, for example before evaluation a JS URL.
#[derive(Clone, Debug, Deserialize, Serialize)]
@ -581,37 +535,6 @@ pub struct IFrameLoadInfoWithData {
pub window_size: WindowSizeData,
}
bitflags! {
#[derive(Debug, Default, Deserialize, Serialize)]
/// Specifies if rAF should be triggered and/or CSS Animations and Transitions.
pub struct AnimationTickType: u8 {
/// Trigger a call to requestAnimationFrame.
const REQUEST_ANIMATION_FRAME = 0b001;
/// Trigger restyles for CSS Animations and Transitions.
const CSS_ANIMATIONS_AND_TRANSITIONS = 0b010;
}
}
/// Data about the window size.
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct WindowSizeData {
/// The size of the initial layout viewport, before parsing an
/// <http://www.w3.org/TR/css-device-adapt/#initial-viewport>
pub initial_viewport: Size2D<f32, CSSPixel>,
/// The resolution of the window in dppx, not including any "pinch zoom" factor.
pub device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
}
/// The type of window size change.
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
pub enum WindowSizeType {
/// Initial load.
Initial,
/// Window resize.
Resize,
}
/// Resources required by workerglobalscopes
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct WorkerGlobalScopeInit {

View file

@ -11,10 +11,9 @@ use base::id::{
MessagePortRouterId, PipelineId, ServiceWorkerId, ServiceWorkerRegistrationId, WebViewId,
};
use canvas_traits::canvas::{CanvasId, CanvasMsg};
use constellation_traits::{LogEntry, TraversalDirection};
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
use embedder_traits::{
EmbedderMsg, MediaSessionEvent, TouchEventType, TouchSequenceId, TraversalDirection,
};
use embedder_traits::{EmbedderMsg, MediaSessionEvent, TouchEventType, TouchSequenceId};
use euclid::Size2D;
use euclid::default::Size2D as UntypedSize2D;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
@ -55,19 +54,6 @@ pub enum TouchEventResult {
DefaultPrevented(TouchSequenceId, TouchEventType),
}
/// A log entry reported to the constellation
/// We don't report all log entries, just serious ones.
/// We need a separate type for this because `LogLevel` isn't serializable.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum LogEntry {
/// Panic, with a reason and backtrace
Panic(String, String),
/// Error, with a reason
Error(String),
/// warning, with a reason
Warn(String),
}
/// Messages from the script to the constellation.
#[derive(Deserialize, IntoStaticStr, Serialize)]
pub enum ScriptMsg {

View file

@ -2,11 +2,12 @@
* 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/. */
use base::id::ScrollTreeNodeId;
use euclid::Size2D;
use webrender_api::units::LayoutVector2D;
use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, SpatialId};
use webrender_traits::display_list::{
AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollTreeNodeId, ScrollableNodeInfo,
AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollableNodeInfo,
};
fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId {

View file

@ -16,6 +16,7 @@ base = { workspace = true }
app_units = { workspace = true }
atomic_refcell = { workspace = true }
canvas_traits = { workspace = true }
constellation_traits = { workspace = true }
euclid = { workspace = true }
fnv = { workspace = true }
fonts = { path = "../../fonts" }

View file

@ -20,6 +20,7 @@ use atomic_refcell::AtomicRefCell;
use base::Epoch;
use base::id::{BrowsingContextId, PipelineId, WebViewId};
use canvas_traits::canvas::{CanvasId, CanvasMsg};
use constellation_traits::{ScrollState, UntrustedNodeAddress, WindowSizeData};
use euclid::Size2D;
use euclid::default::{Point2D, Rect};
use fnv::FnvHashMap;
@ -30,10 +31,7 @@ use malloc_size_of_derive::MallocSizeOf;
use net_traits::image_cache::{ImageCache, PendingImageId};
use profile_traits::mem::Report;
use profile_traits::time;
use script_traits::{
InitialScriptState, LoadData, Painter, ScriptThreadMessage, UntrustedNodeAddress,
WindowSizeData,
};
use script_traits::{InitialScriptState, LoadData, Painter, ScriptThreadMessage};
use serde::{Deserialize, Serialize};
use servo_arc::Arc as ServoArc;
use servo_url::{ImmutableOrigin, ServoUrl};
@ -51,7 +49,7 @@ use style::selector_parser::{PseudoElement, RestyleDamage, Snapshot};
use style::stylesheets::Stylesheet;
use style_traits::CSSPixel;
use webrender_api::ImageKey;
use webrender_traits::{CrossProcessCompositorApi, ScrollState};
use webrender_traits::CrossProcessCompositorApi;
pub type GenericLayoutData = dyn Any + Send + Sync;

View file

@ -17,6 +17,7 @@ no-wgl = ["surfman/sm-angle-default"]
[dependencies]
base = { workspace = true }
constellation_traits = { workspace = true }
embedder_traits = { workspace = true }
euclid = { workspace = true }
image = { workspace = true }

View file

@ -4,6 +4,7 @@
//! Defines data structures which are consumed by the Compositor.
use base::id::ScrollTreeNodeId;
use embedder_traits::Cursor;
use serde::{Deserialize, Serialize};
use style::values::specified::Overflow;
@ -54,18 +55,6 @@ pub struct HitTestInfo {
pub scroll_tree_node: ScrollTreeNodeId,
}
/// An id for a ScrollTreeNode in the ScrollTree. This contains both the index
/// to the node in the tree's array of nodes as well as the corresponding SpatialId
/// for the SpatialNode in the WebRender display list.
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct ScrollTreeNodeId {
/// The index of this scroll tree node in the tree's array of nodes.
pub index: usize,
/// The WebRender spatial id of this scroll tree node.
pub spatial_id: SpatialId,
}
/// Data stored for nodes in the [ScrollTree] that actually scroll,
/// as opposed to reference frames and sticky nodes which do not.
#[derive(Debug, Deserialize, Serialize)]

View file

@ -11,17 +11,15 @@ use core::fmt;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use base::id::{PipelineId, WebViewId};
use display_list::{CompositorDisplayListInfo, ScrollTreeNodeId};
use embedder_traits::Cursor;
use euclid::Vector2D;
use base::id::WebViewId;
use constellation_traits::CompositorHitTestResult;
use display_list::CompositorDisplayListInfo;
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 serde::{Deserialize, Serialize};
use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize};
use webrender_api::units::{DevicePoint, LayoutPixel, LayoutPoint, TexelRect};
use webrender_api::units::{DevicePoint, LayoutPoint, TexelRect};
use webrender_api::{
BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData,
ExternalImageHandler, ExternalImageId, ExternalImageSource, ExternalScrollId,
@ -480,63 +478,3 @@ impl From<SerializableImageData> for ImageData {
}
}
}
/// The address of a node. Layout sends these back. They must be validated via
/// `from_untrusted_node_address` before they can be used, because we do not trust layout.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct UntrustedNodeAddress(pub *const c_void);
#[allow(unsafe_code)]
unsafe impl Send for UntrustedNodeAddress {}
impl Serialize for UntrustedNodeAddress {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
(self.0 as usize).serialize(s)
}
}
impl<'de> Deserialize<'de> for UntrustedNodeAddress {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<UntrustedNodeAddress, D::Error> {
let value: usize = Deserialize::deserialize(d)?;
Ok(UntrustedNodeAddress::from_id(value))
}
}
impl UntrustedNodeAddress {
/// Creates an `UntrustedNodeAddress` from the given pointer address value.
#[inline]
pub fn from_id(id: usize) -> UntrustedNodeAddress {
UntrustedNodeAddress(id as *const c_void)
}
}
/// The result of a hit test in the compositor.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CompositorHitTestResult {
/// The pipeline id of the resulting item.
pub pipeline_id: PipelineId,
/// The hit test point in the item's viewport.
pub point_in_viewport: euclid::default::Point2D<f32>,
/// The hit test point relative to the item itself.
pub point_relative_to_item: euclid::default::Point2D<f32>,
/// The node address of the hit test result.
pub node: UntrustedNodeAddress,
/// The cursor that should be used when hovering the item hit by the hit test.
pub cursor: Option<Cursor>,
/// 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<f32, LayoutPixel>,
}