diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 7b0314e0d54..628dff1fb9e 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -3,7 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use compositor_layer::{CompositorData, CompositorLayer, WantsScrollEventsFlag}; -use compositor_task::{CompositorEventListener, CompositorProxy, CompositorReceiver, Msg}; +use compositor_task::{CompositorEventListener, CompositorProxy}; +use compositor_task::{CompositorReceiver, InitialCompositorState, Msg}; use constellation::SendableFrameTree; use pipeline::CompositionPipeline; use scrolling::ScrollingTimerProxy; @@ -248,23 +249,19 @@ pub fn reporter_name() -> String { } impl IOCompositor { - fn new(window: Rc, - sender: Box, - receiver: Box, - constellation_chan: ConstellationChan, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan) + fn new(window: Rc, state: InitialCompositorState) -> IOCompositor { // Register this thread as a memory reporter, via its own channel. let (reporter_sender, reporter_receiver) = ipc::channel().unwrap(); - let compositor_proxy_for_memory_reporter = sender.clone_compositor_proxy(); + let compositor_proxy_for_memory_reporter = state.sender.clone_compositor_proxy(); ROUTER.add_route(reporter_receiver.to_opaque(), box move |reporter_request| { let reporter_request: ReporterRequest = reporter_request.to().unwrap(); compositor_proxy_for_memory_reporter.send(Msg::CollectMemoryReports( reporter_request.reports_channel)); }); let reporter = Reporter(reporter_sender); - mem_profiler_chan.send(mem::ProfilerMsg::RegisterReporter(reporter_name(), reporter)); + state.mem_profiler_chan.send( + mem::ProfilerMsg::RegisterReporter(reporter_name(), reporter)); let window_size = window.framebuffer_size(); let hidpi_factor = window.hidpi_factor(); @@ -276,7 +273,7 @@ impl IOCompositor { IOCompositor { window: window, native_display: native_display, - port: receiver, + port: state.receiver, context: None, root_pipeline: None, pipeline_details: HashMap::new(), @@ -286,8 +283,8 @@ impl IOCompositor { }), window_size: window_size, hidpi_factor: hidpi_factor, - channel_to_self: sender.clone_compositor_proxy(), - scrolling_timer: ScrollingTimerProxy::new(sender), + channel_to_self: state.sender.clone_compositor_proxy(), + scrolling_timer: ScrollingTimerProxy::new(state.sender), composition_request: CompositionRequest::NoCompositingNecessary, pending_scroll_events: Vec::new(), composite_target: composite_target, @@ -300,9 +297,9 @@ impl IOCompositor { zoom_time: 0f64, got_load_complete_message: false, frame_tree_id: FrameTreeId(0), - constellation_chan: constellation_chan, - time_profiler_chan: time_profiler_chan, - mem_profiler_chan: mem_profiler_chan, + constellation_chan: state.constellation_chan, + time_profiler_chan: state.time_profiler_chan, + mem_profiler_chan: state.mem_profiler_chan, fragment_point: None, last_composite_time: 0, has_seen_quit_event: false, @@ -311,19 +308,9 @@ impl IOCompositor { } } - pub fn create(window: Rc, - sender: Box, - receiver: Box, - constellation_chan: ConstellationChan, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan) + pub fn create(window: Rc, state: InitialCompositorState) -> IOCompositor { - let mut compositor = IOCompositor::new(window, - sender, - receiver, - constellation_chan, - time_profiler_chan, - mem_profiler_chan); + let mut compositor = IOCompositor::new(window, state); // Set the size of the root layer. compositor.update_zoom_transform(); diff --git a/components/compositing/compositor_task.rs b/components/compositing/compositor_task.rs index 56f007d8fa1..eaf0645d2df 100644 --- a/components/compositing/compositor_task.rs +++ b/components/compositing/compositor_task.rs @@ -260,28 +260,16 @@ pub struct CompositorTask; impl CompositorTask { pub fn create(window: Option>, - sender: Box, - receiver: Box, - constellation_chan: ConstellationChan, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan) + state: InitialCompositorState) -> Box where Window: WindowMethods + 'static { match window { Some(window) => { - box compositor::IOCompositor::create(window, - sender, - receiver, - constellation_chan, - time_profiler_chan, - mem_profiler_chan) + box compositor::IOCompositor::create(window, state) as Box } None => { - box headless::NullCompositor::create(receiver, - constellation_chan, - time_profiler_chan, - mem_profiler_chan) + box headless::NullCompositor::create(state) as Box } } @@ -296,3 +284,17 @@ pub trait CompositorEventListener { /// Requests that the compositor send the title for the main frame as soon as possible. fn title_for_main_frame(&self); } + +/// Data used to construct a compositor. +pub struct InitialCompositorState { + /// A channel to the compositor. + pub sender: Box, + /// A port on which messages inbound to the compositor can be received. + pub receiver: Box, + /// A channel to the constellation. + pub constellation_chan: ConstellationChan, + /// 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, +} diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index 716bd2a5898..46088f4dc09 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -9,7 +9,7 @@ //! navigation context, each `Pipeline` encompassing a `ScriptTask`, //! `LayoutTask`, and `PaintTask`. -use pipeline::{Pipeline, CompositionPipeline}; +use pipeline::{Pipeline, CompositionPipeline, InitialPipelineState}; use canvas::canvas_paint_task::CanvasPaintTask; use canvas::webgl_paint_task::WebGLPaintTask; @@ -139,6 +139,28 @@ pub struct Constellation { webgl_paint_tasks: Vec>, } +/// State needed to construct a constellation. +pub struct InitialConstellationState { + /// A channel through which messages can be sent to the compositor. + pub compositor_proxy: Box, + /// A channel to the developer tools, if applicable. + pub devtools_chan: Option>, + /// A channel to the image cache task. + pub image_cache_task: ImageCacheTask, + /// A channel to the font cache task. + pub font_cache_task: FontCacheTask, + /// A channel to the resource task. + pub resource_task: ResourceTask, + /// A channel to the storage task. + pub storage_task: StorageTask, + /// 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, + /// Whether the constellation supports the clipboard. + pub supports_clipboard: bool, +} + /// Stores the navigation context for a single frame in the frame tree. pub struct Frame { prev: Vec, @@ -219,28 +241,19 @@ enum ExitPipelineMode { } impl Constellation { - pub fn start(compositor_proxy: Box, - resource_task: ResourceTask, - image_cache_task: ImageCacheTask, - font_cache_task: FontCacheTask, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan, - devtools_chan: Option>, - storage_task: StorageTask, - supports_clipboard: bool) - -> ConstellationChan { + pub fn start(state: InitialConstellationState) -> ConstellationChan { let (constellation_port, constellation_chan) = ConstellationChan::new(); let constellation_chan_clone = constellation_chan.clone(); spawn_named("Constellation".to_owned(), move || { let mut constellation: Constellation = Constellation { chan: constellation_chan_clone, request_port: constellation_port, - compositor_proxy: compositor_proxy, - devtools_chan: devtools_chan, - resource_task: resource_task, - image_cache_task: image_cache_task, - font_cache_task: font_cache_task, - storage_task: storage_task, + compositor_proxy: state.compositor_proxy, + devtools_chan: state.devtools_chan, + resource_task: state.resource_task, + image_cache_task: state.image_cache_task, + font_cache_task: state.font_cache_task, + storage_task: state.storage_task, pipelines: HashMap::new(), frames: HashMap::new(), pipeline_to_frame_map: HashMap::new(), @@ -250,8 +263,8 @@ impl Constellation { root_frame_id: None, next_frame_id: FrameId(0), focus_pipeline_id: None, - time_profiler_chan: time_profiler_chan, - mem_profiler_chan: mem_profiler_chan, + time_profiler_chan: state.time_profiler_chan, + mem_profiler_chan: state.mem_profiler_chan, window_size: WindowSizeData { visible_viewport: opts::get().initial_window_size.as_f32() * ScaleFactor::new(1.0), @@ -260,7 +273,7 @@ impl Constellation { device_pixel_ratio: ScaleFactor::new(1.0), }, phantom: PhantomData, - clipboard_ctx: if supports_clipboard { + clipboard_ctx: if state.supports_clipboard { ClipboardContext::new().ok() } else { None @@ -296,21 +309,23 @@ impl Constellation { let spawning_paint_only = script_channel.is_some(); let (pipeline, mut pipeline_content) = - Pipeline::create::(pipeline_id, - parent_info, - self.chan.clone(), - self.compositor_proxy.clone_compositor_proxy(), - self.devtools_chan.clone(), - self.image_cache_task.clone(), - self.font_cache_task.clone(), - self.resource_task.clone(), - self.storage_task.clone(), - self.time_profiler_chan.clone(), - self.mem_profiler_chan.clone(), - initial_window_rect, - script_channel, - load_data, - self.window_size.device_pixel_ratio); + Pipeline::create::(InitialPipelineState { + id: pipeline_id, + parent_info: parent_info, + constellation_chan: self.chan.clone(), + compositor_proxy: self.compositor_proxy.clone_compositor_proxy(), + devtools_chan: self.devtools_chan.clone(), + image_cache_task: self.image_cache_task.clone(), + font_cache_task: self.font_cache_task.clone(), + resource_task: self.resource_task.clone(), + storage_task: self.storage_task.clone(), + time_profiler_chan: self.time_profiler_chan.clone(), + mem_profiler_chan: self.mem_profiler_chan.clone(), + window_rect: initial_window_rect, + script_chan: script_channel, + load_data: load_data, + device_pixel_ratio: self.window_size.device_pixel_ratio, + }); // TODO(pcwalton): In multiprocess mode, send that `PipelineContent` instance over to // the content process and call this over there. diff --git a/components/compositing/headless.rs b/components/compositing/headless.rs index 0fa3ad5d04b..c5216152095 100644 --- a/components/compositing/headless.rs +++ b/components/compositing/headless.rs @@ -2,7 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use compositor_task::{CompositorEventListener, CompositorReceiver, Msg}; +use compositor_task::{CompositorEventListener, CompositorReceiver}; +use compositor_task::{InitialCompositorState, Msg}; use windowing::WindowEvent; use euclid::scale_factor::ScaleFactor; @@ -29,28 +30,17 @@ pub struct NullCompositor { } impl NullCompositor { - fn new(port: Box, - constellation_chan: ConstellationChan, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan) - -> NullCompositor { + fn new(state: InitialCompositorState) -> NullCompositor { NullCompositor { - port: port, - constellation_chan: constellation_chan, - time_profiler_chan: time_profiler_chan, - mem_profiler_chan: mem_profiler_chan, + port: state.receiver, + constellation_chan: state.constellation_chan, + time_profiler_chan: state.time_profiler_chan, + mem_profiler_chan: state.mem_profiler_chan, } } - pub fn create(port: Box, - constellation_chan: ConstellationChan, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan) - -> NullCompositor { - let compositor = NullCompositor::new(port, - constellation_chan, - time_profiler_chan, - mem_profiler_chan); + pub fn create(state: InitialCompositorState) -> NullCompositor { + let compositor = NullCompositor::new(state); // Tell the constellation about the initial fake size. { diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs index 6f6372f3979..c30eab7e9b0 100644 --- a/components/compositing/pipeline.rs +++ b/components/compositing/pipeline.rs @@ -4,8 +4,8 @@ use CompositorProxy; use layout_traits::{LayoutTaskFactory, LayoutControlChan}; -use script_traits::{LayoutControlMsg, ScriptTaskFactory}; -use script_traits::{NewLayoutInfo, ConstellationControlMsg}; +use script_traits::{ConstellationControlMsg, InitialScriptState}; +use script_traits::{LayoutControlMsg, NewLayoutInfo, ScriptTaskFactory}; use compositor_task; use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg}; @@ -63,25 +63,46 @@ pub struct CompositionPipeline { pub chrome_to_paint_chan: Sender, } +/// Initial setup data needed to construct a pipeline. +pub struct InitialPipelineState { + /// The ID of the pipeline to create. + pub id: PipelineId, + /// The subpage ID of this pipeline to create in its pipeline parent. + /// If `None`, this is the root. + pub parent_info: Option<(PipelineId, SubpageId)>, + /// A channel to the associated constellation. + pub constellation_chan: ConstellationChan, + /// A channel to the compositor. + pub compositor_proxy: Box, + /// A channel to the developer tools, if applicable. + pub devtools_chan: Option>, + /// A channel to the image cache task. + pub image_cache_task: ImageCacheTask, + /// A channel to the font cache task. + pub font_cache_task: FontCacheTask, + /// A channel to the resource task. + pub resource_task: ResourceTask, + /// A channel to the storage task. + pub storage_task: StorageTask, + /// A channel to the time profiler thread. + pub time_profiler_chan: time::ProfilerChan, + /// A channel to the memory profiler thread. + pub mem_profiler_chan: profile_mem::ProfilerChan, + /// Information about the initial window size. + pub window_rect: Option>, + /// Information about the device pixel ratio. + pub device_pixel_ratio: ScaleFactor, + /// A channel to the script thread, if applicable. If this is `Some`, + /// then `parent_info` must also be `Some`. + pub script_chan: Option>, + /// Information about the page to load. + pub load_data: LoadData, +} + impl Pipeline { /// Starts a paint task, layout task, and possibly a script task. /// Returns the channels wrapped in a struct. - /// If script_pipeline is not None, then subpage_id must also be not None. - pub fn create(id: PipelineId, - parent_info: Option<(PipelineId, SubpageId)>, - constellation_chan: ConstellationChan, - compositor_proxy: Box, - devtools_chan: Option>, - image_cache_task: ImageCacheTask, - font_cache_task: FontCacheTask, - resource_task: ResourceTask, - storage_task: StorageTask, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: profile_mem::ProfilerChan, - window_rect: Option>, - script_chan: Option>, - load_data: LoadData, - device_pixel_ratio: ScaleFactor) + pub fn create(state: InitialPipelineState) -> (Pipeline, PipelineContent) where LTF: LayoutTaskFactory, STF: ScriptTaskFactory { let (layout_to_paint_chan, layout_to_paint_port) = util::ipc::optional_ipc_channel(); @@ -92,20 +113,20 @@ impl Pipeline { let mut pipeline_port = Some(pipeline_port); let failure = Failure { - pipeline_id: id, - parent_info: parent_info, + pipeline_id: state.id, + parent_info: state.parent_info, }; - let window_size = window_rect.map(|rect| { + let window_size = state.window_rect.map(|rect| { WindowSizeData { visible_viewport: rect.size, initial_viewport: rect.size * ScaleFactor::new(1.0), - device_pixel_ratio: device_pixel_ratio, + device_pixel_ratio: state.device_pixel_ratio, } }); // Route messages coming from content to devtools as appropriate. - let script_to_devtools_chan = devtools_chan.as_ref().map(|devtools_chan| { + let script_to_devtools_chan = state.devtools_chan.as_ref().map(|devtools_chan| { let (script_to_devtools_chan, script_to_devtools_port) = ipc::channel().unwrap(); let devtools_chan = (*devtools_chan).clone(); ROUTER.add_route(script_to_devtools_port.to_opaque(), box move |message| { @@ -115,15 +136,15 @@ impl Pipeline { script_to_devtools_chan }); - let (script_chan, script_port) = match script_chan { + let (script_chan, script_port) = match state.script_chan { Some(script_chan) => { let (containing_pipeline_id, subpage_id) = - parent_info.expect("script_pipeline != None but subpage_id == None"); + state.parent_info.expect("script_pipeline != None but subpage_id == None"); let new_layout_info = NewLayoutInfo { containing_pipeline_id: containing_pipeline_id, - new_pipeline_id: id, + new_pipeline_id: state.id, subpage_id: subpage_id, - load_data: load_data.clone(), + load_data: state.load_data.clone(), paint_chan: box layout_to_paint_chan.clone() as Box, failure: failure, pipeline_port: mem::replace(&mut pipeline_port, None).unwrap(), @@ -140,31 +161,31 @@ impl Pipeline { } }; - let pipeline = Pipeline::new(id, - parent_info, + let pipeline = Pipeline::new(state.id, + state.parent_info, script_chan.clone(), LayoutControlChan(pipeline_chan), chrome_to_paint_chan.clone(), layout_shutdown_port, paint_shutdown_port, - load_data.url.clone(), - window_rect); + state.load_data.url.clone(), + state.window_rect); let pipeline_content = PipelineContent { - id: id, - parent_info: parent_info, - constellation_chan: constellation_chan, - compositor_proxy: compositor_proxy, + id: state.id, + parent_info: state.parent_info, + constellation_chan: state.constellation_chan, + compositor_proxy: state.compositor_proxy, devtools_chan: script_to_devtools_chan, - image_cache_task: image_cache_task, - font_cache_task: font_cache_task, - resource_task: resource_task, - storage_task: storage_task, - time_profiler_chan: time_profiler_chan, - mem_profiler_chan: mem_profiler_chan, + image_cache_task: state.image_cache_task, + font_cache_task: state.font_cache_task, + resource_task: state.resource_task, + storage_task: state.storage_task, + time_profiler_chan: state.time_profiler_chan, + mem_profiler_chan: state.mem_profiler_chan, window_size: window_size, script_chan: script_chan, - load_data: load_data, + load_data: state.load_data, failure: failure, script_port: script_port, layout_to_paint_chan: layout_to_paint_chan, @@ -319,23 +340,22 @@ impl PipelineContent { script_to_compositor_port) }); - ScriptTaskFactory::create(None::<&mut STF>, - self.id, - self.parent_info, - script_to_compositor_chan, - &layout_pair, - self.script_chan.clone(), - mem::replace(&mut self.script_port, None).unwrap(), - self.constellation_chan.clone(), - self.failure.clone(), - self.resource_task, - self.storage_task.clone(), - self.image_cache_task.clone(), - self.time_profiler_chan.clone(), - self.mem_profiler_chan.clone(), - self.devtools_chan, - self.window_size, - self.load_data.clone()); + ScriptTaskFactory::create(None::<&mut STF>, InitialScriptState { + id: self.id, + parent_info: self.parent_info, + compositor: script_to_compositor_chan, + control_chan: self.script_chan.clone(), + control_port: mem::replace(&mut self.script_port, None).unwrap(), + constellation_chan: self.constellation_chan.clone(), + failure_info: self.failure.clone(), + resource_task: self.resource_task, + storage_task: self.storage_task.clone(), + image_cache_task: self.image_cache_task.clone(), + time_profiler_chan: self.time_profiler_chan.clone(), + mem_profiler_chan: self.mem_profiler_chan.clone(), + devtools_chan: self.devtools_chan, + window_size: self.window_size, + }, &layout_pair, self.load_data.clone()); LayoutTaskFactory::create(None::<&mut LTF>, self.id, diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 3d0c4e7c65e..3914e5ff9d2 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -54,9 +54,9 @@ use devtools_traits::ScriptToDevtoolsControlMsg; use devtools_traits::{DevtoolsPageInfo, DevtoolScriptControlMsg}; use msg::compositor_msg::{LayerId, ScriptToCompositorMsg}; use msg::constellation_msg::Msg as ConstellationMsg; -use msg::constellation_msg::{ConstellationChan, FocusType}; -use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType}; -use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId}; +use msg::constellation_msg::{ConstellationChan, FocusType, LoadData}; +use msg::constellation_msg::{MozBrowserEvent, PipelineExitType, PipelineId}; +use msg::constellation_msg::{SubpageId, WindowSizeData, WorkerId}; use msg::webdriver_msg::WebDriverScriptCommand; use net_traits::LoadData as NetLoadData; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult}; @@ -67,10 +67,9 @@ use profile_traits::time::{self, ProfilerCategory, profile}; use script_traits::CompositorEvent::{MouseDownEvent, MouseUpEvent}; use script_traits::CompositorEvent::{MouseMoveEvent, KeyEvent}; use script_traits::CompositorEvent::{ResizeEvent, ClickEvent}; -use script_traits::ConstellationControlMsg; -use script_traits::{CompositorEvent, MouseButton}; -use script_traits::{NewLayoutInfo, OpaqueScriptLayoutChannel}; -use script_traits::{ScriptState, ScriptTaskFactory}; +use script_traits::{CompositorEvent, ConstellationControlMsg}; +use script_traits::{InitialScriptState, MouseButton, NewLayoutInfo}; +use script_traits::{OpaqueScriptLayoutChannel, ScriptState, ScriptTaskFactory}; use string_cache::Atom; use util::opts; use util::str::DOMString; @@ -466,42 +465,25 @@ impl ScriptTaskFactory for ScriptTask { } fn create(_phantom: Option<&mut ScriptTask>, - id: PipelineId, - parent_info: Option<(PipelineId, SubpageId)>, - compositor: IpcSender, + state: InitialScriptState, layout_chan: &OpaqueScriptLayoutChannel, - control_chan: Sender, - control_port: Receiver, - constellation_chan: ConstellationChan, - failure_msg: Failure, - resource_task: ResourceTask, - storage_task: StorageTask, - image_cache_task: ImageCacheTask, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan, - devtools_chan: Option>, - window_size: Option, load_data: LoadData) { - let ConstellationChan(const_chan) = constellation_chan.clone(); + let ConstellationChan(const_chan) = state.constellation_chan.clone(); let (script_chan, script_port) = channel(); let layout_chan = LayoutChan(layout_chan.sender()); - spawn_named_with_send_on_failure(format!("ScriptTask {:?}", id), task_state::SCRIPT, move || { + let failure_info = state.failure_info; + spawn_named_with_send_on_failure(format!("ScriptTask {:?}", state.id), task_state::SCRIPT, move || { let roots = RootCollection::new(); let _stack_roots_tls = StackRootTLS::new(&roots); let chan = MainThreadScriptChan(script_chan); let channel_for_reporter = chan.clone(); - let script_task = ScriptTask::new(compositor, + let id = state.id; + let parent_info = state.parent_info; + let mem_profiler_chan = state.mem_profiler_chan.clone(); + let window_size = state.window_size; + let script_task = ScriptTask::new(state, script_port, - chan, - control_chan, - control_port, - constellation_chan, - Arc::new(resource_task), - storage_task, - image_cache_task, - time_profiler_chan.clone(), - mem_profiler_chan.clone(), - devtools_chan); + chan); SCRIPT_TASK_ROOT.with(|root| { *root.borrow_mut() = Some(&script_task as *const _); @@ -520,7 +502,7 @@ impl ScriptTaskFactory for ScriptTask { // This must always be the very last operation performed before the task completes failsafe.neuter(); - }, ConstellationMsg::Failure(failure_msg), const_chan); + }, ConstellationMsg::Failure(failure_info), const_chan); } } @@ -606,18 +588,9 @@ impl ScriptTask { } /// Creates a new script task. - pub fn new(compositor: IpcSender, + pub fn new(state: InitialScriptState, port: Receiver, - chan: MainThreadScriptChan, - control_chan: Sender, - control_port: Receiver, - constellation_chan: ConstellationChan, - resource_task: Arc, - storage_task: StorageTask, - image_cache_task: ImageCacheTask, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan, - devtools_chan: Option>) + chan: MainThreadScriptChan) -> ScriptTask { let runtime = ScriptTask::new_rt_and_cx(); @@ -639,23 +612,23 @@ impl ScriptTask { page: DOMRefCell::new(None), incomplete_loads: DOMRefCell::new(vec!()), - image_cache_task: image_cache_task, + image_cache_task: state.image_cache_task, image_cache_channel: ImageCacheChan(ipc_image_cache_channel), image_cache_port: image_cache_port, - resource_task: resource_task, - storage_task: storage_task, + resource_task: Arc::new(state.resource_task), + storage_task: state.storage_task, port: port, chan: chan, - control_chan: control_chan, - control_port: control_port, - constellation_chan: constellation_chan, - compositor: DOMRefCell::new(compositor), - time_profiler_chan: time_profiler_chan, - mem_profiler_chan: mem_profiler_chan, + control_chan: state.control_chan, + control_port: state.control_port, + constellation_chan: state.constellation_chan, + compositor: DOMRefCell::new(state.compositor), + time_profiler_chan: state.time_profiler_chan, + mem_profiler_chan: state.mem_profiler_chan, - devtools_chan: devtools_chan, + devtools_chan: state.devtools_chan, devtools_port: devtools_port, devtools_sender: ipc_devtools_sender, diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index a25bfc4fb08..87f336265a8 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -171,26 +171,46 @@ pub enum CompositorEvent { /// crates that don't need to know about them. pub struct OpaqueScriptLayoutChannel(pub (Box, Box)); +/// Data needed to construct a script thread. +pub struct InitialScriptState { + /// The ID of the pipeline with which this script thread is associated. + pub id: PipelineId, + /// The subpage ID of this pipeline to create in its pipeline parent. + /// If `None`, this is the root. + pub parent_info: Option<(PipelineId, SubpageId)>, + /// The compositor. + pub compositor: IpcSender, + /// A channel with which messages can be sent to us (the script task). + pub control_chan: Sender, + /// A port on which messages sent by the constellation to script can be received. + pub control_port: Receiver, + /// A channel on which messages can be sent to the constellation from script. + pub constellation_chan: ConstellationChan, + /// Information that script sends out when it panics. + pub failure_info: Failure, + /// A channel to the resource manager task. + pub resource_task: ResourceTask, + /// A channel to the storage task. + pub storage_task: StorageTask, + /// A channel to the image cache task. + pub image_cache_task: ImageCacheTask, + /// 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, + /// A channel to the developer tools, if applicable. + pub devtools_chan: Option>, + /// Information about the initial window size. + pub window_size: Option, +} + /// This trait allows creating a `ScriptTask` without depending on the `script` /// crate. pub trait ScriptTaskFactory { /// Create a `ScriptTask`. fn create(_phantom: Option<&mut Self>, - id: PipelineId, - parent_info: Option<(PipelineId, SubpageId)>, - compositor: IpcSender, + state: InitialScriptState, layout_chan: &OpaqueScriptLayoutChannel, - control_chan: Sender, - control_port: Receiver, - constellation_msg: ConstellationChan, - failure_msg: Failure, - resource_task: ResourceTask, - storage_task: StorageTask, - image_cache_task: ImageCacheTask, - time_profiler_chan: time::ProfilerChan, - mem_profiler_chan: mem::ProfilerChan, - devtools_chan: Option>, - window_size: Option, load_data: LoadData); /// Create a script -> layout channel (`Sender`, `Receiver` pair). fn create_layout_channel(_phantom: Option<&mut Self>) -> OpaqueScriptLayoutChannel; diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 47cb2fd9ab6..4dcf43c6a10 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -81,6 +81,8 @@ pub use export::gleam::gl; use compositing::CompositorEventListener; use compositing::windowing::WindowEvent; +use compositing::compositor_task::InitialCompositorState; +use compositing::constellation::InitialConstellationState; use compositing::windowing::WindowMethods; use compositing::{CompositorProxy, CompositorTask, Constellation}; @@ -163,12 +165,13 @@ impl Browser { // The compositor coordinates with the client window to create the final // rendered page and display it somewhere. - let compositor = CompositorTask::create(window, - compositor_proxy, - compositor_receiver, - constellation_chan, - time_profiler_chan, - mem_profiler_chan); + let compositor = CompositorTask::create(window, InitialCompositorState { + sender: compositor_proxy, + receiver: compositor_receiver, + constellation_chan: constellation_chan, + time_profiler_chan: time_profiler_chan, + mem_profiler_chan: mem_profiler_chan, + }); Browser { compositor: compositor, @@ -208,17 +211,20 @@ fn create_constellation(opts: opts::Opts, let font_cache_task = FontCacheTask::new(resource_task.clone()); let storage_task: StorageTask = StorageTaskFactory::new(); - let constellation_chan = Constellation::::start( - compositor_proxy, - resource_task, - image_cache_task, - font_cache_task, - time_profiler_chan, - mem_profiler_chan, - devtools_chan, - storage_task, - supports_clipboard); + let initial_state = InitialConstellationState { + compositor_proxy: compositor_proxy, + devtools_chan: devtools_chan, + image_cache_task: image_cache_task, + font_cache_task: font_cache_task, + resource_task: resource_task, + storage_task: storage_task, + time_profiler_chan: time_profiler_chan, + mem_profiler_chan: mem_profiler_chan, + supports_clipboard: supports_clipboard, + }; + let constellation_chan = + Constellation::::start(initial_state); // Send the URL command to the constellation. match opts.url {