Auto merge of #7645 - nox:omtc-types, r=Ms2ger

Introduce structs for compositing and script task constructors' arguments

Extracted from @pcwalton's #4271.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7645)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-09-16 10:41:10 -06:00
commit 2879da54f9
8 changed files with 255 additions and 242 deletions

View file

@ -3,7 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use compositor_layer::{CompositorData, CompositorLayer, WantsScrollEventsFlag}; 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 constellation::SendableFrameTree;
use pipeline::CompositionPipeline; use pipeline::CompositionPipeline;
use scrolling::ScrollingTimerProxy; use scrolling::ScrollingTimerProxy;
@ -248,23 +249,19 @@ pub fn reporter_name() -> String {
} }
impl<Window: WindowMethods> IOCompositor<Window> { impl<Window: WindowMethods> IOCompositor<Window> {
fn new(window: Rc<Window>, fn new(window: Rc<Window>, state: InitialCompositorState)
sender: Box<CompositorProxy + Send>,
receiver: Box<CompositorReceiver>,
constellation_chan: ConstellationChan,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan)
-> IOCompositor<Window> { -> IOCompositor<Window> {
// Register this thread as a memory reporter, via its own channel. // Register this thread as a memory reporter, via its own channel.
let (reporter_sender, reporter_receiver) = ipc::channel().unwrap(); 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| { ROUTER.add_route(reporter_receiver.to_opaque(), box move |reporter_request| {
let reporter_request: ReporterRequest = reporter_request.to().unwrap(); let reporter_request: ReporterRequest = reporter_request.to().unwrap();
compositor_proxy_for_memory_reporter.send(Msg::CollectMemoryReports( compositor_proxy_for_memory_reporter.send(Msg::CollectMemoryReports(
reporter_request.reports_channel)); reporter_request.reports_channel));
}); });
let reporter = Reporter(reporter_sender); 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 window_size = window.framebuffer_size();
let hidpi_factor = window.hidpi_factor(); let hidpi_factor = window.hidpi_factor();
@ -276,7 +273,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
IOCompositor { IOCompositor {
window: window, window: window,
native_display: native_display, native_display: native_display,
port: receiver, port: state.receiver,
context: None, context: None,
root_pipeline: None, root_pipeline: None,
pipeline_details: HashMap::new(), pipeline_details: HashMap::new(),
@ -286,8 +283,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}), }),
window_size: window_size, window_size: window_size,
hidpi_factor: hidpi_factor, hidpi_factor: hidpi_factor,
channel_to_self: sender.clone_compositor_proxy(), channel_to_self: state.sender.clone_compositor_proxy(),
scrolling_timer: ScrollingTimerProxy::new(sender), scrolling_timer: ScrollingTimerProxy::new(state.sender),
composition_request: CompositionRequest::NoCompositingNecessary, composition_request: CompositionRequest::NoCompositingNecessary,
pending_scroll_events: Vec::new(), pending_scroll_events: Vec::new(),
composite_target: composite_target, composite_target: composite_target,
@ -300,9 +297,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
zoom_time: 0f64, zoom_time: 0f64,
got_load_complete_message: false, got_load_complete_message: false,
frame_tree_id: FrameTreeId(0), frame_tree_id: FrameTreeId(0),
constellation_chan: constellation_chan, constellation_chan: state.constellation_chan,
time_profiler_chan: time_profiler_chan, time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: mem_profiler_chan, mem_profiler_chan: state.mem_profiler_chan,
fragment_point: None, fragment_point: None,
last_composite_time: 0, last_composite_time: 0,
has_seen_quit_event: false, has_seen_quit_event: false,
@ -311,19 +308,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
} }
} }
pub fn create(window: Rc<Window>, pub fn create(window: Rc<Window>, state: InitialCompositorState)
sender: Box<CompositorProxy + Send>,
receiver: Box<CompositorReceiver>,
constellation_chan: ConstellationChan,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan)
-> IOCompositor<Window> { -> IOCompositor<Window> {
let mut compositor = IOCompositor::new(window, let mut compositor = IOCompositor::new(window, state);
sender,
receiver,
constellation_chan,
time_profiler_chan,
mem_profiler_chan);
// Set the size of the root layer. // Set the size of the root layer.
compositor.update_zoom_transform(); compositor.update_zoom_transform();

View file

@ -260,28 +260,16 @@ pub struct CompositorTask;
impl CompositorTask { impl CompositorTask {
pub fn create<Window>(window: Option<Rc<Window>>, pub fn create<Window>(window: Option<Rc<Window>>,
sender: Box<CompositorProxy + Send>, state: InitialCompositorState)
receiver: Box<CompositorReceiver>,
constellation_chan: ConstellationChan,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan)
-> Box<CompositorEventListener + 'static> -> Box<CompositorEventListener + 'static>
where Window: WindowMethods + 'static { where Window: WindowMethods + 'static {
match window { match window {
Some(window) => { Some(window) => {
box compositor::IOCompositor::create(window, box compositor::IOCompositor::create(window, state)
sender,
receiver,
constellation_chan,
time_profiler_chan,
mem_profiler_chan)
as Box<CompositorEventListener> as Box<CompositorEventListener>
} }
None => { None => {
box headless::NullCompositor::create(receiver, box headless::NullCompositor::create(state)
constellation_chan,
time_profiler_chan,
mem_profiler_chan)
as Box<CompositorEventListener> as Box<CompositorEventListener>
} }
} }
@ -296,3 +284,17 @@ pub trait CompositorEventListener {
/// Requests that the compositor send the title for the main frame as soon as possible. /// Requests that the compositor send the title for the main frame as soon as possible.
fn title_for_main_frame(&self); fn title_for_main_frame(&self);
} }
/// Data used to construct a compositor.
pub struct InitialCompositorState {
/// A channel to the compositor.
pub sender: Box<CompositorProxy + Send>,
/// A port on which messages inbound to the compositor can be received.
pub receiver: Box<CompositorReceiver>,
/// 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,
}

View file

@ -9,7 +9,7 @@
//! navigation context, each `Pipeline` encompassing a `ScriptTask`, //! navigation context, each `Pipeline` encompassing a `ScriptTask`,
//! `LayoutTask`, and `PaintTask`. //! `LayoutTask`, and `PaintTask`.
use pipeline::{Pipeline, CompositionPipeline}; use pipeline::{Pipeline, CompositionPipeline, InitialPipelineState};
use canvas::canvas_paint_task::CanvasPaintTask; use canvas::canvas_paint_task::CanvasPaintTask;
use canvas::webgl_paint_task::WebGLPaintTask; use canvas::webgl_paint_task::WebGLPaintTask;
@ -139,6 +139,28 @@ pub struct Constellation<LTF, STF> {
webgl_paint_tasks: Vec<Sender<CanvasMsg>>, webgl_paint_tasks: Vec<Sender<CanvasMsg>>,
} }
/// State needed to construct a constellation.
pub struct InitialConstellationState {
/// A channel through which messages can be sent to the compositor.
pub compositor_proxy: Box<CompositorProxy + Send>,
/// A channel to the developer tools, if applicable.
pub devtools_chan: Option<Sender<DevtoolsControlMsg>>,
/// 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. /// Stores the navigation context for a single frame in the frame tree.
pub struct Frame { pub struct Frame {
prev: Vec<PipelineId>, prev: Vec<PipelineId>,
@ -219,28 +241,19 @@ enum ExitPipelineMode {
} }
impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
pub fn start(compositor_proxy: Box<CompositorProxy + Send>, pub fn start(state: InitialConstellationState) -> ConstellationChan {
resource_task: ResourceTask,
image_cache_task: ImageCacheTask,
font_cache_task: FontCacheTask,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
storage_task: StorageTask,
supports_clipboard: bool)
-> ConstellationChan {
let (constellation_port, constellation_chan) = ConstellationChan::new(); let (constellation_port, constellation_chan) = ConstellationChan::new();
let constellation_chan_clone = constellation_chan.clone(); let constellation_chan_clone = constellation_chan.clone();
spawn_named("Constellation".to_owned(), move || { spawn_named("Constellation".to_owned(), move || {
let mut constellation: Constellation<LTF, STF> = Constellation { let mut constellation: Constellation<LTF, STF> = Constellation {
chan: constellation_chan_clone, chan: constellation_chan_clone,
request_port: constellation_port, request_port: constellation_port,
compositor_proxy: compositor_proxy, compositor_proxy: state.compositor_proxy,
devtools_chan: devtools_chan, devtools_chan: state.devtools_chan,
resource_task: resource_task, resource_task: state.resource_task,
image_cache_task: image_cache_task, image_cache_task: state.image_cache_task,
font_cache_task: font_cache_task, font_cache_task: state.font_cache_task,
storage_task: storage_task, storage_task: state.storage_task,
pipelines: HashMap::new(), pipelines: HashMap::new(),
frames: HashMap::new(), frames: HashMap::new(),
pipeline_to_frame_map: HashMap::new(), pipeline_to_frame_map: HashMap::new(),
@ -250,8 +263,8 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
root_frame_id: None, root_frame_id: None,
next_frame_id: FrameId(0), next_frame_id: FrameId(0),
focus_pipeline_id: None, focus_pipeline_id: None,
time_profiler_chan: time_profiler_chan, time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: mem_profiler_chan, mem_profiler_chan: state.mem_profiler_chan,
window_size: WindowSizeData { window_size: WindowSizeData {
visible_viewport: opts::get().initial_window_size.as_f32() * visible_viewport: opts::get().initial_window_size.as_f32() *
ScaleFactor::new(1.0), ScaleFactor::new(1.0),
@ -260,7 +273,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
device_pixel_ratio: ScaleFactor::new(1.0), device_pixel_ratio: ScaleFactor::new(1.0),
}, },
phantom: PhantomData, phantom: PhantomData,
clipboard_ctx: if supports_clipboard { clipboard_ctx: if state.supports_clipboard {
ClipboardContext::new().ok() ClipboardContext::new().ok()
} else { } else {
None None
@ -296,21 +309,23 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let spawning_paint_only = script_channel.is_some(); let spawning_paint_only = script_channel.is_some();
let (pipeline, mut pipeline_content) = let (pipeline, mut pipeline_content) =
Pipeline::create::<LTF, STF>(pipeline_id, Pipeline::create::<LTF, STF>(InitialPipelineState {
parent_info, id: pipeline_id,
self.chan.clone(), parent_info: parent_info,
self.compositor_proxy.clone_compositor_proxy(), constellation_chan: self.chan.clone(),
self.devtools_chan.clone(), compositor_proxy: self.compositor_proxy.clone_compositor_proxy(),
self.image_cache_task.clone(), devtools_chan: self.devtools_chan.clone(),
self.font_cache_task.clone(), image_cache_task: self.image_cache_task.clone(),
self.resource_task.clone(), font_cache_task: self.font_cache_task.clone(),
self.storage_task.clone(), resource_task: self.resource_task.clone(),
self.time_profiler_chan.clone(), storage_task: self.storage_task.clone(),
self.mem_profiler_chan.clone(), time_profiler_chan: self.time_profiler_chan.clone(),
initial_window_rect, mem_profiler_chan: self.mem_profiler_chan.clone(),
script_channel, window_rect: initial_window_rect,
load_data, script_chan: script_channel,
self.window_size.device_pixel_ratio); load_data: load_data,
device_pixel_ratio: self.window_size.device_pixel_ratio,
});
// TODO(pcwalton): In multiprocess mode, send that `PipelineContent` instance over to // TODO(pcwalton): In multiprocess mode, send that `PipelineContent` instance over to
// the content process and call this over there. // the content process and call this over there.

View file

@ -2,7 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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 windowing::WindowEvent;
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
@ -29,28 +30,17 @@ pub struct NullCompositor {
} }
impl NullCompositor { impl NullCompositor {
fn new(port: Box<CompositorReceiver>, fn new(state: InitialCompositorState) -> NullCompositor {
constellation_chan: ConstellationChan,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan)
-> NullCompositor {
NullCompositor { NullCompositor {
port: port, port: state.receiver,
constellation_chan: constellation_chan, constellation_chan: state.constellation_chan,
time_profiler_chan: time_profiler_chan, time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: mem_profiler_chan, mem_profiler_chan: state.mem_profiler_chan,
} }
} }
pub fn create(port: Box<CompositorReceiver>, pub fn create(state: InitialCompositorState) -> NullCompositor {
constellation_chan: ConstellationChan, let compositor = NullCompositor::new(state);
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan)
-> NullCompositor {
let compositor = NullCompositor::new(port,
constellation_chan,
time_profiler_chan,
mem_profiler_chan);
// Tell the constellation about the initial fake size. // Tell the constellation about the initial fake size.
{ {

View file

@ -4,8 +4,8 @@
use CompositorProxy; use CompositorProxy;
use layout_traits::{LayoutTaskFactory, LayoutControlChan}; use layout_traits::{LayoutTaskFactory, LayoutControlChan};
use script_traits::{LayoutControlMsg, ScriptTaskFactory}; use script_traits::{ConstellationControlMsg, InitialScriptState};
use script_traits::{NewLayoutInfo, ConstellationControlMsg}; use script_traits::{LayoutControlMsg, NewLayoutInfo, ScriptTaskFactory};
use compositor_task; use compositor_task;
use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg}; use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg};
@ -63,25 +63,46 @@ pub struct CompositionPipeline {
pub chrome_to_paint_chan: Sender<ChromeToPaintMsg>, pub chrome_to_paint_chan: Sender<ChromeToPaintMsg>,
} }
/// 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<CompositorProxy + 'static + Send>,
/// A channel to the developer tools, if applicable.
pub devtools_chan: Option<Sender<DevtoolsControlMsg>>,
/// 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<TypedRect<PagePx, f32>>,
/// Information about the device pixel ratio.
pub device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>,
/// A channel to the script thread, if applicable. If this is `Some`,
/// then `parent_info` must also be `Some`.
pub script_chan: Option<Sender<ConstellationControlMsg>>,
/// Information about the page to load.
pub load_data: LoadData,
}
impl Pipeline { impl Pipeline {
/// Starts a paint task, layout task, and possibly a script task. /// Starts a paint task, layout task, and possibly a script task.
/// Returns the channels wrapped in a struct. /// Returns the channels wrapped in a struct.
/// If script_pipeline is not None, then subpage_id must also be not None. pub fn create<LTF, STF>(state: InitialPipelineState)
pub fn create<LTF, STF>(id: PipelineId,
parent_info: Option<(PipelineId, SubpageId)>,
constellation_chan: ConstellationChan,
compositor_proxy: Box<CompositorProxy + 'static + Send>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
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<TypedRect<PagePx, f32>>,
script_chan: Option<Sender<ConstellationControlMsg>>,
load_data: LoadData,
device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>)
-> (Pipeline, PipelineContent) -> (Pipeline, PipelineContent)
where LTF: LayoutTaskFactory, STF: ScriptTaskFactory { where LTF: LayoutTaskFactory, STF: ScriptTaskFactory {
let (layout_to_paint_chan, layout_to_paint_port) = util::ipc::optional_ipc_channel(); 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 mut pipeline_port = Some(pipeline_port);
let failure = Failure { let failure = Failure {
pipeline_id: id, pipeline_id: state.id,
parent_info: parent_info, parent_info: state.parent_info,
}; };
let window_size = window_rect.map(|rect| { let window_size = state.window_rect.map(|rect| {
WindowSizeData { WindowSizeData {
visible_viewport: rect.size, visible_viewport: rect.size,
initial_viewport: rect.size * ScaleFactor::new(1.0), 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. // 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 (script_to_devtools_chan, script_to_devtools_port) = ipc::channel().unwrap();
let devtools_chan = (*devtools_chan).clone(); let devtools_chan = (*devtools_chan).clone();
ROUTER.add_route(script_to_devtools_port.to_opaque(), box move |message| { ROUTER.add_route(script_to_devtools_port.to_opaque(), box move |message| {
@ -115,15 +136,15 @@ impl Pipeline {
script_to_devtools_chan script_to_devtools_chan
}); });
let (script_chan, script_port) = match script_chan { let (script_chan, script_port) = match state.script_chan {
Some(script_chan) => { Some(script_chan) => {
let (containing_pipeline_id, subpage_id) = 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 { let new_layout_info = NewLayoutInfo {
containing_pipeline_id: containing_pipeline_id, containing_pipeline_id: containing_pipeline_id,
new_pipeline_id: id, new_pipeline_id: state.id,
subpage_id: subpage_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<Any + Send>, paint_chan: box layout_to_paint_chan.clone() as Box<Any + Send>,
failure: failure, failure: failure,
pipeline_port: mem::replace(&mut pipeline_port, None).unwrap(), pipeline_port: mem::replace(&mut pipeline_port, None).unwrap(),
@ -140,31 +161,31 @@ impl Pipeline {
} }
}; };
let pipeline = Pipeline::new(id, let pipeline = Pipeline::new(state.id,
parent_info, state.parent_info,
script_chan.clone(), script_chan.clone(),
LayoutControlChan(pipeline_chan), LayoutControlChan(pipeline_chan),
chrome_to_paint_chan.clone(), chrome_to_paint_chan.clone(),
layout_shutdown_port, layout_shutdown_port,
paint_shutdown_port, paint_shutdown_port,
load_data.url.clone(), state.load_data.url.clone(),
window_rect); state.window_rect);
let pipeline_content = PipelineContent { let pipeline_content = PipelineContent {
id: id, id: state.id,
parent_info: parent_info, parent_info: state.parent_info,
constellation_chan: constellation_chan, constellation_chan: state.constellation_chan,
compositor_proxy: compositor_proxy, compositor_proxy: state.compositor_proxy,
devtools_chan: script_to_devtools_chan, devtools_chan: script_to_devtools_chan,
image_cache_task: image_cache_task, image_cache_task: state.image_cache_task,
font_cache_task: font_cache_task, font_cache_task: state.font_cache_task,
resource_task: resource_task, resource_task: state.resource_task,
storage_task: storage_task, storage_task: state.storage_task,
time_profiler_chan: time_profiler_chan, time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: mem_profiler_chan, mem_profiler_chan: state.mem_profiler_chan,
window_size: window_size, window_size: window_size,
script_chan: script_chan, script_chan: script_chan,
load_data: load_data, load_data: state.load_data,
failure: failure, failure: failure,
script_port: script_port, script_port: script_port,
layout_to_paint_chan: layout_to_paint_chan, layout_to_paint_chan: layout_to_paint_chan,
@ -319,23 +340,22 @@ impl PipelineContent {
script_to_compositor_port) script_to_compositor_port)
}); });
ScriptTaskFactory::create(None::<&mut STF>, ScriptTaskFactory::create(None::<&mut STF>, InitialScriptState {
self.id, id: self.id,
self.parent_info, parent_info: self.parent_info,
script_to_compositor_chan, compositor: script_to_compositor_chan,
&layout_pair, control_chan: self.script_chan.clone(),
self.script_chan.clone(), control_port: mem::replace(&mut self.script_port, None).unwrap(),
mem::replace(&mut self.script_port, None).unwrap(), constellation_chan: self.constellation_chan.clone(),
self.constellation_chan.clone(), failure_info: self.failure.clone(),
self.failure.clone(), resource_task: self.resource_task,
self.resource_task, storage_task: self.storage_task.clone(),
self.storage_task.clone(), image_cache_task: self.image_cache_task.clone(),
self.image_cache_task.clone(), time_profiler_chan: self.time_profiler_chan.clone(),
self.time_profiler_chan.clone(), mem_profiler_chan: self.mem_profiler_chan.clone(),
self.mem_profiler_chan.clone(), devtools_chan: self.devtools_chan,
self.devtools_chan, window_size: self.window_size,
self.window_size, }, &layout_pair, self.load_data.clone());
self.load_data.clone());
LayoutTaskFactory::create(None::<&mut LTF>, LayoutTaskFactory::create(None::<&mut LTF>,
self.id, self.id,

View file

@ -54,9 +54,9 @@ use devtools_traits::ScriptToDevtoolsControlMsg;
use devtools_traits::{DevtoolsPageInfo, DevtoolScriptControlMsg}; use devtools_traits::{DevtoolsPageInfo, DevtoolScriptControlMsg};
use msg::compositor_msg::{LayerId, ScriptToCompositorMsg}; use msg::compositor_msg::{LayerId, ScriptToCompositorMsg};
use msg::constellation_msg::Msg as ConstellationMsg; use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::{ConstellationChan, FocusType}; use msg::constellation_msg::{ConstellationChan, FocusType, LoadData};
use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType}; use msg::constellation_msg::{MozBrowserEvent, PipelineExitType, PipelineId};
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId}; use msg::constellation_msg::{SubpageId, WindowSizeData, WorkerId};
use msg::webdriver_msg::WebDriverScriptCommand; use msg::webdriver_msg::WebDriverScriptCommand;
use net_traits::LoadData as NetLoadData; use net_traits::LoadData as NetLoadData;
use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult}; 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::{MouseDownEvent, MouseUpEvent};
use script_traits::CompositorEvent::{MouseMoveEvent, KeyEvent}; use script_traits::CompositorEvent::{MouseMoveEvent, KeyEvent};
use script_traits::CompositorEvent::{ResizeEvent, ClickEvent}; use script_traits::CompositorEvent::{ResizeEvent, ClickEvent};
use script_traits::ConstellationControlMsg; use script_traits::{CompositorEvent, ConstellationControlMsg};
use script_traits::{CompositorEvent, MouseButton}; use script_traits::{InitialScriptState, MouseButton, NewLayoutInfo};
use script_traits::{NewLayoutInfo, OpaqueScriptLayoutChannel}; use script_traits::{OpaqueScriptLayoutChannel, ScriptState, ScriptTaskFactory};
use script_traits::{ScriptState, ScriptTaskFactory};
use string_cache::Atom; use string_cache::Atom;
use util::opts; use util::opts;
use util::str::DOMString; use util::str::DOMString;
@ -466,42 +465,25 @@ impl ScriptTaskFactory for ScriptTask {
} }
fn create(_phantom: Option<&mut ScriptTask>, fn create(_phantom: Option<&mut ScriptTask>,
id: PipelineId, state: InitialScriptState,
parent_info: Option<(PipelineId, SubpageId)>,
compositor: IpcSender<ScriptToCompositorMsg>,
layout_chan: &OpaqueScriptLayoutChannel, layout_chan: &OpaqueScriptLayoutChannel,
control_chan: Sender<ConstellationControlMsg>,
control_port: Receiver<ConstellationControlMsg>,
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<IpcSender<ScriptToDevtoolsControlMsg>>,
window_size: Option<WindowSizeData>,
load_data: LoadData) { 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 (script_chan, script_port) = channel();
let layout_chan = LayoutChan(layout_chan.sender()); 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 roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots); let _stack_roots_tls = StackRootTLS::new(&roots);
let chan = MainThreadScriptChan(script_chan); let chan = MainThreadScriptChan(script_chan);
let channel_for_reporter = chan.clone(); 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, script_port,
chan, 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);
SCRIPT_TASK_ROOT.with(|root| { SCRIPT_TASK_ROOT.with(|root| {
*root.borrow_mut() = Some(&script_task as *const _); *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 // This must always be the very last operation performed before the task completes
failsafe.neuter(); 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. /// Creates a new script task.
pub fn new(compositor: IpcSender<ScriptToCompositorMsg>, pub fn new(state: InitialScriptState,
port: Receiver<MainThreadScriptMsg>, port: Receiver<MainThreadScriptMsg>,
chan: MainThreadScriptChan, chan: MainThreadScriptChan)
control_chan: Sender<ConstellationControlMsg>,
control_port: Receiver<ConstellationControlMsg>,
constellation_chan: ConstellationChan,
resource_task: Arc<ResourceTask>,
storage_task: StorageTask,
image_cache_task: ImageCacheTask,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>)
-> ScriptTask { -> ScriptTask {
let runtime = ScriptTask::new_rt_and_cx(); let runtime = ScriptTask::new_rt_and_cx();
@ -639,23 +612,23 @@ impl ScriptTask {
page: DOMRefCell::new(None), page: DOMRefCell::new(None),
incomplete_loads: DOMRefCell::new(vec!()), 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_channel: ImageCacheChan(ipc_image_cache_channel),
image_cache_port: image_cache_port, image_cache_port: image_cache_port,
resource_task: resource_task, resource_task: Arc::new(state.resource_task),
storage_task: storage_task, storage_task: state.storage_task,
port: port, port: port,
chan: chan, chan: chan,
control_chan: control_chan, control_chan: state.control_chan,
control_port: control_port, control_port: state.control_port,
constellation_chan: constellation_chan, constellation_chan: state.constellation_chan,
compositor: DOMRefCell::new(compositor), compositor: DOMRefCell::new(state.compositor),
time_profiler_chan: time_profiler_chan, time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: mem_profiler_chan, mem_profiler_chan: state.mem_profiler_chan,
devtools_chan: devtools_chan, devtools_chan: state.devtools_chan,
devtools_port: devtools_port, devtools_port: devtools_port,
devtools_sender: ipc_devtools_sender, devtools_sender: ipc_devtools_sender,

View file

@ -171,26 +171,46 @@ pub enum CompositorEvent {
/// crates that don't need to know about them. /// crates that don't need to know about them.
pub struct OpaqueScriptLayoutChannel(pub (Box<Any + Send>, Box<Any + Send>)); pub struct OpaqueScriptLayoutChannel(pub (Box<Any + Send>, Box<Any + Send>));
/// 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<ScriptToCompositorMsg>,
/// A channel with which messages can be sent to us (the script task).
pub control_chan: Sender<ConstellationControlMsg>,
/// A port on which messages sent by the constellation to script can be received.
pub control_port: Receiver<ConstellationControlMsg>,
/// 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<IpcSender<ScriptToDevtoolsControlMsg>>,
/// Information about the initial window size.
pub window_size: Option<WindowSizeData>,
}
/// This trait allows creating a `ScriptTask` without depending on the `script` /// This trait allows creating a `ScriptTask` without depending on the `script`
/// crate. /// crate.
pub trait ScriptTaskFactory { pub trait ScriptTaskFactory {
/// Create a `ScriptTask`. /// Create a `ScriptTask`.
fn create(_phantom: Option<&mut Self>, fn create(_phantom: Option<&mut Self>,
id: PipelineId, state: InitialScriptState,
parent_info: Option<(PipelineId, SubpageId)>,
compositor: IpcSender<ScriptToCompositorMsg>,
layout_chan: &OpaqueScriptLayoutChannel, layout_chan: &OpaqueScriptLayoutChannel,
control_chan: Sender<ConstellationControlMsg>,
control_port: Receiver<ConstellationControlMsg>,
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<IpcSender<ScriptToDevtoolsControlMsg>>,
window_size: Option<WindowSizeData>,
load_data: LoadData); load_data: LoadData);
/// Create a script -> layout channel (`Sender`, `Receiver` pair). /// Create a script -> layout channel (`Sender`, `Receiver` pair).
fn create_layout_channel(_phantom: Option<&mut Self>) -> OpaqueScriptLayoutChannel; fn create_layout_channel(_phantom: Option<&mut Self>) -> OpaqueScriptLayoutChannel;

View file

@ -81,6 +81,8 @@ pub use export::gleam::gl;
use compositing::CompositorEventListener; use compositing::CompositorEventListener;
use compositing::windowing::WindowEvent; use compositing::windowing::WindowEvent;
use compositing::compositor_task::InitialCompositorState;
use compositing::constellation::InitialConstellationState;
use compositing::windowing::WindowMethods; use compositing::windowing::WindowMethods;
use compositing::{CompositorProxy, CompositorTask, Constellation}; use compositing::{CompositorProxy, CompositorTask, Constellation};
@ -163,12 +165,13 @@ impl Browser {
// The compositor coordinates with the client window to create the final // The compositor coordinates with the client window to create the final
// rendered page and display it somewhere. // rendered page and display it somewhere.
let compositor = CompositorTask::create(window, let compositor = CompositorTask::create(window, InitialCompositorState {
compositor_proxy, sender: compositor_proxy,
compositor_receiver, receiver: compositor_receiver,
constellation_chan, constellation_chan: constellation_chan,
time_profiler_chan, time_profiler_chan: time_profiler_chan,
mem_profiler_chan); mem_profiler_chan: mem_profiler_chan,
});
Browser { Browser {
compositor: compositor, compositor: compositor,
@ -208,17 +211,20 @@ fn create_constellation(opts: opts::Opts,
let font_cache_task = FontCacheTask::new(resource_task.clone()); let font_cache_task = FontCacheTask::new(resource_task.clone());
let storage_task: StorageTask = StorageTaskFactory::new(); let storage_task: StorageTask = StorageTaskFactory::new();
let constellation_chan = Constellation::<layout::layout_task::LayoutTask, let initial_state = InitialConstellationState {
script::script_task::ScriptTask>::start( compositor_proxy: compositor_proxy,
compositor_proxy, devtools_chan: devtools_chan,
resource_task, image_cache_task: image_cache_task,
image_cache_task, font_cache_task: font_cache_task,
font_cache_task, resource_task: resource_task,
time_profiler_chan, storage_task: storage_task,
mem_profiler_chan, time_profiler_chan: time_profiler_chan,
devtools_chan, mem_profiler_chan: mem_profiler_chan,
storage_task, supports_clipboard: supports_clipboard,
supports_clipboard); };
let constellation_chan =
Constellation::<layout::layout_task::LayoutTask,
script::script_task::ScriptTask>::start(initial_state);
// Send the URL command to the constellation. // Send the URL command to the constellation.
match opts.url { match opts.url {