mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 01:35:35 +00:00
servo: Merge #7913 - Simplify and unify compositor shutdown code paths (from mrobinson:compositor-shutdown); r=pcwalton
Unify all compositor shutdown code paths into two methods, one which starts the shutdown and the other that finishes it. This simplifies the way the compositor shuts down and prevents "leaking" pixmaps when exiting in uncommon ways. Source-Repo: https://github.com/servo/servo Source-Revision: 26dd1233103eb75c2e94fcc2ba34c18fa4432afc
This commit is contained in:
parent
9a3c41dbd9
commit
2bdc604c66
@ -155,9 +155,6 @@ pub struct IOCompositor<Window: WindowMethods> {
|
|||||||
/// Pending scroll events.
|
/// Pending scroll events.
|
||||||
pending_scroll_events: Vec<ScrollEvent>,
|
pending_scroll_events: Vec<ScrollEvent>,
|
||||||
|
|
||||||
/// Has a Quit event been seen?
|
|
||||||
has_seen_quit_event: bool,
|
|
||||||
|
|
||||||
/// Used by the logic that determines when it is safe to output an
|
/// Used by the logic that determines when it is safe to output an
|
||||||
/// image for the reftest framework.
|
/// image for the reftest framework.
|
||||||
ready_to_save_state: ReadyState,
|
ready_to_save_state: ReadyState,
|
||||||
@ -309,7 +306,6 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||||||
mem_profiler_chan: state.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,
|
|
||||||
ready_to_save_state: ReadyState::Unknown,
|
ready_to_save_state: ReadyState::Unknown,
|
||||||
surface_map: SurfaceMap::new(BUFFER_MAP_SIZE),
|
surface_map: SurfaceMap::new(BUFFER_MAP_SIZE),
|
||||||
pending_subpages: HashSet::new(),
|
pending_subpages: HashSet::new(),
|
||||||
@ -329,25 +325,48 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||||||
compositor
|
compositor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn start_shutting_down(&mut self) {
|
||||||
|
debug!("Compositor sending Exit message to Constellation");
|
||||||
|
let ConstellationChan(ref constellation_channel) = self.constellation_chan;
|
||||||
|
constellation_channel.send(ConstellationMsg::Exit).unwrap();
|
||||||
|
|
||||||
|
self.mem_profiler_chan.send(mem::ProfilerMsg::UnregisterReporter(reporter_name()));
|
||||||
|
|
||||||
|
self.shutdown_state = ShutdownState::ShuttingDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish_shutting_down(&mut self) {
|
||||||
|
debug!("Compositor received message that constellation shutdown is complete");
|
||||||
|
|
||||||
|
// Clear out the compositor layers so that painting tasks can destroy the buffers.
|
||||||
|
if let Some(ref root_layer) = self.scene.root {
|
||||||
|
root_layer.forget_all_tiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drain compositor port, sometimes messages contain channels that are blocking
|
||||||
|
// another task from finishing (i.e. SetFrameTree).
|
||||||
|
while self.port.try_recv_compositor_msg().is_some() {}
|
||||||
|
|
||||||
|
// Tell the profiler, memory profiler, and scrolling timer to shut down.
|
||||||
|
self.time_profiler_chan.send(time::ProfilerMsg::Exit);
|
||||||
|
self.mem_profiler_chan.send(mem::ProfilerMsg::Exit);
|
||||||
|
self.scrolling_timer.shutdown();
|
||||||
|
|
||||||
|
self.shutdown_state = ShutdownState::FinishedShuttingDown;
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_browser_message(&mut self, msg: Msg) -> bool {
|
fn handle_browser_message(&mut self, msg: Msg) -> bool {
|
||||||
match (msg, self.shutdown_state) {
|
match (msg, self.shutdown_state) {
|
||||||
(_, ShutdownState::FinishedShuttingDown) =>
|
(_, ShutdownState::FinishedShuttingDown) =>
|
||||||
panic!("compositor shouldn't be handling messages after shutting down"),
|
panic!("compositor shouldn't be handling messages after shutting down"),
|
||||||
|
|
||||||
(Msg::Exit(chan), _) => {
|
(Msg::Exit(channel), _) => {
|
||||||
debug!("shutting down the constellation");
|
self.start_shutting_down();
|
||||||
let ConstellationChan(ref con_chan) = self.constellation_chan;
|
channel.send(()).unwrap();
|
||||||
con_chan.send(ConstellationMsg::Exit).unwrap();
|
|
||||||
chan.send(()).unwrap();
|
|
||||||
|
|
||||||
self.mem_profiler_chan.send(mem::ProfilerMsg::UnregisterReporter(reporter_name()));
|
|
||||||
|
|
||||||
self.shutdown_state = ShutdownState::ShuttingDown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(Msg::ShutdownComplete, _) => {
|
(Msg::ShutdownComplete, _) => {
|
||||||
debug!("constellation completed shutdown");
|
self.finish_shutting_down();
|
||||||
self.shutdown_state = ShutdownState::FinishedShuttingDown;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1010,12 +1029,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WindowEvent::Quit => {
|
WindowEvent::Quit => {
|
||||||
if !self.has_seen_quit_event {
|
if self.shutdown_state == ShutdownState::NotShuttingDown {
|
||||||
self.has_seen_quit_event = true;
|
debug!("Shutting down the constellation for WindowEvent::Quit");
|
||||||
debug!("shutting down the constellation for WindowEvent::Quit");
|
self.start_shutting_down();
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
|
||||||
chan.send(ConstellationMsg::Exit).unwrap();
|
|
||||||
self.shutdown_state = ShutdownState::ShuttingDown;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1495,10 +1511,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||||||
let composited = self.composite_specific_target(target);
|
let composited = self.composite_specific_target(target);
|
||||||
if composited.is_ok() &&
|
if composited.is_ok() &&
|
||||||
(opts::get().output_file.is_some() || opts::get().exit_after_load) {
|
(opts::get().output_file.is_some() || opts::get().exit_after_load) {
|
||||||
debug!("shutting down the constellation (after generating an output file or exit flag specified)");
|
debug!("Shutting down the Constellation after generating an output file or exit flag specified");
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
self.start_shutting_down();
|
||||||
chan.send(ConstellationMsg::Exit).unwrap();
|
|
||||||
self.shutdown_state = ShutdownState::ShuttingDown;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1807,9 +1821,6 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.shutdown_state == ShutdownState::FinishedShuttingDown {
|
if self.shutdown_state == ShutdownState::FinishedShuttingDown {
|
||||||
// We have exited the compositor and passing window
|
|
||||||
// messages to script may crash.
|
|
||||||
debug!("Exiting the compositor due to a request from script.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1858,23 +1869,6 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown(&mut self) {
|
|
||||||
// Clear out the compositor layers so that painting tasks can destroy the buffers.
|
|
||||||
match self.scene.root {
|
|
||||||
None => {}
|
|
||||||
Some(ref layer) => layer.forget_all_tiles(),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drain compositor port, sometimes messages contain channels that are blocking
|
|
||||||
// another task from finishing (i.e. SetFrameTree).
|
|
||||||
while self.port.try_recv_compositor_msg().is_some() {}
|
|
||||||
|
|
||||||
// Tell the profiler, memory profiler, and scrolling timer to shut down.
|
|
||||||
self.time_profiler_chan.send(time::ProfilerMsg::Exit);
|
|
||||||
self.mem_profiler_chan.send(mem::ProfilerMsg::Exit);
|
|
||||||
self.scrolling_timer.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pinch_zoom_level(&self) -> f32 {
|
fn pinch_zoom_level(&self) -> f32 {
|
||||||
self.viewport_zoom.get() as f32
|
self.viewport_zoom.get() as f32
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,6 @@ impl CompositorTask {
|
|||||||
pub trait CompositorEventListener {
|
pub trait CompositorEventListener {
|
||||||
fn handle_events(&mut self, events: Vec<WindowEvent>) -> bool;
|
fn handle_events(&mut self, events: Vec<WindowEvent>) -> bool;
|
||||||
fn repaint_synchronously(&mut self);
|
fn repaint_synchronously(&mut self);
|
||||||
fn shutdown(&mut self);
|
|
||||||
fn pinch_zoom_level(&self) -> f32;
|
fn pinch_zoom_level(&self) -> f32;
|
||||||
/// 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);
|
||||||
|
@ -69,6 +69,14 @@ impl CompositorEventListener for NullCompositor {
|
|||||||
|
|
||||||
Msg::ShutdownComplete => {
|
Msg::ShutdownComplete => {
|
||||||
debug!("constellation completed shutdown");
|
debug!("constellation completed shutdown");
|
||||||
|
|
||||||
|
// Drain compositor port, sometimes messages contain channels that are blocking
|
||||||
|
// another task 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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,15 +138,6 @@ impl CompositorEventListener for NullCompositor {
|
|||||||
|
|
||||||
fn repaint_synchronously(&mut self) {}
|
fn repaint_synchronously(&mut self) {}
|
||||||
|
|
||||||
fn shutdown(&mut self) {
|
|
||||||
// Drain compositor port, sometimes messages contain channels that are blocking
|
|
||||||
// another task 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pinch_zoom_level(&self) -> f32 {
|
fn pinch_zoom_level(&self) -> f32 {
|
||||||
1.0
|
1.0
|
||||||
}
|
}
|
||||||
|
@ -186,10 +186,6 @@ impl Browser {
|
|||||||
pub fn request_title_for_main_frame(&self) {
|
pub fn request_title_for_main_frame(&self) {
|
||||||
self.compositor.title_for_main_frame()
|
self.compositor.title_for_main_frame()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shutdown(mut self) {
|
|
||||||
self.compositor.shutdown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_constellation(opts: opts::Opts,
|
fn create_constellation(opts: opts::Opts,
|
||||||
|
@ -75,11 +75,6 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
maybe_unregister_glutin_resize_handler(&window);
|
maybe_unregister_glutin_resize_handler(&window);
|
||||||
|
|
||||||
let BrowserWrapper {
|
|
||||||
browser
|
|
||||||
} = browser;
|
|
||||||
browser.shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_register_glutin_resize_handler(window: &Option<Rc<app::window::Window>>,
|
fn maybe_register_glutin_resize_handler(window: &Option<Rc<app::window::Window>>,
|
||||||
|
@ -98,9 +98,4 @@ fn main() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let BrowserWrapper {
|
|
||||||
browser
|
|
||||||
} = browser;
|
|
||||||
browser.shutdown();
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user