mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
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:
parent
64751b8eef
commit
e5b1ec4078
12 changed files with 316 additions and 149 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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>);
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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<()>,
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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 = "*"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
4
components/servo/Cargo.lock
generated
4
components/servo/Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue