script: Split Pipeline::create into chrome process and content

process parts.

This will make it easier to adapt to IPC.

The trickiest part here was to make script tasks spawn new layout tasks
directly instead of having the pipeline do it for them. The latter
approach will not work in multiprocess mode, because layout and script
must run in the same address space and the pipeline cannot inject tasks
into another process.
This commit is contained in:
Patrick Walton 2015-07-13 19:59:13 -07:00
parent 64751b8eef
commit e5b1ec4078
12 changed files with 316 additions and 149 deletions

View file

@ -28,7 +28,7 @@ use layers::platform::surface::NativeDisplay;
use layers::rendergl::RenderContext;
use layers::rendergl;
use layers::scene::Scene;
use layout_traits::{LayoutControlChan, LayoutControlMsg};
use layout_traits::LayoutControlChan;
use msg::compositor_msg::{Epoch, FrameTreeId, LayerId, LayerKind};
use msg::compositor_msg::{LayerProperties, ScrollPolicy};
use msg::constellation_msg::AnimationState;
@ -39,7 +39,7 @@ use msg::constellation_msg::{PipelineId, WindowSizeData};
use png;
use profile_traits::mem;
use profile_traits::time::{self, ProfilerCategory, profile};
use script_traits::{ConstellationControlMsg, ScriptControlChan};
use script_traits::{ConstellationControlMsg, LayoutControlMsg, ScriptControlChan};
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::mem as std_mem;

View file

@ -20,7 +20,7 @@ use euclid::size::Size2D;
use euclid::scale_factor::ScaleFactor;
use gfx::font_cache_task::FontCacheTask;
use ipc_channel::ipc;
use layout_traits::{LayoutControlChan, LayoutControlMsg, LayoutTaskFactory};
use layout_traits::{LayoutControlChan, LayoutTaskFactory};
use libc;
use msg::compositor_msg::{Epoch, LayerId};
use msg::constellation_msg::AnimationState;
@ -37,7 +37,7 @@ use net_traits::image_cache_task::ImageCacheTask;
use net_traits::storage_task::{StorageTask, StorageTaskMsg};
use profile_traits::mem;
use profile_traits::time;
use script_traits::{CompositorEvent, ConstellationControlMsg};
use script_traits::{CompositorEvent, ConstellationControlMsg, LayoutControlMsg};
use script_traits::{ScriptControlChan, ScriptState, ScriptTaskFactory};
use std::borrow::ToOwned;
use std::collections::HashMap;
@ -282,21 +282,31 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let PipelineId(ref mut i) = self.next_pipeline_id;
*i += 1;
let pipeline = Pipeline::create::<LTF, STF>(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);
let spawning_paint_only = script_channel.is_some();
let (pipeline, mut pipeline_content) =
Pipeline::create::<LTF, STF>(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);
// TODO(pcwalton): In multiprocess mode, send that `PipelineContent` instance over to
// the content process and call this over there.
if spawning_paint_only {
pipeline_content.start_paint_task();
} else {
pipeline_content.start_all::<LTF, STF>();
}
assert!(!self.pipelines.contains_key(&pipeline_id));
self.pipelines.insert(pipeline_id, pipeline);

View file

@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use CompositorProxy;
use layout_traits::{LayoutControlMsg, LayoutTaskFactory, LayoutControlChan};
use script_traits::{ScriptControlChan, ScriptTaskFactory};
use layout_traits::{LayoutTaskFactory, LayoutControlChan};
use script_traits::{LayoutControlMsg, ScriptControlChan, ScriptTaskFactory};
use script_traits::{NewLayoutInfo, ConstellationControlMsg};
use compositor_task;
@ -14,17 +14,19 @@ use euclid::scale_factor::ScaleFactor;
use gfx::paint_task::Msg as PaintMsg;
use gfx::paint_task::{PaintChan, PaintTask};
use gfx::font_cache_task::FontCacheTask;
use ipc_channel::ipc;
use ipc_channel::ipc::{self, IpcReceiver};
use layers::geometry::DevicePixel;
use msg::compositor_msg::ScriptListener;
use msg::constellation_msg::{ConstellationChan, Failure, FrameId, PipelineId, SubpageId};
use msg::constellation_msg::{LoadData, WindowSizeData, PipelineExitType, MozBrowserEvent};
use profile_traits::mem;
use profile_traits::mem as profile_mem;
use profile_traits::time;
use net_traits::ResourceTask;
use net_traits::image_cache_task::ImageCacheTask;
use net_traits::storage_task::StorageTask;
use std::sync::mpsc::{Receiver, channel};
use std::any::Any;
use std::mem;
use std::sync::mpsc::{Receiver, Sender, channel};
use std::thread;
use url::Url;
use util::geometry::{PagePx, ViewportPx};
@ -74,118 +76,85 @@ impl Pipeline {
resource_task: ResourceTask,
storage_task: StorageTask,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan,
mem_profiler_chan: profile_mem::ProfilerChan,
window_rect: Option<TypedRect<PagePx, f32>>,
script_chan: Option<ScriptControlChan>,
load_data: LoadData,
device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>)
-> Pipeline
-> (Pipeline, PipelineContent)
where LTF: LayoutTaskFactory, STF:ScriptTaskFactory {
let layout_pair = ScriptTaskFactory::create_layout_channel(None::<&mut STF>);
let (paint_port, paint_chan) = PaintChan::new();
let (paint_shutdown_chan, paint_shutdown_port) = channel();
let (layout_shutdown_chan, layout_shutdown_port) = channel();
let (pipeline_chan, pipeline_port) = ipc::channel().unwrap();
let mut pipeline_port = Some(pipeline_port);
let failure = Failure {
pipeline_id: id,
parent_info: parent_info,
};
let script_chan = match script_chan {
None => {
let (script_chan, script_port) = channel();
let (script_to_compositor_chan, script_to_compositor_port) =
ipc::channel().unwrap();
let window_size = window_rect.map(|rect| {
WindowSizeData {
visible_viewport: rect.size,
initial_viewport: rect.size * ScaleFactor::new(1.0),
device_pixel_ratio: device_pixel_ratio,
}
});
let compositor_proxy_for_script_listener_thread =
compositor_proxy.clone_compositor_proxy();
thread::spawn(move || {
compositor_task::run_script_listener_thread(
compositor_proxy_for_script_listener_thread,
script_to_compositor_port)
});
ScriptTaskFactory::create(None::<&mut STF>,
id,
parent_info,
ScriptListener::new(script_to_compositor_chan),
&layout_pair,
ScriptControlChan(script_chan.clone()),
script_port,
constellation_chan.clone(),
failure.clone(),
resource_task,
storage_task.clone(),
image_cache_task.clone(),
devtools_chan,
window_size,
load_data.clone());
ScriptControlChan(script_chan)
let window_size = window_rect.map(|rect| {
WindowSizeData {
visible_viewport: rect.size,
initial_viewport: rect.size * ScaleFactor::new(1.0),
device_pixel_ratio: device_pixel_ratio,
}
Some(script_chan) => {
let (containing_pipeline_id, subpage_id) =
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,
subpage_id: subpage_id,
layout_chan: ScriptTaskFactory::clone_layout_channel(None::<&mut STF>,
&layout_pair),
load_data: load_data.clone(),
};
});
let ScriptControlChan(ref chan) = script_chan;
chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)).unwrap();
script_chan.clone()
}
if let Some(ref script_chan) = script_chan {
let (containing_pipeline_id, subpage_id) =
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,
subpage_id: subpage_id,
load_data: load_data.clone(),
paint_chan: box() (paint_chan.clone()) as Box<Any + Send>,
failure: failure,
pipeline_port: mem::replace(&mut pipeline_port, None).unwrap(),
layout_shutdown_chan: layout_shutdown_chan.clone(),
};
script_chan.0.send(ConstellationControlMsg::AttachLayout(new_layout_info)).unwrap();
}
let (script_chan, script_port) = channel();
let pipeline = Pipeline::new(id,
parent_info,
ScriptControlChan(script_chan.clone()),
LayoutControlChan(pipeline_chan),
paint_chan.clone(),
layout_shutdown_port,
paint_shutdown_port,
load_data.url.clone(),
window_rect);
let pipeline_content = PipelineContent {
id: id,
parent_info: parent_info,
constellation_chan: constellation_chan,
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,
window_size: window_size,
script_chan: script_chan,
load_data: load_data,
failure: failure,
script_port: script_port,
paint_chan: paint_chan,
paint_port: Some(paint_port),
pipeline_port: pipeline_port,
paint_shutdown_chan: paint_shutdown_chan,
layout_shutdown_chan: layout_shutdown_chan,
};
PaintTask::create(id,
load_data.url.clone(),
paint_chan.clone(),
paint_port,
compositor_proxy,
constellation_chan.clone(),
font_cache_task.clone(),
failure.clone(),
time_profiler_chan.clone(),
mem_profiler_chan.clone(),
paint_shutdown_chan);
LayoutTaskFactory::create(None::<&mut LTF>,
id,
load_data.url.clone(),
parent_info.is_some(),
layout_pair,
pipeline_port,
constellation_chan,
failure,
script_chan.clone(),
paint_chan.clone(),
image_cache_task,
font_cache_task,
time_profiler_chan,
mem_profiler_chan,
layout_shutdown_chan);
Pipeline::new(id,
parent_info,
script_chan,
LayoutControlChan(pipeline_chan),
paint_chan,
layout_shutdown_port,
paint_shutdown_port,
load_data.url,
window_rect)
(pipeline, pipeline_content)
}
pub fn new(id: PipelineId,
@ -289,3 +258,92 @@ impl Pipeline {
script_channel.send(event).unwrap();
}
}
pub struct PipelineContent {
id: PipelineId,
parent_info: Option<(PipelineId, SubpageId)>,
constellation_chan: ConstellationChan,
compositor_proxy: Box<CompositorProxy + Send + 'static>,
devtools_chan: Option<DevtoolsControlChan>,
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_size: Option<WindowSizeData>,
script_chan: Sender<ConstellationControlMsg>,
load_data: LoadData,
failure: Failure,
script_port: Receiver<ConstellationControlMsg>,
paint_chan: PaintChan,
paint_port: Option<Receiver<PaintMsg>>,
paint_shutdown_chan: Sender<()>,
pipeline_port: Option<IpcReceiver<LayoutControlMsg>>,
layout_shutdown_chan: Sender<()>,
}
impl PipelineContent {
pub fn start_all<LTF,STF>(mut self) where LTF: LayoutTaskFactory, STF: ScriptTaskFactory {
let layout_pair = ScriptTaskFactory::create_layout_channel(None::<&mut STF>);
let (script_to_compositor_chan, script_to_compositor_port) = ipc::channel().unwrap();
self.start_paint_task();
let compositor_proxy_for_script_listener_thread =
self.compositor_proxy.clone_compositor_proxy();
thread::spawn(move || {
compositor_task::run_script_listener_thread(
compositor_proxy_for_script_listener_thread,
script_to_compositor_port)
});
ScriptTaskFactory::create(None::<&mut STF>,
self.id,
self.parent_info,
ScriptListener::new(script_to_compositor_chan),
&layout_pair,
ScriptControlChan(self.script_chan.clone()),
self.script_port,
self.constellation_chan.clone(),
self.failure.clone(),
self.resource_task,
self.storage_task.clone(),
self.image_cache_task.clone(),
self.devtools_chan,
self.window_size,
self.load_data.clone());
LayoutTaskFactory::create(None::<&mut LTF>,
self.id,
self.load_data.url.clone(),
self.parent_info.is_some(),
layout_pair,
self.pipeline_port.unwrap(),
self.constellation_chan,
self.failure,
ScriptControlChan(self.script_chan.clone()),
self.paint_chan.clone(),
self.image_cache_task,
self.font_cache_task,
self.time_profiler_chan,
self.mem_profiler_chan,
self.layout_shutdown_chan);
}
pub fn start_paint_task(&mut self) {
PaintTask::create(self.id,
self.load_data.url.clone(),
self.paint_chan.clone(),
mem::replace(&mut self.paint_port, None).unwrap(),
self.compositor_proxy.clone_compositor_proxy(),
self.constellation_chan.clone(),
self.font_cache_task.clone(),
self.failure.clone(),
self.time_profiler_chan.clone(),
self.mem_profiler_chan.clone(),
self.paint_shutdown_chan.clone());
}
}

View file

@ -40,7 +40,7 @@ use gfx::font_cache_task::FontCacheTask;
use gfx::paint_task::Msg as PaintMsg;
use gfx::paint_task::{PaintChan, PaintLayer};
use ipc_channel::ipc::IpcReceiver;
use layout_traits::{LayoutControlMsg, LayoutTaskFactory};
use layout_traits::LayoutTaskFactory;
use log;
use msg::compositor_msg::{Epoch, ScrollPolicy, LayerId};
use msg::constellation_msg::Msg as ConstellationMsg;
@ -53,10 +53,10 @@ use net_traits::image_cache_task::{ImageCacheTask, ImageCacheResult, ImageCacheC
use script::dom::bindings::js::LayoutJS;
use script::dom::node::{LayoutData, Node};
use script::layout_interface::{Animation, ContentBoxResponse, ContentBoxesResponse};
use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC};
use script::layout_interface::{MouseOverResponse, Msg, Reflow, ReflowGoal, ReflowQueryType};
use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC, MouseOverResponse};
use script::layout_interface::{NewLayoutTaskInfo, Msg, Reflow, ReflowGoal, ReflowQueryType};
use script::layout_interface::{ScriptLayoutChan, ScriptReflow, TrustedNodeAddress};
use script_traits::{ConstellationControlMsg, OpaqueScriptLayoutChannel};
use script_traits::{ConstellationControlMsg, LayoutControlMsg, OpaqueScriptLayoutChannel};
use script_traits::{ScriptControlChan, StylesheetLoadResponder};
use std::borrow::ToOwned;
use std::cell::Cell;
@ -559,6 +559,9 @@ impl LayoutTask {
let rw_data = self.lock_rw_data(possibly_locked_rw_data);
sender.send(rw_data.epoch).unwrap();
},
Msg::CreateLayoutTask(info) => {
self.create_layout_task(info)
}
Msg::PrepareToExit(response_chan) => {
self.prepare_to_exit(response_chan, possibly_locked_rw_data);
return false
@ -607,6 +610,24 @@ impl LayoutTask {
reports_chan.send(reports);
}
fn create_layout_task(&self, info: NewLayoutTaskInfo) {
LayoutTaskFactory::create(None::<&mut LayoutTask>,
info.id,
info.url.clone(),
info.is_parent,
info.layout_pair,
info.pipeline_port,
info.constellation_chan,
info.failure,
ScriptControlChan(info.script_chan.clone()),
*info.paint_chan.downcast::<PaintChan>().unwrap(),
self.image_cache_task.clone(),
self.font_cache_task.clone(),
self.time_profiler_chan.clone(),
self.mem_profiler_chan.clone(),
info.layout_shutdown_chan);
}
/// Enters a quiescent state in which no new messages except for
/// `layout_interface::Msg::ReapLayoutData` will be processed until an `ExitNow` is
/// received. A pong is immediately sent on the given response channel.
@ -1399,3 +1420,4 @@ fn get_root_flow_background_color(flow: &mut Flow) -> AzColor {
.resolve_color(kid_block_flow.fragment.style.get_background().background_color)
.to_gfx_color()
}

View file

@ -21,29 +21,17 @@ extern crate util;
// The traits are here instead of in layout so
// that these modules won't have to depend on layout.
use euclid::rect::Rect;
use gfx::font_cache_task::FontCacheTask;
use gfx::paint_task::PaintChan;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use msg::compositor_msg::{Epoch, LayerId};
use msg::constellation_msg::{ConstellationChan, Failure, PipelineId, PipelineExitType};
use msg::constellation_msg::{ConstellationChan, Failure, PipelineId};
use profile_traits::mem;
use profile_traits::time;
use net_traits::image_cache_task::ImageCacheTask;
use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel};
use script_traits::{LayoutControlMsg, ScriptControlChan, OpaqueScriptLayoutChannel};
use std::sync::mpsc::Sender;
use util::geometry::Au;
use url::Url;
/// Messages sent to the layout task from the constellation and/or compositor.
#[derive(Deserialize, Serialize)]
pub enum LayoutControlMsg {
ExitNow(PipelineExitType),
GetCurrentEpoch(IpcSender<Epoch>),
TickAnimations,
SetVisibleRects(Vec<(LayerId, Rect<Au>)>),
}
/// A channel wrapper for constellation messages
#[derive(Clone, Deserialize, Serialize)]
pub struct LayoutControlChan(pub IpcSender<LayoutControlMsg>);

View file

@ -30,6 +30,9 @@ path = "../profile_traits"
[dependencies.script_traits]
path = "../script_traits"
[dependencies.layout_traits]
path = "../layout_traits"
[dependencies.devtools_traits]
path = "../devtools_traits"

View file

@ -10,15 +10,17 @@ use dom::node::LayoutData;
use euclid::point::Point2D;
use euclid::rect::Rect;
use ipc_channel::ipc::IpcSender;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use libc::uintptr_t;
use msg::compositor_msg::LayerId;
use msg::constellation_msg::{PipelineExitType, WindowSizeData};
use msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType, PipelineId};
use msg::constellation_msg::{WindowSizeData};
use msg::compositor_msg::Epoch;
use net_traits::image_cache_task::ImageCacheTask;
use net_traits::PendingAsyncLoad;
use profile_traits::mem::{Reporter, ReportsChan};
use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel, UntrustedNodeAddress};
use script_traits::StylesheetLoadResponder;
use script_traits::{ConstellationControlMsg, LayoutControlMsg, ScriptControlChan};
use script_traits::{OpaqueScriptLayoutChannel, StylesheetLoadResponder, UntrustedNodeAddress};
use std::any::Any;
use std::sync::mpsc::{channel, Receiver, Sender};
use style::animation::PropertyAnimation;
@ -72,7 +74,12 @@ pub enum Msg {
ExitNow(PipelineExitType),
/// Get the last epoch counter for this layout task.
GetCurrentEpoch(IpcSender<Epoch>)
GetCurrentEpoch(IpcSender<Epoch>),
/// Creates a new layout task.
///
/// This basically exists to keep the script-layout dependency one-way.
CreateLayoutTask(NewLayoutTaskInfo),
}
/// Synchronous messages that script can send to layout.
@ -209,3 +216,17 @@ impl Animation {
}
}
pub struct NewLayoutTaskInfo {
pub id: PipelineId,
pub url: Url,
pub is_parent: bool,
pub layout_pair: OpaqueScriptLayoutChannel,
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
pub constellation_chan: ConstellationChan,
pub failure: Failure,
pub script_chan: Sender<ConstellationControlMsg>,
pub image_cache_task: ImageCacheTask,
pub paint_chan: Box<Any + Send>,
pub layout_shutdown_chan: Sender<()>,
}

View file

@ -46,6 +46,7 @@ extern crate fnv;
extern crate hyper;
extern crate ipc_channel;
extern crate js;
extern crate layout_traits;
extern crate libc;
extern crate msg;
extern crate net_traits;

View file

@ -42,8 +42,8 @@ use dom::servohtmlparser::{ServoHTMLParser, ParserContext};
use dom::window::{Window, WindowHelpers, ScriptHelpers, ReflowReason};
use dom::worker::TrustedWorkerAddress;
use parse::html::{ParseContext, parse_html};
use layout_interface::{ScriptLayoutChan, LayoutChan, ReflowGoal, ReflowQueryType};
use layout_interface;
use layout_interface::{self, NewLayoutTaskInfo, ScriptLayoutChan, LayoutChan, ReflowGoal};
use layout_interface::{ReflowQueryType};
use network_listener::NetworkListener;
use page::{Page, IterablePage, Frame};
use timers::TimerId;
@ -925,18 +925,44 @@ impl ScriptTask {
containing_pipeline_id,
new_pipeline_id,
subpage_id,
layout_chan,
load_data,
paint_chan,
failure,
pipeline_port,
layout_shutdown_chan,
} = new_layout_info;
let layout_pair = ScriptTask::create_layout_channel(None::<&mut ScriptTask>);
let layout_chan = LayoutChan(*ScriptTask::clone_layout_channel(
None::<&mut ScriptTask>,
&layout_pair).downcast::<Sender<layout_interface::Msg>>().unwrap());
let layout_creation_info = NewLayoutTaskInfo {
id: new_pipeline_id,
url: load_data.url.clone(),
is_parent: false,
layout_pair: layout_pair,
pipeline_port: pipeline_port,
constellation_chan: self.constellation_chan.clone(),
failure: failure,
paint_chan: paint_chan,
script_chan: self.control_chan.0.clone(),
image_cache_task: self.image_cache_task.clone(),
layout_shutdown_chan: layout_shutdown_chan,
};
let page = self.root_page();
let parent_page = page.find(containing_pipeline_id).expect("ScriptTask: received a layout
whose parent has a PipelineId which does not correspond to a pipeline in the script
task's page tree. This is a bug.");
let parent_window = parent_page.window();
let chan = layout_chan.downcast_ref::<Sender<layout_interface::Msg>>().unwrap();
let layout_chan = LayoutChan(chan.clone());
// Tell layout to actually spawn the task.
parent_window.layout_chan()
.0
.send(layout_interface::Msg::CreateLayoutTask(layout_creation_info))
.unwrap();
// Kick off the fetch for the new resource.
let new_load = InProgressLoad::new(new_pipeline_id, Some((containing_pipeline_id, subpage_id)),
layout_chan, parent_window.r().window_size(),

View file

@ -19,7 +19,13 @@ path = "../util"
[dependencies.devtools_traits]
path = "../devtools_traits"
[dependencies.ipc-channel]
git = "https://github.com/pcwalton/ipc-channel"
[dependencies]
url = "0.2.35"
libc = "*"
euclid = "0.1"
serde = "*"
serde_macros = "*"

View file

@ -6,18 +6,24 @@
//! The traits are here instead of in script so that these modules won't have
//! to depend on script.
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
#![deny(missing_docs)]
extern crate devtools_traits;
extern crate euclid;
extern crate ipc_channel;
extern crate libc;
extern crate msg;
extern crate net_traits;
extern crate serde;
extern crate util;
extern crate url;
use devtools_traits::DevtoolsControlChan;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use libc::c_void;
use msg::compositor_msg::{Epoch, LayerId};
use msg::constellation_msg::{ConstellationChan, PipelineId, Failure, WindowSizeData};
use msg::constellation_msg::{LoadData, SubpageId, Key, KeyState, KeyModifiers};
use msg::constellation_msg::{MozBrowserEvent, PipelineExitType};
@ -29,6 +35,7 @@ use net_traits::storage_task::StorageTask;
use std::any::Any;
use std::sync::mpsc::{Sender, Receiver};
use url::Url;
use util::geometry::Au;
use euclid::point::Point2D;
use euclid::rect::Rect;
@ -40,6 +47,19 @@ use euclid::rect::Rect;
pub struct UntrustedNodeAddress(pub *const c_void);
unsafe impl Send for UntrustedNodeAddress {}
/// Messages sent to the layout task from the constellation and/or compositor.
#[derive(Deserialize, Serialize)]
pub enum LayoutControlMsg {
/// Requests that this layout task exit.
ExitNow(PipelineExitType),
/// Requests the current epoch (layout counter) from this layout.
GetCurrentEpoch(IpcSender<Epoch>),
/// Asks layout to run another step in its animation.
TickAnimations,
/// Informs layout as to which regions of the page are visible.
SetVisibleRects(Vec<(LayerId, Rect<Au>)>),
}
/// The initial data associated with a newly-created framed pipeline.
pub struct NewLayoutInfo {
/// Id of the parent of this new pipeline.
@ -48,11 +68,19 @@ pub struct NewLayoutInfo {
pub new_pipeline_id: PipelineId,
/// Id of the new frame associated with this pipeline.
pub subpage_id: SubpageId,
/// Channel for communicating with this new pipeline's layout task.
/// (This is a LayoutChannel.)
pub layout_chan: Box<Any+Send>,
/// Network request data which will be initiated by the script task.
pub load_data: LoadData,
/// The paint channel, cast to `Box<Any>`.
///
/// TODO(pcwalton): When we convert this to use IPC, this will need to become an
/// `IpcAnySender`.
pub paint_chan: Box<Any + Send>,
/// Information on what to do on task failure.
pub failure: Failure,
/// A port on which layout can receive messages from the pipeline.
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
/// A shutdown channel so that layout can notify others when it's done.
pub layout_shutdown_chan: Sender<()>,
}
/// `StylesheetLoadResponder` is used to notify a responder that a style sheet

View file

@ -1111,6 +1111,7 @@ dependencies = [
"hyper 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
"js 0.1.0 (git+https://github.com/servo/rust-mozjs)",
"layout_traits 0.0.1",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@ -1150,9 +1151,12 @@ version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
"euclid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
"serde 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
]