aboutsummaryrefslogtreecommitdiffstats
path: root/components/compositing
diff options
context:
space:
mode:
Diffstat (limited to 'components/compositing')
-rw-r--r--components/compositing/compositor.rs11
-rw-r--r--components/compositing/compositor_thread.rs29
-rw-r--r--components/compositing/constellation.rs14
-rw-r--r--components/compositing/headless.rs147
-rw-r--r--components/compositing/lib.rs1
-rw-r--r--components/compositing/pipeline.rs14
-rw-r--r--components/compositing/windowing.rs3
7 files changed, 41 insertions, 178 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index b5df18b2564..7f6c28c178e 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -525,6 +525,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
(Msg::InitializeLayersForPipeline(pipeline_id, epoch, properties),
ShutdownState::NotShuttingDown) => {
+ debug!("initializing layers for pipeline: {:?}", pipeline_id);
self.pipeline_details(pipeline_id).current_epoch = epoch;
self.collect_old_layers(pipeline_id, &properties);
@@ -542,7 +543,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
(Msg::GetNativeDisplay(chan),
ShutdownState::NotShuttingDown) => {
- chan.send(Some(self.native_display.clone())).unwrap();
+ chan.send(self.native_display.clone()).unwrap();
}
(Msg::AssignPaintedBuffers(pipeline_id, epoch, replies, frame_tree_id),
@@ -641,7 +642,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
reply.send(img).unwrap();
}
- (Msg::PaintThreadExited(pipeline_id), ShutdownState::NotShuttingDown) => {
+ (Msg::PaintThreadExited(pipeline_id), _) => {
+ debug!("compositor learned about paint thread exiting: {:?}", pipeline_id);
self.remove_pipeline_root_layer(pipeline_id);
}
@@ -690,8 +692,11 @@ impl<Window: WindowMethods> IOCompositor<Window> {
reports_chan.send(reports);
}
- (Msg::PipelineExited(pipeline_id), _) => {
+ (Msg::PipelineExited(pipeline_id, sender), _) => {
+ debug!("Compositor got pipeline exited: {:?}", pipeline_id);
self.pending_subpages.remove(&pipeline_id);
+ self.remove_pipeline_root_layer(pipeline_id);
+ sender.send(()).unwrap();
}
// When we are shutting_down, we need to avoid performing operations
diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs
index eb0020c366d..fdfd4c633bf 100644
--- a/components/compositing/compositor_thread.rs
+++ b/components/compositing/compositor_thread.rs
@@ -9,7 +9,6 @@ use compositor::{self, CompositingReason};
use euclid::point::Point2D;
use euclid::size::Size2D;
use gfx_traits::{Epoch, FrameTreeId, LayerId, LayerProperties, PaintListener};
-use headless;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use layers::layers::{BufferRequest, LayerBufferSet};
use layers::platform::surface::{NativeDisplay, NativeSurface};
@@ -98,6 +97,8 @@ pub fn run_script_listener_thread(compositor_proxy: Box<CompositorProxy + 'stati
ScriptToCompositorMsg::TouchEventProcessed(result) => {
compositor_proxy.send(Msg::TouchEventProcessed(result))
}
+
+ ScriptToCompositorMsg::Exited => break,
}
}
}
@@ -123,7 +124,7 @@ impl PaintListener for Box<CompositorProxy + 'static + Send> {
// just return None in this case, since the paint thread
// will exit shortly and never actually be requested
// to paint buffers by the compositor.
- port.recv().unwrap_or(None)
+ port.recv().ok()
}
fn assign_painted_buffers(&mut self,
@@ -174,9 +175,7 @@ pub enum Msg {
/// Requests the compositor's graphics metadata. Graphics metadata is what the painter needs
/// to create surfaces that the compositor can see. On Linux this is the X display; on Mac this
/// is the pixel format.
- ///
- /// The headless compositor returns `None`.
- GetNativeDisplay(Sender<Option<NativeDisplay>>),
+ GetNativeDisplay(Sender<NativeDisplay>),
/// Tells the compositor to create or update the layers for a pipeline if necessary
/// (i.e. if no layer with that ID exists).
@@ -233,7 +232,11 @@ pub enum Msg {
/// Resize the window to size
ResizeTo(Size2D<u32>),
/// A pipeline was shut down.
- PipelineExited(PipelineId),
+ // This message acts as a synchronization point between the constellation,
+ // when it shuts down a pipeline, to the compositor; when the compositor
+ // sends a reply on the IpcSender, the constellation knows it's safe to
+ // tear down the other threads associated with this pipeline.
+ PipelineExited(PipelineId, IpcSender<()>),
}
impl Debug for Msg {
@@ -276,20 +279,12 @@ impl Debug for Msg {
pub struct CompositorThread;
impl CompositorThread {
- pub fn create<Window>(window: Option<Rc<Window>>,
+ pub fn create<Window>(window: Rc<Window>,
state: InitialCompositorState)
-> Box<CompositorEventListener + 'static>
where Window: WindowMethods + 'static {
- match window {
- Some(window) => {
- box compositor::IOCompositor::create(window, state)
- as Box<CompositorEventListener>
- }
- None => {
- box headless::NullCompositor::create(state)
- as Box<CompositorEventListener>
- }
- }
+ box compositor::IOCompositor::create(window, state)
+ as Box<CompositorEventListener>
}
}
diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs
index f1876e660c7..159477e34cb 100644
--- a/components/compositing/constellation.rs
+++ b/components/compositing/constellation.rs
@@ -648,8 +648,13 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
}
// Update pipeline url after redirections
Request::Script(FromScriptMsg::SetFinalUrl(pipeline_id, final_url)) => {
- debug!("constellation got set final url message");
- self.mut_pipeline(pipeline_id).url = final_url;
+ // The script may have finished loading after we already started shutting down.
+ if let Some(ref mut pipeline) = self.pipelines.get_mut(&pipeline_id) {
+ debug!("constellation got set final url message");
+ pipeline.url = final_url;
+ } else {
+ debug!("constellation got set final url message for dead pipeline");
+ }
}
Request::Script(FromScriptMsg::MozBrowserEvent(pipeline_id,
subpage_id,
@@ -693,9 +698,12 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
}
}
}
- Request::Script(FromScriptMsg::RemoveIFrame(pipeline_id)) => {
+ Request::Script(FromScriptMsg::RemoveIFrame(pipeline_id, sender)) => {
debug!("constellation got remove iframe message");
self.handle_remove_iframe_msg(pipeline_id);
+ if let Some(sender) = sender {
+ sender.send(()).unwrap();
+ }
}
Request::Script(FromScriptMsg::NewFavicon(url)) => {
debug!("constellation got new favicon message");
diff --git a/components/compositing/headless.rs b/components/compositing/headless.rs
deleted file mode 100644
index c46bdd52262..00000000000
--- a/components/compositing/headless.rs
+++ /dev/null
@@ -1,147 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use AnimationTickType;
-use CompositorMsg as ConstellationMsg;
-use compositor_thread::{CompositorEventListener, CompositorReceiver};
-use compositor_thread::{InitialCompositorState, Msg};
-use euclid::scale_factor::ScaleFactor;
-use euclid::{Point2D, Size2D};
-use msg::constellation_msg::WindowSizeData;
-use profile_traits::mem;
-use profile_traits::time;
-use script_traits::AnimationState;
-use std::sync::mpsc::Sender;
-use util::opts;
-use windowing::WindowEvent;
-
-/// Starts the compositor, which listens for messages on the specified port.
-///
-/// This is the null compositor which doesn't draw anything to the screen.
-/// It's intended for headless testing.
-pub struct NullCompositor {
- /// The port on which we receive messages.
- pub port: Box<CompositorReceiver>,
- /// A channel to the constellation.
- constellation_chan: Sender<ConstellationMsg>,
- /// A channel to the time profiler.
- time_profiler_chan: time::ProfilerChan,
- /// A channel to the memory profiler.
- mem_profiler_chan: mem::ProfilerChan,
-}
-
-impl NullCompositor {
- fn new(state: InitialCompositorState) -> NullCompositor {
- NullCompositor {
- port: state.receiver,
- constellation_chan: state.constellation_chan,
- time_profiler_chan: state.time_profiler_chan,
- mem_profiler_chan: state.mem_profiler_chan,
- }
- }
-
- pub fn create(state: InitialCompositorState) -> NullCompositor {
- let compositor = NullCompositor::new(state);
-
- // Tell the constellation about the initial fake size.
- {
- compositor.constellation_chan.send(ConstellationMsg::ResizedWindow(WindowSizeData {
- initial_viewport: Size2D::typed(800_f32, 600_f32),
- visible_viewport: Size2D::typed(800_f32, 600_f32),
- device_pixel_ratio:
- ScaleFactor::new(opts::get().device_pixels_per_px.unwrap_or(1.0)),
- })).unwrap();
- }
-
- compositor
- }
-}
-
-impl CompositorEventListener for NullCompositor {
- fn handle_events(&mut self, _: Vec<WindowEvent>) -> bool {
- match self.port.recv_compositor_msg() {
- Msg::Exit(chan) => {
- debug!("shutting down the constellation");
- self.constellation_chan.send(ConstellationMsg::Exit).unwrap();
- chan.send(()).unwrap();
- }
-
- Msg::ShutdownComplete => {
- debug!("constellation completed shutdown");
-
- // Drain compositor port, sometimes messages contain channels that are blocking
- // another thread from finishing (i.e. SetIds)
- while self.port.try_recv_compositor_msg().is_some() {}
-
- self.time_profiler_chan.send(time::ProfilerMsg::Exit);
- self.mem_profiler_chan.send(mem::ProfilerMsg::Exit);
-
- return false
- }
-
- Msg::GetNativeDisplay(chan) => {
- chan.send(None).unwrap();
- }
-
- Msg::SetFrameTree(_, response_chan, _) => {
- response_chan.send(()).unwrap();
- }
-
- Msg::GetClientWindow(send) => {
- let rect = (Size2D::zero(), Point2D::zero());
- send.send(rect).unwrap();
- }
-
- Msg::ChangeRunningAnimationsState(pipeline_id, animation_state) => {
- match animation_state {
- AnimationState::AnimationsPresent |
- AnimationState::NoAnimationsPresent |
- AnimationState::NoAnimationCallbacksPresent => {}
- AnimationState::AnimationCallbacksPresent => {
- let msg = ConstellationMsg::TickAnimation(pipeline_id, AnimationTickType::Script);
- self.constellation_chan.send(msg).unwrap()
- }
- }
- }
-
- // Explicitly list ignored messages so that when we add a new one,
- // we'll notice and think about whether it needs a response, like
- // SetFrameTree.
-
- Msg::InitializeLayersForPipeline(..) |
- Msg::AssignPaintedBuffers(..) |
- Msg::ScrollFragmentPoint(..) |
- Msg::Status(..) |
- Msg::LoadStart(..) |
- Msg::LoadComplete(..) |
- Msg::DelayedCompositionTimeout(..) |
- Msg::Recomposite(..) |
- Msg::ChangePageTitle(..) |
- Msg::ChangePageUrl(..) |
- Msg::KeyEvent(..) |
- Msg::TouchEventProcessed(..) |
- Msg::SetCursor(..) |
- Msg::ViewportConstrained(..) => {}
- Msg::CreatePng(..) |
- Msg::PaintThreadExited(..) |
- Msg::MoveTo(..) |
- Msg::ResizeTo(..) |
- Msg::IsReadyToSaveImageReply(..) => {}
- Msg::NewFavicon(..) => {}
- Msg::HeadParsed => {}
- Msg::ReturnUnusedNativeSurfaces(..) => {}
- Msg::CollectMemoryReports(..) => {}
- Msg::PipelineExited(..) => {}
- }
- true
- }
-
- fn repaint_synchronously(&mut self) {}
-
- fn pinch_zoom_level(&self) -> f32 {
- 1.0
- }
-
- fn title_for_main_frame(&self) {}
-}
diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs
index c5fc7537e0a..d72c2bace6c 100644
--- a/components/compositing/lib.rs
+++ b/components/compositing/lib.rs
@@ -68,7 +68,6 @@ mod compositor_layer;
pub mod compositor_thread;
pub mod constellation;
mod delayed_composition;
-mod headless;
pub mod pipeline;
#[cfg(not(target_os = "windows"))]
pub mod sandboxing;
diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs
index bbf892048c8..40b1a2baa6a 100644
--- a/components/compositing/pipeline.rs
+++ b/components/compositing/pipeline.rs
@@ -28,13 +28,13 @@ use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg};
use script_traits::{ScriptToCompositorMsg, ScriptThreadFactory, TimerEventRequest};
use std::mem;
use std::sync::mpsc::{Receiver, Sender, channel};
-use std::thread;
use url::Url;
use util;
use util::geometry::{PagePx, ViewportPx};
use util::ipc::OptionalIpcSender;
use util::opts::{self, Opts};
use util::prefs;
+use util::thread;
use webrender_traits;
/// A uniquely-identifiable pipeline of script thread, layout thread, and paint thread.
@@ -290,6 +290,13 @@ impl Pipeline {
pub fn exit(&self) {
debug!("pipeline {:?} exiting", self.id);
+ // The compositor wants to know when pipelines shut down too.
+ // It may still have messages to process from these other threads
+ // before they can be safely shut down.
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.compositor_proxy.send(CompositorMsg::PipelineExited(self.id, sender));
+ receiver.recv().unwrap();
+
// Script thread handles shutting down layout, and layout handles shutting down the painter.
// For now, if the script thread has failed, we give up on clean shutdown.
if self.script_chan
@@ -300,9 +307,6 @@ impl Pipeline {
let _ = self.paint_shutdown_port.recv();
let _ = self.layout_shutdown_port.recv();
}
-
- // The compositor wants to know when pipelines shut down too.
- self.compositor_proxy.send(CompositorMsg::PipelineExited(self.id))
}
pub fn freeze(&self) {
@@ -472,7 +476,7 @@ impl PrivilegedPipelineContent {
let compositor_proxy_for_script_listener_thread =
self.compositor_proxy.clone_compositor_proxy();
let script_to_compositor_port = self.script_to_compositor_port;
- thread::spawn(move || {
+ thread::spawn_named("CompositorScriptListener".to_owned(), move || {
compositor_thread::run_script_listener_thread(
compositor_proxy_for_script_listener_thread,
script_to_compositor_port)
diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs
index 02eda99b521..8719db56a03 100644
--- a/components/compositing/windowing.rs
+++ b/components/compositing/windowing.rs
@@ -15,7 +15,6 @@ use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use net_traits::net_error_list::NetError;
use script_traits::{MouseButton, TouchEventType, TouchId};
use std::fmt::{Debug, Error, Formatter};
-use std::rc::Rc;
use style_traits::cursor::Cursor;
use url::Url;
use util::geometry::ScreenPx;
@@ -142,7 +141,7 @@ pub trait WindowMethods {
///
/// This is part of the windowing system because its implementation often involves OS-specific
/// magic to wake the up window's event loop.
- fn create_compositor_channel(_: &Option<Rc<Self>>)
+ fn create_compositor_channel(&self)
-> (Box<CompositorProxy + Send>, Box<CompositorReceiver>);
/// Requests that the window system prepare a composite. Typically this will involve making