mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
compositing: Move messages that go over the ScriptListener
to go over
an IPC channel instead. Because this used a boxed trait object to invoke messages across a process boundary, and boxed trait objects are not supported across IPC, we spawn a helper thread inside the compositor to perform the marshaling for us.
This commit is contained in:
parent
2947d78e4e
commit
e841065351
14 changed files with 211 additions and 82 deletions
|
@ -52,6 +52,9 @@ git = "https://github.com/servo/rust-png"
|
|||
[dependencies.clipboard]
|
||||
git = "https://github.com/aweinstock314/rust-clipboard"
|
||||
|
||||
[dependencies.ipc-channel]
|
||||
git = "https://github.com/pcwalton/ipc-channel"
|
||||
|
||||
[dependencies]
|
||||
log = "*"
|
||||
num = "0.1.24"
|
||||
|
|
|
@ -13,10 +13,11 @@ use windowing::{WindowEvent, WindowMethods};
|
|||
|
||||
use euclid::point::Point2D;
|
||||
use euclid::rect::Rect;
|
||||
use ipc_channel::ipc::IpcReceiver;
|
||||
use layers::platform::surface::NativeDisplay;
|
||||
use layers::layers::{BufferRequest, LayerBuffer, LayerBufferSet};
|
||||
use msg::compositor_msg::{Epoch, LayerId, LayerProperties, FrameTreeId};
|
||||
use msg::compositor_msg::{PaintListener, ScriptListener};
|
||||
use msg::compositor_msg::{PaintListener, ScriptToCompositorMsg};
|
||||
use msg::constellation_msg::{AnimationState, ConstellationChan, PipelineId};
|
||||
use msg::constellation_msg::{Key, KeyState, KeyModifiers};
|
||||
use profile_traits::mem;
|
||||
|
@ -61,31 +62,28 @@ impl CompositorReceiver for Receiver<Msg> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Implementation of the abstract `ScriptListener` interface.
|
||||
impl ScriptListener for Box<CompositorProxy+'static+Send> {
|
||||
fn scroll_fragment_point(&mut self,
|
||||
pipeline_id: PipelineId,
|
||||
layer_id: LayerId,
|
||||
point: Point2D<f32>) {
|
||||
self.send(Msg::ScrollFragmentPoint(pipeline_id, layer_id, point));
|
||||
}
|
||||
pub fn run_script_listener_thread(mut compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
||||
receiver: IpcReceiver<ScriptToCompositorMsg>) {
|
||||
while let Ok(msg) = receiver.recv() {
|
||||
match msg {
|
||||
ScriptToCompositorMsg::ScrollFragmentPoint(pipeline_id, layer_id, point) => {
|
||||
compositor_proxy.send(Msg::ScrollFragmentPoint(pipeline_id, layer_id, point));
|
||||
}
|
||||
|
||||
fn close(&mut self) {
|
||||
let (chan, port) = channel();
|
||||
self.send(Msg::Exit(chan));
|
||||
port.recv().unwrap();
|
||||
}
|
||||
ScriptToCompositorMsg::Exit => {
|
||||
let (chan, port) = channel();
|
||||
compositor_proxy.send(Msg::Exit(chan));
|
||||
port.recv().unwrap();
|
||||
}
|
||||
|
||||
fn dup(&mut self) -> Box<ScriptListener+'static> {
|
||||
box self.clone_compositor_proxy() as Box<ScriptListener+'static>
|
||||
}
|
||||
ScriptToCompositorMsg::SetTitle(pipeline_id, title) => {
|
||||
compositor_proxy.send(Msg::ChangePageTitle(pipeline_id, title))
|
||||
}
|
||||
|
||||
fn set_title(&mut self, pipeline_id: PipelineId, title: Option<String>) {
|
||||
self.send(Msg::ChangePageTitle(pipeline_id, title))
|
||||
}
|
||||
|
||||
fn send_key_event(&mut self, key: Key, state: KeyState, modifiers: KeyModifiers) {
|
||||
self.send(Msg::KeyEvent(key, state, modifiers));
|
||||
ScriptToCompositorMsg::SendKeyEvent(key, key_state, key_modifiers) => {
|
||||
compositor_proxy.send(Msg::KeyEvent(key, key_state, key_modifiers))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ extern crate azure;
|
|||
extern crate devtools_traits;
|
||||
extern crate euclid;
|
||||
extern crate gfx;
|
||||
extern crate ipc_channel;
|
||||
extern crate layers;
|
||||
extern crate layout_traits;
|
||||
extern crate png;
|
||||
|
|
|
@ -7,13 +7,16 @@ use layout_traits::{LayoutControlMsg, LayoutTaskFactory, LayoutControlChan};
|
|||
use script_traits::{ScriptControlChan, ScriptTaskFactory};
|
||||
use script_traits::{NewLayoutInfo, ConstellationControlMsg};
|
||||
|
||||
use compositor_task;
|
||||
use devtools_traits::DevtoolsControlChan;
|
||||
use euclid::rect::{TypedRect};
|
||||
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 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;
|
||||
|
@ -22,6 +25,7 @@ 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::thread;
|
||||
use url::Url;
|
||||
use util::geometry::{PagePx, ViewportPx};
|
||||
use util::opts;
|
||||
|
@ -91,6 +95,8 @@ impl Pipeline {
|
|||
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 {
|
||||
|
@ -100,10 +106,18 @@ impl Pipeline {
|
|||
}
|
||||
});
|
||||
|
||||
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,
|
||||
compositor_proxy.clone_compositor_proxy(),
|
||||
ScriptListener::new(script_to_compositor_chan),
|
||||
&layout_pair,
|
||||
ScriptControlChan(script_chan.clone()),
|
||||
script_port,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue