aboutsummaryrefslogtreecommitdiffstats
path: root/components/constellation
diff options
context:
space:
mode:
Diffstat (limited to 'components/constellation')
-rw-r--r--components/constellation/Cargo.toml2
-rw-r--r--components/constellation/constellation.rs132
-rw-r--r--components/constellation/pipeline.rs101
3 files changed, 83 insertions, 152 deletions
diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml
index 43a4c7d982d..2f2120070d3 100644
--- a/components/constellation/Cargo.toml
+++ b/components/constellation/Cargo.toml
@@ -29,7 +29,6 @@ gfx_traits = { workspace = true }
http = { workspace = true }
ipc-channel = { workspace = true }
keyboard-types = { workspace = true }
-layout_traits = { workspace = true }
log = { workspace = true }
media = { path = "../media" }
metrics = { path = "../metrics" }
@@ -37,6 +36,7 @@ msg = { workspace = true }
net = { path = "../net" }
net_traits = { workspace = true }
profile_traits = { workspace = true }
+script_layout_interface = { workspace = true }
script_traits = { workspace = true }
serde = { workspace = true }
servo_config = { path = "../config" }
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index e7ddb5a95f5..1acd379d7bf 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -13,8 +13,7 @@
//!
//! * The set of all `Pipeline` objects. Each pipeline gives the
//! constellation's view of a `Window`, with its script thread and
-//! layout threads. Pipelines may share script threads, but not
-//! layout threads.
+//! layout. Pipelines may share script threads.
//!
//! * The set of all `BrowsingContext` objects. Each browsing context
//! gives the constellation's view of a `WindowProxy`.
@@ -45,7 +44,7 @@
//
//! The constellation also maintains channels to threads, including:
//!
-//! * The script and layout threads.
+//! * The script thread.
//! * The graphics compositor.
//! * The font cache, image cache, and resource manager, which load
//! and cache shared fonts, images, or other resources.
@@ -67,12 +66,8 @@
//! sender to send some data. Servo tries to achieve deadlock-freedom by using the following
//! can-block-on relation:
//!
-//! * Layout can block on canvas
-//! * Layout can block on font cache
-//! * Layout can block on image cache
//! * Constellation can block on compositor
//! * Constellation can block on embedder
-//! * Constellation can block on layout
//! * Script can block on anything (other than script)
//! * Blocking is transitive (if T1 can block on T2 and T2 can block on T3 then T1 can block on T3)
//! * Nothing can block on itself!
@@ -124,7 +119,6 @@ use ipc_channel::router::ROUTER;
use ipc_channel::Error as IpcError;
use keyboard_types::webdriver::Event as WebDriverInputEvent;
use keyboard_types::KeyboardEvent;
-use layout_traits::LayoutThreadFactory;
use log::{debug, error, info, trace, warn};
use media::{GLPlayerThreads, WindowGLContext};
use msg::constellation_msg::{
@@ -138,17 +132,18 @@ use net_traits::request::{Referrer, RequestBuilder};
use net_traits::storage_thread::{StorageThreadMsg, StorageType};
use net_traits::{self, FetchResponseMsg, IpcSend, ResourceThreads};
use profile_traits::{mem, time};
+use script_layout_interface::{LayoutFactory, ScriptThreadFactory};
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent};
use script_traits::{
webdriver_msg, AnimationState, AnimationTickType, AuxiliaryBrowsingContextLoadInfo,
BroadcastMsg, CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext,
DocumentActivity, DocumentState, GamepadEvent, HistoryEntryReplacement, IFrameLoadInfo,
- IFrameLoadInfoWithData, IFrameSandboxState, IFrameSizeMsg, Job, LayoutControlMsg,
- LayoutMsg as FromLayoutMsg, LoadData, LoadOrigin, LogEntry, MediaSessionActionType,
- MessagePortMsg, MouseEventType, PortMessageTask, SWManagerMsg, SWManagerSenders,
- ScriptMsg as FromScriptMsg, ScriptThreadFactory, ScriptToConstellationChan,
- ServiceWorkerManagerFactory, ServiceWorkerMsg, StructuredSerializedData, TimerSchedulerMsg,
- UpdatePipelineIdReason, WebDriverCommandMsg, WindowSizeData, WindowSizeType,
+ IFrameLoadInfoWithData, IFrameSandboxState, IFrameSizeMsg, Job, LayoutMsg as FromLayoutMsg,
+ LoadData, LoadOrigin, LogEntry, MediaSessionActionType, MessagePortMsg, MouseEventType,
+ PortMessageTask, SWManagerMsg, SWManagerSenders, ScriptMsg as FromScriptMsg,
+ ScriptToConstellationChan, ServiceWorkerManagerFactory, ServiceWorkerMsg,
+ StructuredSerializedData, TimerSchedulerMsg, UpdatePipelineIdReason, WebDriverCommandMsg,
+ WindowSizeData, WindowSizeType,
};
use serde::{Deserialize, Serialize};
use servo_config::{opts, pref};
@@ -270,7 +265,7 @@ struct BrowsingContextGroup {
/// `LayoutThread` in the `layout` crate, and `ScriptThread` in
/// the `script` crate). Script and layout communicate using a `Message`
/// type.
-pub struct Constellation<Message, LTF, STF, SWF> {
+pub struct Constellation<STF, SWF> {
/// An ipc-sender/threaded-receiver pair
/// to facilitate installing pipeline namespaces in threads
/// via a per-process installer.
@@ -302,11 +297,16 @@ pub struct Constellation<Message, LTF, STF, SWF> {
/// from the background hang monitor.
background_hang_monitor_receiver: Receiver<Result<HangMonitorAlert, IpcError>>,
- /// An IPC channel for layout threads to send messages to the constellation.
- /// This is the layout threads' view of `layout_receiver`.
+ /// A factory for creating layouts. This allows customizing the kind
+ /// of layout created for a [`Constellation`] and prevents a circular crate
+ /// dependency between script and layout.
+ layout_factory: Arc<dyn LayoutFactory>,
+
+ /// An IPC channel for layout to send messages to the constellation.
+ /// This is the layout's view of `layout_receiver`.
layout_sender: IpcSender<FromLayoutMsg>,
- /// A channel for the constellation to receive messages from layout threads.
+ /// A channel for the constellation to receive messages from layout.
/// This is the constellation's view of `layout_sender`.
layout_receiver: Receiver<Result<FromLayoutMsg, IpcError>>,
@@ -455,7 +455,7 @@ pub struct Constellation<Message, LTF, STF, SWF> {
random_pipeline_closure: Option<(ServoRng, f32)>,
/// Phantom data that keeps the Rust type system happy.
- phantom: PhantomData<(Message, LTF, STF, SWF)>,
+ phantom: PhantomData<(STF, SWF)>,
/// Entry point to create and get channels to a WebGLThread.
webgl_threads: Option<WebGLThreads>,
@@ -575,7 +575,6 @@ impl WebDriverData {
enum ReadyToSave {
NoTopLevelBrowsingContext,
PendingChanges,
- WebFontNotLoaded,
DocumentLoading,
EpochMismatch,
PipelineUnknown,
@@ -610,15 +609,15 @@ where
crossbeam_receiver
}
-impl<Message, LTF, STF, SWF> Constellation<Message, LTF, STF, SWF>
+impl<STF, SWF> Constellation<STF, SWF>
where
- LTF: LayoutThreadFactory<Message = Message>,
- STF: ScriptThreadFactory<Message = Message>,
+ STF: ScriptThreadFactory,
SWF: ServiceWorkerManagerFactory,
{
/// Create a new constellation thread.
pub fn start(
state: InitialConstellationState,
+ layout_factory: Arc<dyn LayoutFactory>,
initial_window_size: WindowSizeData,
random_pipeline_closure_probability: Option<f32>,
random_pipeline_closure_seed: Option<usize>,
@@ -738,7 +737,7 @@ where
wgpu_image_map: state.wgpu_image_map,
};
- let mut constellation: Constellation<Message, LTF, STF, SWF> = Constellation {
+ let mut constellation: Constellation<STF, SWF> = Constellation {
namespace_receiver,
namespace_ipc_sender,
script_sender: script_ipc_sender,
@@ -749,6 +748,7 @@ where
layout_sender: layout_ipc_sender,
script_receiver: script_receiver,
compositor_receiver: compositor_receiver,
+ layout_factory,
layout_receiver: layout_receiver,
network_listener_sender: network_listener_sender,
network_listener_receiver: network_listener_receiver,
@@ -1020,7 +1020,7 @@ where
self.public_resource_threads.clone()
};
- let result = Pipeline::spawn::<Message, LTF, STF>(InitialPipelineState {
+ let result = Pipeline::spawn::<STF>(InitialPipelineState {
id: pipeline_id,
browsing_context_id,
top_level_browsing_context_id,
@@ -1037,6 +1037,7 @@ where
.background_hang_monitor_sender
.clone(),
layout_to_constellation_chan: self.layout_sender.clone(),
+ layout_factory: self.layout_factory.clone(),
scheduler_chan: self.scheduler_ipc_sender.clone(),
compositor_proxy: self.compositor_proxy.clone(),
devtools_sender: self.devtools_sender.clone(),
@@ -1652,11 +1653,11 @@ where
FromScriptMsg::ScriptLoadedURLInIFrame(load_info) => {
self.handle_script_loaded_url_in_iframe_msg(load_info);
},
- FromScriptMsg::ScriptNewIFrame(load_info, response_sender) => {
- self.handle_script_new_iframe(load_info, response_sender);
+ FromScriptMsg::ScriptNewIFrame(load_info) => {
+ self.handle_script_new_iframe(load_info);
},
- FromScriptMsg::ScriptNewAuxiliary(load_info, response_sender) => {
- self.handle_script_new_auxiliary(load_info, response_sender);
+ FromScriptMsg::ScriptNewAuxiliary(load_info) => {
+ self.handle_script_new_auxiliary(load_info);
},
FromScriptMsg::ChangeRunningAnimationsState(animation_state) => {
self.handle_change_running_animations_state(source_pipeline_id, animation_state)
@@ -1737,6 +1738,13 @@ where
FromScriptMsg::SetDocumentState(state) => {
self.document_states.insert(source_pipeline_id, state);
},
+ FromScriptMsg::SetLayoutEpoch(epoch, response_sender) => {
+ if let Some(pipeline) = self.pipelines.get_mut(&source_pipeline_id) {
+ pipeline.layout_epoch = epoch;
+ }
+
+ response_sender.send(true).unwrap_or_default();
+ },
FromScriptMsg::GetClientWindow(response_sender) => {
self.compositor_proxy
.send(CompositorMsg::GetClientWindow(response_sender));
@@ -2560,6 +2568,8 @@ where
}
fn handle_exit(&mut self) {
+ debug!("Handling exit.");
+
// TODO: add a timer, which forces shutdown if threads aren't responsive.
if self.shutting_down {
return;
@@ -2638,6 +2648,8 @@ where
}
fn handle_shutdown(&mut self) {
+ debug!("Handling shutdown.");
+
// At this point, there are no active pipelines,
// so we can safely block on other threads, without worrying about deadlock.
// Channels to receive signals when threads are done exiting.
@@ -3233,11 +3245,7 @@ where
});
}
- fn handle_script_new_iframe(
- &mut self,
- load_info: IFrameLoadInfoWithData,
- layout_sender: IpcSender<LayoutControlMsg>,
- ) {
+ fn handle_script_new_iframe(&mut self, load_info: IFrameLoadInfoWithData) {
let IFrameLoadInfo {
parent_pipeline_id,
new_pipeline_id,
@@ -3274,7 +3282,6 @@ where
top_level_browsing_context_id,
None,
script_sender,
- layout_sender,
self.compositor_proxy.clone(),
is_parent_visible,
load_info.load_data,
@@ -3298,11 +3305,7 @@ where
});
}
- fn handle_script_new_auxiliary(
- &mut self,
- load_info: AuxiliaryBrowsingContextLoadInfo,
- layout_sender: IpcSender<LayoutControlMsg>,
- ) {
+ fn handle_script_new_auxiliary(&mut self, load_info: AuxiliaryBrowsingContextLoadInfo) {
let AuxiliaryBrowsingContextLoadInfo {
load_data,
opener_pipeline_id,
@@ -3337,7 +3340,6 @@ where
new_top_level_browsing_context_id,
Some(opener_browsing_context_id),
script_sender,
- layout_sender,
self.compositor_proxy.clone(),
is_opener_visible,
load_data,
@@ -4956,14 +4958,9 @@ where
return ReadyToSave::PendingChanges;
}
- let (state_sender, state_receiver) = ipc::channel().expect("Failed to create IPC channel!");
- let (epoch_ipc_sender, epoch_ipc_receiver) =
- ipc::channel().expect("Failed to create IPC channel!");
-
- // Step through the fully active browsing contexts, checking that the script
- // thread is idle, and that the current epoch of the layout thread
- // matches what the compositor has painted. If all these conditions
- // are met, then the output image should not change and a reftest
+ // Step through the fully active browsing contexts, checking that the script thread is idle,
+ // and that the current epoch of the layout matches what the compositor has painted. If all
+ // these conditions are met, then the output image should not change and a reftest
// screenshot can safely be written.
for browsing_context in
self.fully_active_browsing_contexts_iter(top_level_browsing_context_id)
@@ -4983,22 +4980,6 @@ where
Some(pipeline) => pipeline,
};
- // Check to see if there are any webfonts still loading.
- //
- // If GetWebFontLoadState returns false, either there are no
- // webfonts loading, or there's a WebFontLoaded message waiting in
- // script_chan's message queue. Therefore, we need to check this
- // before we check whether the document is ready; otherwise,
- // there's a race condition where a webfont has finished loading,
- // but hasn't yet notified the document.
- let msg = LayoutControlMsg::GetWebFontLoadState(state_sender.clone());
- if let Err(e) = pipeline.layout_chan.send(msg) {
- warn!("Get web font failed ({})", e);
- }
- if state_receiver.recv().unwrap_or(true) {
- return ReadyToSave::WebFontNotLoaded;
- }
-
// See if this pipeline has reached idle script state yet.
match self.document_states.get(&browsing_context.pipeline_id) {
Some(&DocumentState::Idle) => {},
@@ -5017,25 +4998,14 @@ where
continue;
}
- // Get the epoch that the compositor has drawn for this pipeline.
+ // Get the epoch that the compositor has drawn for this pipeline and then check if the
+ // last laid out epoch matches what the compositor has drawn. If they match (and script
+ // is idle) then this pipeline won't change again and can be considered stable.
let compositor_epoch = pipeline_states.get(&browsing_context.pipeline_id);
match compositor_epoch {
Some(compositor_epoch) => {
- // Synchronously query the layout thread to see if the current
- // epoch matches what the compositor has drawn. If they match
- // (and script is idle) then this pipeline won't change again
- // and can be considered stable.
- let message = LayoutControlMsg::GetCurrentEpoch(epoch_ipc_sender.clone());
- if let Err(e) = pipeline.layout_chan.send(message) {
- warn!("Failed to send GetCurrentEpoch ({}).", e);
- }
- match epoch_ipc_receiver.recv() {
- Err(e) => warn!("Failed to receive current epoch ({:?}).", e),
- Ok(layout_thread_epoch) => {
- if layout_thread_epoch != *compositor_epoch {
- return ReadyToSave::EpochMismatch;
- }
- },
+ if pipeline.layout_epoch != *compositor_epoch {
+ return ReadyToSave::EpochMismatch;
}
},
None => {
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(()) => {},