diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 0f397a7d4f7..75bd9a3f6ca 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -243,6 +243,10 @@ fn initialize_png(width: usize, height: usize) -> (Vec, Vec String { + "compositor-reporter".to_string() +} + impl IOCompositor { fn new(window: Rc, sender: Box, @@ -251,10 +255,11 @@ impl IOCompositor { time_profiler_chan: time::ProfilerChan, mem_profiler_chan: mem::ProfilerChan) -> IOCompositor { - // Create an initial layer tree. - // - // TODO: There should be no initial layer tree until the painter creates one from the - // display list. This is only here because we don't have that logic in the painter yet. + + // Register this thread as a memory reporter, via its own channel. + let reporter = box CompositorMemoryReporter(sender.clone_compositor_proxy()); + mem_profiler_chan.send(mem::ProfilerMsg::RegisterReporter(reporter_name(), reporter)); + let window_size = window.framebuffer_size(); let hidpi_factor = window.hidpi_factor(); let composite_target = match opts::get().output_file { @@ -333,6 +338,9 @@ impl IOCompositor { let ConstellationChan(ref con_chan) = self.constellation_chan; con_chan.send(ConstellationMsg::Exit).unwrap(); chan.send(()).unwrap(); + + self.mem_profiler_chan.send(mem::ProfilerMsg::UnregisterReporter(reporter_name())); + self.shutdown_state = ShutdownState::ShuttingDown; } @@ -482,6 +490,15 @@ impl IOCompositor { self.window.head_parsed(); } + (Msg::CollectMemoryReports(reports_chan), ShutdownState::NotShuttingDown) => { + let mut reports = vec![]; + reports.push(mem::Report { + path: path!["compositor-task", "buffer-map"], + size: self.buffer_map.mem(), + }); + reports_chan.send(reports); + } + // When we are shutting_down, we need to avoid performing operations // such as Paint that may crash because we have begun tearing down // the rest of our resources. @@ -1696,3 +1713,20 @@ pub enum CompositingReason { /// The window has been zoomed. Zoom, } + +struct CompositorMemoryReporter(Box); + +impl CompositorMemoryReporter { + pub fn send(&self, message: Msg) { + let CompositorMemoryReporter(ref proxy) = *self; + proxy.send(message); + } +} + +impl mem::Reporter for CompositorMemoryReporter { + fn collect_reports(&self, reports_chan: mem::ReportsChan) -> bool { + // FIXME(mrobinson): The port should probably return the success of the message here. + self.send(Msg::CollectMemoryReports(reports_chan)); + true + } +} diff --git a/components/compositing/compositor_task.rs b/components/compositing/compositor_task.rs index d8ada04bbdf..07777992541 100644 --- a/components/compositing/compositor_task.rs +++ b/components/compositing/compositor_task.rs @@ -35,7 +35,7 @@ use util::cursor::Cursor; /// process, and so forth. pub trait CompositorProxy : 'static + Send { /// Sends a message to the compositor. - fn send(&mut self, msg: Msg); + fn send(&self, msg: Msg); /// Clones the compositor proxy. fn clone_compositor_proxy(&self) -> Box; } @@ -62,7 +62,7 @@ impl CompositorReceiver for Receiver { } } -pub fn run_script_listener_thread(mut compositor_proxy: Box, +pub fn run_script_listener_thread(compositor_proxy: Box, receiver: IpcReceiver) { while let Ok(msg) = receiver.recv() { match msg { @@ -197,6 +197,8 @@ pub enum Msg { /// Signal that the paint task ignored the paint requests that carried /// these layer buffers, so that they can be re-added to the surface cache. ReturnUnusedLayerBuffers(Vec>), + /// Collect memory reports and send them back to the given mem::ReportsChan. + CollectMemoryReports(mem::ReportsChan), } impl Debug for Msg { @@ -226,6 +228,7 @@ impl Debug for Msg { Msg::NewFavicon(..) => write!(f, "NewFavicon"), Msg::HeadParsed => write!(f, "HeadParsed"), Msg::ReturnUnusedLayerBuffers(..) => write!(f, "ReturnUnusedLayerBuffers"), + Msg::CollectMemoryReports(..) => write!(f, "CollectMemoryReports"), } } } diff --git a/components/compositing/headless.rs b/components/compositing/headless.rs index c4a4368d49b..6d2da22da43 100644 --- a/components/compositing/headless.rs +++ b/components/compositing/headless.rs @@ -112,6 +112,7 @@ impl CompositorEventListener for NullCompositor { Msg::NewFavicon(..) => {} Msg::HeadParsed => {} Msg::ReturnUnusedLayerBuffers(..) => {} + Msg::CollectMemoryReports(..) => {} } true } diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index a9cb24eeb8d..ef27074c96d 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -22,6 +22,7 @@ extern crate script_traits; extern crate msg; extern crate net; extern crate num; +#[macro_use] extern crate profile_traits; extern crate net_traits; extern crate gfx_traits; diff --git a/ports/cef/window.rs b/ports/cef/window.rs index d12770e29b9..29177022469 100644 --- a/ports/cef/window.rs +++ b/ports/cef/window.rs @@ -474,7 +474,7 @@ struct CefCompositorProxy { } impl CompositorProxy for CefCompositorProxy { - fn send(&mut self, msg: compositor_task::Msg) { + fn send(&self, msg: compositor_task::Msg) { self.sender.send(msg).unwrap(); app_wakeup(); } diff --git a/ports/glutin/window.rs b/ports/glutin/window.rs index 6397abb1d1f..20af32e8781 100644 --- a/ports/glutin/window.rs +++ b/ports/glutin/window.rs @@ -805,7 +805,7 @@ struct GlutinCompositorProxy { unsafe impl Send for GlutinCompositorProxy {} impl CompositorProxy for GlutinCompositorProxy { - fn send(&mut self, msg: compositor_task::Msg) { + fn send(&self, msg: compositor_task::Msg) { // Send a message and kick the OS event loop awake. self.sender.send(msg).unwrap(); if let Some(ref window_proxy) = self.window_proxy { diff --git a/ports/gonk/src/window.rs b/ports/gonk/src/window.rs index 1e1b0965163..0d94ddaa7a4 100644 --- a/ports/gonk/src/window.rs +++ b/ports/gonk/src/window.rs @@ -857,7 +857,7 @@ struct GonkCompositorProxy { } impl CompositorProxy for GonkCompositorProxy { - fn send(&mut self, msg: compositor_task::Msg) { + fn send(&self, msg: compositor_task::Msg) { // Send a message and kick the OS event loop awake. self.sender.send(msg).ok().unwrap(); self.event_sender.send(WindowEvent::Idle).ok().unwrap();