mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Auto merge of #6640 - mrobinson:memory-profiling-for-compositor, r=nnethercote
Add memory profiling for the compositor task Currently only the BufferMap is recorded, but a later change will also measure the memory usage of the compositor tree. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6640) <!-- Reviewable:end -->
This commit is contained in:
commit
3f69eadc0d
10 changed files with 54 additions and 12 deletions
|
@ -243,6 +243,10 @@ fn initialize_png(width: usize, height: usize) -> (Vec<gl::GLuint>, Vec<gl::GLui
|
||||||
(framebuffer_ids, texture_ids)
|
(framebuffer_ids, texture_ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reporter_name() -> String {
|
||||||
|
"compositor-reporter".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
impl<Window: WindowMethods> IOCompositor<Window> {
|
impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
fn new(window: Rc<Window>,
|
fn new(window: Rc<Window>,
|
||||||
sender: Box<CompositorProxy+Send>,
|
sender: Box<CompositorProxy+Send>,
|
||||||
|
@ -251,10 +255,11 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
mem_profiler_chan: mem::ProfilerChan)
|
mem_profiler_chan: mem::ProfilerChan)
|
||||||
-> IOCompositor<Window> {
|
-> IOCompositor<Window> {
|
||||||
// Create an initial layer tree.
|
|
||||||
//
|
// Register this thread as a memory reporter, via its own channel.
|
||||||
// TODO: There should be no initial layer tree until the painter creates one from the
|
let reporter = box CompositorMemoryReporter(sender.clone_compositor_proxy());
|
||||||
// display list. This is only here because we don't have that logic in the painter yet.
|
mem_profiler_chan.send(mem::ProfilerMsg::RegisterReporter(reporter_name(), reporter));
|
||||||
|
|
||||||
let window_size = window.framebuffer_size();
|
let window_size = window.framebuffer_size();
|
||||||
let hidpi_factor = window.hidpi_factor();
|
let hidpi_factor = window.hidpi_factor();
|
||||||
let composite_target = match opts::get().output_file {
|
let composite_target = match opts::get().output_file {
|
||||||
|
@ -333,6 +338,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
let ConstellationChan(ref con_chan) = self.constellation_chan;
|
let ConstellationChan(ref con_chan) = self.constellation_chan;
|
||||||
con_chan.send(ConstellationMsg::Exit).unwrap();
|
con_chan.send(ConstellationMsg::Exit).unwrap();
|
||||||
chan.send(()).unwrap();
|
chan.send(()).unwrap();
|
||||||
|
|
||||||
|
self.mem_profiler_chan.send(mem::ProfilerMsg::UnregisterReporter(reporter_name()));
|
||||||
|
|
||||||
self.shutdown_state = ShutdownState::ShuttingDown;
|
self.shutdown_state = ShutdownState::ShuttingDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,6 +490,18 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
self.window.head_parsed();
|
self.window.head_parsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(Msg::CollectMemoryReports(reports_chan), ShutdownState::NotShuttingDown) => {
|
||||||
|
let mut reports = vec![];
|
||||||
|
let name = "compositor-task";
|
||||||
|
reports.push(mem::Report {
|
||||||
|
path: path![name, "buffer-map"], size: self.buffer_map.mem(),
|
||||||
|
});
|
||||||
|
reports.push(mem::Report {
|
||||||
|
path: path![name, "layer-tree"], size: self.scene.get_memory_usage(),
|
||||||
|
});
|
||||||
|
reports_chan.send(reports);
|
||||||
|
}
|
||||||
|
|
||||||
// When we are shutting_down, we need to avoid performing operations
|
// When we are shutting_down, we need to avoid performing operations
|
||||||
// such as Paint that may crash because we have begun tearing down
|
// such as Paint that may crash because we have begun tearing down
|
||||||
// the rest of our resources.
|
// the rest of our resources.
|
||||||
|
@ -1702,3 +1722,20 @@ pub enum CompositingReason {
|
||||||
/// The window has been zoomed.
|
/// The window has been zoomed.
|
||||||
Zoom,
|
Zoom,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CompositorMemoryReporter(Box<CompositorProxy+'static+Send>);
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ use util::cursor::Cursor;
|
||||||
/// process, and so forth.
|
/// process, and so forth.
|
||||||
pub trait CompositorProxy : 'static + Send {
|
pub trait CompositorProxy : 'static + Send {
|
||||||
/// Sends a message to the compositor.
|
/// Sends a message to the compositor.
|
||||||
fn send(&mut self, msg: Msg);
|
fn send(&self, msg: Msg);
|
||||||
/// Clones the compositor proxy.
|
/// Clones the compositor proxy.
|
||||||
fn clone_compositor_proxy(&self) -> Box<CompositorProxy+'static+Send>;
|
fn clone_compositor_proxy(&self) -> Box<CompositorProxy+'static+Send>;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ impl CompositorReceiver for Receiver<Msg> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_script_listener_thread(mut compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
pub fn run_script_listener_thread(compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
||||||
receiver: IpcReceiver<ScriptToCompositorMsg>) {
|
receiver: IpcReceiver<ScriptToCompositorMsg>) {
|
||||||
while let Ok(msg) = receiver.recv() {
|
while let Ok(msg) = receiver.recv() {
|
||||||
match msg {
|
match msg {
|
||||||
|
@ -197,6 +197,8 @@ pub enum Msg {
|
||||||
/// Signal that the paint task ignored the paint requests that carried
|
/// 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.
|
/// these layer buffers, so that they can be re-added to the surface cache.
|
||||||
ReturnUnusedLayerBuffers(Vec<Box<LayerBuffer>>),
|
ReturnUnusedLayerBuffers(Vec<Box<LayerBuffer>>),
|
||||||
|
/// Collect memory reports and send them back to the given mem::ReportsChan.
|
||||||
|
CollectMemoryReports(mem::ReportsChan),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Msg {
|
impl Debug for Msg {
|
||||||
|
@ -226,6 +228,7 @@ impl Debug for Msg {
|
||||||
Msg::NewFavicon(..) => write!(f, "NewFavicon"),
|
Msg::NewFavicon(..) => write!(f, "NewFavicon"),
|
||||||
Msg::HeadParsed => write!(f, "HeadParsed"),
|
Msg::HeadParsed => write!(f, "HeadParsed"),
|
||||||
Msg::ReturnUnusedLayerBuffers(..) => write!(f, "ReturnUnusedLayerBuffers"),
|
Msg::ReturnUnusedLayerBuffers(..) => write!(f, "ReturnUnusedLayerBuffers"),
|
||||||
|
Msg::CollectMemoryReports(..) => write!(f, "CollectMemoryReports"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,7 @@ impl CompositorEventListener for NullCompositor {
|
||||||
Msg::NewFavicon(..) => {}
|
Msg::NewFavicon(..) => {}
|
||||||
Msg::HeadParsed => {}
|
Msg::HeadParsed => {}
|
||||||
Msg::ReturnUnusedLayerBuffers(..) => {}
|
Msg::ReturnUnusedLayerBuffers(..) => {}
|
||||||
|
Msg::CollectMemoryReports(..) => {}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ extern crate script_traits;
|
||||||
extern crate msg;
|
extern crate msg;
|
||||||
extern crate net;
|
extern crate net;
|
||||||
extern crate num;
|
extern crate num;
|
||||||
|
#[macro_use]
|
||||||
extern crate profile_traits;
|
extern crate profile_traits;
|
||||||
extern crate net_traits;
|
extern crate net_traits;
|
||||||
extern crate gfx_traits;
|
extern crate gfx_traits;
|
||||||
|
|
2
components/servo/Cargo.lock
generated
2
components/servo/Cargo.lock
generated
|
@ -679,7 +679,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "layers"
|
name = "layers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/rust-layers#abc4f3803dde8d818343984a28d2e3d1fdad11a3"
|
source = "git+https://github.com/servo/rust-layers#1c9628618803c161753fd9f00f5ef781660ce11e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
|
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
|
||||||
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
2
ports/cef/Cargo.lock
generated
2
ports/cef/Cargo.lock
generated
|
@ -671,7 +671,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "layers"
|
name = "layers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/rust-layers#abc4f3803dde8d818343984a28d2e3d1fdad11a3"
|
source = "git+https://github.com/servo/rust-layers#1c9628618803c161753fd9f00f5ef781660ce11e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
|
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
|
||||||
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -474,7 +474,7 @@ struct CefCompositorProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompositorProxy for 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();
|
self.sender.send(msg).unwrap();
|
||||||
app_wakeup();
|
app_wakeup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -805,7 +805,7 @@ struct GlutinCompositorProxy {
|
||||||
unsafe impl Send for GlutinCompositorProxy {}
|
unsafe impl Send for GlutinCompositorProxy {}
|
||||||
|
|
||||||
impl CompositorProxy 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.
|
// Send a message and kick the OS event loop awake.
|
||||||
self.sender.send(msg).unwrap();
|
self.sender.send(msg).unwrap();
|
||||||
if let Some(ref window_proxy) = self.window_proxy {
|
if let Some(ref window_proxy) = self.window_proxy {
|
||||||
|
|
2
ports/gonk/Cargo.lock
generated
2
ports/gonk/Cargo.lock
generated
|
@ -605,7 +605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "layers"
|
name = "layers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/rust-layers#abc4f3803dde8d818343984a28d2e3d1fdad11a3"
|
source = "git+https://github.com/servo/rust-layers#1c9628618803c161753fd9f00f5ef781660ce11e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
|
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
|
||||||
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cgl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -857,7 +857,7 @@ struct GonkCompositorProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompositorProxy for 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.
|
// Send a message and kick the OS event loop awake.
|
||||||
self.sender.send(msg).ok().unwrap();
|
self.sender.send(msg).ok().unwrap();
|
||||||
self.event_sender.send(WindowEvent::Idle).ok().unwrap();
|
self.event_sender.send(WindowEvent::Idle).ok().unwrap();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue