mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
[NFC] compositing: extract types into new compositing_traits crate (#30125)
* [NFC] compositing: extract types into new compositing_traits crate * [NFC] compositing: move InitialCompositorState back to compositing * [NFC] compositing: rename Msg to CompositorMsg * [NFC] compositing: revert changes to Cargo.toml features section * [NFC] compositing: merge imports
This commit is contained in:
parent
0e7c958bd5
commit
b256a72448
16 changed files with 358 additions and 286 deletions
|
@ -17,6 +17,7 @@ gl = ["gleam", "pixels"]
|
|||
|
||||
[dependencies]
|
||||
canvas = { path = "../canvas" }
|
||||
compositing_traits = { path = "../compositing_traits" }
|
||||
crossbeam-channel = { workspace = true }
|
||||
embedder_traits = { path = "../embedder_traits" }
|
||||
euclid = { workspace = true }
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
* 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 crate::compositor_thread::CompositorReceiver;
|
||||
use crate::compositor_thread::{
|
||||
InitialCompositorState, Msg, WebrenderCanvasMsg, WebrenderFontMsg, WebrenderMsg,
|
||||
};
|
||||
#[cfg(feature = "gl")]
|
||||
use crate::gl;
|
||||
use crate::touch::{TouchAction, TouchHandler};
|
||||
use crate::windowing::{
|
||||
self, EmbedderCoordinates, MouseWindowEvent, WebRenderDebugOption, WindowMethods,
|
||||
};
|
||||
use crate::{CompositionPipeline, ConstellationMsg, SendableFrameTree};
|
||||
use crate::InitialCompositorState;
|
||||
use canvas::canvas_paint_thread::ImageUpdate;
|
||||
use compositing_traits::{
|
||||
CompositingReason, CompositionPipeline, CompositorMsg, CompositorReceiver, ConstellationMsg,
|
||||
SendableFrameTree, WebrenderCanvasMsg, WebrenderFontMsg, WebrenderMsg,
|
||||
};
|
||||
use crossbeam_channel::Sender;
|
||||
use embedder_traits::Cursor;
|
||||
use euclid::{Point2D, Rect, Scale, Vector2D};
|
||||
|
@ -475,40 +475,40 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
self.shutdown_state = ShutdownState::FinishedShuttingDown;
|
||||
}
|
||||
|
||||
fn handle_browser_message(&mut self, msg: Msg) -> bool {
|
||||
fn handle_browser_message(&mut self, msg: CompositorMsg) -> bool {
|
||||
match (msg, self.shutdown_state) {
|
||||
(_, ShutdownState::FinishedShuttingDown) => {
|
||||
error!("compositor shouldn't be handling messages after shutting down");
|
||||
return false;
|
||||
},
|
||||
|
||||
(Msg::ShutdownComplete, _) => {
|
||||
(CompositorMsg::ShutdownComplete, _) => {
|
||||
self.finish_shutting_down();
|
||||
return false;
|
||||
},
|
||||
|
||||
(
|
||||
Msg::ChangeRunningAnimationsState(pipeline_id, animation_state),
|
||||
CompositorMsg::ChangeRunningAnimationsState(pipeline_id, animation_state),
|
||||
ShutdownState::NotShuttingDown,
|
||||
) => {
|
||||
self.change_running_animations_state(pipeline_id, animation_state);
|
||||
},
|
||||
|
||||
(Msg::SetFrameTree(frame_tree), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::SetFrameTree(frame_tree), ShutdownState::NotShuttingDown) => {
|
||||
self.set_frame_tree(&frame_tree);
|
||||
self.send_scroll_positions_to_layout_for_pipeline(&frame_tree.pipeline.id);
|
||||
},
|
||||
|
||||
(Msg::Recomposite(reason), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::Recomposite(reason), ShutdownState::NotShuttingDown) => {
|
||||
self.waiting_on_pending_frame = false;
|
||||
self.composition_request = CompositionRequest::CompositeNow(reason)
|
||||
},
|
||||
|
||||
(Msg::TouchEventProcessed(result), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::TouchEventProcessed(result), ShutdownState::NotShuttingDown) => {
|
||||
self.touch_handler.on_event_processed(result);
|
||||
},
|
||||
|
||||
(Msg::CreatePng(rect, reply), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::CreatePng(rect, reply), ShutdownState::NotShuttingDown) => {
|
||||
let res = self.composite_specific_target(CompositeTarget::WindowAndPng, rect);
|
||||
if let Err(ref e) = res {
|
||||
info!("Error retrieving PNG: {:?}", e);
|
||||
|
@ -519,7 +519,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
}
|
||||
},
|
||||
|
||||
(Msg::IsReadyToSaveImageReply(is_ready), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::IsReadyToSaveImageReply(is_ready), ShutdownState::NotShuttingDown) => {
|
||||
assert_eq!(
|
||||
self.ready_to_save_state,
|
||||
ReadyState::WaitingForConstellationReply
|
||||
|
@ -540,20 +540,23 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
},
|
||||
|
||||
(
|
||||
Msg::PipelineVisibilityChanged(pipeline_id, visible),
|
||||
CompositorMsg::PipelineVisibilityChanged(pipeline_id, visible),
|
||||
ShutdownState::NotShuttingDown,
|
||||
) => {
|
||||
self.pipeline_details(pipeline_id).visible = visible;
|
||||
self.process_animations();
|
||||
},
|
||||
|
||||
(Msg::PipelineExited(pipeline_id, sender), _) => {
|
||||
(CompositorMsg::PipelineExited(pipeline_id, sender), _) => {
|
||||
debug!("Compositor got pipeline exited: {:?}", pipeline_id);
|
||||
self.remove_pipeline_root_layer(pipeline_id);
|
||||
let _ = sender.send(());
|
||||
},
|
||||
|
||||
(Msg::NewScrollFrameReady(recomposite_needed), ShutdownState::NotShuttingDown) => {
|
||||
(
|
||||
CompositorMsg::NewScrollFrameReady(recomposite_needed),
|
||||
ShutdownState::NotShuttingDown,
|
||||
) => {
|
||||
self.waiting_for_results_of_scroll = false;
|
||||
if let Some(result) = self.hit_test_at_device_point(self.cursor_pos) {
|
||||
self.update_cursor(result);
|
||||
|
@ -565,13 +568,13 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
}
|
||||
},
|
||||
|
||||
(Msg::Dispatch(func), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::Dispatch(func), ShutdownState::NotShuttingDown) => {
|
||||
// The functions sent here right now are really dumb, so they can't panic.
|
||||
// But if we start running more complex code here, we should really catch panic here.
|
||||
func();
|
||||
},
|
||||
|
||||
(Msg::LoadComplete(_), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::LoadComplete(_), ShutdownState::NotShuttingDown) => {
|
||||
// If we're painting in headless mode, schedule a recomposite.
|
||||
if self.output_file.is_some() || self.exit_after_load {
|
||||
self.composite_if_necessary(CompositingReason::Headless);
|
||||
|
@ -579,7 +582,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
},
|
||||
|
||||
(
|
||||
Msg::WebDriverMouseButtonEvent(mouse_event_type, mouse_button, x, y),
|
||||
CompositorMsg::WebDriverMouseButtonEvent(mouse_event_type, mouse_button, x, y),
|
||||
ShutdownState::NotShuttingDown,
|
||||
) => {
|
||||
let dppx = self.device_pixels_per_page_px();
|
||||
|
@ -591,29 +594,29 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
});
|
||||
},
|
||||
|
||||
(Msg::WebDriverMouseMoveEvent(x, y), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::WebDriverMouseMoveEvent(x, y), ShutdownState::NotShuttingDown) => {
|
||||
let dppx = self.device_pixels_per_page_px();
|
||||
let point = dppx.transform_point(Point2D::new(x, y));
|
||||
self.on_mouse_window_move_event_class(DevicePoint::new(point.x, point.y));
|
||||
},
|
||||
|
||||
(Msg::PendingPaintMetric(pipeline_id, epoch), _) => {
|
||||
(CompositorMsg::PendingPaintMetric(pipeline_id, epoch), _) => {
|
||||
self.pending_paint_metrics.insert(pipeline_id, epoch);
|
||||
},
|
||||
|
||||
(Msg::GetClientWindow(req), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::GetClientWindow(req), ShutdownState::NotShuttingDown) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.window) {
|
||||
warn!("Sending response to get client window failed ({:?}).", e);
|
||||
}
|
||||
},
|
||||
|
||||
(Msg::GetScreenSize(req), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::GetScreenSize(req), ShutdownState::NotShuttingDown) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.screen) {
|
||||
warn!("Sending response to get screen size failed ({:?}).", e);
|
||||
}
|
||||
},
|
||||
|
||||
(Msg::GetScreenAvailSize(req), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::GetScreenAvailSize(req), ShutdownState::NotShuttingDown) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.screen_avail) {
|
||||
warn!(
|
||||
"Sending response to get screen avail size failed ({:?}).",
|
||||
|
@ -622,7 +625,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
}
|
||||
},
|
||||
|
||||
(Msg::Webrender(msg), ShutdownState::NotShuttingDown) => {
|
||||
(CompositorMsg::Webrender(msg), ShutdownState::NotShuttingDown) => {
|
||||
self.handle_webrender_message(msg);
|
||||
},
|
||||
|
||||
|
@ -1807,8 +1810,8 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
let mut found_recomposite_msg = false;
|
||||
while let Some(msg) = self.port.try_recv_compositor_msg() {
|
||||
match msg {
|
||||
Msg::Recomposite(_) if found_recomposite_msg => {},
|
||||
Msg::Recomposite(_) => {
|
||||
CompositorMsg::Recomposite(_) if found_recomposite_msg => {},
|
||||
CompositorMsg::Recomposite(_) => {
|
||||
found_recomposite_msg = true;
|
||||
compositor_messages.push(msg)
|
||||
},
|
||||
|
@ -1858,7 +1861,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
while self.shutdown_state != ShutdownState::ShuttingDown {
|
||||
let msg = self.port.recv_compositor_msg();
|
||||
let need_recomposite = match msg {
|
||||
Msg::Recomposite(_) => true,
|
||||
CompositorMsg::Recomposite(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
let keep_going = self.handle_browser_message(msg);
|
||||
|
@ -1955,30 +1958,3 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
self.external_present = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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,
|
||||
}
|
||||
|
|
|
@ -1,190 +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/. */
|
||||
|
||||
//! Communication with the compositor thread.
|
||||
|
||||
use crate::compositor::CompositingReason;
|
||||
use crate::{ConstellationMsg, SendableFrameTree};
|
||||
use canvas::canvas_paint_thread::ImageUpdate;
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
use embedder_traits::EventLoopWaker;
|
||||
use euclid::Rect;
|
||||
use gfx_traits::Epoch;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId};
|
||||
use net_traits::image::base::Image;
|
||||
use profile_traits::mem;
|
||||
use profile_traits::time;
|
||||
use script_traits::{AnimationState, EventResult, MouseButton, MouseEventType};
|
||||
use std::fmt::{Debug, Error, Formatter};
|
||||
use std::rc::Rc;
|
||||
use style_traits::CSSPixel;
|
||||
use webrender_api::units::{DeviceIntPoint, DeviceIntSize};
|
||||
use webrender_api::{self, DocumentId, FontInstanceKey, FontKey, ImageKey, RenderApi};
|
||||
use webrender_surfman::WebrenderSurfman;
|
||||
|
||||
/// Sends messages to the compositor.
|
||||
pub struct CompositorProxy {
|
||||
pub sender: Sender<Msg>,
|
||||
pub event_loop_waker: Box<dyn EventLoopWaker>,
|
||||
}
|
||||
|
||||
impl CompositorProxy {
|
||||
pub fn send(&self, msg: Msg) {
|
||||
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<Msg>,
|
||||
}
|
||||
|
||||
impl CompositorReceiver {
|
||||
pub fn try_recv_compositor_msg(&mut self) -> Option<Msg> {
|
||||
self.receiver.try_recv().ok()
|
||||
}
|
||||
pub fn recv_compositor_msg(&mut self) -> Msg {
|
||||
self.receiver.recv().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl CompositorProxy {
|
||||
pub fn recomposite(&self, reason: CompositingReason) {
|
||||
self.send(Msg::Recomposite(reason));
|
||||
}
|
||||
}
|
||||
|
||||
/// Messages from the painting thread and the constellation thread to the compositor thread.
|
||||
pub enum Msg {
|
||||
/// 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>),
|
||||
|
||||
/// Webrender operations requested from non-compositor threads.
|
||||
Webrender(WebrenderMsg),
|
||||
}
|
||||
|
||||
pub enum WebrenderFontMsg {
|
||||
AddFontInstance(FontKey, f32, Sender<FontInstanceKey>),
|
||||
AddFont(gfx_traits::FontData, Sender<FontKey>),
|
||||
}
|
||||
|
||||
pub enum WebrenderCanvasMsg {
|
||||
GenerateKey(Sender<ImageKey>),
|
||||
UpdateImages(Vec<ImageUpdate>),
|
||||
}
|
||||
|
||||
pub enum WebrenderMsg {
|
||||
Layout(script_traits::WebrenderMsg),
|
||||
Net(net_traits::WebrenderImageMsg),
|
||||
Font(WebrenderFontMsg),
|
||||
Canvas(WebrenderCanvasMsg),
|
||||
}
|
||||
|
||||
impl Debug for Msg {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||
match *self {
|
||||
Msg::ShutdownComplete => write!(f, "ShutdownComplete"),
|
||||
Msg::ChangeRunningAnimationsState(_, state) => {
|
||||
write!(f, "ChangeRunningAnimationsState({:?})", state)
|
||||
},
|
||||
Msg::SetFrameTree(..) => write!(f, "SetFrameTree"),
|
||||
Msg::Recomposite(..) => write!(f, "Recomposite"),
|
||||
Msg::TouchEventProcessed(..) => write!(f, "TouchEventProcessed"),
|
||||
Msg::CreatePng(..) => write!(f, "CreatePng"),
|
||||
Msg::IsReadyToSaveImageReply(..) => write!(f, "IsReadyToSaveImageReply"),
|
||||
Msg::PipelineVisibilityChanged(..) => write!(f, "PipelineVisibilityChanged"),
|
||||
Msg::PipelineExited(..) => write!(f, "PipelineExited"),
|
||||
Msg::NewScrollFrameReady(..) => write!(f, "NewScrollFrameReady"),
|
||||
Msg::Dispatch(..) => write!(f, "Dispatch"),
|
||||
Msg::PendingPaintMetric(..) => write!(f, "PendingPaintMetric"),
|
||||
Msg::LoadComplete(..) => write!(f, "LoadComplete"),
|
||||
Msg::WebDriverMouseButtonEvent(..) => write!(f, "WebDriverMouseButtonEvent"),
|
||||
Msg::WebDriverMouseMoveEvent(..) => write!(f, "WebDriverMouseMoveEvent"),
|
||||
Msg::GetClientWindow(..) => write!(f, "GetClientWindow"),
|
||||
Msg::GetScreenSize(..) => write!(f, "GetScreenSize"),
|
||||
Msg::GetScreenAvailSize(..) => write!(f, "GetScreenAvailSize"),
|
||||
Msg::Webrender(..) => write!(f, "Webrender"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data used to construct a compositor.
|
||||
pub struct InitialCompositorState {
|
||||
/// A channel to the compositor.
|
||||
pub sender: CompositorProxy,
|
||||
/// A port on which messages inbound to the compositor can be received.
|
||||
pub receiver: CompositorReceiver,
|
||||
/// A channel to the constellation.
|
||||
pub constellation_chan: Sender<ConstellationMsg>,
|
||||
/// A channel to the time profiler thread.
|
||||
pub time_profiler_chan: time::ProfilerChan,
|
||||
/// A channel to the memory profiler thread.
|
||||
pub mem_profiler_chan: mem::ProfilerChan,
|
||||
/// Instance of webrender API
|
||||
pub webrender: webrender::Renderer,
|
||||
pub webrender_document: DocumentId,
|
||||
pub webrender_api: RenderApi,
|
||||
pub webrender_surfman: WebrenderSurfman,
|
||||
pub webrender_gl: Rc<dyn gleam::gl::Gl>,
|
||||
pub webxr_main_thread: webxr::MainThreadRegistry,
|
||||
}
|
|
@ -7,145 +7,41 @@
|
|||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
pub use crate::compositor::CompositingReason;
|
||||
pub use crate::compositor::IOCompositor;
|
||||
pub use crate::compositor::ShutdownState;
|
||||
pub use crate::compositor_thread::CompositorProxy;
|
||||
use embedder_traits::Cursor;
|
||||
use gfx_traits::Epoch;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use keyboard_types::KeyboardEvent;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use msg::constellation_msg::TopLevelBrowsingContextId;
|
||||
use msg::constellation_msg::{BrowsingContextId, TraversalDirection};
|
||||
use script_traits::{
|
||||
AnimationTickType, LogEntry, WebDriverCommandMsg, WindowSizeData, WindowSizeType,
|
||||
};
|
||||
use script_traits::{
|
||||
CompositorEvent, ConstellationControlMsg, LayoutControlMsg, MediaSessionActionType,
|
||||
};
|
||||
use servo_url::ServoUrl;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::time::Duration;
|
||||
|
||||
use compositing_traits::{CompositorProxy, CompositorReceiver, ConstellationMsg};
|
||||
use crossbeam_channel::Sender;
|
||||
use profile_traits::mem;
|
||||
use profile_traits::time;
|
||||
use std::rc::Rc;
|
||||
use webrender_api::DocumentId;
|
||||
use webrender_api::RenderApi;
|
||||
use webrender_surfman::WebrenderSurfman;
|
||||
|
||||
mod compositor;
|
||||
pub mod compositor_thread;
|
||||
#[cfg(feature = "gl")]
|
||||
mod gl;
|
||||
mod touch;
|
||||
pub mod windowing;
|
||||
|
||||
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>,
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
/// Data used to construct a compositor.
|
||||
pub struct InitialCompositorState {
|
||||
/// A channel to the compositor.
|
||||
pub sender: CompositorProxy,
|
||||
/// A port on which messages inbound to the compositor can be received.
|
||||
pub receiver: CompositorReceiver,
|
||||
/// A channel to the constellation.
|
||||
pub constellation_chan: Sender<ConstellationMsg>,
|
||||
/// A channel to the time profiler thread.
|
||||
pub time_profiler_chan: time::ProfilerChan,
|
||||
/// A channel to the memory profiler thread.
|
||||
pub mem_profiler_chan: mem::ProfilerChan,
|
||||
/// Instance of webrender API
|
||||
pub webrender: webrender::Renderer,
|
||||
pub webrender_document: DocumentId,
|
||||
pub webrender_api: RenderApi,
|
||||
pub webrender_surfman: WebrenderSurfman,
|
||||
pub webrender_gl: Rc<dyn gleam::gl::Gl>,
|
||||
pub webxr_main_thread: webxr::MainThreadRegistry,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue