diff options
Diffstat (limited to 'components/constellation/pipeline.rs')
-rw-r--r-- | components/constellation/pipeline.rs | 101 |
1 files changed, 31 insertions, 70 deletions
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 061cf218789..525fca57f79 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -5,7 +5,6 @@ use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::rc::Rc; -use std::sync::atomic::AtomicBool; use std::sync::Arc; use background_hang_monitor::HangMonitorRegister; @@ -16,13 +15,12 @@ use crossbeam_channel::{unbounded, Sender}; use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg}; use embedder_traits::EventLoopWaker; use gfx::font_cache_thread::FontCacheThread; +use gfx_traits::Epoch; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; use ipc_channel::Error; -use layout_traits::LayoutThreadFactory; use log::{debug, error, warn}; use media::WindowGLContext; -use metrics::PaintTimeMetrics; use msg::constellation_msg::{ BackgroundHangMonitorControlMsg, BackgroundHangMonitorRegister, BrowsingContextId, HangMonitorAlert, HistoryStateId, PipelineId, PipelineNamespace, PipelineNamespaceId, @@ -32,10 +30,11 @@ use net::image_cache::ImageCacheImpl; use net_traits::image_cache::ImageCache; use net_traits::ResourceThreads; use profile_traits::{mem as profile_mem, time}; +use script_layout_interface::{LayoutFactory, ScriptThreadFactory}; use script_traits::{ AnimationState, ConstellationControlMsg, DiscardBrowsingContext, DocumentActivity, - InitialScriptState, LayoutControlMsg, LayoutMsg, LoadData, NewLayoutInfo, SWManagerMsg, - ScriptThreadFactory, ScriptToConstellationChan, TimerSchedulerMsg, WindowSizeData, + InitialScriptState, LayoutMsg, LoadData, NewLayoutInfo, SWManagerMsg, + ScriptToConstellationChan, TimerSchedulerMsg, WindowSizeData, }; use serde::{Deserialize, Serialize}; use servo_config::opts::{self, Opts}; @@ -47,10 +46,8 @@ use webrender_api::DocumentId; use crate::event_loop::EventLoop; use crate::sandboxing::{spawn_multiprocess, UnprivilegedContent}; -/// A `Pipeline` is the constellation's view of a `Document`. Each pipeline has an -/// event loop (executed by a script thread) and a layout thread. A script thread -/// may be responsible for many pipelines, but a layout thread is only responsible -/// for one. +/// A `Pipeline` is the constellation's view of a `Window`. Each pipeline has an event loop +/// (executed by a script thread). A script thread may be responsible for many pipelines. pub struct Pipeline { /// The ID of the pipeline. pub id: PipelineId, @@ -66,9 +63,6 @@ pub struct Pipeline { /// The event loop handling this pipeline. pub event_loop: Rc<EventLoop>, - /// A channel to layout, for performing reflows and shutdown. - pub layout_chan: IpcSender<LayoutControlMsg>, - /// A channel to the compositor. pub compositor_proxy: CompositorProxy, @@ -98,6 +92,10 @@ pub struct Pipeline { /// The title of this pipeline's document. pub title: String, + + /// The last compositor [`Epoch`] that was laid out in this pipeline if "exit after load" is + /// enabled. + pub layout_epoch: Epoch, } /// Initial setup data needed to construct a pipeline. @@ -133,9 +131,12 @@ pub struct InitialPipelineState { /// A channel for the background hang monitor to send messages to the constellation. pub background_hang_monitor_to_constellation_chan: IpcSender<HangMonitorAlert>, - /// A channel for the layout thread to send messages to the constellation. + /// A channel for the layout to send messages to the constellation. pub layout_to_constellation_chan: IpcSender<LayoutMsg>, + /// A fatory for creating layouts to be used by the ScriptThread. + pub layout_factory: Arc<dyn LayoutFactory>, + /// A channel to schedule timer events. pub scheduler_chan: IpcSender<TimerSchedulerMsg>, @@ -212,17 +213,12 @@ pub struct NewPipeline { } impl Pipeline { - /// Starts a layout thread, and possibly a script thread, in - /// a new process if requested. - pub fn spawn<Message, LTF, STF>(state: InitialPipelineState) -> Result<NewPipeline, Error> - where - LTF: LayoutThreadFactory<Message = Message>, - STF: ScriptThreadFactory<Message = Message>, - { + /// Possibly starts a script thread, in a new process if requested. + pub fn spawn<STF: ScriptThreadFactory>( + state: InitialPipelineState, + ) -> Result<NewPipeline, Error> { // Note: we allow channel creation to panic, since recovering from this // probably requires a general low-memory strategy. - let (pipeline_chan, pipeline_port) = ipc::channel().expect("Pipeline main chan"); - let (script_chan, bhm_control_chan) = match state.event_loop { Some(script_chan) => { let new_layout_info = NewLayoutInfo { @@ -233,7 +229,6 @@ impl Pipeline { opener: state.opener, load_data: state.load_data.clone(), window_size: state.window_size, - pipeline_port: pipeline_port, }; if let Err(e) = @@ -299,7 +294,6 @@ impl Pipeline { script_port: script_port, opts: (*opts::get()).clone(), prefs: prefs::pref_map().iter().collect(), - pipeline_port: pipeline_port, pipeline_namespace_id: state.pipeline_namespace_id, webrender_api_sender: state.webrender_api_sender, webrender_image_api_sender: state.webrender_image_api_sender, @@ -324,7 +318,11 @@ impl Pipeline { let register = state .background_monitor_register .expect("Couldn't start content, no background monitor has been initiated"); - unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false, register); + unprivileged_pipeline_content.start_all::<STF>( + false, + state.layout_factory, + register, + ); None }; @@ -338,7 +336,6 @@ impl Pipeline { state.top_level_browsing_context_id, state.opener, script_chan, - pipeline_chan, state.compositor_proxy, state.prev_visibility, state.load_data, @@ -349,15 +346,13 @@ impl Pipeline { }) } - /// Creates a new `Pipeline`, after the script and layout threads have been - /// spawned. + /// Creates a new `Pipeline`, after the script has been spawned. pub fn new( id: PipelineId, browsing_context_id: BrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId, opener: Option<BrowsingContextId>, event_loop: Rc<EventLoop>, - layout_chan: IpcSender<LayoutControlMsg>, compositor_proxy: CompositorProxy, is_visible: bool, load_data: LoadData, @@ -368,7 +363,6 @@ impl Pipeline { top_level_browsing_context_id: top_level_browsing_context_id, opener: opener, event_loop: event_loop, - layout_chan: layout_chan, compositor_proxy: compositor_proxy, url: load_data.url.clone(), children: vec![], @@ -378,6 +372,7 @@ impl Pipeline { history_states: HashSet::new(), completely_loaded: false, title: String::new(), + layout_epoch: Epoch(0), }; pipeline.notify_visibility(is_visible); @@ -418,9 +413,6 @@ impl Pipeline { if let Err(e) = self.event_loop.send(msg) { warn!("Sending script exit message failed ({}).", e); } - if let Err(e) = self.layout_chan.send(LayoutControlMsg::ExitNow) { - warn!("Sending layout exit message failed ({}).", e); - } } /// Notify this pipeline of its activity. @@ -437,7 +429,6 @@ impl Pipeline { id: self.id.clone(), top_level_browsing_context_id: self.top_level_browsing_context_id.clone(), script_chan: self.event_loop.sender(), - layout_chan: self.layout_chan.clone(), } } @@ -504,7 +495,6 @@ pub struct UnprivilegedPipelineContent { script_port: IpcReceiver<ConstellationControlMsg>, opts: Opts, prefs: HashMap<String, PrefValue>, - pipeline_port: IpcReceiver<LayoutControlMsg>, pipeline_namespace_id: PipelineNamespaceId, webrender_api_sender: script_traits::WebrenderIpcSender, webrender_image_api_sender: net_traits::WebrenderIpcSender, @@ -516,29 +506,19 @@ pub struct UnprivilegedPipelineContent { } impl UnprivilegedPipelineContent { - pub fn start_all<Message, LTF, STF>( + pub fn start_all<STF: ScriptThreadFactory>( self, wait_for_completion: bool, + layout_factory: Arc<dyn LayoutFactory>, background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>, - ) where - LTF: LayoutThreadFactory<Message = Message>, - STF: ScriptThreadFactory<Message = Message>, - { + ) { // Setup pipeline-namespace-installing for all threads in this process. // Idempotent in single-process mode. PipelineNamespace::set_installer_sender(self.namespace_request_sender); let image_cache = Arc::new(ImageCacheImpl::new(self.webrender_image_api_sender.clone())); - let paint_time_metrics = PaintTimeMetrics::new( - self.id, - self.time_profiler_chan.clone(), - self.layout_to_constellation_chan.clone(), - self.script_chan.clone(), - self.load_data.url.clone(), - ); let (content_process_shutdown_chan, content_process_shutdown_port) = unbounded(); - let layout_thread_busy_flag = Arc::new(AtomicBool::new(false)); - let layout_pair = STF::create( + STF::create( InitialScriptState { id: self.id, browsing_context_id: self.browsing_context_id, @@ -564,34 +544,15 @@ impl UnprivilegedPipelineContent { webxr_registry: self.webxr_registry, webrender_document: self.webrender_document, webrender_api_sender: self.webrender_api_sender.clone(), - layout_is_busy: layout_thread_busy_flag.clone(), player_context: self.player_context.clone(), inherited_secure_context: self.load_data.inherited_secure_context.clone(), }, + layout_factory, + self.font_cache_thread.clone(), self.load_data.clone(), self.user_agent, ); - LTF::create( - self.id, - self.top_level_browsing_context_id, - self.load_data.url, - self.parent_pipeline_id.is_some(), - layout_pair, - self.pipeline_port, - background_hang_monitor_register, - self.layout_to_constellation_chan, - self.script_chan, - image_cache, - self.font_cache_thread, - self.time_profiler_chan, - self.mem_profiler_chan, - self.webrender_api_sender, - paint_time_metrics, - layout_thread_busy_flag.clone(), - self.window_size, - ); - if wait_for_completion { match content_process_shutdown_port.recv() { Ok(()) => {}, |