Move *_traits and other shared types to shared

This is the start of the organization of types that are in their own
crates in order to break dependency cycles between other crates. The
idea here is that putting these packages into their own directory is the
first step toward cleaning them up. They have grown organically and it
is difficult to explain to new folks where to put new shared types. Many
of these crates contain more than traits or don't contain traits at all.

Notably, `script_traits` isn't touched because it is vendored from
Gecko. Eventually this will move to `third_party`.
This commit is contained in:
Martin Robinson 2023-10-05 19:47:39 +02:00
parent 863529d962
commit f4d3af296c
89 changed files with 244 additions and 226 deletions

View file

@ -0,0 +1,29 @@
[package]
name = "compositing_traits"
version = "0.0.1"
authors = ["The Servo Project Developers"]
license = "MPL-2.0"
edition = "2018"
publish = false
[lib]
name = "compositing_traits"
path = "lib.rs"
[dependencies]
canvas = { path = "../../canvas" }
crossbeam-channel = { workspace = true }
embedder_traits = { workspace = true }
euclid = { workspace = true }
gfx_traits = { workspace = true }
ipc-channel = { workspace = true }
keyboard-types = { workspace = true }
log = { workspace = true }
msg = { workspace = true }
net_traits = { workspace = true }
profile_traits = { workspace = true }
script_traits = { workspace = true }
servo_url = { path = "../../url" }
style_traits = { workspace = true }
webrender_api = { workspace = true }
webrender_surfman = { path = "../../webrender_surfman" }

View file

@ -0,0 +1,120 @@
/* 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/. */
use std::collections::HashMap;
use std::fmt;
use std::time::Duration;
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,
};
use script_traits::{
AnimationTickType, CompositorEvent, LogEntry, MediaSessionActionType, WebDriverCommandMsg,
WindowSizeData, WindowSizeType,
};
use servo_url::ServoUrl;
/// Messages to the constellation.
pub enum ConstellationMsg {
/// Exit the constellation.
Exit,
/// Request that the constellation send the BrowsingContextId corresponding to the document
/// with the provided pipeline id
GetBrowsingContext(PipelineId, IpcSender<Option<BrowsingContextId>>),
/// Request that the constellation send the current pipeline id for the provided
/// browsing context id, over a provided channel.
GetPipeline(BrowsingContextId, IpcSender<Option<PipelineId>>),
/// Request that the constellation send the current focused top-level browsing context id,
/// over a provided channel.
GetFocusTopLevelBrowsingContext(IpcSender<Option<TopLevelBrowsingContextId>>),
/// Query the constellation to see if the current compositor output is stable
IsReadyToSaveImage(HashMap<PipelineId, Epoch>),
/// Inform the constellation of a key event.
Keyboard(KeyboardEvent),
/// Whether to allow script to navigate.
AllowNavigationResponse(PipelineId, bool),
/// Request to load a page.
LoadUrl(TopLevelBrowsingContextId, ServoUrl),
/// Clear the network cache.
ClearCache,
/// Request to traverse the joint session history of the provided browsing context.
TraverseHistory(TopLevelBrowsingContextId, TraversalDirection),
/// Inform the constellation of a window being resized.
WindowSize(TopLevelBrowsingContextId, WindowSizeData, WindowSizeType),
/// 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(TopLevelBrowsingContextId),
/// A log entry, with the top-level browsing context id and thread name
LogEntry(Option<TopLevelBrowsingContextId>, Option<String>, LogEntry),
/// Create a new top level browsing context.
NewBrowser(ServoUrl, TopLevelBrowsingContextId),
/// Close a top level browsing context.
CloseBrowser(TopLevelBrowsingContextId),
/// Panic a top level browsing context.
SendError(Option<TopLevelBrowsingContextId>, String),
/// Make browser visible.
SelectBrowser(TopLevelBrowsingContextId),
/// Forward an event to the script task of the given pipeline.
ForwardEvent(PipelineId, CompositorEvent),
/// Requesting a change to the onscreen cursor.
SetCursor(Cursor),
/// Enable the sampling profiler, with a given sampling rate and max total sampling duration.
EnableProfiler(Duration, Duration),
/// Disable the sampling profiler.
DisableProfiler,
/// Request to exit from fullscreen mode
ExitFullScreen(TopLevelBrowsingContextId),
/// Media session action.
MediaSessionAction(MediaSessionActionType),
/// Toggle browser visibility.
ChangeBrowserVisibility(TopLevelBrowsingContextId, bool),
/// Virtual keyboard was dismissed
IMEDismissed,
/// Compositing done, but external code needs to present.
ReadyToPresent(TopLevelBrowsingContextId),
}
impl fmt::Debug for ConstellationMsg {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
use self::ConstellationMsg::*;
let variant = match *self {
Exit => "Exit",
GetBrowsingContext(..) => "GetBrowsingContext",
GetPipeline(..) => "GetPipeline",
GetFocusTopLevelBrowsingContext(..) => "GetFocusTopLevelBrowsingContext",
IsReadyToSaveImage(..) => "IsReadyToSaveImage",
Keyboard(..) => "Keyboard",
AllowNavigationResponse(..) => "AllowNavigationResponse",
LoadUrl(..) => "LoadUrl",
TraverseHistory(..) => "TraverseHistory",
WindowSize(..) => "WindowSize",
TickAnimation(..) => "TickAnimation",
WebDriverCommand(..) => "WebDriverCommand",
Reload(..) => "Reload",
LogEntry(..) => "LogEntry",
NewBrowser(..) => "NewBrowser",
CloseBrowser(..) => "CloseBrowser",
SendError(..) => "SendError",
SelectBrowser(..) => "SelectBrowser",
ForwardEvent(..) => "ForwardEvent",
SetCursor(..) => "SetCursor",
EnableProfiler(..) => "EnableProfiler",
DisableProfiler => "DisableProfiler",
ExitFullScreen(..) => "ExitFullScreen",
MediaSessionAction(..) => "MediaSessionAction",
ChangeBrowserVisibility(..) => "ChangeBrowserVisibility",
IMEDismissed => "IMEDismissed",
ClearCache => "ClearCache",
ReadyToPresent(..) => "ReadyToPresent",
};
write!(formatter, "ConstellationMsg::{}", variant)
}
}

View file

@ -0,0 +1,215 @@
/* 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/. */
//! Communication with the compositor thread.
mod constellation_msg;
use std::fmt::{Debug, Error, Formatter};
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::{
AnimationState, ConstellationControlMsg, EventResult, LayoutControlMsg, MouseButton,
MouseEventType, ScriptToCompositorMsg,
};
use style_traits::CSSPixel;
use webrender_api::units::{DeviceIntPoint, DeviceIntSize};
use webrender_api::{self, FontInstanceKey, FontKey, ImageKey};
/// Why we performed a composite. This is used for debugging.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CompositingReason {
/// We hit the delayed composition timeout. (See `delayed_composition.rs`.)
DelayedCompositeTimeout,
/// The window has been scrolled and we're starting the first recomposite.
Scroll,
/// A scroll has continued and we need to recomposite again.
ContinueScroll,
/// We're performing the single composite in headless mode.
Headless,
/// We're performing a composite to run an animation.
Animation,
/// A new frame tree has been loaded.
NewFrameTree,
/// New painted buffers have been received.
NewPaintedBuffers,
/// The window has been zoomed.
Zoom,
/// A new WebRender frame has arrived.
NewWebRenderFrame,
/// WebRender has processed a scroll event and has generated a new frame.
NewWebRenderScrollFrame,
/// The window has been resized and will need to be synchronously repainted.
Resize,
}
/// Sends messages to the compositor.
pub struct CompositorProxy {
pub sender: Sender<CompositorMsg>,
pub event_loop_waker: Box<dyn EventLoopWaker>,
}
impl CompositorProxy {
pub fn send(&self, msg: CompositorMsg) {
if let Err(err) = self.sender.send(msg) {
warn!("Failed to send response ({:?}).", err);
}
self.event_loop_waker.wake();
}
}
impl Clone for CompositorProxy {
fn clone(&self) -> CompositorProxy {
CompositorProxy {
sender: self.sender.clone(),
event_loop_waker: self.event_loop_waker.clone(),
}
}
}
/// The port that the compositor receives messages on.
pub struct CompositorReceiver {
pub receiver: Receiver<CompositorMsg>,
}
impl CompositorReceiver {
pub fn try_recv_compositor_msg(&mut self) -> Option<CompositorMsg> {
self.receiver.try_recv().ok()
}
pub fn recv_compositor_msg(&mut self) -> CompositorMsg {
self.receiver.recv().unwrap()
}
}
impl CompositorProxy {
pub fn recomposite(&self, reason: CompositingReason) {
self.send(CompositorMsg::Recomposite(reason));
}
}
/// Messages from (or via) the constellation thread to the compositor.
pub enum CompositorMsg {
/// Informs the compositor that the constellation has completed shutdown.
/// Required because the constellation can have pending calls to make
/// (e.g. SetFrameTree) at the time that we send it an ExitMsg.
ShutdownComplete,
/// Alerts the compositor that the given pipeline has changed whether it is running animations.
ChangeRunningAnimationsState(PipelineId, AnimationState),
/// Replaces the current frame tree, typically called during main frame navigation.
SetFrameTree(SendableFrameTree),
/// Composite.
Recomposite(CompositingReason),
/// Script has handled a touch event, and either prevented or allowed default actions.
TouchEventProcessed(EventResult),
/// Composite to a PNG file and return the Image over a passed channel.
CreatePng(Option<Rect<f32, CSSPixel>>, IpcSender<Option<Image>>),
/// A reply to the compositor asking if the output image is stable.
IsReadyToSaveImageReply(bool),
/// Pipeline visibility changed
PipelineVisibilityChanged(PipelineId, bool),
/// WebRender has successfully processed a scroll. The boolean specifies whether a composite is
/// needed.
NewScrollFrameReady(bool),
/// A pipeline was shut down.
// This message acts as a synchronization point between the constellation,
// when it shuts down a pipeline, to the compositor; when the compositor
// sends a reply on the IpcSender, the constellation knows it's safe to
// tear down the other threads associated with this pipeline.
PipelineExited(PipelineId, IpcSender<()>),
/// Runs a closure in the compositor thread.
/// It's used to dispatch functions from webrender to the main thread's event loop.
/// Required to allow WGL GLContext sharing in Windows.
Dispatch(Box<dyn Fn() + Send>),
/// Indicates to the compositor that it needs to record the time when the frame with
/// the given ID (epoch) is painted and report it to the layout thread of the given
/// pipeline ID.
PendingPaintMetric(PipelineId, Epoch),
/// The load of a page has completed
LoadComplete(TopLevelBrowsingContextId),
/// WebDriver mouse button event
WebDriverMouseButtonEvent(MouseEventType, MouseButton, f32, f32),
/// WebDriver mouse move event
WebDriverMouseMoveEvent(f32, f32),
/// Get Window Informations size and position.
GetClientWindow(IpcSender<(DeviceIntSize, DeviceIntPoint)>),
/// Get screen size.
GetScreenSize(IpcSender<DeviceIntSize>),
/// Get screen available size.
GetScreenAvailSize(IpcSender<DeviceIntSize>),
/// Messages forwarded to the compositor by the constellation from other crates. These
/// messages are mainly passed on from the compositor to WebRender.
Forwarded(ForwardedToCompositorMsg),
}
pub struct SendableFrameTree {
pub pipeline: CompositionPipeline,
pub children: Vec<SendableFrameTree>,
}
/// The subset of the pipeline that is needed for layer composition.
#[derive(Clone)]
pub struct CompositionPipeline {
pub id: PipelineId,
pub top_level_browsing_context_id: TopLevelBrowsingContextId,
pub script_chan: IpcSender<ConstellationControlMsg>,
pub layout_chan: IpcSender<LayoutControlMsg>,
}
pub enum FontToCompositorMsg {
AddFontInstance(FontKey, f32, Sender<FontInstanceKey>),
AddFont(gfx_traits::FontData, Sender<FontKey>),
}
pub enum CanvasToCompositorMsg {
GenerateKey(Sender<ImageKey>),
UpdateImages(Vec<ImageUpdate>),
}
/// Messages forwarded by the Constellation to the Compositor.
pub enum ForwardedToCompositorMsg {
Layout(ScriptToCompositorMsg),
Net(NetToCompositorMsg),
Font(FontToCompositorMsg),
Canvas(CanvasToCompositorMsg),
}
impl Debug for CompositorMsg {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
match *self {
CompositorMsg::ShutdownComplete => write!(f, "ShutdownComplete"),
CompositorMsg::ChangeRunningAnimationsState(_, state) => {
write!(f, "ChangeRunningAnimationsState({:?})", state)
},
CompositorMsg::SetFrameTree(..) => write!(f, "SetFrameTree"),
CompositorMsg::Recomposite(..) => write!(f, "Recomposite"),
CompositorMsg::TouchEventProcessed(..) => write!(f, "TouchEventProcessed"),
CompositorMsg::CreatePng(..) => write!(f, "CreatePng"),
CompositorMsg::IsReadyToSaveImageReply(..) => write!(f, "IsReadyToSaveImageReply"),
CompositorMsg::PipelineVisibilityChanged(..) => write!(f, "PipelineVisibilityChanged"),
CompositorMsg::PipelineExited(..) => write!(f, "PipelineExited"),
CompositorMsg::NewScrollFrameReady(..) => write!(f, "NewScrollFrameReady"),
CompositorMsg::Dispatch(..) => write!(f, "Dispatch"),
CompositorMsg::PendingPaintMetric(..) => write!(f, "PendingPaintMetric"),
CompositorMsg::LoadComplete(..) => write!(f, "LoadComplete"),
CompositorMsg::WebDriverMouseButtonEvent(..) => write!(f, "WebDriverMouseButtonEvent"),
CompositorMsg::WebDriverMouseMoveEvent(..) => write!(f, "WebDriverMouseMoveEvent"),
CompositorMsg::GetClientWindow(..) => write!(f, "GetClientWindow"),
CompositorMsg::GetScreenSize(..) => write!(f, "GetScreenSize"),
CompositorMsg::GetScreenAvailSize(..) => write!(f, "GetScreenAvailSize"),
CompositorMsg::Forwarded(..) => write!(f, "Webrender"),
}
}
}