aboutsummaryrefslogtreecommitdiffstats
path: root/components/constellation/pipeline.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/constellation/pipeline.rs')
-rw-r--r--components/constellation/pipeline.rs101
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(()) => {},