diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index ca0b8e82001..99fc2575747 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -49,6 +49,7 @@ use time::{precise_time_ns, precise_time_s}; use url::Url; use util::geometry::{PagePx, ScreenPx, ViewportPx}; use util::opts; +use util::print_tree::PrintTree; use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg}; const BUFFER_MAP_SIZE: usize = 10000000; @@ -389,6 +390,7 @@ impl IOCompositor { } self.send_buffer_requests_for_all_layers(); + self.dump_layer_tree(); } (Msg::GetNativeDisplay(chan), @@ -876,6 +878,8 @@ impl IOCompositor { self.pending_subpages.insert(subpage_pipeline_id); } } + + self.dump_layer_tree(); } fn send_window_size(&self) { @@ -1573,6 +1577,7 @@ impl IOCompositor { profile(ProfilerCategory::Compositing, None, self.time_profiler_chan.clone(), || { debug!("compositor: compositing"); + self.dump_layer_tree(); // Adjust the layer dimensions as necessary to correspond to the size of the window. self.scene.viewport = Rect { origin: Point2D::zero(), @@ -1750,28 +1755,63 @@ impl IOCompositor { #[allow(dead_code)] fn dump_layer_tree(&self) { + if !opts::get().dump_layer_tree { + return; + } + + let mut print_tree = PrintTree::new("Layer tree".to_owned()); if let Some(ref layer) = self.scene.root { - println!("Layer tree:"); - self.dump_layer_tree_with_indent(&**layer, 0); + self.dump_layer_tree_layer(&**layer, &mut print_tree); } } #[allow(dead_code)] - fn dump_layer_tree_with_indent(&self, layer: &Layer, level: u32) { - let mut indentation = String::new(); - for _ in 0..level { - indentation.push_str(" "); - } + fn dump_layer_tree_layer(&self, layer: &Layer, print_tree: &mut PrintTree) { + let data = layer.extra_data.borrow(); + let layer_string = if data.id == LayerId::null() { + format!("Root Layer (pipeline={})", data.pipeline_id) + } else { + "Layer".to_owned() + }; - println!("{}Layer {:x}: {:?} @ {:?} masks to bounds: {:?} establishes 3D context: {:?}", - indentation, - layer as *const _ as usize, - layer.extra_data, - *layer.bounds.borrow(), - *layer.masks_to_bounds.borrow(), - layer.establishes_3d_context); - for kid in &*layer.children() { - self.dump_layer_tree_with_indent(&**kid, level + 1) + let masks_string = if *layer.masks_to_bounds.borrow() { + " (masks children)" + } else { + "" + }; + + let establishes_3d_context_string = if layer.establishes_3d_context { + " (3D context)" + } else { + "" + }; + + let fixed_string = if data.scroll_policy == ScrollPolicy::FixedPosition { + " (fixed)" + } else { + "" + }; + + let layer_string = format!("{} ({:?}) ({},{} at {},{}){}{}{}", + layer_string, + layer.extra_data.borrow().id, + (*layer.bounds.borrow()).size.to_untyped().width, + (*layer.bounds.borrow()).size.to_untyped().height, + (*layer.bounds.borrow()).origin.to_untyped().x, + (*layer.bounds.borrow()).origin.to_untyped().y, + masks_string, + establishes_3d_context_string, + fixed_string); + + let children = layer.children(); + if !children.is_empty() { + print_tree.new_level(layer_string); + for kid in &*children { + self.dump_layer_tree_layer(&**kid, print_tree); + } + print_tree.end_level(); + } else { + print_tree.add_item(layer_string); } } } diff --git a/components/util/opts.rs b/components/util/opts.rs index 01dfee39491..0454aa78da0 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -150,6 +150,9 @@ pub struct Opts { /// Dumps the display list after optimization (post layout, at painting time). pub dump_display_list_optimized: bool, + /// Dumps the layer tree when it changes. + pub dump_layer_tree: bool, + /// Emits notifications when there is a relayout. pub relayout_event: bool, @@ -205,6 +208,9 @@ pub struct DebugOptions { /// Print optimized display list (at paint time). pub dump_display_list_optimized: bool, + /// Print the layer tree whenever it changes. + pub dump_layer_tree: bool, + /// Print notifications when there is a relayout. pub relayout_event: bool, @@ -264,6 +270,7 @@ impl DebugOptions { "dump-display-list" => debug_options.dump_display_list = true, "dump-display-list-json" => debug_options.dump_display_list_json = true, "dump-display-list-optimized" => debug_options.dump_display_list_optimized = true, + "dump-layer-tree" => debug_options.dump_layer_tree = true, "relayout-event" => debug_options.relayout_event = true, "profile-tasks" => debug_options.profile_tasks = true, "profile-script-events" => debug_options.profile_script_events = true, @@ -406,6 +413,7 @@ pub fn default_opts() -> Opts { dump_display_list: false, dump_display_list_json: false, dump_display_list_optimized: false, + dump_layer_tree: false, relayout_event: false, validate_display_list_geometry: false, profile_tasks: false, @@ -613,6 +621,7 @@ pub fn from_cmdline_args(args: &[String]) { dump_display_list: debug_options.dump_display_list, dump_display_list_json: debug_options.dump_display_list_json, dump_display_list_optimized: debug_options.dump_display_list_optimized, + dump_layer_tree: debug_options.dump_layer_tree, relayout_event: debug_options.relayout_event, validate_display_list_geometry: debug_options.validate_display_list_geometry, sniff_mime_types: opt_match.opt_present("sniff-mime-types"),